ios - Swift Physics-fatal error: unexpectedly found nil while unwrapping an Optional value when two characters collide -
background on game: control character moves right , left , try dodge falling blocks. there 3 players spawned. 1 in middle of screen, , 2 size.width away middle player on either sides.
this error happens once in around 10 collisions playerright or playerleft or player , falling blocks. can see screenshot below, player not seem touching falling block when crashes.
error code , screenshots:
fatal error: unexpectedly found nil while unwrapping optional value (lldb)
thread 1: exc_bad_instruction (code=exc_l386_invop, subcode=0x0)
how game scene stopped
i'm thinking has how built "infinitely" horizontal scrolling player. have 3 separate characters , once middle character goes past size.width or below 0 position on screen changed opposite side of screen making infinite. maybe player teleported inside of block , gives nil error. not sure looks has that. anyway, heres relevant code gamescene.
import spritekit import foundation import uikit //collisions struct physicscategory { static let enemy : uint32 = 1 static let player : uint32 = 2 static let playerright : uint32 = 3 static let playerleft : uint32 = 4 static let enemyright : uint32 = 5 } var transition:sktransition = sktransition.fadewithduration(0.5) class gamescene: skscene, skphysicscontactdelegate { //highscore variable var highscore = int() //score var score : int = 0 var scorelabel = uilabel() //main character var player = skspritenode(imagenamed: "mainplayer.png") //right-far character var playerright = skspritenode(imagenamed: "mainplayer.png") //left-far character var playerleft = skspritenode(imagenamed: "mainplayer.png") //holding vs tapping movement of player var istouching = false var touchxposition:cgfloat = 0 override func didmovetoview(view: skview) { /* setup scene here */ //highscore var highscoredefault = nsuserdefaults.standarduserdefaults() if (highscoredefault.valueforkey("highscore") != nil) { highscore = highscoredefault.valueforkey("highscore") as! nsinteger } else { highscore = 0 } //collisions/physics physicsworld.contactdelegate = self //background color scene?.backgroundcolor = uicolor.blackcolor() //spawn timer enemy blocks var timer = nstimer.scheduledtimerwithtimeinterval(0.4, target: self, selector: selector("spawnenemies"), userinfo: nil, repeats: true) //timer keeping score var scoretimer = nstimer.scheduledtimerwithtimeinterval(0.1, target: self, selector: selector("scorecounter"), userinfo: nil, repeats: true) //player coordinates player.position.x = size.width * 0.5 player.position.y = size.width * 0.11 / 2 //setting player sizes player.size.width = size.width * 0.11 player.size.height = size.width * 0.11 playerright.size.width = size.width * 0.11 playerright.size.height = size.width * 0.11 playerleft.size.width = size.width * 0.11 playerleft.size.height = size.width * 0.11 //initial position of player player.position = cgpoint(x: player.position.x, y: player.position.y) //initial position of far-right player playerright.position = cgpoint(x: player.position.x + size.width, y: player.position.y) //initial position of far-left player playerleft.position = cgpoint(x: player.position.x - size.width, y: player.position.y) //adding physics/collisions player player.physicsbody = skphysicsbody (rectangleofsize: player.size) player.physicsbody?.affectedbygravity = false player.physicsbody?.categorybitmask = physicscategory.player player.physicsbody?.contacttestbitmask = physicscategory.enemy player.physicsbody?.dynamic = false //adding physics/collisions playerright playerright.physicsbody = skphysicsbody (rectangleofsize: playerright.size) playerright.physicsbody?.affectedbygravity = false playerright.physicsbody?.categorybitmask = physicscategory.playerright playerright.physicsbody?.contacttestbitmask = physicscategory.enemy playerright.physicsbody?.dynamic = false //adding physics/collisions playerleft playerleft.physicsbody = skphysicsbody (rectangleofsize: playerright.size) playerleft.physicsbody?.affectedbygravity = false playerleft.physicsbody?.categorybitmask = physicscategory.playerleft playerleft.physicsbody?.contacttestbitmask = physicscategory.enemy playerleft.physicsbody?.dynamic = false //making players visible self.addchild(player) self.addchild(playerright) self.addchild(playerleft) //making score visible scorelabel.text = "\(score)" scorelabel = uilabel(frame: cgrect(x: 0, y: 0, width: 100, height: 20)) scorelabel.font = uifont(name: scorelabel.font.fontname, size:20) scorelabel.textcolor = uicolor.whitecolor() self.view?.addsubview(scorelabel) } func scorecounter() { //setting score score += 1 scorelabel.text = "\(score)" } func didbegincontact(contact: skphysicscontact) { var firstbody : skphysicsbody = contact.bodya var secondbody : skphysicsbody = contact.bodyb //checking player enemy collisions if ((firstbody.categorybitmask == physicscategory.enemy) && (secondbody.categorybitmask == physicscategory.player)){ collisionwithenemy(firstbody.node as! skshapenode, player: secondbody.node as! skspritenode) } else if (firstbody.categorybitmask == physicscategory.player) && (secondbody.categorybitmask == physicscategory.enemy) { collisionwithenemy2(firstbody.node as! skspritenode, enemy: secondbody.node as! skshapenode) } //checking playerright enemy collisions if ((firstbody.categorybitmask == physicscategory.enemy) && (secondbody.categorybitmask == physicscategory.playerright)){ collisionwithenemy(firstbody.node as! skshapenode, player: secondbody.node as! skspritenode) } else if (firstbody.categorybitmask == physicscategory.playerright) && (secondbody.categorybitmask == physicscategory.enemy) { collisionwithenemy2(firstbody.node as! skspritenode, enemy: secondbody.node as! skshapenode) } //checking playerleft enemy collisions if ((firstbody.categorybitmask == physicscategory.enemy) && (secondbody.categorybitmask == physicscategory.playerleft)){ collisionwithenemy(firstbody.node as! skshapenode, player: secondbody.node as! skspritenode) } else if (firstbody.categorybitmask == physicscategory.playerleft) && (secondbody.categorybitmask == physicscategory.enemy) { collisionwithenemy2(firstbody.node as! skspritenode, enemy: secondbody.node as! skshapenode) } } func collisionwithenemy(enemy: skshapenode, player: skspritenode) { //highscore var scoredefault = nsuserdefaults.standarduserdefaults() scoredefault.setvalue(score, forkey: "score") scoredefault.synchronize() if (score > highscore) { var highscoredefault = nsuserdefaults.standarduserdefaults() highscoredefault.setvalue(score, forkey: "highscore") } //var gameover:skscene = gameoverscene(size: self.size) //scorelabel.removefromsuperview() enemy.removefromparent() //player.removefromparent() //self.view?.presentscene(gameover, transition: transition) } func collisionwithenemy2(player: skspritenode, enemy: skshapenode) { //highscore var scoredefault = nsuserdefaults.standarduserdefaults() scoredefault.setvalue(score, forkey: "score") scoredefault.synchronize() if (score > highscore) { var highscoredefault = nsuserdefaults.standarduserdefaults() highscoredefault.setvalue(score, forkey: "highscore") } //var gameover:skscene = gameoverscene(size: self.size) //scorelabel.removefromsuperview() enemy.removefromparent() //player.removefromparent() //self.view?.presentscene(gameover, transition: transition) } override func touchesbegan(touches: set<nsobject>, withevent event: uievent) { /* called when touch begins */ istouching = true touch in (touches as! set<uitouch>) { let location = touch.locationinnode(self) touchxposition = location.x } } override func touchesended(touches: set<nsobject>, withevent event: uievent) { istouching = false } func spawnenemies() { //randomizing width of blocks var blockwidth = int(arc4random_uniform(uint32(size.width / 3)) + uint32(size.width / 5)) //min , max position of blocks var minposition : uint32 = uint32(blockwidth / 2) var maxposition : uint32 = uint32(size.width - cgfloat(blockwidth / 2)) //randomizing block position var blockxposition = arc4random_uniform(maxposition - minposition) + minposition //making blocks var enemy = skshapenode(rectofsize: cgsize(width: blockwidth, height: 5)) enemy.position = cgpointmake (cgfloat(blockxposition), cgfloat(size.height+50)) //coloring blocks enemy.fillcolor = skcolor.whitecolor() //moving blocks let action = skaction.movetoy(-50, duration: 2.5) //removing blocks once off screen let actiondone = skaction.removefromparent() //running above actions enemy.runaction(skaction.sequence([action, actiondone])) //physics/collisions enemy.physicsbody = skphysicsbody(rectangleofsize: cgsize (width: blockwidth, height: 1)) enemy.physicsbody?.categorybitmask = physicscategory.enemy enemy.physicsbody?.affectedbygravity = false enemy.physicsbody?.dynamic = true //adding enemy scene self.addchild(enemy) } override func update(currenttime: cftimeinterval) { /* called before each frame rendered */ var offsetleft = 0 - (player.position.x - 25) player.position = cgpoint(x: player.position.x, y: player.position.y) playerright.position = cgpoint(x: player.position.x + size.width, y: player.position.y) playerleft.position = cgpoint(x: player.position.x - size.width, y: player.position.y) if istouching { if touchxposition > self.size.width / 2 { // move character right. player.position.x += 10 } if touchxposition < self.size.width / 2 { // move character left. player.position.x -= 10 } } if player.position.x < 0 { player.position.x = size.width } if player.position.x > size.width { player.position.x = 0 } } }
everything commented if have questions whats let me know. appreciated!
static let playerright : uint32 = 3 //00000000000000000000000000000100 static let playerleft : uint32 = 4 //00000000000000000000000000001000 static let enemyright : uint32 = 5 //00000000000000000000000000010000
do really believe 3 binary 100
, 4 binary 1000
(and on)? because if do, , if need true, going in huge trouble later if try use these values actual bitmasks.
Comments
Post a Comment