sprite kit - Basic Swift SpriteKit Collisions using PhysicsBodys -
the problem: seem having little trouble getting player collide coin, , adding +1 coinlabel upon collision. player should continue moving after coming in contact coin.
what have now: code have now, player travels through coin, there no collision takes place , +1 isn't added coin label.
i still learning swift language, appreciate given.
code:
struct collidertype { static let playercategory: uint32 = 0x1 << 0 static let boundary: uint32 = 0x1 << 1 static let coincategory: uint32 = 0x1 << 2 static let bodya: uint32 = 0x1 << 4 static let bodyb: uint32 = 0x1 << 8 } override func didmovetoview(view: skview) { var coinint = 0 self.physicsworld.gravity = cgvectormake(0.0, -7.0) physicsworld.contactdelegate = self player = skspritenode(imagenamed: "player") player.zposition = 1 player.position = cgpoint(x: cgrectgetmidx(self.frame), y: cgrectgetmidy(self.frame)) player.physicsbody = skphysicsbody(circleofradius: player.size.width / 5.12) player.physicsbody?.dynamic = true player.physicsbody?.allowsrotation = false self.addchild(player) generatecoins() coin = skspritenode( imagenamed: "coin") coin.physicsbody? = skphysicsbody(circleofradius: coin.size.height / 10) coin.physicsbody?.dynamic = false coin.physicsbody?.allowsrotation = false coin.zposition = 1 self.addchild(coin) player.physicsbody?.categorybitmask = collidertype.playercategory player.physicsbody?.contacttestbitmask = collidertype.boundary player.physicsbody?.collisionbitmask = collidertype.coincategory | collidertype.boundary coin.physicsbody?.categorybitmask = collidertype.coincategory coin.physicsbody?.contacttestbitmask = collidertype.playercategory coin.physicsbody?.collisionbitmask = collidertype.playercategory func didplayercollidewithcoin(player: skspritenode, coin: skspritenode) { self.coin.removefromparent() self.coin += 1 coinlabel.text = "\(coinint)" } func generatecoins() { if(self.actionforkey("spawning") != nil){return} let cointimer = skaction.waitforduration(7, withrange: 2) let spawncoin = skaction.runblock { self.coin = skspritenode( imagenamed: "coin") self.coin.physicsbody = skphysicsbody(circleofradius: self.coin.size.height / 10) self.coin.name = "coin" self.coin.physicsbody?.dynamic = false self.coin.physicsbody?.allowsrotation = false var coinposition = array<cgpoint>() coinposition.append((cgpoint(x:340, y:103))) coinposition.append((cgpoint(x:340, y:148))) coinposition.append((cgpoint(x:340, y:218))) coinposition.append((cgpoint(x: 340, y:343))) let spawnlocation = coinposition[int(arc4random_uniform(uint32(coinposition.count)))] let action = skaction.repeatactionforever(skaction.movetox(+self.xscale, duration: 4.4)) self.coin.runaction(action) self.coin.position = spawnlocation self.addchild(self.coin) print(spawnlocation) } let sequence = skaction.sequence([cointimer, spawncoin]) self.runaction(skaction.repeatactionforever(sequence), withkey: "spawning") } func didbegincontact(contact:skphysicscontact) { let bodya: skphysicsbody = contact.bodya let bodyb: skphysicsbody = contact.bodyb if ((bodya.categorybitmask == collidertype.playercategory) && (bodyb.categorybitmask == collidertype.coincategory)){ didplayercollidewithcoin(bodya.node as! skspritenode, coin: bodyb.node as! skspritenode) } }
you try leaving contacttestbitmasks same remove collisionbitmasks between player , coin:
player.physicsbody?.categorybitmask = collidertype.playercategory player.physicsbody?.contacttestbitmask = collidertype.boundary player.physicsbody?.collisionbitmask = collidertype.boundary coin.physicsbody?.categorybitmask = collidertype.coincategory coin.physicsbody?.contacttestbitmask = collidertype.playercategory
this way, when player collides coin register, wont "bounce off" , continue moving in same direction.
*note: using may require use
func didbegincontact(contact: skphysicscontact) {
method instead of
func didplayercollidewithcoin(player: skspritenode, coin: skspritenode) {
but recommend trying didplayercollidewithcoin() method first.
in case need it, implemented this:
func didbegincontact(contact: skphysicscontact) { var firstbody: skphysicsbody var secondbody: skphysicsbody if contact.bodya.categorybitmask < contact.bodyb.categorybitmask { firstbody = contact.bodya secondbody = contact.bodyb } else { firstbody = contact.bodyb secondbody = contact.bodya } if firstbody.categorybitmask == playercategory && secondbody.categorybitmask == coincategory { print("your player passes through coin") score = score + 1 } }
for more details see tutorial ray wenderlich: https://www.raywenderlich.com/123393/how-to-create-a-breakout-game-with-sprite-kit-and-swift