Memo

メモ > 技術 > IDE: Xcode > UIKit+Game

■UIKit+Game
■デフォルトのプロジェクト 「Game」で以下の設定で新規作成する Product Name: game2d Language: Swift Game Technology: SpritKit 実行すると画面に「Hello, World!」と表示され、 画面をタップすると画面に反応がある 以下を参考に、引き続き調整していく iOS GameplayKitの「Agents, Goals, and Behaviors」で作る、鬼ごっごの鬼AI https://atmarkit.itmedia.co.jp/ait/articles/1701/30/news021.html ■不要な処理を削除してプレイヤーを表示 GameScene.sks を開き、Sceneの下にある helloLabel を削除する GameScene.swift のコードを、以下のように最低限のものに変更する GameScene.swift
import SpriteKit import GameplayKit class GameScene: SKScene { // プレイヤー let player = SKShapeNode(circleOfRadius: 10) // GameSceneがviewに設置されたとき(画面が表示されたとき)に呼ばれる override func didMove(to view: SKView) { // プレイヤー(黄色い丸)を画面に表示 player.fillColor = UIColor(red: 0.90, green: 0.90, blue: 0.10, alpha: 1.0) addChild(player) } }
■プレイヤーを動かす処理を追加 GameSceneクラスに以下のメソッドを追加する GameScene.swift
// タッチされた位置に向かってプレイヤーを移動 override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { // すべてのタッチ位置を処理 touches.forEach { // タッチされた位置を取得 let point = $0.location(in: self) // 移動方向を決定 let path = CGMutablePath() path.move(to: CGPoint()) path.addLine(to: CGPoint(x: point.x - player.position.x, y: point.y - player.position.y)) // 設定済みのアニメーションを削除 player.removeAllActions() // SKActionでSKNodeをアニメーション(移動) player.run(SKAction.follow(path, speed: 50.0)) } }
■敵を追加 GameScene.swift
// 敵 var enemies = [SKShapeNode]() var timer: Timer? var prevTime: TimeInterval = 0 // GameSceneがviewに設置されたとき(画面が表示されたとき)に呼ばれる override func didMove(to view: SKView) { 〜略〜 // 敵を作成し続ける setCreateEnemyTimer() // 敵が落下しないようにする physicsWorld.gravity = CGVector() } 〜略〜 // 1フレームごとに呼ばれる override func update(_ currentTime: TimeInterval) { if prevTime == 0 { prevTime = currentTime } // プレイヤーの位置が変わるので、1秒ごとに移動方向を調整 if Int(currentTime) != Int(prevTime) { // すべての敵を処理 enemies.forEach { // 移動方向を決定 let path = CGMutablePath() path.move(to: CGPoint()) path.addLine(to: CGPoint(x: player.position.x - $0.position.x, y: player.position.y - $0.position.y)) // 設定済みのアニメーションを削除 $0.removeAllActions() // SKActionでSKNodeをアニメーション(移動) $0.run(SKAction.follow(path, speed: 50.0)) } } prevTime = currentTime } // 敵を作成し続ける func setCreateEnemyTimer() { timer?.invalidate() // 5秒ごとにcreateEnemyを呼び出す timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(GameScene.createEnemy), userInfo: nil, repeats: true) timer?.fire() } // 敵を作成する @objc func createEnemy() { // 敵(赤い丸)を画面に表示する let enemy = SKShapeNode(circleOfRadius: 10) enemy.position.x = size.width / 2 enemy.fillColor = UIColor(red: 0.90, green: 0.10, blue: 0.10, alpha: 1.0) enemy.physicsBody = SKPhysicsBody(circleOfRadius: enemy.frame.width / 2) addChild(enemy) // 敵を配列で管理する enemies.append(enemy) }
■ゲームオーバーを追加 GameScene.swift
// 終了判定 var startTime: TimeInterval = 0 var isGameFinished = false 〜略〜 // 1フレームごとに呼ばれる override func update(_ currentTime: TimeInterval) { if prevTime == 0 { prevTime = currentTime startTime = currentTime } 〜略〜 // ゲームオーバーを判定 if !isGameFinished { // すべての敵を処理 for enemy in enemies { // 敵の位置を取得 let dx = enemy.position.x - player.position.x let dy = enemy.position.y - player.position.y // プレイヤーと敵の接触を確認 if sqrt(dx*dx + dy*dy) < player.frame.width / 2 + enemy.frame.width / 2 { // ゲームを終了 isGameFinished = true timer?.invalidate() // 結果を表示 let label = SKLabelNode(text: "記録:\(Int(currentTime - startTime))秒") label.fontSize = 80 label.position = CGPoint(x: 0, y: -100) addChild(label) break } } } prevTime = currentTime }

Advertisement