n-HIROKIの日常

n-HIROKIの取り組みを記録したものです。

シューティングゲームのプレイヤー機を動かすプログラム

こんにちは、n-hirokiです!
今回はシューティングゲームのプレイヤーのプログラムです。



前回の敵のプログラムはこちら
hiroki-prog.hatenablog.com



動作:十字キー or マウスで動き、shiftキーで弾を撃ちます。

完成したものはこちら

boxオブジェクト(プレーヤー)
var box, Box;

box = function(){
    this.x = 250; //x座標
    this.y = 400; //y座標
    this.r = 60; //辺の長さ
    this.maxX = canvas.width - this.r; //canvasでのx軸の移動範囲
    this.maxY = canvas.height - this.r; //canvasでのy軸の移動範囲
    this.color = "#000000"; //プレイヤーの色
    this.draw = function(){ //プレイヤー描画メソッド
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.r, this.r);
    };
    this.move = function(){ //プレイヤーがcanvasからはみ出さない
        if(this.x >= this.maxX){
            this.x = this.maxX;
        }
        if(this.x < 0){
            this.x = 0;
        }
        if(this.y >= this.maxY){
            this.y = this.maxY;
        }
        if(this.y < 0){
            this.y = 0;
        }
    };
};
boxをドラッグ&ドロップで動かす
var mousedown, mouseX, mouseY;
canvas.addEventListener('mousedown',function(de){ //mousedownしたら実行
    var x, y, rect;
    rect = de.target.getBoundingClientRect(); //windowとcanvasとの差を埋める
    x = de.clientX - rect.left; //canvas上のマウスポインタの座標を取得
    y = de.clientY - rect.top;
    //boxの上でクリックされたか
    if(Box.x < x && Box.x + Box.r > x){ 
        if(Box.y < y && Box.y + Box.r > y){
            mousedown = true; //mousedownしている間true
            mouseX = x; //mouseポインタの初期位置取得
            mouseY = y;
        }
    }
});
canvas.addEventListener('mouseup', function(){ //mouseupしたら実行
    mousedown = false;  //mouseupしたらflagをfalseに
});
canvas.addEventListener('mousemove', function(me){//mousemoveしたら実行
    var x, y, rect;
    var goX, goY;
    if(mousedown == true){ //mousedownしているか
        rect = me.target.getBoundingClientRect(); //windowとcanvasの座標の差を埋める
        x = me.clientX - rect.left; //mouseの座標を取得
        y = me.clientY - rect.top;
        Box.x = Box.x + (x - mouseX); //mouseが動いた分だけboxを動かす
        Box.y = Box.y + (y - mouseY);
        mouseX = x; //基となるmouseの座標を更新
        mouseY = y;
    }
});
キーボードイベント
var mousedown, mouseX, mouseY;
var temp = {
    "key37" : 0,
    "key38" : 0,
    "key39" : 0,
    "key40" : 0
};
document.onkeydown = function(e){ //キーボードが入力されたら実行
    if(e.keyCode == 37){ //←キー判定
        tempClear("key37"); //←キーが連続で押された回数を加算
        if(temp.key37 >= 3){ //連続で3回以上押されていたら加速
            Box.x -= 13;
        }else{
            Box.x -= 5; //通常のスピード
        }
    }else if(e.keyCode == 38){//↑キー判定
        tempClear("key38");
        if(temp.key38 >= 3){ //連続で3回以上押されていたら加速
            Box.y -= 13;
        }else{
            Box.y -= 5; //通常のスピード
        }
    }else if(e.keyCode == 39){//→キー判定
        tempClear("key39");
        if(temp.key39 >= 3){ //連続で3回以上押されていたら加速
            Box.x += 13;
        }else{
            Box.x += 5; //通常のスピード
        }
    }else if(e.keyCode == 40){//↓キー判定
        tempClear("key40");
        if(temp.key40 >= 3){ //連続で3回以上押されていたら加速
            Box.y += 13;
        }else{
            Box.y += 5; //通常のスピード
        }
    }
    function tempClear(index){ //十字キーの連続で押された回数をカウント
        if(index == "key37"){
            temp.key37++;
            temp.key38 = temp.key39 = temp.key40 = 0; //他のキーが押されたらクリア
        }else if(index == "key38"){
            temp.key38++;
            temp.key37 = temp.key39 = temp.key40 = 0;
        }else if(index == "key39"){
            temp.key39++;
            temp.key37 = temp.key38 = temp.key40 = 0;
        }else if(index == "key40"){
            temp.key40++;
            temp.key37 = temp.key38 = temp.key39 = 0;
        }
    }
    if(e.shiftKey){ //shiftキー判定
        console.log("shift");
        //ビームを一つ追加 20発まで
        if(Beams.length < 20){ //弾を撃つ
            Beams.push(new beam());
        }
    }
    if(e.altKey){//altキー判定
        console.log("alt");
    }
    if(e.ctrlKey){//ctrlキー判定
        console.log("ctrl");
    }
};
弾オブジェクト
var beam, Beams = [];
beam = function(){
    this.x = Box.x + Box.r / 2; //boxの真ん中から撃つ(x軸)
    this.y = Box.y - 10; //boxから少し離す(y軸)
    this.r = 2; //辺の長さ
    this.color = "#FF0000"; //弾の色
    this.draw = function(){ //描画
        ctx.fillStyle = this.color;
        ctx.fillRect(this.x, this.y, this.r, this.r);
    };
};
全体の動き
var stage, Stage;
stage = function(){
    //画面初期化
    this.clear = function(){
        ctx.fillStyle = "#ecf0f1";
        ctx.fillRect(0, 0, canvas.width, canvas.height);
    };
    //基本処理
    this.update = function(){
        this.clear(); //canvasクリア
        Box.move(); //boxの位置がcanvasからはみ出していないかチェック
        Box.draw(); //box描画
        //弾を描画
        for(var i = 0; Beams.length >= i + 1; i++){
            Beams[i].y -= 5; //弾のスピード
            //はみ出し判定
            if(Beams[i].y <= 0){
                Beams.splice(i, 1); //canvasからはみ出したら弾を消す
            }else{
                Beams[i].draw(); //はみ出していなければ描画
            }
        }
        //タイマー
        setTimeout(function(){ //100ms間隔で繰り返す
            this.update();
        }.bind(this), 100);
    }
};
全体のコード
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>boxSystem</title>
</head>
<body>
    <canvas id="mycanvas" width="500" height="500">
        Canvasに対応したブラウザを使ってください。
    </canvas>
    <script>
        (function(){
            'use strict';
            var canvas, ctx;
            var box, Box;
            var beam, Beams = [];
            var stage, Stage;
            var mousedown, mouseX, mouseY;
            var temp = {
                "key37" : 0,
                "key38" : 0,
                "key39" : 0,
                "key40" : 0
            };
            
            canvas = document.getElementById('mycanvas');
            if(!canvas || !canvas.getContext) return false;
            ctx = canvas.getContext('2d');
            
            document.onkeydown = function(e){
                if(e.keyCode == 37){
                    tempClear("key37");
                    if(temp.key37 >= 3){
                        Box.x -= 13;
                    }else{
                        Box.x -= 5;
                    }
                }else if(e.keyCode == 38){
                    tempClear("key38");
                    if(temp.key38 >= 3){
                        Box.y -= 13;
                    }else{
                        Box.y -= 5;
                    }
                }else if(e.keyCode == 39){
                    tempClear("key39");
                    if(temp.key39 >= 3){
                        Box.x += 13;
                    }else{
                        Box.x += 5;
                    }
                }else if(e.keyCode == 40){
                    tempClear("key40");
                    if(temp.key40 >= 3){
                        Box.y += 13;
                    }else{
                        Box.y += 5;
                    }
                }
                
                function tempClear(index){
                    if(index == "key37"){
                        temp.key37++;
                        temp.key38 = temp.key39 = temp.key40 = 0;
                    }else if(index == "key38"){
                        temp.key38++;
                        temp.key37 = temp.key39 = temp.key40 = 0;
                    }else if(index == "key39"){
                        temp.key39++;
                        temp.key37 = temp.key38 = temp.key40 = 0;
                    }else if(index == "key40"){
                        temp.key40++;
                        temp.key37 = temp.key38 = temp.key39 = 0;
                    }
                }
                if(e.shiftKey){
                    console.log("shift");
                    if(Beams.length < 20){
                        Beams.push(new beam());
                    }
                }
                if(e.altKey){
                    console.log("alt");
                }
                if(e.ctrlKey){
                    console.log("ctrl");
                }
            };
            canvas.addEventListener('mousedown',function(de){
                var x, y, rect;
                rect = de.target.getBoundingClientRect();
                x = de.clientX - rect.left;
                y = de.clientY - rect.top;
                if(Box.x < x && Box.x + Box.r > x){
                    if(Box.y < y && Box.y + Box.r > y){
                        mousedown = true;
                        mouseX = x;
                        mouseY = y;
                    }
                }
            });
            canvas.addEventListener('mouseup', function(){
                mousedown = false; 
            });
            canvas.addEventListener('mousemove', function(me){
                var x, y, rect;
                var goX, goY;
                if(mousedown == true){
                    rect = me.target.getBoundingClientRect();
                    x = me.clientX - rect.left;
                    y = me.clientY - rect.top;
                    Box.x = Box.x + (x - mouseX);
                    Box.y = Box.y + (y - mouseY);
                    mouseX = x;
                    mouseY = y;
                }
            });
            stage = function(){
                this.clear = function(){
                    ctx.fillStyle = "#ecf0f1";
                    ctx.fillRect(0, 0, canvas.width, canvas.height);
                };
                this.update = function(){
                    this.clear();
                    Box.move();
                    Box.draw();
                    for(var i = 0; Beams.length >= i + 1; i++){
                        Beams[i].y -= 5;
                        if(Beams[i].y <= 0){
                            Beams.splice(i, 1);
                        }else{
                            Beams[i].draw();
                        }
                    }
                    setTimeout(function(){
                        this.update();
                    }.bind(this), 100);
                }
            };
            beam = function(){
                this.x = Box.x + Box.r / 2;
                this.y = Box.y - 10;
                this.r = 2;
                this.color = "#FF0000";
                this.draw = function(){
                    ctx.fillStyle = this.color;
                    ctx.fillRect(this.x, this.y, this.r, this.r);
                };
            };
            box = function(){
                this.x = 250;
                this.y = 400;
                this.r = 60;
                this.maxX = canvas.width - this.r;
                this.maxY = canvas.height - this.r;
                this.color = "#000000";
                this.draw = function(){
                    ctx.fillStyle = this.color;
                    ctx.fillRect(this.x, this.y, this.r, this.r);
                };
                this.move = function(){
                    if(this.x >= this.maxX){
                        this.x = this.maxX;
                    }
                    if(this.x < 0){
                        this.x = 0;
                    }
                    if(this.y >= this.maxY){
                        this.y = this.maxY;
                    }
                    if(this.y < 0){
                        this.y = 0;
                    }
                };
            };
            Box = new box();
            Stage = new stage();
            Stage.update();
        })();
    </script>
</body>
</html>


結構ドラッグアンドドロップで動かすプログラミングに手こずりました。
addEventListenerを初めて使ったのでかなり勉強になりました。

最初はaddEventListener(マウスダウン)の中にaddEventListener(マウスムーブ)を入れればうまく行くんじゃないのか?と思って試したらマウスダウンしてないときにもマウスムーブのaddEventListenerが反応していてうまくいかなかったり、初歩的なことでつまずいたりしていました。

ですが、そのデバッグのおかげで理解が深まり ためになりました!

何よりも、コピペじゃなくて自分で考えて書けたのがとても嬉しかってです!


次は、シューティングゲームの全体のブログを書きますのでよろしくお願いします!