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)
}
}
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