👾

JavaScriptでゲーム制作⑤ ~リンゴの落下を不規則に繰り返す~

2022/05/03に公開

JavaScriptでゲーム制作④ ~落ちてくるリンゴを作る~で落下するリンゴを作ることができました。続いてリンゴの落下を調整します。

■落下を繰り返す

今のままではリンゴは1度落ちたきりで終わってしまいます。下に落ちて見えなくなったら、また上から落ちてくるようにしましょう。
前回、app.tickerというループ処理のプログラムを記述しました。そこに新たにコードを追加します。★のある行が新コードです。

    // ループ処理の実装
    app.ticker.add(function(){
        //Pixiアプリの子要素に対する処理
        app.stage.children.forEach(element => {
            //カゴ以外の場合、落下処理を実施する
            if(basket != element){
                element.y = element.y + 1;//落下移動
                //★リンゴのy位置が画面を超えた場合、新しいy位置を設定する
                if(element.y > app.view.scrollHeight){//★
                    element.y = 0;//★
                }//★
            }
        });
    });

リンゴが画面下の位置に移動したかどうかを判定します。
画面の高さはapp.viewというゲーム背景の高さを取得すればわかります。viewはscrollHeightという高さを表す値を持っています。
リンゴの垂直位置(y)がviewの高さ以上に下に移動したら垂直位置を0に戻してみましょう。
このコードをブラウザで実行すると画面最下部に移動したリンゴが再び上から落ちてくるようになります。

■落下に不規則性を持たせる

現在は4つのリンゴが同じ垂直位置から落下しています。これを不規則にしてみましょう。
「JavaScriptでゲーム制作④ ~落ちてくるリンゴを作る~」で水平位置を4つ定義しました。
それと同じく垂直位置も定義しましょう。

    // y位置
    const ypos1 = -96;
    const ypos2 = (ypos1*2);
    const ypos3 = (ypos1*3);
    const ypos4 = (ypos1*4);
    const y_positions = [ypos1, ypos2, ypos3, ypos4];

この4つの位置を不規則に4つのリンゴに適用するようにしましょう。
リンゴを追加するコードを改良します。★のある行が改良コードです。

    //リンゴを追加
    x_positions.forEach(function(xpos){ //水平位置の設定を1つずつ処理する
        let apple = PIXI.Sprite.from('apple.png');//リンゴの画像を変数に格納
        apple.anchor.set(0.5);//基準点は中央にする
        apple.scale.set(2);//2倍の大きさにする
        apple.x = xpos;//水平位置

        //★配列からランダムにy位置を取得
        random = Math.floor( Math.random() * y_positions.length );//★
        apple.y = y_positions[random];//★垂直位置

        app.stage.addChild(apple);//画面に追加する
    });

Math.random()関数は0以上1未満のランダムな小数(0, 0.1, 0.2,...)を返します。y_positions.lengthはy位置配列に格納された変数の数(4つ)を返します。randam()に4をかけると0、0.4、0.8、1.2などの値が結果として返ってきます。それをMath.floor()で小数を切り捨てます。

結果、0から3のいずれかの値が変数randomに格納されます。
その後、配列にrandomを指定するとその位置に格納された変数の値がapple.yに格納されます。。(apple.y = y_positions[random];)

また、配列の1番目を取得するには0を指定します。JavaScriptにおける配列は0番目から始まるルールになっています。

このコードをブラウザで確認すると下図の通り落下が不規則になりました。

しかし、このままでは一度落下した後に再び同じ垂直位置から落下することが続きます。
さらに不規則にしていきましょう。
ループ処理のリンゴに不規則な垂直位置を設定していきましょう。
★のある行が改良コードです。

    // ループ処理の実装
    app.ticker.add(function(){
        //Pixiアプリの子要素に対する処理
        app.stage.children.forEach(element => {
            //カゴ以外の場合、落下処理を実施する
            if(basket != element){
                element.y = element.y + 1;//落下移動
                //リンゴのy位置が画面を超えた場合、新しいy位置を設定する
                if(element.y > app.view.scrollHeight){
                    //★配列からランダムにy位置を取得
                    random = Math.floor( Math.random() * y_positions.length );//★
                    element.y = y_positions[random];//★垂直位置にランダム値を設定
                }
            }
        });
    });

リンゴを追加するコードと同じくランダム値をリンゴの垂直位置に設定することで不規則性を出します。これをブラウザで確認すると落下の不規則性が増していると思います。

■カゴとリンゴの表示順序を変更する

最後にカゴとリンゴの表示を変更します。現在はリンゴのほうがカゴより手前に表示されています。

後の項でカゴがリンゴをキャッチするようにプログラムするので、いまの表示のままだと不都合です。順序を変えましょう。カゴを画面変数(app.stage)に入れるタイミングをリンゴの後にします。★が変更した箇所です。

    //かご
    const basket = PIXI.Sprite.from('basket.png');//画像
    basket.width = 64;//幅
    basket.height = 34;//高さ
    basket.x = 96;//x座標
    basket.y = app.view.height - basket.height;//y座標
    basket.anchor.set(0.5);//中心点。0が左端、0.5が中央、1が右端
    //app.stage.addChild(basket);★コメントアウト
    //カゴの操作
    document.addEventListener('keydown',
        function (key){
            // 左キー
            if (key.keyCode === 65 || key.keyCode === 37) {
                if ( (basket.position.x - ( basket.width / 2 )) > 96) {
                    basket.position.x -= 96;
                }
            }
            // 右キー
            if (key.keyCode === 68 || key.keyCode === 39) {
                if ( (basket.position.x + ( basket.width / 2 )) < 384 ) {
                    basket.position.x += 96;
                }
            }
        }
    );

    // リンゴの水平位置
    const xpos1 = 96;
    const xpos2 = (xpos1*2);
    const xpos3 = (xpos1*3);
    const xpos4 = (xpos1*4);
    const x_positions = [xpos1, xpos2, xpos3, xpos4];
    // リンゴの垂直位置
    const ypos1 = -96;
    const ypos2 = (ypos1*2);
    const ypos3 = (ypos1*3);
    const ypos4 = (ypos1*4);
    const y_positions = [ypos1, ypos2, ypos3, ypos4];

    //リンゴを追加
    x_positions.forEach(function(xpos){ //水平位置の設定を1つずつ処理する
        let apple = PIXI.Sprite.from('apple.png');//リンゴの画像を変数に格納
        apple.anchor.set(0.5);//基準点は中央にする
        apple.scale.set(2);//2倍の大きさにする
        apple.x = xpos;//水平位置

        //配列からランダムにy位置を取得
        random = Math.floor( Math.random() * y_positions.length );
        apple.y = y_positions[random];//垂直位置

        app.stage.addChild(apple);//画面に追加する
    });
    app.stage.addChild(basket);//★ここに移動

コメントアウトするとプログラム処理を実行しなくなります。”//”を先頭に付与しましょう。

結果をブラウザで確認しましょう。

カゴにリンゴが収まるような表示になりました。

次はカゴがリンゴをキャッチし得点するようにします。
https://zenn.dev/genmakai/articles/86272220e4805c

Discussion