如何最好地在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属性(例如,如果你有一个名为SKSpriteNodebox1你应该实现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中编写撤销功能?的主要内容,如果未能解决你的问题,请参考以下文章

如何最好地在 NHibernate 中检索和更新这些对象?

如何最好地在 ASP.NET 中填充 HTML 表?

Scala 类型关键字:如何最好地在多个类中使用它

通过在 SpriteKit/Swift 中向上滑动来跳跃角色

tvOS SpriteKit 应用程序中的菜单按钮

如何使用 Swift 在 SpriteKit 上绘制贝塞尔曲线?