##はじめに
####学習するに至った経緯
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!)]
(https://www.youtube.com/watch?v=3Nz4Yp7Y_uA&t=692s)