游戏

时间:2016-04-11 17:30:43

标签: java stack game-development

我正在开发一款游戏,玩家可以在棋盘/网格中移动。它有moveLeft(),moveRight(),moveUp()和moveDown()方法,可以在棋盘周围一次移动玩家1个空间。

我试图计划我对玩家移动所需的撤消/重做功能的方法(例如,如果玩家向左移动了一个空格,并且调用撤消,玩家将向右移动一个空格)。我是一名学生,正在研究Stacks。

然而,在编程之前在纸上规划逻辑时(我发现这有助于我在做作业时),我不知道Stacks是否适合基于以下问题......

当调用每个移动方法时,字符串为' Up',' Down',' Left'' Right'添加到堆栈1,取决于调用的方法。这可以跟踪玩家在棋盘周围的移动情况。

如果调用了undo(),则删除堆栈1顶部的字符串,并将其添加到新堆栈“堆栈2'”。这用于跟踪'撤消'移动,以便redo()有一个跟随的路径。

如果调用redo(),则删除堆栈2上的字符串,然后将其添加到堆栈1。

这种方法非常有效,但前提是你将Redo()调用与Undo()的次数完全相同,并且直接调用它后。

E.g:

  1. 玩家进行4次移动:(堆栈1现在有4个字符串)
  2. Undo()被调用一次:( Stack 1现在有3个字符串,Stack 2有1个字符串)
  3. 玩家再做4次动作:(堆栈1现在有7个字符串,堆栈2仍然有1个字符串)
  4. Undo()被调用一次:( Stack 1现在有6个字符串,Stack 2有2个字符串)
  5. 调用Redo():(这是问题)这可以被调用两次,因为Stack 2有2个字符串,但实际上Board上的Player应该只能调用一次Redo()。
  6. 在过去的4小时里,我一直在努力研究这背后的逻辑!任何建议表示赞赏即 - 基于上述情况,是否仍然可以做我需要做的Stacks,我需要找到解决问题的方法?或者我应该放弃,因为这是不可能的。

4 个答案:

答案 0 :(得分:1)

如果您不想使用Stacks,因为您不确定何时清除撤消Stack,则可以使用List执行此操作。然后,您的逻辑可以以类似的方式维护:

  • 保留您所在移动的索引(从0开始,每次新移动增加1)
  • 如果撤消已完成,则减少索引(除非您位于列表的开头)
  • 如果重做完成,请递增索引(除非您位于列表的末尾)
  • 如果执行新移动,请递增索引并清除大于或等于索引的所有移动(从而清除撤消/重做移动)

然后,你的例子是:

  1. 玩家进行4次移动(索引为3,列表有4个项目)
  2. Undo()被调用一次(index是2,list有4个项目)
  3. 播放器再进行4次移动(索引为6,列表有7个项目,所有撤消/重做项目都已清除)
  4. Undo()被调用一次(索引是5,列表有7个项目)
  5. 重做一次调用(索引是6,列表有7个项目)
  6. 再次调用重做(因为没有可用的重做动作而被拒绝)

答案 1 :(得分:0)

以这种方式思考..撤消和重做的整个想法都在于应用程序(程序)的状态。撤消意味着您希望立即进入应用程序的先前状态;类似于重做的情况。是的,堆栈是保存以前状态的最佳解决方案。对于撤消,您可以执行弹出并将其推送到另一个堆栈。使用另一个堆栈进行重做操作。 您可能希望为撤消和重做设置限制。 如何保存应用程序的状态取决于您。

答案 2 :(得分:0)

在第3步

Player makes 4 more moves: (Stack 1 now has 7 strings, Stack 2 still has 1 string) 

你必须清空第二叠。

答案 3 :(得分:0)

修复起来很简单。基本上,只有当前一个动作是撤消时,重做才有效。

一个解决方案是:当玩家进行移动然后清空堆栈2(撤消堆栈,用于重做)。

其他解决方案:将堆栈2清除延迟到以后。保持一个布尔标志,用于跟踪先前的操作是否为撤消(例如 boolean isRecentActionUndo ),它应始终表示先前的操作是否为撤消,通过在每次调用撤消()和设置时将其设置为true每次调用Move()时它都为false。在重做()中检查此标志。

if(isRecentActionUndo) { // perform redo } else { // clear stack 2 }

可能有其他更好的解决方案来实现相同的,以执行有效的重做()。