如何使用swift将touchesbegan事件委托给实体组件?

时间:2016-01-26 11:33:27

标签: ios swift delegates sprite-kit gesture-recognition

我正在使用swift为ios创建游戏。我已经从Apples GameplayKit实现了组件实体系统,与this tutorial中显示的非常相似。

我添加了一个正方形网格,我想以不同的方式对点按手势做出反应。当点击UI元素时,我将使用状态机更改游戏状态,但我还想更改每个方块对轻击手势的反应方式。根据我目前有限的理解,最好的方法是更改​​点按手势委托。但是,我找不到任何关于如何做到这一点的简单例子。 sqaures是SKSpriteNodes。

可根据要求提供代码;但是,我正在寻找一个脱离上下文的例子,说明如何以最简单的方式完成这项工作。

有谁知道如何做到这一点,或者可以建议一种“更好”的方式。为了避免主观性,我在结构方面更好地定义了更好的结构。 (例如,单个手势处理程序中的多个if语句似乎是错误的方法。)

2 个答案:

答案 0 :(得分:1)

我已根据我所拥有的各种帮助和想法找到了解决问题的有效方案,但我仍然非常愿意接受其他解决方案。

这个问题所提出的主要问题是如何从spritenode引用回实体。 通过阅读SKSpriteNode上的文档,我发现它的父类SKNode有一个userData attribute,它允许您在该节点中存储数据。

将实体实例附加到需要在SpriteComponent中发生的节点,因为这是构造节点的地方,但它不能在构造函数中发生,因此它必须位于SpriteComponent中的函数中。

func addToNodeKey() {
    self.node.userData = NSMutableDictionary()
    self.node.userData?.setObject(self.entity!, forKey: "entity")
  }

然后在将compoennt添加到自身后,在Enity类构造中调用该函数。

addComponent(spriteComponent)
spriteComponent.addToNodeKey()

现在可以从触摸事件访问Enity实例,我需要一种方法在该实例上执行一个函数,但是你不知道该实例是否是GKEntity的子类,也不知道是哪种类型。< / p>

因此,我创建了另一个组件TouchableSpriteComponent。经过一番尝试后,init函数将一个函数作为参数,然后从场景触摸事件中调用,该事件允许创建TouchableSpriteComponent的实体定义它如何处理事件。

我创建了一个gist for this solution,因为这里可能放了太多代码。这是个绝缘。

我真的很想知道这是否是一个“好”的解决方案,或者是否有更清晰的路线会产生相同的效果(没有遍历所有实体或节点)。

答案 1 :(得分:1)

如果我说得好,你应该有类似的东西:

MySQL

在您的GKEntity子类中。

我在游戏中这样做:

func entityTouched(touches: Set<UITouch>, withEvent event: UIEvent?)

<强> GameScene:

class Square: MainEntity {
    override func entityTouched(touches: Set<UITouch>, withEvent event: UIEvent?) {
        //DO something
    }
}

其中:

<强> EntityNode:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    super.touchesBegan(touches, withEvent: event)

    let touch = touches.first!
    let viewTouchLocation = touch.locationInView(self.view)
    let sceneTouchPoint = self.convertPointFromView(viewTouchLocation)
    let touchedNode = self.nodeAtPoint(sceneTouchPoint)

    let touchedEntity = (touchedNode as? EntityNode)?.entity

    if let myVC = touchedEntity as? MainEntity {
        myVC.entityTouched(touches, withEvent: event)
    }

<强> SpriteComponent:

class EntityNode: SKSpriteNode {
    // MARK: Properties
    weak var entity: GKEntity!
}

MainEntity:

class SpriteComponent: GKComponent {

    let node : EntityNode

    init(entity: GKEntity, texture: SKTexture, size: CGSize) {
        node = EntityNode(texture: texture, color: SKColor.whiteColor(), size: size)
        node.entity = entity
    }
}

让我知道你是否正在寻找。