Изменить дочернего родителя в GameKit - PullRequest
0 голосов
/ 24 сентября 2018

Я работаю над игрой стрельбы из стрел - игрок должен выпустить 3 стрелы в движущуюся цель (цель движется слева направо).Когда стрелка попадает в цель, она должна двигаться вместе с ней (слева направо).Самое очевидное, что нужно сделать, - это изменить родителя стрелки на цель.По какой-то причине это вызывает у меня некоторые проблемы -

  1. Я пытался --- arrow.move (toParent: target), и я не вижу стрелку на экране даже после того, как я установил новое местоположение дляэто
  2. Если я просто --- target.addChild (стрелка), я получаю ошибку, так как я не удалил стрелку из ее родителя (который в данном случае является сценой)
  3. Когда я--- arrow.removeFromParent (), а затем target.addChild (стрелка), в результате чего другие стрелки сталкиваются друг с другом, и я до сих пор не вижу стрелки на экране.

Это мойкод -

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 голосов
/ 23 октября 2018

Что в итоге решило для меня это использование этого метода --- move (toParent:)

Это мой код -

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