4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

javascriptでインベーダーゲームをつくってみた

Posted at

はじめに

Javascriptの勉強のため,ゲームを作ってみました.よろしければどうぞ!!
インベーダーゲーム

プログラム

place.html
<canvas id="myCanvas" width="320" height="320"></canvas>
place.css
canvas {
	background: #eee;
	}
place.js
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var ballRadius = 5;
var myMisileX = canvas.width/2;
var myMisileY = canvas.height-30;
var enemyMisileX = -10;
var enemyMisileY = 0;
var enemyMisileDy = 2;
var enemyMisileExist = false;
var startFlag = true;
var hitStatus = true;
var myMisileDy = -5;
var paddleHeight = 10;
var paddleWidth = 75;
var paddleX = (canvas.width-paddleWidth)/2;
var mouseClicked = false;
var brickRowCount = 5;
var brickColumnCount = 3;
var brickWidth = 45;
var brickHeight = 20;
var brickPadding = 10;
var brickOffsetTop = 30;
var brickOffsetLeft = 30;
var score = 0;
var lives = 3;

/* ブロック初期化 */
var bricks = [];
for(var c=0; c<brickColumnCount; c++) {
  bricks[c] = [];
  for(var r=0; r<brickRowCount; r++) {
    bricks[c][r] = { x: 0, y: 0, status: 1, misile: 0 };
  }
}

document.addEventListener("mousemove", mouseMoveHandler, false);
document.addEventListener("click", mouseClickHandler, false);

/* 敵ミサイルの状態 */
var enemyMisileStatus = setInterval(function(){
  if(!enemyMisileExist){
		for(var c=0; c<brickColumnCount; c++) {
			for(var r=0; r<brickRowCount; r++) {
				bricks[c][r].misile = 0;
				}
			}
		var randomC = Math.floor( Math.random() * brickColumnCount );
		var randomR = Math.floor( Math.random() * brickRowCount );
		if(bricks[randomC][randomR].status == 1){
			bricks[randomC][randomR].misile = 1;
		}
	}
}, 3000-moveCount*100);

/* 発射ミサイル位置設定 */
var enemyMisilePosition = setInterval(function(){
	if(!enemyMisileExist){
		for(var c=0; c<brickColumnCount; c++) {
			for(var r=0; r<brickRowCount; r++) {
				if(bricks[c][r].misile == 1) {
					enemyMisileX = bricks[c][r].x+brickWidth/2;
					enemyMisileY = bricks[c][r].y;
				}
			}
		}
	}
}, 3000-moveCount*100);

var moveCount = 0;
var rightFlag = 1;
/* 敵位置の変更 */
var enemyPosition = setInterval(function(){
	startFlag = false;
	var moveX = 5;
	var moveY = 0;
	if(moveCount>75){
		//敵が迫ってきたので,ゲームオーバー
		//alert("GAME OVER");
		document.location.reload();
	}
	if(moveCount % 10 == 5){
		moveX = 0;
		moveY = 20;
		rightFlag = -rightFlag;
	} else {
		moveX = rightFlag*5;
	}
	for(var c=0; c<brickColumnCount; c++) {
		for(var r=0; r<brickRowCount; r++) {
			bricks[c][r].x += moveX;
			bricks[c][r].y += moveY;
		}
	}
	moveCount++;
}, 1000);

/* パドル位置の取得 */
function mouseMoveHandler(e) {
  var relativeX = e.clientX - canvas.offsetLeft;
  if(relativeX > 0 && relativeX < canvas.width) {
    paddleX = relativeX - paddleWidth/2;
  }
}

/* クリック位置の取得 */
function mouseClickHandler(e) {
  var relativeX = e.clientX - canvas.offsetLeft;
	if(!mouseClicked){
		myMisileX = relativeX;
		mouseClicked = true;
	}
}

/* ミサイルヒット判定 */
function collisionDetection() {
  for(var c=0; c<brickColumnCount; c++) {
    for(var r=0; r<brickRowCount; r++) {
      var b = bricks[c][r];
      if(b.status == 1) {
        if(myMisileX > b.x && myMisileX < b.x+brickWidth && myMisileY > b.y && myMisileY < b.y+brickHeight) {
          mouseClicked = false;
					myMisileY = canvas.height-30;
          b.status = 0;
          score++;
					console.log("敵にhit");
          if(score == brickRowCount*brickColumnCount) {
            alert("You win, congratulations!");
            document.location.reload();
          }
        }
      }
    }
  }
}

/* ミサイルの生成 */
function drawMyMisile() {
  ctx.beginPath();
  ctx.arc(myMisileX, myMisileY, ballRadius, 0, Math.PI*2);
  ctx.fillStyle = "#ff69b4";
  ctx.fill();
  ctx.closePath();
}

/* 敵ミサイルの生成 */
function drawEnemyMisile() {
  ctx.beginPath();
  ctx.arc(enemyMisileX, enemyMisileY, ballRadius, 0, Math.PI*2);
  ctx.fillStyle = "#0095DD";
  ctx.fill();
  ctx.closePath();
}

/* パドルの生成 */
function drawPaddle() {
  ctx.beginPath();
  ctx.rect(paddleX, canvas.height-paddleHeight, paddleWidth, paddleHeight);
  ctx.fillStyle = "#ff69b4";
  ctx.fill();
  ctx.closePath();
}

/* ブロックの生成 */
function drawBricks() {
  for(var c=0; c<brickColumnCount; c++) {
    for(var r=0; r<brickRowCount; r++) {
      if(bricks[c][r].status == 1) {
				if(startFlag){
					bricks[c][r].x = (r*(brickWidth+brickPadding))+brickOffsetLeft;
	        bricks[c][r].y = (c*(brickHeight+brickPadding))+brickOffsetTop;
				}
        ctx.beginPath();
        ctx.rect(bricks[c][r].x, bricks[c][r].y, brickWidth, brickHeight);
        ctx.fillStyle = "#0095DD";
        ctx.fill();
        ctx.closePath();
      }
    }
  }
}

/* スコア表示 */
function drawScore() {
  ctx.font = "16px Arial";
  ctx.fillStyle = "#0095DD";
  ctx.fillText("Score: "+score, 8, 20);
}

/* HP表示 */
function drawLives() {
  ctx.font = "16px Arial";
  ctx.fillStyle = "#0095DD";
  ctx.fillText("Lives: "+lives, canvas.width-65, 20);
}

/* 描画 */
function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBricks();
	drawEnemyMisile();
  drawPaddle();
  drawScore();
  drawLives();
  collisionDetection();
	
	enemyMisileY += enemyMisileDy + 0.1*moveCount;
	if(enemyMisileY>canvas.height){
		enemyMisileExist = false;
		hitStatus = true;
	} else {
		enemyMisileExist = true;
	}
	if(hitStatus){
		if(canvas.height >= enemyMisileY && enemyMisileY >= canvas.height-ballRadius) {
			if(enemyMisileX > paddleX && enemyMisileX < paddleX + paddleWidth) {
				lives--;
				hitStatus = false;
				if(!lives) {
					//alert("GAME OVER");
					document.location.reload();
				}
			}
		}
	}
	
	if(mouseClicked){
		drawMyMisile();
		myMisileY += myMisileDy;
		if(myMisileY<=0){
			mouseClicked = false;
			myMisileY = canvas.height-30;
		}
	}
	if(myMisileY > enemyMisileY-ballRadius && enemyMisileY+ballRadius > myMisileY){
		if(myMisileX > enemyMisileX-ballRadius*2 && enemyMisileX+ballRadius*2 > myMisileX){
			console.log("MISILE同士がhit");
			enemyMisileExist = false;
			mouseClicked = false;
			myMisileY = canvas.height-30;
		}
	}
  requestAnimationFrame(draw);
}

draw();
4
3
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
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?