“This is the 12th day of my participation in the First Challenge 2022. For details: First Challenge 2022.”
Writing in the front
- Recently in order to sort out the knowledge of JavaScript object-oriented, I have to say that object-oriented is still very classic programming paradigm
- Through the abstraction of things in the real world, the behavior and attributes of things are encapsulated and aggregated. When needed, an object can be directly instantiated and the program we want can be realized through the operation of the object
- Light said not practice false handle, direct use of object-oriented thought to achieve a snake small game
- For the sake of object-oriented elegance, the code in this article is written in native JavaScript
- Here’s how it looks:
- The snake head element defaults to green, the snake body element defaults to white, the food color is random, and the location is random
abstract
- What we want to achieve is: snake game
- mentioned
snake
That’s for surefood
和The snake
Two of the more obvious classes - Snakes need a place to move, so we can abstract another one
The map
类 - We are implementing a game. Does the main flow of the game need to be abstracted into a class?
- According to the idea of encapsulation advocated by object orientation, I think it is necessary
- Encapsulating the main flow of the game as a class makes our overall implementation clearer and the code elegant
- If, in the future, we want to change the snake game, all we need to do is replace this
games
This also shows that code that follows the object-oriented paradigm is easy to maintain
- To sum up, we need to implement four classes in order to implement snake games
-
The map class
-
Food class
-
snakes
-
games
-
Implement map class
- Obviously, the map class is responsible for rendering logic for all elements on the map
class Map {
/** * el represents the dom element of the map * rect cell width and height */
constructor({ el, rect }) {
this.el = el;
this.rect = rect || 10;
// Store snake and food location and color data
this.data = [];
this.rows = 0;
this.columns = 0;
this.adjustMap();
}
// Clear the map of element data
clear() {
this.data.length = 0;
}
// Determine if the incoming data already exists on the current map
check({ x, y }) {
return!!!!!this.data.find((i) = > {
i.x === x && i.y === y;
});
}
setData(newData) {
this.data = this.data.concat(newData);
}
adjustMap() {
const { el, rect } = this;
// The length and width of the cell
this.rows = Math.ceil(Map.getStyle(el, 'height') / rect);
this.columns = Math.ceil(Map.getStyle(el, 'width') / rect);
// Reverse the length and width of the map according to the grid
Map.setStyle(el, 'height'.this.rows * rect);
Map.setStyle(el, 'width'.this.columns * rect);
}
static getStyle(el, attr) {
return parseInt(getComputedStyle(el)[attr]);
}
static setStyle(el, attr, num) {
el.style[attr] = num + 'px';
}
// Render elements on the map
render() {
this.el.innerHTML = this.data
.map((i) = > {
return `
<span
style="position: absolute;
left: ${i.x * this.rect}px;
top: ${i.y * this.rect}px;
width: The ${this.rect}px;
height: The ${this.rect}px;
background: ${i.color}"
>
</span>
`;
})
.join(' '); }}Copy the code
Initialize the
- In the map above, we receive two parameters at initialization
- El is the DOM element of the map
- Rect, which represents the width and height of each cell in the map, defines each cell as a square for ease of calculation
- The rect by default
10px
- The rect by default
- Finally, initialize an array data to store the coordinate data of the snake body and the coordinate data of the food
Corrected map width and height in reverse
- Since recT may not fill the entire map in integer multiples when we sample the map, we need to implement a function that reverse-corrects the width and height of the map, as shown in the code
adjustMap
,getStyle
,setStyle
- Get the true width and height of the map based on the incoming EL, then divide by RECT to calculate the actual number of cells
- Then the width and height of the actual map can be calculated according to the number of cells and the size of incoming cells
Render elements on the map
- The implementation method is very simple, through the coordinate information of data in data, generate a SPAN label
- The tag string is then inserted into innerHTML of the map’S DOM element
summary
- So here, our map class is pretty much done
- As you can see from the code above, there are three more methods:
clear
,setData
,check
, did not mention - We implement it on demand, and we’ll come back to the usefulness of these methods as needed in a later article
- In order not to affect the reading experience, I will divide the implementation process of this demo into 4 articles, and the next one will implement the food category
The last
- That’s all for today’s sharing. Please leave your comments in the comments section
- If you think the article is good, I hope you don’t begrudge praise, everyone’s encouragement is the biggest power I share 🥰