獣は月夜に何を見る...

SpriteKitでゲーム その1- SPACE SHOOTER⑧

f:id:tukumosanzou:20180702205113p:plain

SpriteKit での作業も終盤にさしかかってきました、つたない説明が続きますが、お付き合いくださいませ。


今回は lives = 0 でゲームオーバーになる時の処理も追加していきます。


それにまだ player の移動処理を追加していないのでそれも追加します。


ついでにゲームの状態によってディスプレイの表示を管理したいと思います。

ゲームの状態を管理する変数をつくります。

var livesImages = SKSpriteNode の直前に追加してください、以下のようになります。

//ゲームの状態を管理する変数。
var gameState = GameState.startGame

var livesImages = [SKSpriteNode]()

var lives = 3

var player: SKSpriteNode!



次の列挙型を override func didMove() の直前に追加します。

enum GameState {
    case startGame
    case endGame
}

列挙型(enum)とは関連性のある事柄、データを一つにまとめた定数のようなものです。


switch文の

列挙型の内部データにアクセスするには ” . " で区切って”GameState.startGame " と書きます。

Enumerations — The Swift Programming Language (Swift 4.2)


override func touchesBegan() を以下のように変更します。


playerゲームオーバーの移動処理を追加していきます。

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    //画面にタッチしたかどうかの判定。
    guard let touch = touches.first else { return }

    //ゲームの状態によって処理を分ける。
    switch gameState {
    
    //gameStateがstartGameのとき。
    case .startGame:

        //タッチした位置を取得する。
        let location = touch.location(in: self)

        //タッチした位置がplayerのx軸の位置より小さい(左側)場合。
        if location.x < player.position.x {

            //playerの位置を-50移動する(左に50)
            player.position.x -= 50

        //タッチした位置がplayerのx軸の位置より大きい(右側)場合。
        } else if location.x > player.position.x {

            //playerの位置を+50移動する(右に50)
            player.position.x += 50
        }
    
        //playerの右方向の移動範囲の最大値を決める。
        if player.position.x > frame.maxX - player.size.width {
            player.position.x = frame.maxX - player.size.width / 2
        }

        //playerの左方向の移動範囲の最大値を決める。
        if player.position.x < frame.minX + player.size.width {
            player.position.x = frame.minX + player.size.width / 2
        }

        createLaser()

    //gameStateがendGameのとき。
    case .endGame

        //何も処理をしない。
        break
    }
}

player の中心点、つまり SpriteNode の anchorPoint より右側をタッチすれば右方向に+50移動し、左側をタッチすれば左に-50移動します。

しかし移動範囲は画面の幅以内にしたいので、以下の部分で

//playerの右方向の移動範囲の最大値を決める。
if player.position.x > frame.maxX - player.size.width {
    player.position.x = frame.maxX - player.size.width / 2
}

//playerの左方向の移動範囲の最大値を決める。
if player.position.x < frame.minX + player.size.width {
    player.position.x = frame.minX + player.size.width / 2
}

としていますが、playeranchorPoint(0.5, 0.5) つまり中心なので player の大きさの半分の幅を移動範囲の最大・最小から取り除かないと player の半分が画面からはみ出してしまいます。


ゲームオーバー時の処理に移ります。

以下のコードを func subtractLife() に追加します。

//残機数がゼロならば。
if lives == 0 {

    //gameStateをendGameに変更する。
    gameState = .endGame

    //ゲームオーバーの処理を実行する。
    runGameOver()
}



追加する位置は、以下のようになります。

func subtractLife() {
    
    //初期値から-1する。
    lives -= 1

    //関数内部で使う変数を設定。
    var life: SKSpriteNode

    if lives == 2 {
        life = livesImages[0]
    } else if lives == 1 {
        life = livesImages[1]
    } else {
        life = livesImages[2]
    }

    //GameSceneから削除する。
    life.removeFromParent()

    //残機数がゼロならば。
    if lives == 0 {

        //gameStateをendGameに変更する。
        gameState = .endGame

        //ゲームオーバーの処理を実行する。
        runGameOver()
    }

}



ゲームオーバーの処理を行う func runGameOver() func subtractLife() の直前に追加します。

func runGameOver() {

    //Timerがまだ有効になっているかチェックする。
    if getTimer != nil {

        //タイマーを破棄する
        getTimer.invalidate()

        //Timerを無効にする。
        getTimer = nil
    }

    //func changeSceneを実行するアクションを作成。
    let changeSceneAction = SKAction.run(changeScene)

    //2.5秒のアイドル状態のアクションを作成します。
    let waitToChangeScene = SKAction.wait(forDuration: 2.5)

    //アクションのコレクションを順番に実行するアクションを作成。
    let changeSceneSequence = SKAction.sequence([waitToChangeScene, changeSceneAction])

    //アクションを実行する。
    run(changeSceneSequence)
}

getTimerTimer.scheduledTimer(timeInterval:target:selector:userInfo:repeats:) を格納しています、パラメーターを repeats: true にしてあるので無効になるまでタイマーを繰返しますのでゲームオーバー時には無効にする必要があります。


先ずその処理を行い、次に2.5秒おいて画面をゲームオーバーの画面に切り替える処理を行います。

Timer.scheduledTimer(timeInterval:target:selector:userInfo:repeats:) wait(forDuration:) - SKAction | Apple Developer Documentation sequence(_:) - SKAction | Apple Developer Documentation


画面をゲームオーバーの画面に切り替える処理を作成します。

func changeScene() func runGameOver() の直前に追加します。

func changeScene() {
    
    //sceneにGameOverSceneを指定しサイズを端末の画面にします。
    let scene = GameOverScene(size: frame.size)

    //シーンを提示するビューにシーンがどのようにマッピングされるかを定義します。
    scene.scaleMode = self.scaleMode

    //画面遷移のアニメーションを作成する。
    let transition = SKTransition.crossFade(withDuration: 1.5)

    //現在のシーンから新しいシーンに移行します
    view?.presentScene(scene, transition: transition)
}

この処理でゲームオーバー時に表示する画面に切り替えます。


移動先の画面を指定し、アニメーションで1.5秒かけて徐々に画面が現れるように調整します。
SKScene - SpriteKit | Apple Developer Documentation scaleMode - SKScene | Apple Developer Documentation SKTransition - SpriteKit | Apple Developer Documentation crossFade(withDuration:) - SKTransition | Apple Developer Documentation presentScene(_: transition:) - SKView | Apple Developer Documentation


以下のような画面に切り替わるようにしたいと思います。
f:id:tukumosanzou:20180727234533p:plain


では、ゲームオーバーの画面を作成していきます。


新しくファイルをつくります。

File / New / File / ios / Swift File で GameOverScene.swift を作成しましょう。

コードは以下のようになります。

import Foundation
import SpriteKit

class GameOverScene: SKScene {
    

    //テキストラベルを表示するノードを作成し、フォントを指定する。
    let restartLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-Bold")
    
    override func didMove(to view: SKView) {
        
        //背景のノードを作成。
        let background = SKSpriteNode(imageNamed: "background")
        //位置を指定。
        background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
        //重なり順を指定。
        background.zPosition = 0
        //GameOverSceneに追加。
        addChild(background)
        

        //GAME OVERのテキストラベルを表示するノードを作成し、フォントを指定する。
        let gameeOverLabel = SKLabelNode(fontNamed: "Helvetica-Bold")
        //表示するテクストを指定。
        gameeOverLabel.text = "GAME OVER"
        //フォントのサイズを指定。
        gameeOverLabel.fontSize = 60
        //フォントのカラーを指定。
        gameeOverLabel.fontColor = SKColor.white
        //位置を指定。
        gameeOverLabel.position = CGPoint(x: frame.size.width * 0.5, y: frame.size.height * 0.7)
        //重なり順を指定。
        gameeOverLabel.zPosition = 1
        //GameOverSceneに追加。
        addChild(gameeOverLabel)
        
        //SCOREのテキストラベルを表示するノードを作成し、フォントを指定する。
        let scoreLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-Bold")
        //表示するテクストを指定。
        scoreLabel.text = "SCORE: \(gameScore)"
        //フォントのサイズを指定。
        scoreLabel.fontSize = 30
        //フォントのカラーを指定。
        scoreLabel.fontColor = SKColor.white
         //位置を指定。
        scoreLabel.position = CGPoint(x: frame.size.width / 2, y: frame.size.height * 0.55)
        //重なり順を指定。
        scoreLabel.zPosition = 1
        //GameOverSceneに追加。
        addChild(scoreLabel)
        
        //ユーザーのデフォルトデータベースとのインターフェイス。
        let defaults = UserDefaults()
        //保存するデータと関連づけるためのキーを作成。
        var highScoreNumber = defaults.integer(forKey: "highScoreSaved")
        //得点が過去の得点より高いならば。
        if gameScore > highScoreNumber {
            //ハイスコアをゲームスコアで更新する。
            highScoreNumber = gameScore
            //デフォルト・データベースに格納するオブジェクトとデフォルトキーの値を設定します。 
            defaults.set(highScoreNumber, forKey: "highScoreSaved")
        }
        
        //ハイスコア(HIGH SCORE)用。
        let highScoreLabel = SKLabelNode(fontNamed: "AppleSDGothicNeo-Bold")
        highScoreLabel.text = "HIGH SCORE: \(highScoreNumber)"
        highScoreLabel.fontSize = 30
        highScoreLabel.fontColor = SKColor.white
        highScoreLabel.zPosition = 1
        highScoreLabel.position = CGPoint(x: frame.size.width / 2, y: frame.size.height * 0.45)
        addChild(highScoreLabel)
        
        //再スタート(Restart)用。
        restartLabel.text = "Restart"
        restartLabel.fontSize = 30
        restartLabel.fontColor = SKColor.white
        restartLabel.zPosition = 1
        restartLabel.position = CGPoint(x: frame.size.width / 2, y: frame.size.height * 0.3)
        addChild(restartLabel)

    }
    
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch: AnyObject in touches {
            //タッチした位置を検出。
            let pointOfTouch = touch.location(in :self)
            //タッチした位置が"Restart"の位置に含まれるかチェックする。
            if restartLabel.contains(pointOfTouch) {
                let scene = GameScene(size: self.size)
                scene.scaleMode = self.scaleMode
                let transition = SKTransition.crossFade(withDuration: 0.5)
                view?.presentScene(scene, transition: transition)
            }
        }
    }
}

GAME OVER, SCORE, HIGH SCORE, Restart のそれぞれのテキストを表示するだけです。


ポイントは得点(SCORE)を表示する部分とハイスコア(HIGH SCORE)を毎回リセットする部分とタッチするとゲームを再開(Restart)するリスタートの部分です。


SCOREgameScoreGameScene.swiftグローバル変数として定義しているので GameOverScene.swift からでも取得できるので簡単です。


HIGH SCORE は取得した SCORE より大きければ デフォルトキーを関連付けてデフォルトデータベースHIGH SCORE として格納し使用します。


Restartゲームオーバー画面に遷移する GameScene.swiftfunc changeScene() の内部処理と同じです、違う点は override touchesBegan() の内部で呼び出しを行い Restart のテキストをタッチしたら GameScene.swift を呼び出しゲームが再開することです。

SKLabelNode - SpriteKit | Apple DeveloperDocumentation SKSpriteNode - SpriteKit | Apple DeveloperDocumentation UseDefault - Foundation | Apple DeveloperDocumentation integer(forKye:) - UserDefaults | Apple Developer Documentation set(_: forKey:) - UserDefaults | Apple Developer Documentation

UITouch - UIKit | Apple Developer Documentation location(in:) - UITouch | Apple Developer Documentation


最後にデバイスごとの表示の調整をします。

GameViewController.swift を開きます。

以下の部分を見つけてください。

if let view = self.view as! SKView {
    //Load the SKScene from 'GameScene.sks'
    if let Scene = SKScene(fileNamed: "GameScene") {
        //Set the scale mode to scale to fit the window
        scene.scaleMode = .aspectFill

        //Present the scene
        view.presentScene(scene)
    }

    view.ignoresSiblingOrder = true

    view.showsFPS = true
    view.showsNodeCount = true
    view.showsPhysics = true
}

そしてこのように変更します。

if let view = self.view as! SKView? {
    //シーンにGameSceneがセットされているならば
    if let scene = SKScene(fileNamed: "GameScene") {
        //デバイスがiPadならば。
        if (UIDevice.current.model.range(of: "iPad") != nil) {
            //シーンのサイズが常にビューのサイズと一致するように、自動的に変更されます。
            scene.scaleMode = .resizeFill
        //デバイスの画面サイズの高さのピクセルが2436.0であるならば。
        } else if UIScreen.main.nativeBounds.height == 2436.0 {
            //シーンのサイズが常にビューのサイズと一致するように、自動的に変更されます。
            scene.scaleMode = .resizeFill
        //上記いがいならば
        } else {
            //シーンのサイズが画面に収まるように切り取ります。
            scene.scaleMode = .aspectFill
        }
        //現在のシーンにセットする。
        view.presentScene(scene)
    }

    view.ignoresSiblingOrder = true
    
    view.showsFPS = true
    view.showsNodeCount = true
    view.showsPhysics = true
}

シーンの遷移のときにでてきた部分にデバイスの判別を追加しています。

1番目にデバイスiPadなのか識別し、2番目は iPhone X 用ですデバイスの画面の高さをピクセルで取得し iPhone X の画面の高さと同じならばシーンのサイズを自動的に調整します。

3番目はiPhone 5s 以降で iPhone X 以外の iPhone 用になります、シーンの大きさはアスペクト比の大きい方をもとにスケーリングされるので切り取られる場合があります。

showsFPSshowsNOdeCount はゲームをプレイしているときの画面の右下に出ている nodefps の表示の切り替えです、false にすると消えます。

showsPhysics は player やその他の物理ボディのまわりの青い円の表示を切り替えます、false にすると消えます。

UIDevice - UIKit |Apple Developer Ducumentation
SKSceneScaleMode - SpriteKit | Apple Developer Documentation
presentScene(_:) - SKView | Apple Dveloper Documentation
showsFPS - SKView | Apple Developer Documntation
showsNodeCount - SKView | Apple Developer Documentation
showsPhysics - SKView | Apple Developer Documentation



以上で、シューティングゲームとしての最低限のものは完成したと思います。

今回は以上です。


swiftを学ぶなら!
TechAcademy オンラインブートキャンプ iPhoneアプリコース

SpriteKitでゲーム その1- SPACE SHOOTER⑦

f:id:tukumosanzou:20180702205113p:plain

今回は、 player の残機数を表示とカウントの処理を作成します。


使用するプロパティを var player: SKSpriteNode! の直前に追加

//playerの残機数を格納する配列を準備する。
var livesImages = [SKSpriteNode]()

//playerの残機数の初期値。
var lives = 3

var player: SKSpriteNode!



呼び出しを createScore() の直後に追加。

createScore()

//playerの残機数を表示。
createLives()



その処理内容を func createScore() の直前に追加。

func createLives() {

    for i in 0 ..< lives {

        let spriteNode = SKSpriteNode(imageNamed: "player")

        //表示する位置。
        spriteNode.position = CGPoint(x: frame.minX + 40 + CGFloat(i * 99) * 0.25, y: UIScreen.main.bounds.height * 0.90)

        //スケールを調整する。
        spriteNode.setScale(0.25)

        //GameSceneに追加。
        addChild(spriteNode)

        //配列に入れる。
        liveImages.append(spriteNode)
    }
}



for i in 0..< lives でlives に初期値3なのでゲーム開始直後は残機数が3つ表示される、後はこれを player が enemy と衝突するたびに-1するようにして再表示する処理を作成すればよい。


次はその処理を作成する。


func subtractLife() を作成します。


以下の呼び出しを didBegin() 内部の createPlayer() の呼び出し直前に追加します。

//playerの残機数を変更する。    
subtractLife()



追加すると、以下のようになります。

func didBegin(_ contact: SKPhysicsContact) {
    if contact.bodyA.node?.name == "laser" || contact.bodyB.node?.name == "laser" {
        //省略
    }

    if contact.bodyA.node?.name == "player" || contact. bodyB.node?.name == "player" {
        //省略
        
        contact.bodyA.node?.removeFromParent()
        contact.bodyB.node?.removeFromParent()

        //playerの残数をのカウントと表示。
        subtractLife()

        createPlayer()

    }

}



subtractLife() の処理内容を作成します。

func createLives() の直前に追加します。

func subtractLife() {
    
    //初期値から-1する。
    lives -= 1

    //関数内部で使う変数を設定。
    var life: SKSpriteNode

    if lives == 2 {
        life = livesImages[0]
    } else if lives == 1 {
        life = livesImages[1]
    } else {
        life = livesImages[2]
    }

    //GameSceneから削除する。
    life.removeFromParent()

}


func createLives() {
    //省略
}

配列 livesImages に入っている SpriteNode lives の数に応じてSpriteNodeindexで指定し 内部変数 life に入れなおしてそれを削除することで player の残機数をカウントしているように見せています。

今回は、ちょと短いですが以上になります。

また次回。


SpriteKitでゲーム その1- SPACE SHOOTER⑥

f:id:tukumosanzou:20180702205113p:plain

今回は、Player や enemy が爆発した時のエフェクトを作るところから始めたいと思います。


シューティングゲームであれば衝突 -> 爆発ですから、衝突したときの爆発のエフェクトが必要になります。


画像を使う方法もありますが今回は、SpriteKit の SKEmitterNode を使用したいので次の様にします。


メニューで、File / New / File / iOS / Resource / SpriteKit Particle File を選択して Next。

f:id:tukumosanzou:20180722223806p:plain


Particle Template は Fire で Next。

f:id:tukumosanzou:20180722223940p:plain

ファイル名を ExplosionEffect.sks で Create。

f:id:tukumosanzou:20180723080616p:plain



次に、ExplosionEffect.sks を開いて各パラメーターを図の様にします。

SpriteKit Particle Emitter エディターが表示されます。

爆発のエフェクトができてます。


パラメーターはいろいろ調整してみてください。

f:id:tukumosanzou:20180723080849p:plain



これで衝突判定を行うための準備ができました。


衝突判定を行う func didBegin(_ contact: SKPhysicsContact){ } を作成します。

SKPhysicsContactDelegate と physicsWorld.contactDelegate = self を追加しましたがそれによってfunc didBegin() が使えるようになります。

SKEmitterNode - SpriteKit | Apple Developer Documentation

SPRITEKIT PARTICLE EMITTER EDITOR


全体図をはこうなります。

func didBegin(_ contact: SKPhysicsContact) {

    //衝突した2つの物体のどちらかの名前が"laser"であるか判定する。
    if contact.bodyA.node?.name == "laser" || contact.bodyB.node?.name == "laser" {

        //bodyAの名前が"enemy"のとき。
        if contact.bodyA.node?.name == "enemy" {

            //両方の物体をGameSceneから削除する。
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
            

            //爆発の画像を読み込む。    
            if let explosion = SKEmitterNode(fileNamed: "ExplosionEffect") {

                //爆発の画像をenemyの位置に表示する。
                explosion.position = (contact.bodyA.node?.position)!

                //GameSceneに追加する。
                addChild(explosion)
            }
                
        } else {

            //両方の物体をGameSceneから削除する。
            contact.bodyA.node?.removeFromParent()
            contact.bodyB.node?.removeFromParent()
            

            //爆発の画像を読み込む。
            if let explosion = SKEmitterNode(fileNamed: "ExplosionEffect") {

                //爆発の画像をenemyの位置に表示する。
                explosion.position = (contact.bodyB.node?.position)!

                //GameSceneに追加する。
                addChild(explosion)
            }
        }
        

        //爆発した時のサウンドを再生する。    
        run(explosionSound)
        
        return
    }
        
    guard contact.bodyA.node != nil && contact.bodyB.node != nil else { return }
       

    //衝突した2つの物体のどちらかの名前が"player"であるか判定する。
    if contact.bodyA.node?.name == "player" || contact.bodyB.node?.name == "player" {

         //爆発の画像を読み込む。
        if let explosion = SKEmitterNode(fileNamed: "ExplosionEffect") {

            //爆発の画像をenemyの位置に表示する。
            explosion.position = player.position

            //GameSceneに追加する。
            addChild(explosion)
        }
         

        //爆発した時のサウンドを再生する。   
        run(explosionSound)
        

        //両方の物体をGameSceneから削除する。    
        contact.bodyA.node?.removeFromParent()
        contact.bodyB.node?.removeFromParent()
    

        //playerを作成する。
        createPlayer()
            
    }
}




didBegin(_:) - Spritekit | Apple Developer Documentation にあるようにcontactパラメータに記述されている2つの物理的ボディは、保証された順序で渡されません。




どういう事かと言いますと。


衝突判定で使う didBegin() は bodyA、bodyB というふたつのパラメーターがあるんですが、これがぶつかる二つの物体になるわけです。


ただ、この物体はどちらが laser または enemy なのか決まっておらず、その時々で bodyA が laser だったり bodyB がlaser だったりするので2通りの判定が必要になるわけです。


ですので以下のように。


didBegi(_:) のcontactパラメーター(SKPhysicsContactクラスを継承)にはbodyA bodyB の二つの物理ボディがあり、これを使って衝突判定をするのですが前述にあるように必ずしも意図した順番ではないので、コードにあるようにそれぞれの物体に対して判定が必要になります。

SKPhysicsContact - SpriteKit | Apple Developer Documentation


今回は laser と enemy、player と enemy のそれぞれの衝突において bodyA bodyB の判定が必要になります。


前述の様なコードになります。

内容は特に難しいものではないと思います。


これで衝突判定はできましたが、せっかくですからもっとゲームらしくlaserがenemy当たったら得点が入るようにし、playerも3機までと限界を決めます。


まず得点からいきます。


import GameplayKit の直後に追加。

//得点の初期値
var gameScore = 0




var getTimer: Timer! の直後に追加。

//スコアを表示するためのプロパティをつくる。
var scoreLabel: SKLabelNode!

//scoreを監視し変更があればそれを反映させる。
var score = gameScore {

    //内包したものを監視する。
    didSet {
        scoreLabel.text = "SCORE: \(score)"
    }
}

didSet は内包したプロパティ(この場合 score)を監視し変更があればそれをリアルタイムで反映させることが出来ます。


ここでは得点が加算される度に表示が変わっていきます。


加算する処理追加します。


didBegin() の laser と enemy との衝突判定の処理の中の run(explosionSound) の直後に以下のコードを追加。

//gameScoreに1を足す。
gameScore += 1

//変数scoreを更新する。
score = gameScore



以下のようになります。

func didBegin(_ contact: SKPhysicsContact) {
    if contact.bodyA.node?.name == "laser" || contact.bodyB.node?.name == "laser" {
    
        //省略

    run(explosionSound)

    //ここに追加します。
    gameScore += 1
    score = gameScore

    }
}

これで enemy が laser で破壊されるたび変数 gameScore に1が加算されていきます、あとはそれを画面上に表示させれば良いだけですね。



続いて、画面上に表示する関数createScore()をつくり、それを呼び出すようにします。


createPlayer() の呼び出しの直後にcreateScore() を追加します。

createPlayer()

//得点を表示する。
createScore()



その処理内容を @objc func createEnemy() の直前に追加。

func createScore() {

    //フォントを指定する。
    scoreLabel = SKLabelNode(fontNamed: "Optima-ExtraBlack")

    //フォンサイズを指定する。
    scoreLabel.fontSize = 24

    //表示する位置。
    scoreLabel.position = CGPoint(x: frame.minX + 80, y: UIScreen.main.bounds.height * 0.92)

    //表示するテキスト。
    scoreLabel.text = "SCORE:0"

    //テキストの色を指定。
    scoreLabel.fontColor = UIColor.white

    //GameSceneに追加。
    addChild(scoreLabel)
}

@objc func createEnemy(){...}

内容は単純なのでわかりやすいと思います。


frame.minX は画面のx軸の最小値です(つまり0です)、そこから+80で少し右に寄せてます。


UIScreen.main.bounds.height はデバイス毎のスクリーンサイズの高さを取得できます、それによりデバイス毎の誤差をなるべく小さくするようにしています。

SKLabelNode - SpriteKit || Apple Developer Documentation



ここで、シミュレーターで確認して見ましょう。


laser で enemy が破壊される左上の得点が加算されていれば成功です。


次回は player の残機数を設定したいと思います。


今回は以上です。


フジテレビの公式【FODプレミアム(1ヶ月無料)】

f:id:tukumosanzou:20180721165559j:plain


最近、動画配信サービスが流行ってるけど、どうなんだろう?

なんて疑問、ありませんか?

そんなわけで、今回は「FODプレミアム」をご紹介します。





✅見逃したドラマや映画をまとめて見れるかも!

✅DVDレンタルするより、はるかにお得です!

✅返却する手間が要りません!

✅しかも好きな時間に見れるから安心!

✅懐かしの、あのドラマ・映画が見れるかも!


フジテレビの動画が豊富!しかも独占タイトルが5,000本以上!


フジテレビの現在放送中のタイトルだけでなく、『コード・ブルー』『リッチマン、プアウーマン』『昼顔』などの過去の名作ドラマを中心に5,000本以上の独占タイトルを配信しています!

それ以外にもバラエティ、アニメ、 映画など様々なジャンルから、選りすぐりのラインアップ!あの大人気タイトルがいつでもどこでも楽しめます[PR]。


毎月「フジテレビの日」(最大1200ポイントプレゼント)キャンペーン実施中!


FODプレミアム会員限定で合計で最大1200ポイント(1200円分)プレゼントします!

8のつく8日、18日、28日に400ポイントゲット出来ますのでFODプレミアム全会員にプレゼント される100ポイントも合わせて毎月8日には500ポイントも無料でゲット出来ちゃいます!

『火花』や『劇場版 昼顔』などの映画視聴には500ポイント必要ですが、 これで毎月8日にはドラマ以外にも映画も無料で見れちゃいます!

月末までには更にもう1本見れちゃいます!

毎月実施予定でもし停止となる場合は事前にご連絡させて頂きますのでご安心下さいませ[PR]。


新番組配信などの更新情報を入手し易い!

下記URLで詳細をご確認頂けます。

プレスリリース一覧

新番組・プレゼントキャンペーンなどの告知

フェイスブック

ツイッター



まとめ


忙しくて、すきなドラマや映画が見れないアナタ、「動画配信サービス」を利用して見ませんか?。

✅まずは無料お試しで!【フジテレビオンデマンド】

【Webデザイン 独学】地方に住んでても何とかなる?

f:id:tukumosanzou:20180719205000j:plain



「Webデザインをどうすれば学べるんだろう?」

「独学でやってみたいけど、どうすればいいのだろう?」


今回は独学でこれからWebデザインを学びたい方たちへ


地方に住んでても、学校が無くても学べる方法があるんです。


そう、インターネット環境さえあれば!

このやり方で一から未経験でもWebサイトを作ることができるようになります。


はじめに言っておきますが、初心者は本を買うのは後回しですよ。


本は情報の更新が止まってしまうので、適切なサイトで学んだあとで参考書がわりに買うのがベストです。


自分にとってどのような内容の本が必要か、自分で判断できるからです。




目次

・ HTML/CSSを学ぶ。

デベロッパーツールを学ぶ。

・ Sassを学ぶ

・ サイトのコピーを作る。

JavaScriptを学ぶ。

jQueryを学ぶ。

・ Bootstrapをまなぶ。

WordPressを学ぶ。

・おすすめ情報サイト

・おすすめ本

・まとめ



Webデザインの独学という選択肢。

少し前まではWebデザインを未経験で独学するとなると大変でした。

しかし今はインターネットで学べるようになりました。

良い時代になりましたよね。

自宅等で気軽にオンラインで学べるプログラミングスクールも増えてきましたね。


HTML/CSSを学ぶ。

Webデザインを学ぶにはまずHTMLとCSSを学ばないと始まりません。


とても簡単なので心配は要りません。


使いやすくてしかも、基礎的な部分は無料で学べる質の高いサイトが出てきてますので、とりあえずはそういうところで試して見ましょう。


無料で学ぶという選択肢。
気軽に始めるためには、無料で始めるのがオススメです。


TechAcademy [テックアカデミー] ではWebデザインを含めコースも豊富でいろいろ学べます。

オンラインなので、自宅にいながら学習可能です。

※1週間の無料体験ができるので、その間に Webデザインの基礎を学ぶのもありです。
オンラインブートキャンプ 無料体験 はこちら



Progateが超おすすめです!。

f:id:tukumosanzou:20180717153828p:plain

基礎部分は無料でまなべます。


スライド中心で学べるようになってます。


サイト内に学習環境が準備してあるので登録するだけですぐ始められるのもうれしいです。


実際にエンジニアに就職・転職した方も多数いるので信頼性は高いです。




デベロッパーツールを学ぶ。

Progateで学べます


HTML/CSSのコースが終了したら、ページの下の方にチュートリアルが3つありますのでそれも学んでしまいましょう。


とくに真ん中の検証ツールの使い方は学んでおくと便利です。


f:id:tukumosanzou:20180719212401j:plain




Sassを学ぶ

またまたProgateで学べます。


SassはCSSをより便利に効率的にするための言語です。


最初のうちはCSSでも事足りるのですが、Webデザインが複雑になるにつれて必ず役に立ちますから、この機会に学んでおきましょう。


f:id:tukumosanzou:20180719214740j:plain


サイトのコピーを作る



Webデザインの初心者からレベルアップするにはサイトのコピーを作成すると勉強になります。


この段階では、サイトの形だけをコピーしてください。

アニメーションなどの動きの部分は、無視してかまいません。


テンプレートをコピーするのも良いです、無料のテンプレートにはレベルの高いものがたくさんあるので、勉強になりますよ。


TEMPLATEDというサイトがオススメです。


そのためにはProgateHTML/CSSの学習コースにあるミニチュートリアルの「HTML/CSSの開発環境を用意しよう!」を学習してください。


テンプレートをデベロッパーツールで解析しながら見た目が同じになるようにコピーします。


全く同じにコピーするのもいいのですが、答えは必ずしも一つではないので同じやり方にこだわらなくても大丈夫です、見た目が同じなら良しとして数をこなしましょう。


10個くらいコピーをこなすとレベルがアップしますよ。


YouTubeにオススメのチャンネルがあります。

Mackenzie Child

ここでデザインからコーディングまでの流れが学習できます。 私もここでかなり勉強させてもらいました。




JavaScriptを学ぶ

WebデザインでWebサイトやWebアプリケーションにアニメーション等の動きを追加することができます。
CSSでもある程度は、できますがCSSはあくまで装飾が担当だと思うので。

Progate

f:id:tukumosanzou:20180720140145j:plain




jQueryを学ぶ。

JavaScriptコードをより容易に記述できるようにするために設計されたJavaScriptライブラリです。

Progate

f:id:tukumosanzou:20180720140629j:plain




ここで、またサイトのコピーをしてみてください。

今回は、アニメーションなどの動きの部分もチャレンジしてみてください。

Bootstrapを学ぶ

BootstrapはWebデザインを効率よく行うためのデザインテンプレートの集合体です。


HTML/CSS/Sass/JavaScript/jQueryの基礎がわかってないと、使うのが大変なので基礎はしっかり学びましょう。


実際の製作現場でも使われているので使えるようになっておくと便利です。



Bootstrapは慣れると簡単ですが、コツをつかむのには動画の方が適しています。


ドットインストールで学べます。

動画で様々なプログラミングを学ぶことができるサイトです。
国内でここまでレベルの高い動画があるのは、今のところここだけですね。

f:id:tukumosanzou:20180720093611j:plain




PHPを学ぶ

HTML/CSSがフロントエンドの言語と言われるのに対し、サーバーサイドの言語といわれます。


データのやり取りなどを制御するために使われます。

WordPressを学ぶ上で必ず必要となりますので学びましょう。

Progateで学びましょう。

f:id:tukumosanzou:20180720101521j:plain




SQLを学ぶ

SQLはデータの管理や分析を行うデータベース言語です。

f:id:tukumosanzou:20180720130906j:plain

PHPSQLWordPressの内部処理で使用されています。


基礎だけでも学んでおくとWordPressを学ぶ中で役に立ちますよ。



WordPressを学ぶ

ブログを作成するためにつくられたソフトウエアです。



最初は少し戸惑いますが、使うとブログを製作・運営するのが楽になります。


Webデザインでは使えるのが現状必須となりますので学んでおきましょう。


WordPressとは何か?
サルワカさんでわかりやすく解説されています。


株式会社デザインプラスWordPressテーマを販売する人気のサイトです、その中の「WordPressの使い方大全集」で学ぶと良いでしょう。

f:id:tukumosanzou:20180720135246j:plain
f:id:tukumosanzou:20180720135458j:plain




おすすめ情報サイト

PhotoshopVIP
Webデザインの情報サイトですがデザイン寄りの情報が多いです。

コリス
Webデザインの総合情報サイトです。

普段からチェックしておくことをオススメします。


おすすめ本



参考書として、一冊あると便利です。


HTML



CSS



JavaScript



php

まとめ



BootStrapやWordPressは基礎で学んだ技術の集合体です。


ですので、それを利用するにはその基礎になっている技術を理解しておく必要があるわけです。


Webデザインを学ぶ上で必要な技術について、おおまかではありますが紹介させてもらいました。





今回は以上です。

【無理じゃない】プログラミングの独学は地方に住んでてもOK?!

f:id:tukumosanzou:20180712125855j:plain



プログラミングを独学したい!
でもどうすれば学べるの?
地方住みだから学べる学校なんて無いよ?



プログラムを学んだらそれからどうするの?
エンジニアに就職・転職できたら良いよね?。



そんな方たちへ・・・

地方住みでも、学校が無くても
プログラミングを独学で学べる方法をまとめました。



「 写経 」をする

プログラミングを学ぶ上で多くの方が行っています。 といってもお経を書くあれではないです。 とにかくサンプルコードを実際にキーボードで打ち込みましょう。

人によっては本や資料を読んでからコーディングに入る のも有りですが、プログラミングも手を動かしながらの方が覚えが早いです。

また理解していなくても良いので実際のコードを書いて実行することで そのプログラムの動きが見えてくるので理解も早まりますよ。



学んだことをアウトプットする

学んだことをノート代わりにブログ等でアウトプットすると、他人にたいしてどうすればわかり易く説明できるか考えるので、理解が早まる効果があります。

可能であれば、おすすめです。

プログラミングを学習する時間を作るには?

がんばって作るしかないと思います。

でもやり通せたなら必ず得るものがあるはずです。

根性でがんばりましょう。


プログラミングを独学する目的を明確にする

プログラミングを学びたくてもどうすれば良いのかわからない人は 目的をはっきりさせることが大事です、プログラミング言語といっても200種類ぐらいあるらしいです。


そのうち20から30種類がエンジニアやプログラマに使用されているといわれます。

その中から決めるのですから初心者には戸惑います。

ではどうするのか?


目的をハッキリさせることで絞り込んでいきます。



大きく分類してすると、こんな感じだとおもいます。

これを元にプログラミング言語を絞り込んでいきます。
※ザックリとです。

Webサービス向けの言語 Webデザイン(サイト)を作成向けの言語 スマホアプリ開発向けの言語
HTML
CSS
JavaScript
php
Ruby
Python
Swift
Java



Webサービス向けは大きく二つに分かれます。

クライアントサイド サーバーサイド
サービスを利用する側の処理を開発、ザックリ言うと見た目のこと。 サービスを提供する側、ザックリ言うと見えない部分の内部処理
HTML php
CSS Ruby
JavaScript Python



プログラミングの独学(プログラマー・エンジニアへの道)

先ずは初歩を学ぶ。

・本で学ぶ。
・Webサイトで学ぶ。
・オンラインレッスンを受ける(有料・無料)



プログラムを独学するときにおすすめの本。

プログラミングの独学で初心者の入門に書籍を紹介しておきます。


HTML

実際にサイトを作りながらHTMLとCSSの基礎が学べます。
図解が多く、用語の説明もしっかりしているので読みやすいです。
2013年発行で、累計4万部のロングセラーになっているのであんしんです。


HTML&CSSについて、かなり突っ込んだところまで説明している本です。
初心者だと少し情報量が多くて戸惑うかもですが、内容は実践的でレッスンごとにレベルアップできる内容になってます。


Webサイトの製作で実際の使われる、多くの役立つテクニックを収録したサンプル集となってます。
「あれ?このやりかたどうするんだっけ」といったときに役立ちます。


CSS

CSSの初心者向けに、Webページとは何か?の基本からわかりやすく説明した本です。
文字、色、レイアウトといった具合に、そのときに使えるCSSについてわかりやすく説明がされてます。
CSSについてはこれがあれば初心者には大丈夫です、ずっと使える参考書です。


JavaScript

まったくの初心者でもわかりやくすく、HTMLとCSSをまじえて基本からJavaScriptが学べる本です。
スマホ対応、AjaxjQueryJSONといったものまでまなべます。

JavaScriptとは何かから説明してあるので、JavaScriptがまったくわからない人にとって、最初に読むのに向いている本です。
かんたんなプログラムをつくりながら、すこしづつレベルアップしていく内容になってます。


PHP

とてもわかりやすく書かれていて、基礎の基礎が学べます。
初めての一冊には向いていると思います。

PHPでやりたいことがみつかるレシピ集です。
こういうものがあると、時間をロスすることなく学習できるので便利です。


Ruby

Rubyの開発者が監修している10年以上つづくロングセラーの本です、Rubyを学ぶのには定番中の定番です。
基礎から応用まで学べる内容となってます。

まったくの初心者向けに書かれた本になってます。
図解も多く、入門にはうってつけだと思います。


Python

こちらはKindle版になります。
3部作の内の1作目ですが、いきなり分厚い本より学習する内容をしぼったものの方が、初心者にはいいのかもしれません。
価格も安いでしすし、気に入ったら続きの2部・3部を学習しても良いのかなと思います。

Pythonの基本からわかりやすく説明がされているので初心者には向いています。
イラストなどで解説もしてあるので、たのしみながら学習できます。


Java

Javaは多くの本が出ているのですが、その中でも初心者にはわかりやすいと人気の本です。
たくさんのイラストで楽しみながら学べます。
はじめてJavaをやる人はこれを選ぶべきでしょう。

Javaプログラミングを基礎からやさしく説明してあります。
基本の文法からクラス・オブジェクト指向まで、無理なく理解できるようになってます。


Swift

Swiftはバージョンアップが早いのでできるだけ最新のバージョンに対応した本を選ぶのが良いです、そのなかでも他の本とはちがいSwiftの文法だけではなく、ボタンなどの「部品」の使い方も説明してあるのが特徴です。

iOSアプリの開発は本ではなかなか学習するのはむずかしいのですが、そんななかでも何とか工夫をこらしているように思います。
第6版まででているので、それなりの信頼度はあるようです。





プログラムが独学できるWebサイト。

HTML / CSS


Progate
※文句なしにここがおススメです。
無料で始められて、有料で実践編もまなべます。


HTMLクイックリファレンス
※基本的な使い方がわかる、htmlタグの詳細が乗ってるので重宝する。

w3school.com
※サンプルコードがあるので視覚的にわかり易い。






JavaScript


Progate
※文句なしにここがおススメです。
無料で始められて、有料で実践編もまなべます。 また出ましたが、今回紹介したプログラミング言語の基礎は全てProgateで大丈夫なくらいです。


とほほのJavaScriptリファレンス
※初心者から大丈夫、日本語なのとJavaScriptとは何か?から詳細な説明があり、サンプルコードもある。






php


PHP入門
※基礎から説明されていて初心者には最適です。


PonkSoft
※初心者にもわかり易くプロレベルのブログやショッピングサイトを作る方法まで解説されています。






Ruby


Rubyがミニツク
Rubyの開発者がわかり易く説明してます。


Ruby オフィシャルサイト
※ここで基礎から学べる、初心者からプロまでの御用達サイト。


プログラミング言語 Ruby リファレンスマニュアル ※ここもRuby界隈では定番のサイト。


Ruby on Rails チュートリアル
※言わずと知れた、無料でウェブサービスの開発から公開までの流れを実例を通して学習できるサイト、ProgateRubyの基礎を学んでから利用する良いです。






Python


Aidemy
pythonに特化した学習サイトで、基礎から機械学習ブロックチェーン等も学べるようになってます。
基礎は無料で学べます。


Python.izm
※初心者からでもレベルにあわせて学べる。






Java


マンガで分かるJava入門講座
※タイトル通りマンガで説明がしてあるので、初心者にもイメージをつかみやすと思います。


Java初心者入門講座
※入門向けとしては非常に最適なサイトです。






Swift


Progate
※基礎部分は、やはりこのサイトがオススメです。


Swift学習・Xcode使い方入門|iOSアプリ開発初心者が最初に知りたかったのはこれ
iOSアプリ開発にはかかせない、Xcodeについて詳しく説明されてます。





オンラインレッスンを受ける(有料・無料)

動画形式


Udemy
※有料利用でき、動画でさまざまなジャンルの学習ができるのが特徴です。
英語での解説が主ですが、ジャンルによっては日本語もあります。
いくつか受講しましたが、なかなか良いと思いました。


ドットインストール
※日本語の唯一のサイト。
プログラミングの独学にはもってこいの初心者から学べるサイトです。 メジャーな言語はほぼ網羅してます。 入門レベルは無料で利用できます、有料でレベルアップもできます。




スライド形式


Progate
※紹介したプログラミング言語の基礎が独学で無料ではじめられるので便利です。
有料で実践レベルも学べます。


codecademy
※英語ですが、Webデザイン・Webアプリ系のプログラミングの基礎が一通り学べます。 無料だと初歩的な部分だけなので、有料でpro版にアップグレードする必要がある。






オンラインスクール(有料・無料体験あり)を使ってみる

独学だと心配になりますよね?。


そんなときは、有料のオンラインスクールもありだと思います。


就職・転職のサポートもついてるところもあるので安心です。

Webデザイン



DMM WEBCAMP ONLINE
※有料でWebデザインが学べます、ついでにPhotoShopも学べる。
オンラインだから好きな時間に学べて、メンターのサポートもある。
インターンや転職先も紹介と初心者にやさしい。
無料体験も受けられます。




Webデザイン・Webアプリ・スマホアプリ開発



TechAcademy [テックアカデミー]
※未経験からプロレベルになれます、話題のブロックチェーンコース iPhoneアプリ・Webデザイン・Webアプリなど豊富な学習コースがあり、
オンラインブートキャンプ 無料体験 もあるので試してみることもできます。


現役エンジニアのオンライン家庭教師【CodeCamp】
※Webサイト制作・Webアプリ開発・Webデザイン・iPhone/Androidアプリ開発を学べるコースがあります。
就職・転職サポートありです。
無料体験もありますよ。


侍エンジニア
※アプリ・Webサービス機械学習・ゲーム開発等が学べます。
就職・転職サポートもありです。
無料体験レッスンもあります。






独学でプログラミングを学んで就職できるか?。

大きく分けてコツは5つぐらいかと思います。


  1. インターンシップに参加
      ・就業体験(無償、有給と企業による)

  2. Wantedlyを使って会社訪問する。
      ・Facebookのつながり

  3. スクールの就職・転職サポートを利用する。

    侍エンジニア
    現役エンジニアのオンライン家庭教師【CodeCamp】

  1. ハッカソンに参加する。
      ・ソフトウェア関連プロジェクトのイベント

  2. 就職活動をする。
      ・求人サイトを利用する。
      ・フリーランス在宅ワーク)になる。

    ITエンジニアの無料カウンセリング【ポテパンフリーランス】 などに登録する。


エンジニア・プログラマーの将来性

プログラミングはその後の仕事に役立つよ

論理的思考が養える。
お小遣い程度なら自力で稼げるようになる。
フリーランスで仕事ができ、役立たずの上司が必要なくなる。
孫に自慢できる。
異性の人気者になれるかもしれない。
億万長者になれるかもしれない。
etc....


プログラミング学びたくなりませんか?

まとめ



1.サイトで学ぶ
    おススメはProgate、基礎部分は無料ですから気軽に学習できます。
    有料会員なって中級以上を学ぶのも良しです。

2.書籍を一冊買う
    経験的に最初から本を買うのはおススメしません。
    あくまで補助的に使用するのが良いですね。
    まずはWebサイトからはじめることをおすすめします。

3.Udemyでオンライン学習してみる。
    有料ですが、動画ですので理解はしやすとおもいます。
    英語主体なのですが、日本語でも可能なものもあるので挑戦してみては?。

4、自分なりになにか作ってみましょう。
    Webサイトでもできるようになったら仕事になるかもしれません。
    そしてどんな形でもいいので外にだしましょう。

5、仕事にしてみる。
    知り合いのサイトを作ってみるとかでも良いので安い報酬でも良いので
    対価を得る感覚を味わってみると良いでしょう。
    もしかしたらそこから繋がりが出来るかもしれません。


     そんな感じの順序が良いと思います。


    仕事の部分はいろんな形があるので、そこは自分しだいですが
    やってみて損はないと思いますよ。



自分で就職・転職まではちょっとという方には

オンラインスクールなら、基礎から学び就職・転職も可能でコースが豊富なTechAcademy [テックアカデミー]等も全然ありだと思いますよ。



可能性は無限大!


今回は以上です。
ありがとうございました。

SpriteKitでゲーム その1- SPACE SHOOTER⑤

f:id:tukumosanzou:20180702205113p:plain

今回は以前作成しました、func createPlayer()にレーザー砲を追加したいと思います。

ここで発射音に使うパラメーターを追加しますが、ついでに物理ボディが衝突した時の爆発音とゲームのBGMの各パラメーターも追加したいと思います。



まず効果音に使うサウンドファイルを追加します。

SpriteKitはサウンドファイルを簡単に追加する方法があります。


struct PhysicsCategories {} の直前に以下のコードを追加します。

//BGM用のパラメーターを作成。
var backgroundMusic = SKAudioNode()
//BGMで流れるゲーム音楽。
let musicURL = Bundle.main.url(forResource: "music", withExtension: "m4a")

//laserを発射するときの効果音。    
let laserSound = SKAction.playSoundFileNamed("LaserSoundEffect.mp3", waitForCompletion: false)
    
//playerやenemyが爆発したときの効果音。
let explosionSound = SKAction.playSoundFileNamed("explosion.wav", waitForCompletion: false)

Budle.main.url(forResource: "ファイル名" withEtension: "ファイルの拡張子") で文字列でプロジェクトにバンドルされたファイルを探します。

playSoundNamed("ファイル名.拡張子", waitCompletion: bool値) で waitCompletion がtrueの場合、このアクションの継続時間はオーディオ再生の長さと同じです。

falseの場合、アクションはすぐに完了したものとみなされます。


BGMを追加するのは簡単です。

didMove() 内にbadkgroundMusic = SKAudioNode(url: musicUrl) で音源をセットし addChild(backgroundMusic) でGameScene に追加するだけです。

didMove()の終了直前に追加します。

url(forResource:withExtention:) - Bundle | Apple Developer Documentation
SKAudioNode - SpriteKit | Apple Developer Documentation
playSoundFileNamed(_:waitForCompletion) - SKAction | Apple Developer Documentation



全体図はこうなります。

import SpriteKit

import GameplayKit

class GameScene: SKScene, SKPhysicsContactDelegate {
    
        //省略
    
    //BGM用のパラメーターを作成。
    var backgroundMusic = SKAudioNode()
    //BGMで流れるゲーム音楽。
    let musicURL = Bundle.main.url(forResource: "music", withExtension: "m4a")

    //laserを発射するときの効果音。    
    let laserSound = SKAction.playSoundFileNamed("LaserSoundEffect.mp3", waitForCompletion: false)
    
    //playerやenemyが爆発したときの効果音。
    let explosionSound = SKAction.playSoundFileNamed("explosion.wav", waitForCompletion: false)

    struct PhysicsCategories {
       //省略
    }

    override func didMove(to view: SKView) {

        //省略

        //BGM用の音楽をセットする
        backgroundMusic = SKAudioNode(url: musicURL!)
        //GameSceneに追加する。
        addChild(backgroundMusic)
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        //最初のタッチがあったら以降の処理を実行します、なければ処理を抜けます。
        guard let touch = touches.first else { return }
        
        //laserを作成する関数を呼び出す。      
        createLaser()
            
        
    }

    createEnemy(){
        //省略
    }

    func createLaser() {

        //SpriteNodeを作成する
        let laser = SKSpriteNode(imageNamed: "laser")
        
        //物理ボディを設定。
        laser.physicsBody = SKPhysicsBody(circleOfRadius: max(laser.size.width / 2, laser.size.height / 2))

        //物理ボディにカテゴリマスクを設定する。
        laser.physicsBody!.categoryBitMask = PhysicsCategories.laser

        //物理ボディに衝突マスクを設定する。
        laser.physicsBody!.collisionBitMask = PhysicsCategories.none

        //物理ボディにコンタクトテストマスクを設定する。
        laser.physicsBody!.contactTestBitMask = PhysicsCategories.enemy
        
        //重なり順番を5に設定する。
        laser.zPosition = 5

        //名前をつける。
        laser.name = "laser"

        //ポジションをplayerのすぐ上にする。
        laser.position = CGPoint(x: player.position.x, y: player.position.y + player.size.height * 0.8)

        //GameSceneに追加する。
        addChild(laser)
        
        // 1秒間隔でlaserの高さ分Y軸方向に移動する。
        let moveLaser = SKAction.moveTo(y: self.size.height + laser.size.height, duration: 1)

        //GameSceneから削除。
        let moveReset = SKAction.removeFromParent()

        //順番にアクションを実行するsequenceを作る。
        let moveSequence = SKAction.sequence([laserSound, moveLaser, moveReset])
        
        //アクショッンを実行する。
        laser.run(moveSequence)
    }

    createPlayer() {
        //省略
    }

    createBackground() {
        //省略
    }

}



createLaser() は createEnemy() とほぼ同じです。

SpriteKitはこのように同じようなコードが出てきますので慣れてきたらリファクタリングで整理すると良いと思います。

違う部分といえば、今まではdidMove()内部に関数の呼び出しを追加してましたが、タッチするたびにレーザーがplayerから発射されるようにしたいので、override func touchesBegan() によって createLaser() が呼び出されるようにします。


以下のようになっている部分です。

//省略

//タッチするたびに呼び出される処理。
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

        //最初のタッチがあったら以降の処理を実行します、なければ処理を抜けます。
        guard let touch = touches.first else { return }
        
        //laserを作成する関数を呼び出す。      
        createLaser()
            
}

//省略



touches.firstとは最初のタッチのことです、それを検出したら以降の処理を行うようにしています。

gurad 条件 else { return }は条件が満たされない場合はreturnで処理を抜けます。
SpriteKit(swift)プログラミングではよく見られる手法です。

touchesBegan(_:with) - UIResponder
Statements — The Swift Programming Language (Swift 4.2)



ここでシミュレーターで確認すると、画面をタッチしたらレーザーが発射されると思います。



今回は以上です、また次回。