2017-06-29 6 views
1

Ich mache ein Spiel, wo der Spieler Hindernissen ausweichen und Punkte sammeln soll. Ein kleines Problem allerdings. Wenn der Spieler mit den Punkten kollidiert (ein weiterer SKSpriteNode), springt der Spieler ein wenig zurück. Ich möchte, dass es einfach "durchläuft", ohne dass es von der Kollision betroffen ist.Die "Bounce" loswerden, wenn der Spieler mit anderen SKSpriteNodes kollidiert

Dies ist die Spielerklasse:

import SpriteKit 

struct ColliderType { 
static let Player: UInt32 = 1 
static let Swan: UInt32 = 2 
static let Branch: UInt32 = 3 
static let Score: UInt32 = 4 
static let Wall1: UInt32 = 5 
static let Wall2: UInt32 = 6 
} 

class Player: SKSpriteNode { 

func initialize() { 
    self.name = "Player" 
    self.zPosition = 4 
    self.setScale(0.3) 
    self.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    self.physicsBody = SKPhysicsBody(circleOfRadius: self.size.height/
2 - 5) 
    self.physicsBody?.affectedByGravity = false 
    self.physicsBody?.restitution = 0 
    self.physicsBody?.categoryBitMask = ColliderType.Player 
    self.physicsBody?.collisionBitMask = ColliderType.Swan | 
ColliderType.Branch | ColliderType.Wall1 | ColliderType.Wall2 
    self.physicsBody?.contactTestBitMask = ColliderType.Swan | 
ColliderType.Score | ColliderType.Branch | ColliderType.Wall1 | 
ColliderType.Wall2 


} 

} 

Dies ist GameplayScene:

import SpriteKit 

class GameplayScene: SKScene, SKPhysicsContactDelegate { 

var player = Player() 

var swan = SKSpriteNode() 

var frog = SKSpriteNode() 

var egg = SKSpriteNode() 

var branch = SKSpriteNode() 

var scoreLabel = SKLabelNode() 
var score = 0 

var gameStarted = false 
var isAlive = false 

var press = SKSpriteNode() 

var touched: Bool = false 

var location = CGPoint.zero 

override func didMove(to view: SKView) { 
    initialize() 
} 

override func update(_ currentTime: TimeInterval) { 

    if isAlive { 
     moveBackgrounds() 
    } 

    if (touched) { 
     moveNodeToLocation() 
    } 
} 

override func touchesBegan(_ touches: Set<UITouch>, with event: 
UIEvent?) { 

    if gameStarted == false { 
     isAlive = true 
     gameStarted = true 
     press.removeFromParent() 
     spawnSwans() 
     spawnEggs() 
     spawnBranches() 
    } 

    touched = true 
    for touch in touches { 
     location = touch.location(in:self) 
    } 

    for touch in touches { 

     let location = touch.location(in: self) 

     if atPoint(location).name == "Retry" { 
      self.removeAllActions() 
      self.removeAllChildren() 
      initialize() 
     } 

     if atPoint(location).name == "Quit" { 
      let mainMenu = MainMenuScene(fileNamed: "MainMenuScene") 
      mainMenu!.scaleMode = .aspectFill 
      self.view?.presentScene(mainMenu!, transition: 
SKTransition.fade(withDuration: TimeInterval(1))) 
     } 

    } 

} 

override func touchesEnded(_ touches: Set<UITouch>, with event: 
UIEvent?) { 
    touched = false 
} 

override func touchesMoved(_ touches: Set<UITouch>, with event: 
UIEvent?) { 

    for touch in touches { 
     location = touch.location(in: self) 
    } 
} 

func didBegin(_ contact: SKPhysicsContact) { 

    var firstBody = SKPhysicsBody() 
    var secondBody = SKPhysicsBody() 

    if contact.bodyA.node?.name == "Player" { 
     firstBody = contact.bodyA 
     secondBody = contact.bodyB 
    } else { 
     firstBody = contact.bodyB 
     secondBody = contact.bodyA 
    } 

    if firstBody.node?.name == "Player" && secondBody.node?.name == 
"Egg" { 
     incrementScore() 
     secondBody.node?.removeFromParent() 
    } else if firstBody.node?.name == "Player" && secondBody.node?.name 
== "Swan" { 
     if isAlive { 
      playerDied() 
      firstBody.node?.removeFromParent() 
     } 
    } else if firstBody.node?.name == "Player" && secondBody.node?.name 
== "Branch" { 
     if isAlive { 
      playerDied() 
      firstBody.node?.removeFromParent() 
     } 
    } else if firstBody.node?.name == "Player" && secondBody.node?.name 
== "Wall1" { 
     if isAlive { 
      playerDied() 
      firstBody.node?.removeFromParent() 
     } 
    } else if firstBody.node?.name == "Player" && secondBody.node?.name 
== "Wall2" { 
     if isAlive { 
      playerDied() 
      firstBody.node?.removeFromParent() 
     } 
    } 


} 

func initialize() { 

    gameStarted = false 
    isAlive = false 
    score = 0 

    physicsWorld.contactDelegate = self 

    createInstructions() 
    createPlayer() 
    createBackgrounds() 
    createWall1() 
    createWall2() 
    createLabel() 
} 

func createInstructions() { 
    press = SKSpriteNode(imageNamed: "Press") 
    press.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    press.position = CGPoint(x: 0, y: 100) 
    press.setScale(0.4) 
    press.zPosition = 10 
    self.addChild(press) 
} 

func createPlayer() { 
    player = Player(imageNamed: "Player") 
    player.initialize() 
    player.position = CGPoint(x: 0, y: 0) 
    self.addChild(player) 
} 

func createBackgrounds() { 
    for i in 0...2 { 
     let bg = SKSpriteNode(imageNamed: "BG") 
     bg.name = "BG" 
     bg.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
     bg.position = CGPoint(x: 0, y: CGFloat(i) * bg.size.height) 
     self.addChild(bg) 
    } 
} 

func createWall1() { 
    for i in 0...2 { 
     let wall = SKSpriteNode(imageNamed: "Wall1") 
     wall.name = "Wall1" 
     wall.zPosition = 4 
     wall.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
     wall.position = CGPoint(x: -(self.frame.size.width/2) + 23, 
y: CGFloat(i) * wall.size.height) 
     wall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
wall.size.width - 30, height: wall.size.height)) 
     wall.physicsBody?.affectedByGravity = false 
     wall.physicsBody?.isDynamic = false 
     wall.physicsBody?.categoryBitMask = ColliderType.Wall1 
     self.addChild(wall) 
    } 
} 

func createWall2() { 
    for i in 0...2 { 
     let wall = SKSpriteNode(imageNamed: "Wall2") 
     wall.name = "Wall2" 
     wall.zPosition = 4 
     wall.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
     wall.position = CGPoint(x: (self.frame.size.width/2) - 23, y: 
CGFloat(i) * wall.size.height) 
     wall.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
wall.size.width - 30, height: wall.size.height)) 
     wall.physicsBody?.affectedByGravity = false 
     wall.physicsBody?.isDynamic = false 
     wall.physicsBody?.categoryBitMask = ColliderType.Wall2 
     self.addChild(wall) 
    } 
} 

func moveBackgrounds() { 

    enumerateChildNodes(withName: "BG", using: ({ 
     (node, error) in 

     node.position.y -= 5 

     if node.position.y < -(self.frame.height) { 
      node.position.y += self.frame.height * 3 
     } 

    })) 

    enumerateChildNodes(withName: "Wall1", using: ({ 
     (node, error) in 

     node.position.y -= 5 

     if node.position.y < -(self.frame.height) { 
      node.position.y += self.frame.height * 3 
     } 

    })) 

    enumerateChildNodes(withName: "Wall2", using: ({ 
     (node, error) in 

     node.position.y -= 5 

     if node.position.y < -(self.frame.height) { 
      node.position.y += self.frame.height * 3 
     } 

    })) 
} 

func createSwans() { 

    swan = SKSpriteNode(imageNamed: "Swan") 
    swan.name = "Swan" 

    swan.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    swan.position = CGPoint(x: 0, y: 300) 
    swan.zPosition = 5 
    swan.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
swan.size.width - 50, height: swan.size.height - 50)) 
    swan.physicsBody?.categoryBitMask = ColliderType.Swan 
    swan.physicsBody?.affectedByGravity = false 
    swan.physicsBody?.isDynamic = false 

    swan.position.y = self.size.height + 100 
    swan.position.x = CGFloat.randomBetweenNumbers(firstNum: -255, 
secondNum: 255) 

    self.addChild(swan) 

    let destination = self.frame.height * 2 
    let move = SKAction.moveTo(y: -destination, duration: 
TimeInterval(10)) 
    let remove = SKAction.removeFromParent() 

    swan.run(SKAction.sequence([move, remove]), withKey: "MoveSwans") 


} 

func spawnSwans() { 

    let spawn = SKAction.run({() -> Void in 
     self.createSwans() 
    }) 

    let delay = SKAction.wait(forDuration: TimeInterval(0.8)) 
    let sequence = SKAction.sequence([spawn, delay]) 

    self.run(SKAction.repeatForever(sequence), withKey: "SpawnSwans") 
} 

func createBranches() { 
    let branch = SKSpriteNode(imageNamed: "Branch") 
    branch.name = "Branch" 

    branch.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    branch.position = CGPoint(x: 0, y: 500) 
    branch.zPosition = 4 
    branch.physicsBody = SKPhysicsBody(rectangleOf: CGSize(width: 
branch.size.width - 30, height: branch.size.height - 30)) 
    branch.physicsBody?.categoryBitMask = ColliderType.Branch 
    branch.physicsBody?.affectedByGravity = false 
    branch.physicsBody?.isDynamic = false 
    branch.position.y = self.frame.height + 500 
    branch.position.x = CGFloat.randomBetweenNumbers(firstNum: -228, 
secondNum: 228) 

    self.addChild(branch) 

    let destination = self.size.height/1.5 
    let move = SKAction.moveTo(y: -destination, duration: 
TimeInterval(10)) 
    let remove = SKAction.removeFromParent() 

    branch.run(SKAction.sequence([move, remove]), withKey: 
"MoveBranches") 
} 

func spawnBranches() { 
    let spawn = SKAction.run({() -> Void in 
     self.createBranches() 
    }) 

    let delay = SKAction.wait(forDuration: TimeInterval(1.5)) 
    let sequence = SKAction.sequence([spawn, delay]) 

    self.run(SKAction.repeatForever(sequence), withKey: 
"SpawnBranches") 
} 

func createEggs() { 

    let egg = SKSpriteNode(imageNamed: "Egg") 
    egg.name = "Egg" 

    egg.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    egg.position = CGPoint(x: 0, y: 500) 
    egg.zPosition = 3 
    egg.setScale(0.3) 
    egg.physicsBody = SKPhysicsBody(circleOfRadius: egg.size.height/2 
- 5) 
    egg.physicsBody?.categoryBitMask = ColliderType.Score 
    egg.physicsBody?.collisionBitMask = 0 
    egg.physicsBody?.affectedByGravity = false 
    egg.physicsBody?.restitution = 0 
    egg.physicsBody?.isDynamic = false 

    egg.position.y = self.frame.height + 500 
    egg.position.x = CGFloat.randomBetweenNumbers(firstNum: -250, 
secondNum: 250) 

    self.addChild(egg) 

    let destination = self.size.height/2 
    let move = SKAction.moveTo(y: -destination, duration: 
TimeInterval(10)) 
    let remove = SKAction.removeFromParent() 

    egg.run(SKAction.sequence([move, remove]), withKey: "MoveEggs") 

} 
//testa göra likadant med createCrocodiles och spawnCrocodiles som du 
gör med createScore och spawnScore 
func spawnEggs() { 

    let spawn = SKAction.run({() -> Void in 
     self.createEggs() 
    }) 

    let delay = SKAction.wait(forDuration: TimeInterval(3)) 
    let sequence = SKAction.sequence([spawn, delay]) 

    self.run(SKAction.repeatForever(sequence), withKey: "SpawnEggs") 
} 

func createLabel() { 
    scoreLabel.zPosition = 7 
    scoreLabel.position = CGPoint(x: 0, y: -300) 
    scoreLabel.fontName = "Bradley Hand" 
    scoreLabel.fontSize = 120 
    scoreLabel.text = "0" 
    self.addChild(scoreLabel) 
} 

func incrementScore() { 
    score += 1 
    scoreLabel.text = String(score) 
} 

func playerDied() { 

    self.removeAction(forKey: "SpawnSwans") 
    self.removeAction(forKey: "SpawnBranches") 
    self.removeAction(forKey: "SpawnEggs") 

    for child in children { 
     if child.name == "Swan" { 
      child.removeAction(forKey: "MoveSwans") 
     } else if child.name == "Branch" { 
      child.removeAction(forKey: "MoveBranches") 
     } else if child.name == "Egg" { 
      child.removeAction(forKey: "MoveEggs") 
     } 
    } 

    isAlive = false 

    let highscore = GameManager.instance.getHighscore() 

    if highscore < score { 
     GameManager.instance.setHighscore(highscore: score) 
    } 

    let retry = SKSpriteNode(imageNamed: "Retry") 
    let quit = SKSpriteNode(imageNamed: "Quit") 

    retry.name = "Retry" 
    retry.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    retry.position = CGPoint(x: -150, y: 0) 
    retry.zPosition = 8 
    retry.setScale(0) 

    quit.name = "Quit" 
    quit.anchorPoint = CGPoint(x: 0.5, y: 0.5) 
    quit.position = CGPoint(x: 150, y: 0) 
    quit.zPosition = 8 
    quit.setScale(0) 

    let scaleUp = SKAction.scale(to: 1, duration: TimeInterval(0.5)) 

    retry.run(scaleUp) 
    quit.run(scaleUp) 

    self.addChild(retry) 
    self.addChild(quit) 


} 

func moveNodeToLocation() { 
    // Compute vector components in direction of the touch 
    var dx = location.x - player.position.x 
    // How fast to move the node. Adjust this as needed 
    let speed:CGFloat = 0.08 
    // Scale vector 
    dx = dx * speed 
    player.position = CGPoint(x:player.position.x+dx, y: 0) 
} 

} 

Antwort

0

ich Ihr Problem hier zu sehen, also wenn ich richtig verstehe, wollen Sie in der Lage sein, ein zu holen Power-Up oder eine Münze, ohne dass es mit Ihrem Player kollidiert.

In diesem Fall müssen Sie nur das Element, mit dem Sie nicht kollidieren wollen, von Ihrem Spieler collisionBitMask und umgekehrt entfernen, da dies bestimmt, was mit was kollidiert. Sie können den Kontakt mit contactBitMask noch überprüfen. Auch hier ist ein Link, der collisionBitMasks im Detail erklärt How does collisionBitMask work? Swift/SpriteKit!

+0

Ja genau, das ist was ich will. Das einzige Problem ist, dass ich nicht einmal die "Münze" in meinem Player CollisionBitMask habe, nur in der contactBitMask. Ich habe auch versucht, ".physicsbody.collisionBitMask = 0" sowohl auf den Spieler als auch auf die Münze zu setzen. Aber ich bekomme immer noch diese kleine Kollision, auch wenn es nicht so schlimm ist, es ist immer noch nervig. – Flinigan

Verwandte Themen