Gameplaykit:使用 GKStatemachines 管理多个对象
Gameplaykit: Managing multiple objects using GKStatemachines
我正在编写一个游戏,其中包含许多可以由游戏玩家移动的开关精灵。
我打算使用 'Game-play-kit' 状态机来组织我的代码。
我不知道如何管理多个状态机 - 特别是我将我的开关存储在一个数组中,每个开关对象都包含一个状态机 -
我如何引用 'parent'从 GKState classses 中切换以更改其属性(在本例中 运行 一个新动画?)
这是我的开关class:
class RailSwitch: SKSpriteNode {
var switchID: Int
var currentSwitchPosition: switchPosition
var initialSwitchPosition: switchPosition
var switchLocation: CGPoint
var isSwitchLocked: Bool
var isLeftMiddleSwitch: Bool
var currentAnimation: switchAnimation /* this is a dictionary of animation textures */
var stateMachine : GKStateMachine!
init(switchID: Int,
switchLocation: CGPoint,
initialSwitchPosition: switchPosition,
isSwitchLocked: Bool,
isLeftMiddleSwitch: Bool,
currentAnimation: switchAnimation,
texture:SKTexture!) {
self.switchID = switchID
self.switchLocation = switchLocation
self.initialSwitchPosition = initialSwitchPosition
self.currentSwitchPosition = initialSwitchPosition
self.isSwitchLocked = isSwitchLocked
self.isLeftMiddleSwitch = isLeftMiddleSwitch
self.currentAnimation = currentAnimation
super.init (texture: texture!, color: UIColor.clearColor(), size: texture!.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
这是我的交换机网络class:
class SwitchNetwork {
var level : Int
var switchNetwork = [RailSwitch]()
var railSwitchAnimation : [switchAnimationState: switchAnimation]
init (level:Int) {
self.level = level
self.switchNetwork = []
self.railSwitchAnimation = [:]
}
func initialiseSwitches() {
/* one test example switch - in practice there will be many*/
railSwitchAnimation = loadSwitchAnimations()
switchNetwork.append(RailSwitch(switchID: 1,
switchLocation: CGPointMake(400,300),
initialSwitchPosition: (.left) ,
isSwitchLocked: false,
isLeftMiddleSwitch: true,
currentAnimation: railSwitchAnimation[.left]!,
texture: railSwitchAnimation[.left]!.textures[0]
))
}
我从 GameScene 中启动开关:
func initiateSwitchNetwork() {
for thisSwitch in 0 ... switches.switchNetwork.count - 1 {
switches.switchNetwork[thisSwitch].stateMachine = GKStateMachine(states: [
GameStart(scene: self),
SwitchLeft(scene: self),
SwitchRight(scene: self),
SwitchMiddle(scene: self),
SwitchLeftLocked(scene: self),
SwitchRightLocked(scene: self),
SwitchMiddleLocked(scene: self)])
switches.switchNetwork[thisSwitch].stateMachine.enterState(GameStart)
}
这是我的问题。
在开关状态机 gkstate classes 中,我应该更改谁的动画?
我需要访问包含状态机不知何故?
class GameStart: GKState {
unowned let scene: GameScene
init(scene: SKScene) {
self.scene = scene as! GameScene
super.init()
}
override func didEnterWithPreviousState(previousState: GKState?) {
// scene.addChild(scene.switches.switchNetwork[0].currentAnimation.textures[0])
}
}
要考虑的一种方法是不将场景传递到每个状态的 init 函数,而是传递对父开关的引用?所以你所在州的 init 函数看起来像这样;
init(switch: RailSwitch) {
self.railSwitch = switch
super.init()
}
然后你的 RailSwitch
可能有一个函数来改变你将在状态的 updateWithDeltaTime
函数中调用的动画。
override func updateWithDeltaTime(seconds: NSTimeInterval) {
self.railSwitch.changeAnimation(to switchTexture: .left)
}
请注意,您可以访问每个状态的状态机;
override func updateWithDeltaTime(seconds: NSTimeInterval) {
self.stateMachine?.enterState(SwitchRight.self)
}
顺便说一句,我更愿意使用 Strategy Pattern
来实现这种功能,除非切换下一个状态是由当前状态强烈决定的。策略更适合外部因素决定下一次变化的情况。
我正在编写一个游戏,其中包含许多可以由游戏玩家移动的开关精灵。
我打算使用 'Game-play-kit' 状态机来组织我的代码。
我不知道如何管理多个状态机 - 特别是我将我的开关存储在一个数组中,每个开关对象都包含一个状态机 -
我如何引用 'parent'从 GKState classses 中切换以更改其属性(在本例中 运行 一个新动画?)
这是我的开关class:
class RailSwitch: SKSpriteNode {
var switchID: Int
var currentSwitchPosition: switchPosition
var initialSwitchPosition: switchPosition
var switchLocation: CGPoint
var isSwitchLocked: Bool
var isLeftMiddleSwitch: Bool
var currentAnimation: switchAnimation /* this is a dictionary of animation textures */
var stateMachine : GKStateMachine!
init(switchID: Int,
switchLocation: CGPoint,
initialSwitchPosition: switchPosition,
isSwitchLocked: Bool,
isLeftMiddleSwitch: Bool,
currentAnimation: switchAnimation,
texture:SKTexture!) {
self.switchID = switchID
self.switchLocation = switchLocation
self.initialSwitchPosition = initialSwitchPosition
self.currentSwitchPosition = initialSwitchPosition
self.isSwitchLocked = isSwitchLocked
self.isLeftMiddleSwitch = isLeftMiddleSwitch
self.currentAnimation = currentAnimation
super.init (texture: texture!, color: UIColor.clearColor(), size: texture!.size())
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
这是我的交换机网络class:
class SwitchNetwork {
var level : Int
var switchNetwork = [RailSwitch]()
var railSwitchAnimation : [switchAnimationState: switchAnimation]
init (level:Int) {
self.level = level
self.switchNetwork = []
self.railSwitchAnimation = [:]
}
func initialiseSwitches() {
/* one test example switch - in practice there will be many*/
railSwitchAnimation = loadSwitchAnimations()
switchNetwork.append(RailSwitch(switchID: 1,
switchLocation: CGPointMake(400,300),
initialSwitchPosition: (.left) ,
isSwitchLocked: false,
isLeftMiddleSwitch: true,
currentAnimation: railSwitchAnimation[.left]!,
texture: railSwitchAnimation[.left]!.textures[0]
))
}
我从 GameScene 中启动开关:
func initiateSwitchNetwork() {
for thisSwitch in 0 ... switches.switchNetwork.count - 1 {
switches.switchNetwork[thisSwitch].stateMachine = GKStateMachine(states: [
GameStart(scene: self),
SwitchLeft(scene: self),
SwitchRight(scene: self),
SwitchMiddle(scene: self),
SwitchLeftLocked(scene: self),
SwitchRightLocked(scene: self),
SwitchMiddleLocked(scene: self)])
switches.switchNetwork[thisSwitch].stateMachine.enterState(GameStart)
}
这是我的问题。
在开关状态机 gkstate classes 中,我应该更改谁的动画?
我需要访问包含状态机不知何故?
class GameStart: GKState {
unowned let scene: GameScene
init(scene: SKScene) {
self.scene = scene as! GameScene
super.init()
}
override func didEnterWithPreviousState(previousState: GKState?) {
// scene.addChild(scene.switches.switchNetwork[0].currentAnimation.textures[0])
}
}
要考虑的一种方法是不将场景传递到每个状态的 init 函数,而是传递对父开关的引用?所以你所在州的 init 函数看起来像这样;
init(switch: RailSwitch) {
self.railSwitch = switch
super.init()
}
然后你的 RailSwitch
可能有一个函数来改变你将在状态的 updateWithDeltaTime
函数中调用的动画。
override func updateWithDeltaTime(seconds: NSTimeInterval) {
self.railSwitch.changeAnimation(to switchTexture: .left)
}
请注意,您可以访问每个状态的状态机;
override func updateWithDeltaTime(seconds: NSTimeInterval) {
self.stateMachine?.enterState(SwitchRight.self)
}
顺便说一句,我更愿意使用 Strategy Pattern
来实现这种功能,除非切换下一个状态是由当前状态强烈决定的。策略更适合外部因素决定下一次变化的情况。