SpriteKit enemy sprites skip after contact with player -


i have made game basic idea player sprite has either collide or avoid falling enemy sprites depending on letter assigned enemy. problem when player makes contact sprite, surrounding enemies skip forward significantly. makes game hard play because there isn't enough time player move out of way of oncoming enemy sprites. happens on device , simulator.

to see mean, @ brief video. can see lag @ 00:06 , 00:013: https://www.dropbox.com/s/8pp66baxc9uhy26/simulatorscreensnapz002.mov?dl=0

here code player , enemy contact:

class gameplaysceneclass: skscene, skphysicscontactdelegate {  private var player:player?  private var center = cgfloat()  private var canmove = false, moveleft = false  private var itemcontroller = itemcontroller()  private var scorelabel: sklabelnode?  private var wordlabel: sklabelnode?  private var score = 0  private var theword = ""  private var vowelpressed = false  let correct = soundsfx("correct.wav")  let wrong = soundsfx("nomatch.wav")  let explosion = soundsfx("explosion.wav")  var arrayofstrings: [string]?  var thecheckedword = ""  var currentcount = 0  var itemsarray = [string]()  var partialexists = false  var characterscore = 0  var onepointletters = [12, 14, 18, 19, 20]  var twopointletters = [4, 7]  var threepointletters = [2, 3, 13, 16]  var fourpointletters = [6, 8, 22, 23, 25]  var fivepointletters = [11]  var eightpointletters = [10, 24]  var tenpointletters = [17, 26]  var letter = 0  var scorearray = [int]()  var matchingterms = [string]()  var gravity:cgfloat = -0.35  var result = cgsize()  let synth = avspeechsynthesizer() var myutterance = avspeechutterance(string:"")    override func didmove(to view: skview) {      soundengine.shared.backgroundmusicvolume = 1.0      soundengine.shared.playbackgroundmusic("jungle audio-1.m4a", loop: true)      initializegame()    }  override func update(_ currenttime: timeinterval) {     manageplayer() }   override func touchesbegan(_ touches: set<uitouch>, event: uievent?) {      touch in touches {          let location = touch.location (in: self)           if atpoint(location).name == "lettera" {              print ("letter pressed")             vowelpressed = true             theword = theword + "a"             wordlabel?.text = theword             if theword.characters.count >= 3 {                 checkword()              }              vowelpressed = false          }          else if atpoint(location).name == "lettere" {          print ("letter e pressed")             vowelpressed = true             theword = theword + "e"             wordlabel?.text = theword             if theword.characters.count >= 3 {                 checkword()              }             vowelpressed = false      }          else if atpoint(location).name == "letteri" {              print ("letter pressed")             vowelpressed = true             theword = theword + "i"             wordlabel?.text = theword             if theword.characters.count >= 3 {                 checkword()              }              vowelpressed = false           }          else if atpoint(location).name == "lettero" {              print ("letter o pressed")             vowelpressed = true             theword = theword + "o"             wordlabel?.text = theword             if theword.characters.count >= 3 {             checkword()              }              vowelpressed = false          }          else if atpoint(location).name == "letteru" {              print ("letter u pressed")             vowelpressed = true             theword = theword + "u"             wordlabel?.text = theword             if theword.characters.count >= 3 {                 checkword()              }              vowelpressed = false           }          else if atpoint(location).name == "pause"  {              showpausealert()           }            else if atpoint(location).name == "delete" {              theword = ""             thecheckedword = ""             wordlabel?.text = theword          }              else {           if location.x > center && !vowelpressed {              moveleft = false         }          else if location.x < center && !vowelpressed {              moveleft = true         }        canmove = true          }     } }  override func touchesended(_ touches: set<uitouch>, event: uievent?) {     canmove = false }  func didbegin(_ contact: skphysicscontact) {      if !gamepaused {      var firstbody = skphysicsbody()     var secondbody = skphysicsbody()      if contact.bodya.node?.name == "player" {          firstbody = contact.bodya         secondbody = contact.bodyb      }          else {              firstbody = contact.bodyb             secondbody = contact.bodya          }      if firstbody.node?.name == "player" && secondbody.node?.name == "tile" {           letter = secondbody.node?.userdata?.value(forkey:"key") as! int         print ("the value of letter \(letter)")         var lettercode = string(describing: letter)         var lettervalue = int(lettercode)         var finallettervalue = lettervalue!+64         var asciicode = character(unicodescalar(finallettervalue)!)         var letterstring = string(describing:asciicode)         theword = theword + letterstring         print (theword)          if onepointletters.contains(letter) {              characterscore += 1            }          else if twopointletters.contains(letter) {              characterscore += 2           }          else if threepointletters.contains(letter) {              characterscore += 3           }          else if fourpointletters.contains(letter) {              characterscore += 4                         }          else if fivepointletters.contains(letter) {              characterscore += 5           }           else if eightpointletters.contains(letter) {              characterscore += 8          }          else if tenpointletters.contains(letter) {              characterscore += 10          }          wordlabel?.text = theword         thecheckedword = theword.lowercased()         print ("the checked word \(thecheckedword)")           checkword()          secondbody.node?.removefromparent()      }       if firstbody.node?.name == "player" && secondbody.node?.name == "bomb" {          explosion.play()         firstbody.node?.removefromparent()         secondbody.node?.removefromparent()         theword = ""         score = 0         scorelabel?.text = string(score)         var delaytimer = skaction.wait(forduration:1)         run (delaytimer)         restartgame()      }   }  }    private func initializegame() {          {         // solution assumes  you've got file in bundle         if let path = bundle.main.path(forresource: "en", oftype: "txt"){             let data = try string(contentsoffile:path, encoding: string.encoding.utf8)             arrayofstrings = data.components(separatedby: "\n")          }     } catch let err nserror {         // error         print(err)     }      physicsworld.contactdelegate = self     physicsworld.gravity = cgvector(dx:0,dy:gravity)          player = childnode(withname: "player") as? player!     player?.initializeplayer()     player?.position = cgpoint(x:0, y: -420)     scorelabel = childnode(withname: "scorelabel") as? sklabelnode!     scorelabel?.text = string(score)     wordlabel = childnode(withname:"wordlabel") as? sklabelnode!     wordlabel?.text = ""     center = self.frame.size.width/self.frame.size.height        var spawnblocks = skaction.repeatforever(skaction.sequence([skaction.wait(forduration:1),skaction.run(spawnitems)]))        var removeblocks = skaction.repeatforever(skaction.sequence([skaction.wait(forduration:1),skaction.run(removeitems)]))       if gamepaused == true {          self.scene?.ispaused = true      }      self.run(spawnblocks)       self.run(removeblocks)   }  private func checkword() {      thecheckedword = theword.lowercased()       if (arrayofstrings?.contains(thecheckedword))! {          print ("yes! \(thecheckedword) word")              correct.play()         print ("the current value of score \(score)")         score += characterscore         print ("current gravity setting \(gravity)")         scorelabel?.text = string(score)         characterscore = 0          matchingterms = (arrayofstrings?.filter({$0.hasprefix(thecheckedword)          }))!           if matchingterms.count == 1 {               characterscore = 0             print ("current gravity setting \(gravity)")             theword = ""             thecheckedword = ""             wordlabel?.text = ""           }      }        else if !(arrayofstrings?.contains(thecheckedword))! {            matchingterms = (arrayofstrings?.filter({$0.hasprefix(thecheckedword)          }))!            if matchingterms.count == 0 {              wrong.play()              characterscore = 0              if score >= 5 {                  score -= 5              }                theword = ""             thecheckedword = ""             wordlabel?.text = ""          }     }    } 

here code enemies:

import spritekit  struct collidertype {  static let player: uint32 = 0 static let tile_and_bomb: uint32 = 1;  }   public var bounds = uiscreen.main.bounds public var width = bounds.size.width public var height = bounds.size.height   class itemcontroller {    private var minx = cgfloat(-(width/2)), maxx = cgfloat(width/2)  private var vowelnumbers = [1, 5, 9, 15, 21]  func spawnitems() -> skspritenode {     let item: skspritenode?      if int(randombetweennumbers(firstnum: 0, secondnum: 10)) > 7 {         item = skspritenode(imagenamed: "bomb")         item!.name = "bomb"         item!.setscale(0.6)         item!.physicsbody = skphysicsbody(circleofradius:          item!.size.height / 2)         print ("the value of width \(width)")      } else {         var num = int(randombetweennumbers(firstnum: 1, secondnum: 26))          if vowelnumbers.contains(num) {              num = num + 1         }          item = skspritenode(imagenamed: "tile \(num)")         item?.userdata = nsmutabledictionary()         item!.name = "tile"         item!.userdata!.setvalue(num, forkey:"key")         item!.zrotation = 0         item!.setscale(0.9)         item!.physicsbody = skphysicsbody(circleofradius:   item!.size.height / 2)         if gamepaused == true {              item!.ispaused = true          }          else {              item!.ispaused = false          }     }      item!.physicsbody?.categorybitmask = collidertype.tile_and_bomb;     item!.physicsbody?.isdynamic = true      item!.zposition = 3     item!.anchorpoint = cgpoint(x: 0.5, y: 0.5)      item!.position.x = randombetweennumbers(firstnum: minx, secondnum: maxx)     item!.position.y = 600      return item! }    func randombetweennumbers(firstnum: cgfloat, secondnum: cgfloat) -> cgfloat {     return cgfloat(arc4random()) / cgfloat(uint32_max) * abs(firstnum - secondnum) + min(firstnum, secondnum); }  } 

and here code player:

import spritekit  class player: skspritenode {  private var minx = cgfloat(-300), maxx = cgfloat(300)  func initializeplayer() {      name = "player"      physicsbody = skphysicsbody(circleofradius: size.height/2)     physicsbody?.affectedbygravity = false     physicsbody?.isdynamic = false     physicsbody?.categorybitmask = collidertype.player     physicsbody?.contacttestbitmask = collidertype.tile_and_bomb     }   func move(left:bool){      if left {     position.x -= 15          if position.x < minx {              position.x = minx         }    }   else {      position.x += 15          if position.x > maxx {              position.x = maxx         }        }     }  } 

consider calling checkword() method skaction:

let checkwordsaction = skaction.run() {     [weak self] in     self?.checkword() } self.run(checkwordsaction) 

that way, if array big, code not interrupted because walking check word.

also i'm not sure of trying wait action @ end of didbegin(contact:) method, when colliding bombs. if trying wait 1 second before restarting game, keep in mind calling wait action way not pause code. put scene on idle 1 second , restart game in background. if intended effect, it's ok, might better using run(_:completion:) method instead , call restartgame() completion closure:

let waitaction = skaction.wait(1) self.run(waitaction) { [weak self] in     self?.restartgame() } 

hope helps!


Comments

Popular posts from this blog

php - Permission denied. Laravel linux server -

google bigquery - Delta between query execution time and Java query call to finish -

python - Pandas two dataframes multiplication? -