在GameKit中更改孩子的父母

时间:2018-09-24 18:02:33

标签: swift sprite-kit

我正在开发箭射击游戏-玩家需要向移动的目标射击3支箭(目标从左向右移动)。当箭头击中目标时,它应随之移动(从左到右)。最明显的事情是将箭头父级更改为目标。由于某种原因,这给我带来了一些麻烦-

  1. 我尝试了--- arrow.move(toParent:target),即使为它设置了新位置,我也看不到屏幕上的箭头
  2. 如果我只是--- target.addChild(arrow),我会失败,因为我没有从其父级中删除箭头(在这种情况下为场景)
  3. 当我--- arrow.removeFromParent()然后target.addChild(arrow)导致其他箭头相互碰撞时,我仍然看不到屏幕上的箭头。

这是我的代码-

class GameScene: SKScene, SKPhysicsContactDelegate {

var target:SKSpriteNode?
var arrows = [SKSpriteNode]()
var arrowContactPoint:CGPoint?

let noCategory:UInt32 = 0
let arrowCategory:UInt32 = 0b1
let targetCategory:UInt32 = 0b1 << 1
let obstacleCategory:UInt32 = 0b1 << 2

override func didMove(to view: SKView) {
    allowCollisionDetection()
    setTarget()
    moveTargetFromSideToSide()
    newArrow()
}

func didBegin(_ contact: SKPhysicsContact) {
    let categoryBitMaskBodyA:UInt32 = contact.bodyA.categoryBitMask
    let categoryBitMaskBodyB:UInt32 = contact.bodyB.categoryBitMask

    if ((categoryBitMaskBodyA == targetCategory && categoryBitMaskBodyB == arrowCategory) || (categoryBitMaskBodyA == arrowCategory && categoryBitMaskBodyB == targetCategory)) {
        arrowContactPoint = contact.contactPoint
        arrowCollideWithTarget()
    } else if (categoryBitMaskBodyA == obstacleCategory || categoryBitMaskBodyB == obstacleCategory) {
        let obstacleNode:SKNode = ((categoryBitMaskBodyA == arrowCategory) ? contact.bodyA.node! : contact.bodyB.node)!
        arrowCollideWithObstacle(obstacle:obstacleNode)
    } else if (categoryBitMaskBodyA == arrowCategory && categoryBitMaskBodyB == arrowCategory) {
        newGame()
    } else {
        print("Something went wrong")
    }

    newArrow()
}

func touchDown(atPoint pos : CGPoint) {

}

func touchMoved(toPoint pos : CGPoint) {

}

func touchUp(atPoint pos : CGPoint) {
    shootArrow()
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchDown(atPoint: t.location(in: self)) }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchMoved(toPoint: t.location(in: self)) }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
    for t in touches { self.touchUp(atPoint: t.location(in: self)) }
}

override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered

}

func allowCollisionDetection() {
    self.physicsWorld.contactDelegate = self
}

func setTarget() {
    target = self.childNode(withName: "target") as? SKSpriteNode
    //Set the target bit mask, it's tag
    target?.physicsBody?.categoryBitMask = targetCategory
    //Set with which objects the target collide
    target?.physicsBody?.collisionBitMask = noCategory
    //Set to which coliision we want to responde/handle - didBegin will get triggered
    target?.physicsBody?.contactTestBitMask = arrowCategory
}

func moveTargetFromSideToSide() {
    let moveRight = SKAction.moveBy(x: frame.size.width - (target?.size.width)!, y: 0, duration: 2)
    let moveLeft = SKAction.moveBy(x: -(frame.size.width - (target?.size.width)!), y: 0, duration: 2)
    let moveBackAndForth = SKAction.repeatForever(SKAction.sequence([moveRight, moveLeft]))
    target?.run(moveBackAndForth)
}

func newArrow() {
    let arrow = SKSpriteNode(imageNamed: "arrow1")
    let arrowTexture = SKTexture(imageNamed: "arrow1")
    arrow.position = CGPoint.zero
    self.addChild(arrow)
    arrow.physicsBody = SKPhysicsBody(texture: arrowTexture, size: arrowTexture.size())
    arrow.physicsBody?.isDynamic = true
    arrow.physicsBody?.allowsRotation = true
    arrow.physicsBody?.affectedByGravity = false
    arrow.physicsBody?.friction = 0.2
    arrow.physicsBody?.restitution = 0.2
    arrow.physicsBody?.linearDamping = 0.1
    arrow.physicsBody?.angularDamping = 0.1
    arrow.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
    arrow.physicsBody?.categoryBitMask = arrowCategory
    arrow.physicsBody?.collisionBitMask = noCategory
    arrow.physicsBody?.contactTestBitMask = arrowCategory | obstacleCategory | targetCategory
    arrows.append(arrow)
}

func shootArrow(){
    print("shootArrow")
    arrows.last!.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 80))
}

func arrowCollideWithTarget() {
    print("arrowCollideWithTarget")
    arrows.last!.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
    arrows.last!.move(toParent: target!)
}

func arrowCollideWithObstacle(obstacle:SKNode) {
    print("arrowCollideWithObstacle")
    arrows.last!.removeFromParent()
    arrows.removeLast()
}

func newGame() {
    print("New Game")
    for i in 0 ..< (arrows.count) {
        arrows[i].removeFromParent()
    }
    arrows.removeAll()
}

}

1 个答案:

答案 0 :(得分:0)

最终为我解决的是使用此方法- move(toParent:)

这是我的代码-

func arrowCollideWithTarget() {
    arrows.last!.move(toParent:target!)
}