0

In my game I have planes moving around. In my game, I want so that if any plane collides with another, it prints "game over". I have added SKPhysicsContactDelegate to my gamescene. I added a physics bodies to my planes. Then, I added this function to my didMoveToView function:

  func didBegin(_ contact: SKPhysicsContact){
        print("Game over")
        }

Now, when I run my game, and the planes collide, nothing prints to the console. How can I change my code so if any plane collides with another (there are more than 2) it prints game over to the console?

Edit: I have set the physics world contact delegate to self. I have not called this function - do I have to - I thought that this function runs when there is a collision in the scene.

Here is my code:

//
//  GameScene.swift
//  PlaneGame
//
//  Created by Lucas Farleigh on 09/04/2017.
//  Copyright © 2017 Farleigh Tech. All rights reserved.
//

import SpriteKit
import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {

private let Background = SKSpriteNode(imageNamed: "Background")
private let PlaneRed = SKSpriteNode(imageNamed: "PlaneRed")
private let PlaneBlue = SKSpriteNode(imageNamed: "PlaneBlue")
private let PlaneRed2 = SKSpriteNode(imageNamed: "PlaneRed2")
private let PlaneBlue2 = SKSpriteNode(imageNamed: "PlaneBlue2")
private let StartButton = SKLabelNode(fontNamed: "Chalkduster")
private let Trail = SKSpriteNode(imageNamed: "BlueTrail")
private let Center = SKNode()
private let Center2 = SKNode()
var GameHasStarted = false




override func didMove(to view: SKView) {

    //Defining the position,size and ZPosition for the background
    Background.position = CGPoint(x:self.frame.midX / 2,y: self.frame.midY)
    Background.xScale = 10.0
    Background.yScale = 10.0
    Background.zPosition = -10
    addChild(Background)



    //Defining a start button - will be used later as a button
    StartButton.position = CGPoint(x:self.frame.midX,y:self.frame.minY + 100)
    StartButton.text = "Tap Anywhere To Start"
    StartButton.fontSize = 50.0
    StartButton.name = "StartButton"
    addChild(StartButton)

    //Setting the planered position and size up for the plane, ready to start the game
    PlaneRed.position = CGPoint(x:self.frame.midX - 250,y: self.frame.midY)
    PlaneRed.xScale = 0.13
    PlaneRed.yScale = 0.13
    PlaneRed.zPosition = 10
    //Setting the planeblue position and size up for the plane, ready to start the game
    PlaneBlue.position = CGPoint(x:self.frame.midX + 250,y: self.frame.midY)
    PlaneBlue.xScale = 0.13
    PlaneBlue.yScale = -0.13
    PlaneBlue.zPosition = 10

    //Setting the planered position and size up for the plane, ready to start the game
    PlaneRed2.position = CGPoint(x:self.frame.midX,y: self.frame.midY + 250)
    PlaneRed2.xScale = -0.13
    PlaneRed2.yScale = 0.13
    PlaneRed2.zPosition = 10
    //Setting the planeblue position and size up for the plane, ready to start the game
    PlaneBlue2.position = CGPoint(x:self.frame.midX,y: self.frame.midY - 250)
    PlaneBlue2.xScale = 0.13
    PlaneBlue2.yScale = 0.13
    PlaneBlue2.zPosition = 10


    //Making the trail
    Trail.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    Trail.xScale = 1.08
    Trail.yScale = 1.08
    addChild(Trail)

    //In order to rotate the planes around a point, we must create the point as an SKNode, and make the planes a child of the point
    //The point then rotates bringing the planes with it
    //Setting up the point where the plane will rotate around
    Center.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    addChild(Center)
    Center2.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    addChild(Center2)
    Center.addChild(PlaneRed)
    Center.addChild(PlaneBlue)
    Center2.addChild(PlaneRed2)
    Center2.addChild(PlaneBlue2)



    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //ADDING PHYSICS TO PLANES
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //Defining the red planes physics body
    PlaneRed.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed.size)
    PlaneRed2.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed2.size)
    physicsWorld.contactDelegate = self
    physicsWorld.gravity = CGVector.zero
    func didBegin(contact: SKPhysicsContact){
        print("Game over")

    }
}








func Start(){
    //Defining an SKAction for the plane to orbit the center
    let OrbitCenter = SKAction.rotate(byAngle: CGFloat(-2), duration: 3.8)
    let Orbit = SKAction.repeatForever(OrbitCenter)
    //Creating the action for the center 2 to rotate anti clockwise
    let AntiOrbitCenter = SKAction.rotate(byAngle: CGFloat(2), duration: 3.8)
    let AntiOrbit = SKAction.repeatForever(AntiOrbitCenter)

    //Running the SKAction on the plane
    Center.run(Orbit)
    Center2.run(AntiOrbit)


}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?){
    for touch in touches{
    //Setting up the touch settings - these two variables store the nodes that the user has touched by first defining the location and then checking for nodes at this location
    let location = touch.location(in: self)
    let node = self.atPoint(location)


        if GameHasStarted == false{
            Start()
            GameHasStarted = true

        }





    }
}




override func update(_ currentTime: TimeInterval) {
    // Called before each frame is rendered
} 
}
Alessandro Ornano
  • 34,887
  • 11
  • 106
  • 133
Lucas Smith
  • 698
  • 2
  • 9
  • 17

1 Answers1

2

First

Your didBegin func needs to be outside of didMove func

override func didMove(to view: SKView) {
}

func didBegin(_ contact: SKPhysicsContact) {

    print("Game over")
}

second

you need to setup some physics categories for your objects so they know what they can collide with, what they can pass through and what collisions don't matter. You can put this outside your class declaration

//Game Physics
struct PhysicsCategory {
    static let plane: UInt32 = 0x1 << 0
    static let plane2: UInt32 = 0x1 << 1
    static let obstacle: UInt32 = 0x1 << 2
}

third

You need to add those physics decorations to your objects

    //Defining the red planes physics body
    PlaneRed.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed.size)
    PlaneRed.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneRed.physicsBody?.isDynamic = true

    PlaneRed2.physicsBody = SKPhysicsBody(rectangleOf: PlaneRed2.size)
    PlaneRed2.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneRed2.physicsBody?.isDynamic = true

    PlaneBlue.physicsBody = SKPhysicsBody(rectangleOf: PlaneBlue.size)
    PlaneBlue.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneBlue.physicsBody?.isDynamic = true

    PlaneBlue2.physicsBody = SKPhysicsBody(rectangleOf: PlaneBlue2.size)
    PlaneBlue2.physicsBody?.categoryBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.collisionBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.contactTestBitMask = PhysicsCategory.plane
    PlaneBlue2.physicsBody?.isDynamic = true

    self.physicsWorld.contactDelegate = self
    self.physicsWorld.gravity = CGVector.zero
Ron Myschuk
  • 6,011
  • 2
  • 20
  • 32
  • How come all the physics categories are set to the same value(0 x 1) – Lucas Smith Apr 25 '17 at 12:22
  • They look the same but they're not. They're bitmasks You can also set them to powers of 2 plane = 0, plane2 = 1 obstacle = 2, ground = 4. more can be read here http://stackoverflow.com/questions/24069703/how-to-define-category-bit-mask-enumeration-for-spritekit-in-swift – Ron Myschuk Apr 25 '17 at 13:31
  • Why do we need to use UInt32 for categories? Also - I have seen the word bitmask many times in different places. I know a very very basic definition however, I have seen it in many places, for example, categoryBitMask - what would be a basic definition universally? – Lucas Smith Apr 25 '17 at 15:10
  • Lucas, I'm not an expert on bitmasks. I barely understand them myself. If you have a day to invest I suggest you read up on them, but it's not an easy subject – Ron Myschuk Apr 25 '17 at 15:13
  • Ok, thank you very much, however, why do I need to add static when defining the categories, because when I do not I get an error. – Lucas Smith Apr 25 '17 at 16:20
  • Sorry @LucasFarleigh i'm at work and can't really get into this. My best suggestion would be to post these as a new question regarding physicsBody categories. As it really is part of this question – Ron Myschuk Apr 25 '17 at 16:29