前提・実現したいこと
「SpriteKitではじめる2Dゲームプログラミング」という本を読んでiOSゲームを勉強して
いる初心者です。
「HelpNagoyaSpeciality」というサンプルゲームをつくりました。
Swift5の環境で動作することは確認できました。
ただこのサンプルコードでは、ゲームオーバーしたあとのリスタートとするためのコードが
実装されておりません。画面をタッチするだけで簡単にリスタートするように改造したいと
思っていますが、具体的にどうやれば良いのかがわかりません。
実現したいことは、ゲームオーバー後に画面をタッチすると「GAME OVER」や落下してきた
スプライトを消せて、スコアも「0」に戻しリスタートさせたいと思っています。
考え方を含めどのようにすればよいのか具体的な方法を教えてもらえないでしょうか。
発生している問題・エラーメッセージ
エラーメッセージ
該当のソースコード
Swift5 import Foundation import SpriteKit class GameScene: SKScene, SKPhysicsContactDelegate { // どんぶり var bowl: SKSpriteNode? // タイマー var timer: Timer? // 落下判定用しシェイプ var lowestShape: SKShapeNode? // スコア用プロパティ var score = 0 var scoreLabel: SKLabelNode? // 名古屋名物ごとのスコア var scoreList = [100, 200, 300, 500, 800, 1000, 1500] override func didMove(to view: SKView) { self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -2.0) self.physicsWorld.contactDelegate = self // 背景スプライトの追加 let background = SKSpriteNode(imageNamed: "background") background.position = CGPoint(x: self.size.width*0.5, y: self.size.height*0.5) background.size = self.size self.addChild(background) // 落下検知用シェイプノードを追加 let lowestShape = SKShapeNode(rectOf: CGSize(width: self.size.width*3, height: 10)) // 画面外に配置 lowestShape.position = CGPoint(x: self.size.width*0.5, y: -10) // シェイプに合わせてPhysicsBodyを生成 // シェイプの大きさで物理シミュレーションを行う let physicsBody = SKPhysicsBody(rectangleOf: lowestShape.frame.size) // 落下しないよう固定 physicsBody.isDynamic = false // 衝突を検知する対象のビットマスクを指定 // 名古屋名物との衝突を検知する physicsBody.contactTestBitMask = 0x1 << 1 lowestShape.physicsBody = physicsBody self.addChild(lowestShape) self.lowestShape = lowestShape // どんぶりを追加 let bowlTexture = SKTexture(imageNamed: "bowl") let bowl = SKSpriteNode(texture: bowlTexture) bowl.position = CGPoint(x: self.size.width*0.5, y: 100) bowl.size = CGSize(width: bowlTexture.size().width*0.5, height: bowlTexture.size().height*0.5) // テクスチャの不透過部分の形状で物理シミュレーションを行う bowl.physicsBody = SKPhysicsBody(texture: bowlTexture, size: bowl.size) // 落下しないよう固定 bowl.physicsBody?.isDynamic = false self.bowl = bowl self.addChild(bowl) // スコア用ラベル var scoreLabel = SKLabelNode(fontNamed: "Helvetica") scoreLabel.position = CGPoint(x: self.size.width*0.92, y: self.size.height*0.78) scoreLabel.text = "¥0" scoreLabel.fontSize = 32 scoreLabel.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.right // 右寄せ scoreLabel.fontColor = UIColor.green self.addChild(scoreLabel) self.scoreLabel = scoreLabel self.fallNagoyaSpecialty() // タイマーを生成 self.timer = Timer.scheduledTimer(timeInterval: 3.0, target: self, selector: #selector(GameScene.fallNagoyaSpecialty), userInfo: nil, repeats: true) } // 名古屋名物を落下させる @objc func fallNagoyaSpecialty() { // 0〜6のランダムな整数を発生させる let index = Int(arc4random_uniform(7)) // 選択された番号のテクスチャを読み込む let texture = SKTexture(imageNamed: "(index)") // テクスチャからスプライトを生成する let Nagoyasprite = SKSpriteNode(texture: texture) Nagoyasprite.position = CGPoint(x: self.size.width*0.5, y: self.size.height) Nagoyasprite.size = CGSize(width: texture.size().width*0.5, height: texture.size().height*0.5) // テクスチャからPhysicsBodyを追加 Nagoyasprite.physicsBody = SKPhysicsBody(texture: texture, size: Nagoyasprite.size) Nagoyasprite.physicsBody?.contactTestBitMask = 0x1 << 1 // 衝突を検知する対象のビットマスクを指定 self.addChild(Nagoyasprite) // 落下した物に応じてスコアを加算する self.score += self.scoreList[index] // 金額のラベルを更新 self.scoreLabel?.text = "¥(self.score)" } // 衝突が発生したときに呼ばれるメソッド func didBegin(_ contact: SKPhysicsContact) { // 衝突した一方が落下判定用シェイプだったら if contact.bodyA.node == self.lowestShape || contact.bodyB.node == self.lowestShape { // ゲームオーバースプライトを表示 let GameOversprite = SKSpriteNode(imageNamed: "gameover") GameOversprite.position = CGPoint(x: self.size.width*0.5, y: self.size.height*0.5) self.addChild(GameOversprite) // アクションを停止させる self.isPaused = true // タイマーを止める self.timer?.invalidate() } } // タッチ開始時に呼ばれるメソッド override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { for touch: AnyObject in touches { // シーン上のタッチされた位置を取得する let location = touch.location(in: self) // タッチされた位置にノードを移動させるアクションを作成する let action = SKAction.move(to: location, duration: 0.2) // どんぶりのスプライトでアクションを実行する self.bowl?.run(action) } } // ドラック時 override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { for touch: AnyObject in touches { let location = touch.location(in: self) let action = SKAction.move(to: location, duration: 0.2) self.bowl?.run(action) } } }
試したこと
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
for touch: AnyObject in touches {
この部分にやりたいことをコード化して実装してやればできると思いやってみようとしましたが
具体的な方法がわからずギブアップ状態です。
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。