DAY 16
1
Modern Web

# 前情提要

Day12 - 貪吃蛇篇：蛇的原理及資料結構規劃 我們有提到，蛇的身體是一個佇列(Queue)， 我們要用陣列搭配 push() 和 shift() 這兩個方法，來實現具有先進先出(FIFO, First-In-First-Out, FIFO)行為模式的陣列。push() 方法會將一或多個值加入至一個陣列中。shift() 方法會移除並回傳陣列的第一個元素。

``````const snake = {
x: 0,
y: 0,
},
body: [],
maxLength: 2,
direction: {
x: 1,
y: 0,
},
speed: SNAKE_INITIAL_SPEED,
};
``````

# 畫出蛇的身體

### 處理蛇的身體的資料

``````body = [ {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0} ];
``````

``````headPosition = {5, 0};
direction = {1, 0};
body = [ {0, 0}, {1, 0}, {2, 0}, {3, 0}, {4, 0} ];
maxLength = 5;
``````

``````headPosition = {6, 0};
direction = {1, 0};
body = [ {1, 0}, {2, 0}, {3, 0}, {4, 0}, {5, 0} ];
maxLength = 5;
``````

containers/SnakeGame/reducer.js

``````function snakeGameReducer(state = initialState, action) {
switch (action.type) {
case SET_SNAKE_MOVING: {
const direction = state.getIn(['snake', 'direction']);
const maxLength = state.getIn(['snake', 'maxLength']);
return state
.set('x', updatePosition(headPosition.get('x') + direction.get('x'))) // 新的頭的位置是舊的位置加上方向向量
)
// update snake body
.updateIn(['snake', 'body'], (body) => {
let updatedBody = body.push(fromJS({   // 把頭加入到 body 陣列來更新
}));
if (updatedBody.size > maxLength) {    // 若身體長度大於最大長度
updatedBody = updatedBody.shift(); // 從尾巴拿掉一個元素
}
return fromJS(updatedBody);
});
}
// ...
}
}
``````

### 地圖上畫出蛇的身體

``````const updateGameView = (snake, block) => {
if (snake.getIn(['headPosition', 'x']) === block.get('x') &&
return 'snake-game__map-block-item snake-game__draw-snake-body';
}
const snakeBody = snake.get('body');
if (snakeBody.size > 1) { // body 裡面有東西才需要畫身體
const found = snakeBody.find((bodyPos) => {
return bodyPos.get('x') === block.get('x') &&
bodyPos.get('y') === block.get('y');
});
// draw snake body
if (found) { // 若方格的位置等於身體的位置，就把身體畫出來，塗成白色
return 'snake-game__map-block-item snake-game__draw-snake-body';
}
}
return 'snake-game__map-block-item';
};
``````
``````<div className="snake-game__map-wrapper">
{
blocks.map((rows) => (
rows.map((block) => (
<div
key={block.get('id')}
className={updateGameView(snake, block)}
>
</div>
))
))
}
</div>
``````

Snake - Github