LoginSignup
2
1

More than 3 years have passed since last update.

【JavaScript】2人プレイのディフェンスゲームを作ってみた

Last updated at Posted at 2019-10-21

はじめに

JavaScriptでcanvasを使って、2人プレイのディフェンスゲームを作ってみました。

プレイはこちらから→ディフェンスゲーム

環境

  • Windows 10 home
  • Google Chrome

ルール

2人プレイのゲームになります。
黄色の玉が画面右から左へ移動します。
画面左まで移動したときに、HPが減っていき、HPが0になるとゲーム終了です。
プレイヤー1と2は黄色の玉が画面の左へ移動するのを阻止する必要があります。
プレイヤー1は赤色の玉、プレイヤー2は青色の玉をそれぞれ操作し、黄色の玉に当たることで、黄色の玉を消すことができます。
このようにして、黄色の玉の移動を阻止していきましょう!
また、それぞれ黄色の玉に当たると得点も付くようにしているので、協力し合うことも、対戦で遊ぶこともできます。

操作方法

1P 矢印キーでの移動
上に移動
下に移動
右に移動
左に移動
2P WASDキーでの移動
W 上に移動
S 下に移動
A 右に移動
D 左に移動

プログラム

index.html
<style>body{margin:0;}</style>
<canvas class="canvas">
<script>
"use strict";
{
const WIDTH = 1200; //キャンバスの横軸
const HEIGHT = 600; //キャンバスの縦軸
const HTML_CVS = document.querySelector(".canvas"); //キャンバスの領域の取得
const CANVAS = HTML_CVS.getContext("2d"); //キャンバスの描画機能を有効

class Circle{ //円クラス
  constructor(canvas,x,y,r,color){
    this.canvas = canvas;
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = color;
  }

  draw(){ //描画
    this.canvas.beginPath(); //パスの初期化
    this.canvas.fillStyle = this.color;
    this.canvas.arc(this.x,this.y,this.r,0*Math.PI,2*Math.PI,true);
    this.canvas.closePath(); //パスを閉じる
    this.canvas.fill();
  }
}

class Player extends Circle{ //プレイヤークラス
  constructor(canvas,x,y,r,color){
    super(canvas,x,y,r,color);

    this.speed = 20; //プレイヤーの移動の速さ
    this.score = 0; //プレイヤーの得点

    this.up = false;
    this.down = false;
    this.right = false;
    this.left = false;
  }

  move(){ //キー操作での動き
    if(this.up && this.y-(this.r+this.speed)>=0){this.y -= this.speed;}
    if(this.down && this.y+(this.r+this.speed)<=HEIGHT){this.y += this.speed;}
    if(this.right && this.x+(this.r+this.speed)<=WIDTH){this.x += this.speed;}
    if(this.left && this.x-(this.r+this.speed)>=0){this.x -= this.speed;}
  }

  toEnemyDistance(enemy){ //敵との距離を算出
    return Math.sqrt((enemy.x-this.x)**2+(enemy.y-this.y)**2);
  }
}

class Enemy extends Circle{ //敵クラス
  constructor(canvas,x,y,r,color){
    super(canvas,x,y,r,color);
    this.y = Math.floor(Math.random()*(HEIGHT-this.r*2))+this.r;
    this.speed = 12;
  }

  move(){ //右から左への動き
    if(this.x > 0+this.r){
      this.x -= this.speed;
    }
  }
}

class ScoreLabel{
  constructor(canvas){
    this.canvas = canvas;
    this.x = 10;
    this.y = 40;
    this.hp = 20;
  }

  draw(p1,p2){
    this.canvas.fillStyle = "white";
    this.canvas.font = "30px Arial";
    this.canvas.fillText("hp : "+this.hp +" / P1 : "+p1.score+" / P2 : "+p2.score,this.x,this.y);
  }
}

class Game{
  constructor(){
    HTML_CVS.width = WIDTH;
    HTML_CVS.height = HEIGHT;

    this.PlayerRadius = 60; //プレイヤーの玉の半径
    this.EnemyRadius = 10; //敵の玉の半径
    this.frameRate = 50; //フレーム数
    this.timeCounter = 0; //タイムカウンタ
    this.intervalTime = 0.2; //敵の生成間隔時間
    this.gameflag = true;

    this.player1 = new Player(CANVAS,this.PlayerRadius,this.PlayerRadius,this.PlayerRadius,"red"); //1P
    this.player2 = new Player(CANVAS,this.PlayerRadius,HEIGHT-this.PlayerRadius,this.PlayerRadius,"blue"); //2P
    this.enemy = [];
    this.scoreLabel = new ScoreLabel(CANVAS);

    window.setInterval(()=>{ //ループ処理(フレーム数はFRAME_RATE)
      CANVAS.fillStyle = "black";
      CANVAS.fillRect(0,0,WIDTH,HEIGHT) //キャンバスを描画

      if(this.gameflag){
        this.player1.draw(); //プレイヤー1の描画
        this.player1.move(); //プレイヤー1の動き

        this.player2.draw(); //プレイヤー2の描画
        this.player2.move(); //プレイヤー2動き


        for(let i=0;i<this.enemy.length;i++){
          this.enemy[i].draw(); //敵の描画
          this.enemy[i].move(); //敵の動き
          if(this.enemy[i].x <= 0+this.enemy[i].r){
            this.enemy.splice(i,1);
            this.scoreLabel.hp--;
          }
          if(this.player1.toEnemyDistance(this.enemy[i])<=this.player1.r+this.enemy[i].r){ //距離による当たり判定
            this.enemy.splice(i,1);
            this.player1.score++;
            continue;
          }
          if(this.player2.toEnemyDistance(this.enemy[i])<=this.player2.r+this.enemy[i].r){ //距離による当たり判定
            this.enemy.splice(i,1);
            this.player2.score++;
            continue;
          }
        }
        this.timeCounter++;

        if(this.timeCounter % (this.frameRate*this.intervalTime) == 0){
          this.enemy.push(new Enemy(CANVAS,WIDTH-this.EnemyRadius,HEIGHT/2,this.EnemyRadius,"yellow"));
        }

        this.scoreLabel.draw(this.player1,this.player2);
        if(this.scoreLabel.hp <= 0){this.gameflag=false;}
        }else{alert("ゲームオーバー!");} //アラートでゲームオーバーを表示

    },1000/this.frameRate);

    window.addEventListener("keydown",()=>{ //キーボードのキーを押したときに処理
      if(event.keyCode==38){this.player1.up=true;} //上矢印キー
      if(event.keyCode==40){this.player1.down=true;} //下矢印キー
      if(event.keyCode==39){this.player1.right=true;} //右矢印キー
      if(event.keyCode==37){this.player1.left=true;} //左矢印キー

      if(event.keyCode==87){this.player2.up=true;} //Wキー
      if(event.keyCode==83){this.player2.down=true;} //Sキー
      if(event.keyCode==68){this.player2.right=true;} //Dキー
      if(event.keyCode==65){this.player2.left=true;} //A印キー
    });

    window.addEventListener("keyup",()=>{ //キーボードのキーを離したときに処理
      if(event.keyCode==38){this.player1.up=false;} //上矢印キー
      if(event.keyCode==40){this.player1.down=false;} //下矢印キー
      if(event.keyCode==39){this.player1.right=false;} //右矢印キー
      if(event.keyCode==37){this.player1.left=false;} //左矢印キー

      if(event.keyCode==87){this.player2.up=false;} //Wキー
      if(event.keyCode==83){this.player2.down=false;} //Sキー
      if(event.keyCode==68){this.player2.right=false;} //Dキー
      if(event.keyCode==65){this.player2.left=false;} //Aキー
    });
  }
}

new Game(); //ゲーム開始
}
</script>

以上で終了です!
ここまで読んでいただき、ありがとうございました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1