質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SpriteKit

SpriteKitは、iOSやOS Xで使用できるApple社製の2Dゲーム開発フレームワークです。

Q&A

解決済

1回答

1373閲覧

現在表示しているSceneを最初から再読み込みする際にノードが正しく動作しない。

gesuyabami13579

総合スコア11

SpriteKit

SpriteKitは、iOSやOS Xで使用できるApple社製の2Dゲーム開発フレームワークです。

0グッド

0クリップ

投稿2019/07/10 11:09

前提・実現したいこと

Swift SpriteKit でFlappyBirdの様なゲームを作成しています。

しかし"やり直す"ボタンを押すことで現在表示しているScene再読み込みすることで
画面を最初から表示する機能を実装中に以下のエラーメッセージが発生しました。
最初に起動した際には正しく動作しています。

発生している問題・エラーメッセージ

おそらくdidMove内のif文の中身を実行するタイミングで SIGABRTエラーが出て
クラッシュしています。

該当のソースコード

import SpriteKit
import GameplayKit
import Foundation

let bard = SKSpriteNode(imageNamed: "bard")
let stop = SKSpriteNode(imageNamed: "stop")
let scorel = SKLabelNode(fontNamed: "Helvetica Neue")

struct category {
static let Wall: UInt32 = 1
static let player: UInt32 = 2
static let frame: UInt32 = 3
static let score: UInt32 = 4
}

var timer = Timer()
var label = UILabel()
var flag = true
var stopCount = 0
var score = 0
var scoreFlag = true

class GameScene: SKScene,SKPhysicsContactDelegate{

override func didMove(to view: SKView) { print("1") if flag == true { print("2") //床のアニメーション timer = Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(self.yukaAnime) , userInfo: nil, repeats: true ) //壁のアニメーション timer = Timer.scheduledTimer(timeInterval: 2, target: self, selector: #selector(self.wall), userInfo: nil, repeats: true) //最初の床アニメーション yukaAnime1() //最初の壁アニメーション wall() //スコア scorel.text = "score (score)" scorel.position = CGPoint(x: -200, y:500) scorel.fontSize = 30 scorel.zPosition = 10 addChild(scorel) self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -10.0) //鳥 bard.position = CGPoint(x: -230, y: 200) bard.size = CGSize(width: bard.size.width * 0.25, height: bard.size.height * 0.25) bard.physicsBody = SKPhysicsBody(rectangleOf: bard.size ) bard.physicsBody?.categoryBitMask = category.player bard.physicsBody?.collisionBitMask = category.Wall bard.physicsBody?.contactTestBitMask = category.Wall bard.physicsBody?.isDynamic = true self.addChild(bard) self.physicsWorld.contactDelegate = self //一時停止 stop.position = CGPoint(x: 280, y: 550) stop.zPosition = 10 stop.name = "stop" stop.size = CGSize(width: 80, height: 80) self.addChild(stop) } } func scoreCount() { if scoreFlag == true { score = score + 100 } scorel.text = "score (score)" print("(score)") } func didBegin(_ contact: SKPhysicsContact) { let firstBody: SKPhysicsBody = contact.bodyA let secondBody: SKPhysicsBody = contact.bodyB if ((firstBody.categoryBitMask == category.Wall) && (secondBody.categoryBitMask == category.player)) || ((firstBody.categoryBitMask == category.player) && (secondBody.categoryBitMask == category.Wall)){ flag = false gameover() reset() scoreFlag = false } if ((firstBody.categoryBitMask == category.score) && (secondBody.categoryBitMask == category.player)) || ((firstBody.categoryBitMask == category.player) && (secondBody.categoryBitMask == category.score)) { scoreCount() } } func gameover(){ let label = SKLabelNode(fontNamed: "Helvetica Neue") label.fontSize = 100 label.position = CGPoint(x: 0, y: 0) label.zPosition = 5 label.text = "gameover" addChild(label) } func reset(){ let reset = SKLabelNode(fontNamed: "Helvetica Neue") reset.fontSize = 40 reset.position = CGPoint(x: 0, y: -100) reset.zPosition = 5 reset.text = "やり直す" reset.name = "reset" flag = true addChild(reset) } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { for touch : AnyObject in touches { let location = touch.location(in: self) let touchedNode = self.atPoint(location) if let name = touchedNode.name { if name == "stop" && stopCount % 2 == 0 { self.isPaused = true stopCount += 1 bard.color = UIColor.white } else if name == "stop" && stopCount % 2 == 1{ self.isPaused = false stopCount += 1 } else if name == "reset" { let result = GameScene(fileNamed: "GameScene") result?.scaleMode = .aspectFill self.view?.presentScene(result) } } } } @objc func wall(){ let wallpair = SKNode() let topWall = SKSpriteNode(imageNamed: "wall") let btmWall = SKSpriteNode(imageNamed: "wall") let score = SKSpriteNode(imageNamed: "score") let random = Int.random(in: -400...400) topWall.position = CGPoint(x: 360, y: random + 600) btmWall.position = CGPoint(x: 360, y: random + -600) score.position = CGPoint(x: 360, y: random) score.zPosition = -2 topWall.size = CGSize(width: topWall.size.width * 0.5, height: topWall.size.height * 0.5) btmWall.setScale(0.5) score.setScale(0.5) let action = SKAction.moveTo(x: -2000, duration: 7) let actionDone = SKAction.removeFromParent() wallpair.run(SKAction.sequence([action, actionDone])) topWall.physicsBody = SKPhysicsBody(rectangleOf: topWall.size ) topWall.physicsBody?.categoryBitMask = category.Wall topWall.physicsBody?.collisionBitMask = category.player topWall.physicsBody?.contactTestBitMask = category.player topWall.physicsBody?.isDynamic = false topWall.physicsBody?.affectedByGravity = false btmWall.physicsBody = SKPhysicsBody(rectangleOf: btmWall.size ) btmWall.physicsBody?.categoryBitMask = category.Wall btmWall.physicsBody?.collisionBitMask = category.player btmWall.physicsBody?.contactTestBitMask = category.player btmWall.physicsBody?.isDynamic = false btmWall.physicsBody?.affectedByGravity = false score.physicsBody = SKPhysicsBody(rectangleOf: score.size) score.physicsBody?.categoryBitMask = category.score score.physicsBody?.collisionBitMask = category.player score.physicsBody?.contactTestBitMask = category.player score.physicsBody?.isDynamic = false score.physicsBody?.affectedByGravity = false wallpair.addChild(score) wallpair.addChild(topWall) wallpair.addChild(btmWall) self.addChild(wallpair) } func yukaAnime1(){ let yuka = SKSpriteNode(imageNamed: "yuka") yuka.position = CGPoint(x: 300, y: -640) yuka.size = CGSize(width: yuka.size.width * 0.2, height: yuka.size.height * 0.2) let action = SKAction.moveTo(x: -2000, duration: 7) let actionDone = SKAction.removeFromParent() yuka.zPosition = 1 yuka.run(SKAction.sequence([action, actionDone])) addChild(yuka) } @objc func yukaAnime(){ let yuka = SKSpriteNode(imageNamed: "yuka") yuka.position = CGPoint(x: 300, y: -640) yuka.size = CGSize(width: yuka.size.width * 0.2, height: yuka.size.height * 0.2) yuka.physicsBody = SKPhysicsBody(rectangleOf: yuka.size) yuka.physicsBody?.categoryBitMask = category.frame yuka.physicsBody?.collisionBitMask = category.frame yuka.physicsBody?.contactTestBitMask = category.player yuka.physicsBody?.isDynamic = false yuka.physicsBody?.affectedByGravity = false let action = SKAction.moveTo(x: -2000, duration: 15) let actionDone = SKAction.removeFromParent() yuka.zPosition = 1 yuka.run(SKAction.sequence([action, actionDone])) addChild(yuka) } override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { print("touch") if flag == true { bard.physicsBody?.velocity = CGVector(dx: 0, dy: 0) bard.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 130)) }else if flag == false { bard.physicsBody?.velocity = CGVector(dx: 0, dy: 0) bard.physicsBody?.applyImpulse(CGVector(dx: 0, dy: -50)) } }

}

試したこと

didMove内のif文の外にノードを配置してみたら、再読み込みした際に
そのノードだけ表示することはできました。(右下のnode数からみて、画面外にはみ出ている可能性や
zPositionの設定で重なっているなどの可能性はなさそうです。)

なのでおそらくif文の中に原因がある様なのですが手掛かりが掴めません。

didMove内のtimer2つを消してみて再読み込みしてみると
一応クラッシュはしませんでしたが、鳥のサイズや重力関係がおかしくなってしまいます。

補足情報(FW/ツールのバージョンなど)

まだ初心者で読みにくいと思いますが、回答して頂けると幸いです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決

ごめんなさい。自己解決致しました

投稿2019/07/13 16:25

gesuyabami13579

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問