【发布时间】:2016-05-15 04:41:10
【问题描述】:
这是我的第一个 redux 项目。我正在尝试制作一个可以教你平假名/片假名的抽认卡游戏。我陷入了一些状态流程......
游戏状态可视化
{
// the current displayed card
currentCard: null | {q: 'き', a: 'ki'},
// time the game was started
timestamp: millisecondTimestamp,
// submitted answers
answers: [
{
card: {q: 'か', a: 'ka'},
answer: 'ka'
},
{
card: {q: 'な', a: 'na'},
answer: 'na'
},
...
],
// remaining cards in the deck
deck: [
{q: 'く', a: 'ku'},
{q: 'け', a: 'ke'},
{q: 'こ', a: 'ko'}
...
]
}
stores/game.js
import {BEGIN_GAME, NEXT_CARD, SUBMIT_ANSWER} from '../actions/';
import {isEmpty, first, rest} from '../utilities/';
const gameReducer = (state=null, action) => {
switch (action.type) {
case BEGIN_GAME:
return Object.assign({}, state, {deck: action.deck});
case NEXT_CARD:
return isEmpty(state.deck)
? Object.assign({}, state, {
currentCard: null
})
: Object.assign({}, state, {
currentCard: first(state.deck),
deck: rest(state.deck)
})
;
case SUBMIT_ANSWER:
return Object.assign({}, state, {
currentCard: null,
answers: state.answers.concat({
card: state.currentCard,
answer: action.answer
})
});
default:
return state;
}
};
export default gameReducer;
actions/index.js
import {shuffle} from '../utilities/';
export const BEGIN_GAME = 'BEGIN_GAME';
export const NEXT_CARD = 'NEXT_CARD';
export const SUBMIT_ANSWER = 'SUBMIT_ANSWER';
export const beginGame = deck => ({
type: BEGIN_GAME,
deck: shuffle(deck)
});
export const nextCard = () => ({
type: NEXT_CARD
});
export const submitAnswer = answer => ({
type: SUBMIT_ANSWER,
answer
});
我认为游戏循环会像这样工作:
- 当
state为null时,等待用户按下开始游戏 按钮,该按钮调度BEGIN_GAME动作 - 此时,开始主游戏循环
- 发送
CHECK_END_GAME以确定牌组中是否还有牌 - 发送
NEXT_CARD以显示牌组中的下一张牌 - 等待点击答案,然后发送
SUBMIT_ANSWER操作 - 记录答案后,重复循环,从
CHECK_END_GAME开始,接着是NEXT_CARD,接着是等待SUBMIT_ANSWER等 - 在某些时候
CHECK_END_GAME应该触发DISPLAY_RESULTS操作... ??
看,我有点迷路了...使用 redux,我认为我不能(或不应该)从商店 in 调度另一个动作。但是我该如何分解这些动作或状态检查呢?
我的大脑目前正在使用这样的模型进行思考:
BEGIN_GAME(deck)
LOOP(
CHECK_END_GAME()->NEXT_CARD()->SUBMIT_ANSWER(answer)->
)
DISPLAY_RESULTS()
问题是,我不知道如何链接这样的操作,或者是否建议这样做。我愿意以完全不同的方式设计动作/商店。我是这里的菜鸟,所以如果我做错了什么,请告诉我。
任何向正确方向轻推都会有所帮助。谢谢!
【问题讨论】:
-
我建议你用Redux Saga描述控制流,并使用Redux主要用于更新状态而不是控制流逻辑。 Redux Saga 让您可以使用
take和putRedux 操作的 ES6 生成器编写游戏循环。 -
@DanAbramov 我很高兴收到您的回复!我一定会去看看 ^__^
-
@DanAbramov 所以我已经阅读了一些有关 Saga 模式的内容,观看了 Redux Saga 文档中的 Applying Saga Pattern video,并使用了一些 Redux Saga 示例。在我继续尝试使用它之前,我只想明确一点,我的游戏是一个纯粹的本地/同步游戏,除了在第一场比赛之前异步加载一次完整的甲板,并在比赛结束后异步提交统计数据.
-
@DanAbramov 似乎 Saga 模式可能更适合具有高度异步行为的应用程序。如果您仍然认为它适用,您认为您可以为我提供一个起点吗?我将不胜感激。
-
是的,也许。我还没有深入阅读您的应用程序的功能,这就是为什么我留下评论而不是答案的原因。 Sagas 是异步的,因为用户输入是异步的。不确定这是否对您有帮助。我认为您的问题最大的问题是我不明白您发布的代码是否有效,或者您是否有问题。有点不清楚。你搞定了吗?
标签: javascript reactjs redux