DAY 15
2
Modern Web

# 新增蛇的物件

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

# 在地圖上畫出蛇的頭

containers/SnakeGame/index.js 裡面，我們昨天使用迭代的方式把 30x30 的地圖方格一個一個畫出來，所以如果方格的座標位置跟蛇的頭的位置是一樣的，我就把那一格的顏色樣式給定`白色`，其餘的方格給他`黑色`

``````<div className="snake-game__map-wrapper">
{
blocks.map((rows) => (
rows.map((block) => (
<div
key={block.get('id')}
className={updateGameView(snake, block)}
>
</div>
))
))
}
</div>
``````

containers/SnakeGame/index.js

``````const updateGameView = (snake, block) => {
if (snake.getIn(['headPosition', 'x']) === block.get('x') &&
return 'snake-game__map-block-item snake-game__draw-snake-body';
}
return 'snake-game__map-block-item';
};
``````

containers/SnakeGame/Styled.js

``````.snake-game__map-block-item {
border: 1px solid black;
box-sizing: border-box;
}
.snake-game__draw-snake-body {
background: white;
transition: all 0.1s;
}
``````

# 讓頭動起來

MDN web doc - setInterval()
Window clearInterval() Method

containers/SnakeGame/index.js

``````componentDidMount() {
const {
snake,
handleOnSetSnakeMoving,
} = this.props;
gameInterval = setInterval(() => {
handleOnSetSnakeMoving()
}, snake.get('speed'));
}

componentWillUnmount() {
clearInterval(gameInterval);
}
``````
``````const mapDispatchToProps = dispatch => ({
handleOnSetSnakeMoving: () => dispatch(setSnakeMoving()),
});
``````

containers/SnakeGame/reducer.js

``````function snakeGameReducer(state = initialState, action) {
switch (action.type) {
case SET_SNAKE_MOVING: {
const direction = state.getIn(['snake', 'direction']);
return state
);
}

default:
return state;
}
}
``````

``````const updatePosition = (position) => {
if (position > GAME_WIDTH - 1) {
return 0;
} else if (position < 0) {
return GAME_WIDTH;
}
return position;
};
``````

# 事件處理 - 改變蛇的移動方向

``````document.addEventListener('keydown', this.handleOnKeyDown);
``````

``````document.removeEventListener('keydown', this.handleOnKeyDown);
``````

``````handleOnKeyDown = (event) => {
const {
handleOnSetSnakeDirection,
} = this.props;
handleOnSetSnakeDirection(event.code);
}
``````

containers/SnakeGame/constants.js

``````export const ARROW_UP = 'ArrowUp';
export const ARROW_DOWN = 'ArrowDown';
export const ARROW_LEFT = 'ArrowLeft';
export const ARROW_RIGHT = 'ArrowRight';
``````

containers/SnakeGame/reducer.js

``````const direction = {};
direction[ARROW_UP] = { x: 0, y: -1 };
direction[ARROW_DOWN] = { x: 0, y: 1 };
direction[ARROW_LEFT] = { x: -1, y: 0 };
direction[ARROW_RIGHT] = { x: 1, y: 0 };

case SET_SNAKE_DIRECTION: {
return state;
}

return state.updateIn(['snake', 'direction'], (dir) => {
if (dir.get('x') * -1 === direction[action.payload].x &&
dir.get('y') * -1 === direction[action.payload].y) {
return dir;
}
});
}
``````

Snake - Github