如何最好地在SpriteKit中编写撤销功能?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何最好地在SpriteKit中编写撤销功能?相关的知识,希望对你有一定的参考价值。
我正在创建一个基于精灵工具包的游戏,允许玩家建造建筑物。我想创建一个撤消按钮,如果玩家放置一个块并使整个建筑物分崩离析,该按钮会返回一个步骤。
我正在考虑一种方法,就在它们放置sprite-kit场景的东西之前,如果他们点击“撤消”,它将用先前保存的场景替换场景。
这是最好的使用方法,以及最小化内存使用的最佳方法吗?是否有可以使用的预装到spite-kit中的东西?
在sprite-kit
没有预先建立特定的UNDO技术。我对节省内存和性能的建议是构建一堆用户操作。你可以做类似的东西:
public struct Stack<T> {
fileprivate var array = [T]()
public var count: Int {
return array.count
}
public var isEmpty: Bool {
return array.isEmpty
}
public mutating func push(_ element: T) {
array.append(element)
}
public mutating func pop() -> T? {
return array.popLast()
}
public var top: T? {
return array.last
}
}
enum ActionType:String {
case remove, add, moveTo, scale, rotate // add all the available user actions
}
struct UserAction {
var type: ActionType
var objectName: String
}
所以,首先你可以创建LIFO(后进先出顺序),你最后推送的元素是第一个用下一个pop弹出的元素。然后你可以创建你在这个例子UserAction
中调用的自定义LIFO元素,你可以在其中保存所涉及对象的动作类型(删除,添加,旋转...)和name
属性(例如,如果你有一个名为SKSpriteNode
的box1
你应该实现box1.name = "box1"
也只是为了识别你所涉及的节点。
用法:
var undoArray = Stack(array:[])
let currentAction = UserAction.init(type: .remove, objectName: "box1")
print(" - User has (currentAction.type.rawValue) the (currentAction.objectName)")
undoArray.push(currentAction)
显然,这只是UNDO阵列的实现。您的下一步应该是构建每个单独的操作,如删除,添加,旋转,以复制用户操作。
换句话说,当用户按下UNDO按钮时,另一个例子是你应该从堆栈中“弹出”一个元素:
// ...
if let lastEl = undoArray.pop() {
let lastUserAction = lastEl as! UserAction
switch lastUserAction.type {
case .remove: print("replicate remove action")
case .add: print("replicate add action")
case .moveTo : print("replicate moveTo action")
// ... add the other user actions
default:break
}
}
我只是制作你的GameScene的副本,然后当你需要撤消时,只需重新加载副本。
let copy = scene.copy() as? GameScene
view.presentScene(copy)
除非你开始看到问题,否则我不会过分关注内存消耗。我们有时倾向于做的是优化到没有投资回报(ROI)的程度。只要您没有对正在保留或创建僵尸的对象进行错误管理,使用此方法就不会有太多问题。
以上是关于如何最好地在SpriteKit中编写撤销功能?的主要内容,如果未能解决你的问题,请参考以下文章