Reputation: 411
I have been working at this for about a week now, and I am in need of help. Please figure out why this won't work!
(P.S. I have SKPhysicsContactDelegate in my GameScene. Also, I have self.physicsWorld.contactDelegate = self
in my didMoveToView.)
Here is my code:
This is out outside of the didMoveToView:
let squareGroup: UInt32 = 1
let obstacleGroup: UInt32 = 2
This is inside my didMoveToView:
square.position = CGPointMake(self.size.width/2, self.size.height/1.5)
square.zPosition = 35
square.size = CGSize(width: 40, height: 40)
square.physicsBody = SKPhysicsBody(rectangleOfSize: square.size)
square.physicsBody?.affectedByGravity = false
square.physicsBody?.dynamic = true
square.physicsBody?.allowsRotation = false
square.physicsBody?.categoryBitMask = squareGroup
square.physicsBody?.collisionBitMask = obstacleGroup
square.physicsBody?.contactTestBitMask = obstacleGroup
square.name = "Square"
self.addChild(square)
This is also inside my didMoveToView: *AND: Nothing happens when the square and obstacle touch. It doesn't print contact or anything.
func didBeginContact(contact: SKPhysicsContact) {
print("contact")
let newScene = GameplayScene(size: self.size)
_ = SKTransition.fadeWithDuration(1)
self.view?.presentScene(newScene)
}
Lastly, this is my obstacle code, which is outside of the didMoveToView: Please NOTE: I am only trying out Obstacle 2 at the moment to get it to work.
func addObstacles() {
let obstacle1 = SKSpriteNode(imageNamed: "Obstacle")
let obstacle2 = SKSpriteNode(imageNamed: "Obstacle")
obstacle1.xScale = 2
obstacle2.xScale = 2
func randInRange(range: Range<Int>) -> Int {
return Int(arc4random_uniform(UInt32(range.endIndex - range.startIndex))) + range.startIndex
}
let random = randInRange(205...470)
let moveDown1 = SKAction.moveByX(0, y: -self.size.width, duration: 2.5)
let repeatAction1 = SKAction.repeatActionForever(moveDown1)
let removeObstacle1 = SKAction.removeFromParent()
let moveAndRemove1 = SKAction.sequence([repeatAction1, removeObstacle1])
obstacle1.position = CGPointMake(CGFloat(random), self.frame.size.height * 2)
obstacle1.zPosition = 40
obstacle1.physicsBody = SKPhysicsBody(rectangleOfSize: obstacle1.size)
obstacle1.physicsBody?.affectedByGravity = false
obstacle1.physicsBody?.dynamic = false
obstacle1.runAction(moveAndRemove1)
self.addChild(obstacle1)
let moveDown2 = SKAction.moveByX(0, y: -self.size.width, duration: 2.5)
let repeatAction2 = SKAction.repeatActionForever(moveDown2)
let removeObstacle2 = SKAction.removeFromParent()
let moveAndRemove2 = SKAction.sequence([repeatAction2, removeObstacle2])
obstacle2.position = CGPointMake(CGFloat(random) + 460, self.frame.size.height * 2)
obstacle2.zPosition = 40
obstacle2.physicsBody = SKPhysicsBody(rectangleOfSize: obstacle2.size)
obstacle2.physicsBody?.affectedByGravity = false
obstacle2.physicsBody?.dynamic = false
obstacle2.physicsBody?.categoryBitMask = obstacleGroup
obstacle2.name = "Obstacle2"
obstacle2.runAction(moveAndRemove2)
self.addChild(obstacle2)
}
func repeatObstacles() {
let generateObstacles = SKAction.sequence([SKAction.runBlock(self.addObstacles), SKAction.waitForDuration(1.3)])
let endlessAction = SKAction.repeatActionForever(generateObstacles)
runAction(endlessAction)
}
I've been stuck on this for a while now. If you need more information just ask me! I need help.
Upvotes: 1
Views: 78
Reputation: 16837
First: change your contact code to look like this
func didBeginContact(contact: SKPhysicsContact) {
print("contact")
if ((contact.bodyA.categoryBitMask == squareGroup && contact.bodyB.categoryBitMask == obstacleGroup) ||
(contact.bodyA.categoryBitMask == obstacleGroup && contact.bodyB.categoryBitMask == squareGroup)) {
NSNotificationCenter.defaultCenter().postNotificationName("Gameover",object:nil,userInfo:nil);
}
}
It is bad practice to assign a new scene inside of your current scene, this is something that you should be telling the view to do. Start a chat with me on here and I will go over how to set this up in your view, since this is not part of the current answer. There are better ways to handle this, posting a notification is the easiest way to get you started with communicating your view, lets get this working, then you can research how to create delegates.
Second, add the contact and collision groups to your obstacle 2 object:
obstacle2.physicsBody?.collisionBitMask = obstacleGroup
obstacle2.physicsBody?.contactTestBitMask = squareGroup
as pointed out by @Darvydas
Third, switch obstacle2 dynamic to true since you want this to interact with other items:
obstacle2.physicsBody?.dynamic = false
Now you should be getting into the didBeginContact method, put a breakpoint on the print("contact")
to see if you are getting in there.
Fourth, take the didBeginContact
function out of the didMoveToView otherwise it will never get called. (If we had seen this code in the question correctly, it would have been solved)
Upvotes: 1
Reputation: 974
categoryBitMask
should be defined like this:
let squareGroup: UInt32 = 0x1 << 1
let obstacleGroup: UInt32 = 0x1 << 2
Also define obstacles collisionBitMask
obstacle2.physicsBody?.collisionBitMask = obstacleGroup
And your obstacle contactTestBitMask
obstacle2.physicsBody?.contactTestBitMask = squareGroup
Check for contact:
func didBeginContact(contact: SKPhysicsContact) {
if ((contact.bodyA.categoryBitMask == squareGroup && contact.bodyB.categoryBitMask == obstacleGroup) ||
(contact.bodyA.categoryBitMask == obstacleGroup && contact.bodyB.categoryBitMask == squareGroup)) {
// Handle Contact
}
}
Upvotes: 2