Tuesday 15 May 2012

ios - Swift/SpriteKit Multiple Collision Detection? -



ios - Swift/SpriteKit Multiple Collision Detection? -

hello.

i have multiple collision problem. there bullet, hits enemy(red rectangle). then, ++ score. there spiral (red circle) supossed trigger scene end when enemy (red rectangle) touches it.

in situation, when enemy hits spiral, works, scene ends, , go menu screen. but, when bullet hits enemy, same thing happens, , don't know why.

now, here's code:

struct physicscategory { static allow none : uint32 = 0 static allow : uint32 = uint32.max static allow enemyone : uint32 = 0b1 static allow enemytwo : uint32 = 0b1 static allow bullet : uint32 = 0b10 static allow spiral : uint32 = 0b111 } spiral.physicsbody = skphysicsbody(rectangleofsize: spiral.size) spiral.physicsbody?.categorybitmask = physicscategory.spiral spiral.physicsbody?.contacttestbitmask = physicscategory.enemyone spiral.physicsbody?.collisionbitmask = physicscategory.none ... enemyone.physicsbody = skphysicsbody(rectangleofsize: enemyone.size) enemyone.physicsbody?.dynamic = true enemyone.physicsbody?.categorybitmask = physicscategory.enemyone enemyone.physicsbody?.contacttestbitmask = physicscategory.bullet | physicscategory.spiral enemyone.physicsbody?.collisionbitmask = physicscategory.none ... bullet.physicsbody = skphysicsbody(circleofradius: bullet.size.width / 2) bullet.physicsbody?.dynamic = true bullet.physicsbody?.categorybitmask = physicscategory.bullet bullet.physicsbody?.contacttestbitmask = physicscategory.enemyone bullet.physicsbody?.collisionbitmask = physicscategory.none bullet.physicsbody?.usesprecisecollisiondetection = true ... func bulletdidcollidewithenemy(bullet: skspritenode, enemyone: skspritenode) { scoreonscreen.text = string(score) score++ bullet.removefromparent() enemyone.removefromparent() } func enemydidcollidewithspiral(enemyone: skspritenode, spiral: skspritenode) { allow transition = sktransition.revealwithdirection(sktransitiondirection.down, duration: 1.0) allow skview = self.view! skview allow scene = menuscene(size: skview.bounds.size) scene.scalemode = skscenescalemode.aspectfill skview.presentscene(scene, transition: sktransition.crossfadewithduration(0.5)) } // did begin contact func didbegincontact(contact: skphysicscontact) { var firstbody : skphysicsbody var secondbody : skphysicsbody var thirdbody : skphysicsbody var fourthbody : skphysicsbody if contact.bodya.categorybitmask < contact.bodyb.categorybitmask { firstbody = contact.bodya secondbody = contact.bodyb } else { firstbody = contact.bodyb secondbody = contact.bodya } if contact.bodya.categorybitmask < contact.bodyb.categorybitmask { thirdbody = contact.bodya fourthbody = contact.bodyb } else { thirdbody = contact.bodyb fourthbody = contact.bodya } if (firstbody.categorybitmask & physicscategory.enemyone != 0) && (secondbody.categorybitmask & physicscategory.bullet != 0) { bulletdidcollidewithenemy(firstbody.node skspritenode, enemyone : secondbody.node skspritenode) } if (thirdbody.categorybitmask & physicscategory.enemyone != 0) && (fourthbody.categorybitmask & physicscategory.spiral != 0) { enemydidcollidewithspiral(thirdbody.node skspritenode, spiral : fourthbody.node skspritenode) }

now, know it's mess, can help me? think problem has bodya.categorybitmask , bodyb beingness set different things thought same(?). don't know. anyone?

several problems here.

you're defining categories in way keeps them beingness tested. you're testing categories in way doesn't unique answers want. you've confused code trying track 4 bodies in 1 contact. contact have 2 bodies.

let's solve them 1 @ time...

1. defining categories

you wan define collision categories each kind of body in game uses own bit in mask. (you've got thought using swift's binary literal notation, you're defining categories overlap.) here's illustration of non-overlapping categories:

enum physicscategory : uint32 { case none = 0 case = 0xffffffff case enemy = 0b001 case bullet = 0b010 case spiral = 0b100 }

i'm using swift enum this, since makes defining unique values easy. also, i'm using binary literal notation , whitespace , zeroes in code it's easy create sure each category gets own bit — enemy gets to the lowest degree important bit, bullet next one, etc.

2 & 3. testing & tracking categories

i utilize two-tiered approach contact handlers. first, check kind of collision — bullet/enemy collision or bullet/spiral collision or spiral/enemy collision? then, if necessary check see body in collision which. doesn't cost much in terms of computation, , makes clear @ every point in code what's going on.

func didbegincontact(contact: skphysicscontact) { // step 1. bitiwse or bodies' categories find out kind of contact have allow contactmask = contact.bodya.categorybitmask | contact.bodyb.categorybitmask switch contactmask { case physicscategory.enemy.rawvalue | physicscategory.bullet.rawvalue: // step 2. disambiguate bodies in contact if contact.bodya.categorybitmask == physicscategory.enemy.rawvalue { handlecollision(enemy: contact.bodya.node skspritenode, bullet: contact.bodyb.node skspritenode) } else { handlecollision(enemy: contact.bodyb.node skspritenode, bullet: contact.bodya.node skspritenode) } case physicscategory.enemy.rawvalue | physicscategory.spiral.rawvalue: // here don't care body which, scene ending gotoendgame() case physicscategory.bullet.rawvalue | physicscategory.spiral.rawvalue: println("bullet + spiral") // maybe don't care bullet/spiral collision? // set here completeness, can omit // or set contacttestbitmask ignore exclusively default: // nobody expects this, satisfy compiler , grab // ourselves if didn't plan fatalerror("other collision: \(contactmask)") } }

ios swift sprite-kit collision-detection collision

No comments:

Post a Comment