【问题标题】:How can I save the previous state in a way that allows it to be entered again with GKStateMachine?如何以允许使用 GKStateMachine 再次输入的方式保存以前的状态?
【发布时间】:2016-02-25 09:45:20
【问题描述】:

我正在使用 GKStateMachine 来跟踪我游戏中图块的状态。

当我放置一个项目时,该项目所覆盖的图块将进入“计划”状态。如何存储图块并在稍后将图块恢复到以前的状态?

以下是我认为与我的问题相关的代码部分。很高兴就具体要求分享更多信息。

//...
// Have previously entered the tiles stored in the global Game object into a state which is not "planned" state
  class func movePlannedObject(x: Int, y: Int) {

    //DO Some things

    for tile in Game.sharedInstance.plannedBuildingTiles {
      tile.stateMachine.enterState(tile.previousState!)
    }

    // Set new position and change state of tiles to planned

  }

//...

还有状态机:

class TileState : GKState{

  var tile : Tile?

  init( tile: Tile ) {
    super.init()
    self.tile = tile
  }
}


class TileTileState: TileState {
}

class TileGrassState: TileState {
}

class TilePathState: TileState {
}

class TilePlanState: TileState {

  override func didEnterWithPreviousState(previousState: GKState?) {
    super.didEnterWithPreviousState(previousState)

    tile?.previousState = // What?
    print(tile?.previousState)

    Game.sharedInstance.plannedBuildingTiles.append(tile!)
  }

}

要点:https://gist.github.com/Relequestual/dac6d51c923e5ce4224e

如果我将 previousState 设置为 previousState,则我无法使用该变量进入状态...

// In the tile class
var previousState: GKState?

// In states function didEnterWithPreviousState
tile?.previousState = previousState

// Elsewhere
tile.stateMachine.enterState(tile.previousState!)

编译时错误:

Cannot convert value of type 'GKState' to expected argument type 'AnyClass' (aka 'AnyObject.Type')

【问题讨论】:

  • #swift-lang 上的一些好心人帮我解决了这个问题。希望下周我会发布解决方案。
  • 你是怎么解决这个问题的?
  • @mfessenden 抱歉,我是没有发布解决方案的“那个人”。这是简化版:gist.github.com/Relequestual/548c0f858f04e2d2a07550a1e6125afe - 原来我实际上并不想这样做,但我从我的 git 历史中为你挖出了代码 =] 如果我能提供更多帮助,请告诉我。
  • 感谢分享!你为什么决定不想使用这种方法?我试图轻松地将游戏从任何状态切换到暂停状态,但现在我自己质疑这种方法的实用性。
  • 我最初需要这样做,因为我正在设置瓷砖的状态,从任何类型的瓷砖(草或瓷砖)到构建状态(显示不同的颜色),然后返回到以前的瓷砖类型。我想了想,得出的结论是,这不是一个好方法。根据您的要求,我不确定什么是最好的,但它听起来像一个跟踪暂停状态的全局布尔值会比离开之前的游戏状态更好。

标签: ios swift state-machine gameplay-kit


【解决方案1】:

如果这个问题还没有得到解答,这可能是一种解决方案:快速:

在你的主游戏类中声明一个变量:

var previousState: AnyClass?

GKState 类有一个 willExit 函数,在这个函数中你可以定义这个 var,因为这个相同的类将是之前的状态:

override func willExit(to nextState: GKState) {

    self....?.previousState = ThisClassState.self
}

然后在你的主游戏类中,你可以调用这个 var :

self.myGameStateMachine?.enter(self.previousState)

我希望这足以让你继续。

【讨论】:

  • 谢谢。我没有考虑到当 willExit 被调用时,当前状态将是 self,因为它还没有改变。我不确定我是否真的需要再这样做了,所以我自己没有检查过代码。不过看起来不错。
  • 我确实以另一种方式解决了这个问题。我应该发布我的解决方案。它在问题的 cmets 中。
【解决方案2】:

在您的场景或 StateClass 中创建属性

var previousState: GKState?

在您的 GKStates didEnter 方法中更新属性

override func didEnter(from previousState: GKState?) {
    super.didEnter(from: previousState)
    self.previousState = previousState
}

并使用它调用

if let previousState = previousState {
    stateMachine.enter(type(of: previousState))
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-19
    • 2019-06-13
    • 2015-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-10-10
    相关资源
    最近更新 更多