2017-04-14 6 views
0

私は、プレイヤーのスプライトが敵に割り当てられた文字に応じて敵のスプライトと衝突するか、落ちないようにするという基本的な考え方でゲームを作った。問題は、プレイヤーがスプライトに接触したときに、周囲の敵が前方に飛ばしてしまうことです。これは、プレイヤーが対向する敵のスプライトから離れて移動するのに十分な時間がないため、ゲームをプレイするのが難しくなります。これは、デバイスとシミュレータで発生します。SpriteKitの敵のスプライトはプレイヤーとの接触後にスキップする

私が何を意味するか見るには、この簡単なビデオを見てください。 013:あなたは午後12時06分と00で遅れを見ることができますhttps://www.dropbox.com/s/8pp66baxc9uhy26/SimulatorScreenSnapz002.mov?dl=0

ここでプレイヤーと敵の接触のために私のコードです:

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>, with event: UIEvent?) { 

    for touch in touches { 

     let location = touch.location (in: self) 


     if atPoint(location).name == "LetterA" { 

      print ("Letter A 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 I 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>, with 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 is \(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 is \(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() { 





    do { 
     // This solution assumes you've got the file in your 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 as NSError { 
     // do something with 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) is a word") 





     correct.play() 
     print ("The current value of score is \(score)") 
     score += characterScore 
     print ("Current gravity setting is \(gravity)") 
     scoreLabel?.text = String(score) 
     characterScore = 0 

     matchingTerms = (arrayOfStrings?.filter({$0.hasPrefix(theCheckedWord) 

     }))! 


     if matchingTerms.count == 1 { 


      characterScore = 0 
      print ("Current gravity setting is \(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 = "" 

     } 
    } 



} 

ここで敵のために私のコードです:

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 is \(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); 
} 

} 

そして、ここでは、プレーヤーのために私のコードです:

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 
     } 


    } 

    } 

} 
+0

これはデバイスでも起こっていますか? – BadgerBadger

+0

あなたの 'arrayOfStrings'にはいくつの文字列がありますか? – nathan

+0

また、あなたのcheckWordsメソッドと文字のチェック方法は、skspritenodeのサブクラスを使って、文字のプロパティなどを追加した方がずっと効率的です。 – BadgerBadger

答えて

0

はを呼び出して考えてみましょうSKActionから3210方法:お使いの配列が大きすぎる場合は、それはあなたの言葉をチェックするために歩いているので

let checkWordsAction = SKAction.run() { 
    [weak self] in 
    self?.checkWord() 
} 
self.run(checkWordsAction) 

そうすれば、コードは中断されません。

また、didBegin(contact:)メソッドの終了時に待機アクションで何をしようとしているのかわからないときに、爆弾と衝突しています。ゲームを再開する前に1秒間待つつもりなら、あなたのやり方で待機アクションを呼び出すとコードが一時停止しないことに注意してください。実際には、シーンを1秒間アイドル状態にして、バックグラウンドでゲームを再開します。それは意図した効果がある場合、それは大丈夫ですが、あなたの代わりにrun(_:completion:)メソッドを使用して良くなると完了閉鎖からrestartGame()を呼ぶかもしれない:

let waitAction = SKAction.wait(1) 
self.run(waitAction) { [weak self] in 
    self?.restartGame() 
} 

ホープ、このことができます! didBegin(_接触:SKPhysicsContact)で

+0

問題は明らかにあなたが提案したように配列の大きさでした。私は自分の単純な「独自のロール」からLexicontextに切り替えました.Lexicontextは、20ドルで簡単かつ即座に解決策を提供します。おそらくそこには無料のソリューションもあるかもしれませんが、Lexicontextは単語ゲーム用に実装するのが簡単です。 – user3140521

0

:あなたは2つの新しい物理ボディを作成するので、たぶん遅れが作成された

var firstBody = SKPhysicsBody() 
var secondBody = SKPhysicsBody() 

、あなたは二つの物理学のボディを作成します。物理団体を作成せず、の既存の参照を作成するとどうなりますか?のものは何ですか?私はこれを試したことはありませんが、多分試してみてください:

let firstBody: SKPhysicsBody 
let secondBody: SKPhysicsBody 

if contact.bodyA.node?.name == "Player" { 

    firstBody = contact.bodyA 
    secondBody = contact.bodyB 
} 

else { 
    firstBody = contact.bodyB 
    secondBody = contact.bodyA 
} 
+0

ああ!それは良い呼び出しです!間違いなく助けにはならない! – BadgerBadger

関連する問題