我正在创建一个基于精灵套件的游戏,允许玩家建造建筑。我想要创建一个撤销按钮,如果一个球员放置一个街区,并使整个建筑倒塌,退一步。
我在考虑一种方法,在他们放置一些东西之前,精灵-工具包场景被保存,如果他们点击“撤销”,它将取代以前保存的场景。
这是最好的使用方法,也是最小化内存使用的最佳方法吗?有什么东西是可以用的吗?
发布于 2018-08-29 07:31:03
在中没有预先构建的特定的撤销技术。为了节省内存和性能,我的建议是构建一个用户操作堆栈。你可以做这样的事情:
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属性(例如,如果您有一个名为box1的SKSpriteNode,则还应该实现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按钮时,您应该从堆栈中“弹出”一个元素:
// ...
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
}
}发布于 2018-08-29 13:24:47
我只需制作一个GameScene的副本,然后当您需要撤消时,只需重新加载该副本。
let copy = scene.copy() as? GameScene
view.presentScene(copy)除非你开始发现问题,否则我不会太专注于内存消耗。我们有时会做的事情是过度优化,以至于没有投资回报(ROI)。只要您没有错误地管理您要保留或创建僵尸的对象,您就不会发现使用此方法存在太多问题。
https://stackoverflow.com/questions/52069012
复制相似问题