【JavaScript】2人プレイのディフェンスゲームを作ってみた
はじめに
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>
<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>
以上で終了です!
ここまで読んでいただき、ありがとうございました。
Author And Source
この問題について(【JavaScript】2人プレイのディフェンスゲームを作ってみた), 我々は、より多くの情報をここで見つけました https://qiita.com/michimichix521/items/c8c1a88fe35358532766著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .