LoginSignup
0
0

More than 1 year has passed since last update.

JavaScriptでアプリを作成しました【7】【Space Invaders】

Last updated at Posted at 2021-09-06

はじめに

学習するに至った経緯

2020年より、未経験からエンジニアへの転職を目指し、某プログラミングスクールへ通う。入学後、『Ruby』を未経験から学ぶ人が多いのと『Ruby』の求人が思っていた以上に少ないので、卒業後、フロントエンドのエンジニアを目指す事に。
Javascriptの学習した事を言語化し、認識の深化による備忘録として記載。

index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">

    <title>Space Invaders</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <h1 class="results">0</h1>
    <div class="grid"></div>
    <script src="main.js"></script>

</body>
</html>
styles.css
.grid {
    width: 300px;
    height: 300px;
    border: solid black 1px;
    display: flex;
    flex-wrap: wrap;
}
.grid div{
    width: 20px;
    height: 20px;
}

.invader {
    background-color: purple;
    border-radius: 10px;
}

.shooter {
    background-color: green;
}

.laser {
    background-color: orange;
}

.boom {
    background-color: red;
}
main.js
//gridを取得
const grid = document.querySelector(".grid");
const resultsDisplay = document.querySelector(".results");

let currentShooterIndex = 202;
let width = 15;
let direction = 1;
let invadersId;
let goingRight = true;
let aliensRemoved = [];
let results = 0;

//forループを使用して正方形を作成
for (let i = 0; i < 225; i++) {
  //forループを実行し、ループするたび正方形を作成する
  const square = document.createElement("div");
  grid.appendChild(square);
}
//全ての正方形を取得
const squares = Array.from(document.querySelectorAll(".grid div"));
//エイリアンを取得 配列を使用
const alienInvaders = [
  0,1,2,3,4,5,6,7,8,9,
  15,16,17,18,19,20,21,
  22,23,24,30,31,32,33,
  34,35,36,37,38,39,
];
//インヴェーダーを正方形の中に配置する
function draw() {
  for (let i = 0; i < alienInvaders.length; i++) {
    if (!aliensRemoved.includes(i)) {
      squares[alienInvaders[i]].classList.add("invader");
    }
  }
}

draw();
//削除したインベーダーを作成する
function remove() {
  for (let i = 0; i < alienInvaders.length; i++) {
    squares[alienInvaders[i]].classList.remove("invader");
  }
}

squares[currentShooterIndex].classList.add("shooter");

//シューターを動かす
function moveShooter(e) {
  squares[currentShooterIndex].classList.remove("shooter");
  //キーボタンを押したら左右に1マスずつ移動する
  switch (e.key) {
    case "ArrowLeft":
      if (currentShooterIndex % width !== 0) currentShooterIndex -= 1;
      break;
    case "ArrowRight":
      if (currentShooterIndex % width < width - 1) currentShooterIndex += 1;
      break;
  }
  squares[currentShooterIndex].classList.add("shooter");
}
document.addEventListener("keydown", moveShooter);

//インベーダーが移動する
function moveInvaders() {
  const leftEdge = alienInvaders[0] % width === 0;
  const rightEdge = alienInvaders[alienInvaders.length - 1] % width === width - 1;
  remove();
  //最後のインベーダーが右端にいたら一段下げる
  if (rightEdge && goingRight) {
    //iを0にするためには、各インベーダーをループさせる。
    for (let i = 0; i < alienInvaders.length; i++) {
      alienInvaders[i] += width + 1;
      direction = -1;
      goingRight = false;
    }
  }
  //最後のインベーダーが左端にいたら一段下げる
  if (leftEdge && !goingRight) {
    for (let i = 0; i < alienInvaders.length; i++) {
      alienInvaders[i] += width - 1;
      direction = 1;
      goingRight = true;
    }
  }

  for (let i = 0; i < alienInvaders.length; i++) {
    alienInvaders[i] += direction;
  }
  draw();
  //シューターがインベーダーに当たったら、GAME OVER
  if (squares[currentShooterIndex].classList.contains("invader", "shooter")) {
    resultsDisplay.innerHTML = "GAME OVER";
    clearInterval(invadersId);
  }
  //インべーダーが底に当たったら、GAME OVER
  for (let i = 0; i < alienInvaders.length; i++) {
    if (alienInvaders[i] > squares.length + 100) {
      //   console.log("squares.length", squares.length);
      resultsDisplay.innerHTML = "GAME OVER";
      clearInterval(invadersId);
    }
  }
  if (aliensRemoved.length === alienInvaders.length) {
    resultsDisplay.innerHTML = "YOU WIN! WIN!";
    clearInterval(invadersId);
  }
}
invadersId = setInterval(moveInvaders, 300);

//インベーダーを射撃する
function shoot(e) {
  let laserId;
  let currentLaserIndex = currentShooterIndex;
  function moveLaser() {
    squares[currentLaserIndex].classList.remove("laser");
    currentLaserIndex -= width;
    squares[currentLaserIndex].classList.add("laser");

    //インベーダーにレーザーが当たると削除される
    if (squares[currentLaserIndex].classList.contains("invader")) {
      squares[currentLaserIndex].classList.remove("laser");
      squares[currentLaserIndex].classList.remove("invader");
      squares[currentLaserIndex].classList.add("boom");

      //レーザーによる爆発が起きたら、300ミリ秒後に削除される
      setTimeout(() => squares[currentLaserIndex].classList.remove("boom"), 300);
      clearInterval(laserId);
      //インベーダーにレーザーが当たっても再描画されているので、レーザーが当たると削除される
      const alienRemoved = alienInvaders.indexOf(currentLaserIndex);
      aliensRemoved.push(alienRemoved);
      //スコアを追加
      results++;
      //結果を表示する
      resultsDisplay.innerHTML = results;
      console.log(aliensRemoved);
    }
  }
  //キーの上を押すと射撃する
  switch (e.key) {
    case "ArrowUp":
      laserId = setInterval(moveLaser, 100);
  }
}
document.addEventListener("keydown", shoot);

参考サイト

Space Invaders in JavaScript (no-nonsense version!)

0
0
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
0
0