Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift中的实体组件_Swift_Xcode_Sprite Kit_Entity Component System - Fatal编程技术网

Swift中的实体组件

Swift中的实体组件,swift,xcode,sprite-kit,entity-component-system,Swift,Xcode,Sprite Kit,Entity Component System,我正在尝试使用实体组件架构构建一个简单的iOS游戏,类似于上面所描述的 我想在游戏中实现的是,当用户触摸屏幕时,检测触摸发生的位置,并将一种类型的所有实体移向特定方向(方向取决于用户触摸的位置,屏幕右侧=向上,屏幕左侧=向下) 到目前为止,游戏非常简单,我只是刚刚开始,但我被困在这个简单的功能中: 我的问题是,SKAction应该在一个类型的所有实体上运行,但根本不会发生 在我将游戏重新设计为ECS方法之前,这一切都很好 下面是我在Lines.swift中声明的GKEntity子类: class

我正在尝试使用实体组件架构构建一个简单的iOS游戏,类似于上面所描述的

我想在游戏中实现的是,当用户触摸屏幕时,检测触摸发生的位置,并将一种类型的所有实体移向特定方向(方向取决于用户触摸的位置,屏幕右侧=向上,屏幕左侧=向下)

到目前为止,游戏非常简单,我只是刚刚开始,但我被困在这个简单的功能中:

我的问题是,
SKAction
应该在一个类型的所有实体上运行,但根本不会发生

在我将游戏重新设计为ECS方法之前,这一切都很好

下面是我在Lines.swift中声明的
GKEntity
子类:

class Lines: GKEntity {

    override init() {
        super.init()
        let LineSprite = SpriteComponent(color: UIColor.white, size: CGSize(width: 10.0, height: 300))
        addComponent(LineSprite)

        // Set physics body
        if let sprite = component(ofType: SpriteComponent.self)?.node {

            sprite.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: sprite.size.width, height: sprite.size.height))
            sprite.physicsBody?.isDynamic = false
            sprite.physicsBody?.restitution = 1.0
            sprite.physicsBody?.friction = 0.0
            sprite.physicsBody?.linearDamping = 0.0
            sprite.physicsBody?.angularDamping = 0.0
            sprite.physicsBody?.mass = 0.00
            sprite.physicsBody?.affectedByGravity = false
            sprite.physicsBody?.usesPreciseCollisionDetection = true
            sprite.physicsBody?.categoryBitMask = 0b1
            sprite.zPosition = 10
        } 
    }   
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}
touchsbegind
中,我正在调用函数
Move(XAxisPoint:t.location(In:self))
,该函数在
游戏场景中声明

   ///Determines direction of movement based on touch location, calls MoveUpOrDown for movement
    func move(XAxisPoint: CGPoint){
        let Direction: SKAction
        let Key: String

        if XAxisPoint.x >= 0 {
            Direction = SKAction.moveBy(x: 0, y: 3, duration: 0.01)
            Key = "MovingUp"
        } else {
            Direction = SKAction.moveBy(x: 0, y: -3, duration: 0.01)
            Key = "MovingDown"
        }
        moveUpOrDown(ActionDirection: Direction, ActionKey: Key)
    }

    ///Moves sprite on touch
    func moveUpOrDown(ActionDirection: SKAction, ActionKey: String) {
        let Line = Lines()
        if let sprite = Line.component(ofType: SpriteComponent.self)?.node {
            if sprite.action(forKey: ActionKey) == nil {
                stopMoving()
                let repeatAction = SKAction.repeatForever(ActionDirection)
                sprite.run(repeatAction, withKey: ActionKey)
            }
        }
    }

    ///Stops movement
    func stopMoving() {
        let Line = Lines()
        if let sprite = Line.component(ofType: SpriteComponent.self)?.node {
            sprite.removeAllActions()
        }
    }
我猜这行代码
line.component(of type:SpriteComponent.self)?.node有问题,但是编译器没有抛出任何错误,我不确定我的错误在哪里


任何帮助/指导都将不胜感激

问题出现在
MoveUpOrDown
StopMoving

let Line = Lines()
它创建一个新的
对象,然后告诉它运行一个操作。因为它是新的,所以它没有被添加到场景中,所以它没有被绘制或执行

您应该获取一个现有的
对象并对其进行修改,而不是创建一个新的



作为旁注,命名方法和变量的常见约定是使用
camelCase
,这意味着
MoveUpOrDown
应该是
MoveUpOrDown
。另一方面,
SnakeCase
用于类结构和协议,因此
SpriteComponent
是最新的。这使您可以一眼就知道您是在使用类型还是变量。

感谢@Cleverror的帮助!我似乎正在创建几个
对象,而不是引用以前创建的
对象,因此操作是针对不同的对象执行的。我会更加小心命名约定,再次感谢!