【发布时间】:2019-12-01 10:29:48
【问题描述】:
我通过创建一个小型 RPG 游戏来测试 Redux。
我有一个名为 Monster 的组件,它在地图上移动。位置、方向和 spriteLocation 由 store 控制。怪物减速器是这样的:
const intialState = {
position: [0,360],
spriteLocation: '0px 80px',
direction: 'EAST',
walkIndex : 0
}
const monsterReducer = (state = intialState, action) => {
switch(action.type){
case 'MOVE_MONSTER':
return {
...action.payload
}
default:
return state
}
}
export default monsterReducer
动作是这样分派的:
import store from '../../config/store'
import {SPRITE_SIZE, MAP_WIDTH, MAP_HEIGHT} from '../../config/constants'
export default function handleMovement(monster){
//APPEL AU DEPLACEMENT TOUTES LES X secondes
// setInterval(handleMove(store.getState().monster.direction), 500);
setInterval(() => {
handleMove(store.getState().monster.direction)
}, 300);
function handleMove(direction){
switch(direction){
case 'WEST':
return attemptMove('WEST')
case 'EAST':
return attemptMove('EAST')
case 'NORTH':
return attemptMove('NORTH')
case 'SOUTH':
return attemptMove('SOUTH')
default:
}
}
function attemptMove(direction){
const oldPos = store.getState().monster.position
const newPos = getNewPosition(oldPos,direction)
if(observeBoundaries(newPos) && observeImpassable(newPos)){
dispatchMove(direction, newPos)
}else{
switch(direction){
case 'WEST':
return attemptMove('EAST')
case 'EAST':
return attemptMove('WEST')
case 'NORTH':
return attemptMove('SOUTH')
case 'SOUTH':
return attemptMove('NORTH')
default:
}
}
}
//UPDATE DE LA POSITION
function getNewPosition(oldPos, direction){
switch(direction){
case 'WEST':
return [oldPos[0]-SPRITE_SIZE, oldPos[1]]
case 'EAST':
return [oldPos[0]+SPRITE_SIZE, oldPos[1]]
case 'NORTH':
return [oldPos[0], oldPos[1]-SPRITE_SIZE]
case 'SOUTH':
return [oldPos[0], oldPos[1]+SPRITE_SIZE]
default:
}
}
function observeBoundaries(newPos){
//SI ON EST DANS LA MAP ON RETOURNE TRUE SINON FALSE
return (newPos[0] >= 0 && newPos[0] <= MAP_WIDTH-SPRITE_SIZE) &&
(newPos[1] >= 0 && newPos[1] <= MAP_HEIGHT-SPRITE_SIZE)
}
function observeImpassable(newPos){
//TEST DES OBSTACLES
const tiles = store.getState().map.tiles
const y = newPos[1] / SPRITE_SIZE
const x = newPos[0] / SPRITE_SIZE
const nextTile = tiles[y][x]
return nextTile < 5
}
function getWalkIndex(){
const walkIndex = store.getState().monster.walkIndex
return walkIndex >= 4 ? 0 : walkIndex+1
}
function getSpriteLocation(direction, walkIndex){
switch (direction){
case 'EAST' :
return `${SPRITE_SIZE*walkIndex}px ${SPRITE_SIZE*2}px`
case 'SOUTH' :
return `${SPRITE_SIZE*walkIndex}px ${SPRITE_SIZE*0}px`
case 'WEST' :
return `${SPRITE_SIZE*walkIndex}px ${SPRITE_SIZE*3}px`
case 'NORTH' :
return `${SPRITE_SIZE*walkIndex}px ${SPRITE_SIZE*1}px`
default:
}
}
//DISPATCH DE LA NOUVELLE POSITION ET DIRECTION POUR ANIMATION DU PERSO AU STORE
function dispatchMove(direction, newPos){
const walkIndex = getWalkIndex()
store.dispatch({
type: 'MOVE_MONSTER',
payload: {
position: newPos,
direction,
walkIndex,
spriteLocation : getSpriteLocation(direction, walkIndex)
}
})
}
return monster
}
我想创建另一个 Monster 组件,但初始状态不同,但使用相同的 reducer。
也许使用 reducer 不是一个好的解决方案?
【问题讨论】:
标签: reactjs redux react-redux