Reputation: 53
I followed many different tutorials on collision and created my own game where i want to declare a collision between a coin and a player. However, after implementing the collision code my two nodes are not responding to the collision...can someone help me out please?
import SpriteKit
import GameplayKit
// Collision categories
enum ColliderType: UInt32 {
case playerCase = 1
case coinCase = 2
case borderCase = 3
}
class GameScene: SKScene, SKPhysicsContactDelegate {
let player = SKSpriteNode(imageNamed:"block")
let buttonDirLeft = SKSpriteNode(imageNamed: "left")
let buttonDirRight = SKSpriteNode(imageNamed: "right")
let coins = SKSpriteNode(imageNamed: "coins")
let background = SKSpriteNode(imageNamed: "background")
var pressedButtons = [SKSpriteNode]()
override func didMove(to view: SKView) {
self.physicsWorld.contactDelegate = self
//score label
let points = SKLabelNode(text: "0")
points.position = CGPoint(x: 530, y: 260)
points.zPosition = 6
points.fontColor = UIColor.black
points.fontSize = 50
addChild(points)
//Set Background
background.zPosition = 1
background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
background.size.width = 580
background.size.height = 320
addChild(background)
// Player
player.position = CGPoint(x: 250, y: 40)
player.zPosition = 2
player.texture?.filteringMode = .nearest
// player!.collisionBitMask = 0 //
player.physicsBody = SKPhysicsBody(circleOfRadius: player.size.height / 2.0)
player.physicsBody?.isDynamic = false
player.physicsBody?.allowsRotation = false
player.physicsBody?.affectedByGravity = false
player.physicsBody!.categoryBitMask = ColliderType.playerCase.rawValue
player.physicsBody!.contactTestBitMask = ColliderType.coinCase.rawValue
player.physicsBody!.collisionBitMask = ColliderType.coinCase.rawValue
self.addChild(player)
// button left
buttonDirLeft.position = CGPoint(x: 30, y: 35)
buttonDirLeft.zPosition = 4
buttonDirLeft.size.width = 270
buttonDirLeft.size.height = 320
buttonDirLeft.alpha = 0.0
self.addChild(buttonDirLeft)
// button right
buttonDirRight.position = CGPoint(x: 530, y: 35)
buttonDirRight.zPosition = 4
buttonDirRight.size.width = 270
buttonDirRight.size.height = 320
buttonDirRight.alpha = 0.0
self.addChild(buttonDirRight)
// setting border around game
let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
borderBody.friction = 0
self.physicsBody = borderBody
//ENEMY SETTINGS START
//repeat coing spawning
run(SKAction.repeatForever(
SKAction.sequence([
SKAction.run(spawnCoins),
SKAction.wait(forDuration: 1.0)])))
}
//coin settings
func random() -> CGFloat {
return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}
func random(min: CGFloat, max: CGFloat) -> CGFloat {
return random() * (max - min) + min
}
//spawn coins
func spawnCoins() {
// 2
let coins = SKSpriteNode(imageNamed: "coins")
coins.zPosition = 2
coins.size.width = 40
coins.size.height = 40
let action = SKAction.moveTo(y: -350, duration: TimeInterval(random(min: 1, max: 5)))
let remove = SKAction.run({coins.removeFromParent(); print("coins removed from scene")})
let sequence = SKAction.sequence([action,remove])
coins.physicsBody = SKPhysicsBody(rectangleOf: coins.size )
coins.physicsBody?.isDynamic = false
coins.physicsBody!.affectedByGravity = false
coins.physicsBody!.categoryBitMask = ColliderType.coinCase.rawValue
coins.physicsBody!.contactTestBitMask = ColliderType.playerCase.rawValue
coins.physicsBody!.collisionBitMask = ColliderType.playerCase.rawValue
coins.run(sequence)
coins.size.width = 20
coins.size.height = 20
coins.name = "coins"
// coins.physicsBody!.collisionBitMask = 0
coins.position = CGPoint(x: frame.size.width * random(min: 0, max: 1), y: frame.size.height + coins.size.height/2)
addChild(coins)
}
override func update(_ currentTime: TimeInterval) {
// Called before each frame is rendered
/* Called before each frame is rendered */
if pressedButtons.index(of: buttonDirLeft) != nil {
player.position.x -= 3.0
}
if pressedButtons.index(of: buttonDirRight) != nil {
player.position.x += 3.0
}
// Update entities
}
//MOVEMENT FUNCTIONS START HERE
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
for button in [buttonDirLeft, buttonDirRight] {
// I check if they are already registered in the list
if button.contains(location) && pressedButtons.index(of: button) == nil {
pressedButtons.append(button)
}
}
}
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
for button in [buttonDirLeft, buttonDirRight] {
// if I get off the button where my finger was before
if button.contains(previousLocation)
&& !button.contains(location) {
// I remove it from the list
let index = pressedButtons.index(of: button)
if index != nil {
pressedButtons.remove(at: index!)
}
}
// if I get on the button where I wasn't previously
else if !button.contains(previousLocation)
&& button.contains(location)
&& pressedButtons.index(of: button) == nil {
// I add it to the list
pressedButtons.append(button)
}}}}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
for button in [buttonDirLeft, buttonDirRight] {
if button.contains(location) {
let index = pressedButtons.index(of: button)
if index != nil {
pressedButtons.remove(at: index!)
}
}
else if (button.contains(previousLocation)) {
let index = pressedButtons.index(of: button)
if index != nil {
pressedButtons.remove(at: index!)
}
}
}
}
}
override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
let location = touch.location(in: self)
let previousLocation = touch.previousLocation(in: self)
for button in [buttonDirLeft, buttonDirRight] {
if button.contains(location) {
let index = pressedButtons.index(of: button)
if index != nil {
pressedButtons.remove(at: index!)
}
}
else if (button.contains(previousLocation)) {
let index = pressedButtons.index(of: button)
if index != nil {
pressedButtons.remove(at: index!)
}
}
}
}
}
func didBeginContact(contact: SKPhysicsContact){
print("colliding!")
}
Upvotes: 2
Views: 49
Reputation: 13665
Contact will happen only if at least one body is dynamic. So either set your player or coin to be dynamic and if everything else is set correctly (if categories are set properly and didBeginContact
method implementation is correct) your bodies will now collide / make contacts. If you are interested only in contacts, set collision bit mask to 0.
Upvotes: 2