HTML, CSS, 자바스크립트 배우기 - 존 콘웨이의 인생 게임 재현
46572 단어 htmljavascripttutorialbraziliandevs
Versão PT-BR
머리말:
안녕하십니까, 자바스크립트, CSS, HTML 기술을 향상시키기 위해 멋진 프로젝트를 찾고 계십니까?
이 강좌에서, 나는 너에게 너 자신의 버전의 생활 게임을 어떻게 하는지 가르쳐 줄 것이다. 이것은 영국 수학자 존 콘웨이가 개발한 게임 이념이다.
이 게임은'세포 자동기'라는 라벨의 일부로 위키백과에 따르면'복잡한 행동을 보여줄 수 있는 더 간단한 시간 진화 모델'이라는 뜻이다.
그러나 이 복잡한 해석을 걱정하지 마라. 우리는 기본적으로 게이머가 없는 게임을 만들 것이다. 마치 그것이 살아있는 것처럼.
이 필드는 미리 정의된 규칙에 따라 상태를 변경하는 블록으로 채워집니다.
다음은 Github 저장소입니다.
https://github.com/akadot/game-of-life
그래, 우리 시작하자.
시공:
이 프로젝트를 구축하기 위해서 Canvas API 라는 강력한 HTML 자원을 사용합니다. 일반 자바스크립트를 사용해서 2D 또는 3D 폼만 만들 수 있습니다.하지만 걱정하지 마십시오. 모든 것이 간단합니다. Canvas API는 기본 HTML 태그입니다.
첫 번째 단계는 HTML 파일에서 사용할 세 개의 파일을 만드는 것입니다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="style.css" />
<title>Jogin da Vida</title>
</head>
<body>
<canvas id="board"></canvas>
<script src="game.js"></script>
</body>
</html>
Google은 <canvas>
표시만 사용하고, JS 파일에서 idreference를 사용합니다.이제 간단한 CSS 파일을 만듭니다.
* {
padding: 0;
margin: 0;
outline: 0;
box-sizing: border-box;
}
body {
display: flex;
align-items: center;
justify-content: center;
height: 100vh;
background-color: #000000;
}
#board {
border: 5px solid #5c3ec9;
border-radius: 5px;
background-color: #f8f8f2;
box-shadow: 0px 0px 10px #5c3ec9;
}
완료, 이제 브라우저에서 열 수 있습니다...알았어, 알았어. 빈 널빤지일 뿐이야. 하지만 멋있을 거야.
현재 우리는 캔버스 속성을 설정해야 한다. 이 점을 할 수 있는 많은 방법이 있지만, 나는 자바스크립트 파일에서 모든 작업을 완성하는 것을 더 좋아한다.
논리:
코드를 제대로 익히자.먼저 JS 파일에서 ID
<canvas>
를 참조하여 사용할 컨텍스트(2D 또는 3D)를 정의해야 합니다.const canvas = document.querySelector("#board");
const ctx = canvas.getContext("2d");
//ctx define o contexto do nosso canvas, no caso será 2D
그런 다음 코드를 완료할 수 있도록 상수를 설정합니다.const GRID_WIDTH = 500;
const GRID_HEIGHT = 500;
const RES = 5;
const COL = GRID_WIDTH / RES;
const ROW = GRID_HEIGHT / RES;
이제 이러한 상수를 사용하여 캔버스의 높이와 너비를 정의할 수 있습니다.canvas.width = GRID_WIDTH;
canvas.height = GRID_HEIGHT;
자, 이제 우리가 뭔가를 볼 수 있을 거라고 확신합니다.그러나 확인을 위해 코드가 실행되기 전에 HTML 컨텐트가 로드될 때까지 코드 주위에 addEventListener()
를 배치합니다.document.addEventListener("DOMContentLoaded", () => {
const canvas = document.querySelector("#board");
const ctx = canvas.getContext("2d");
const GRID_WIDTH = 500;
const GRID_HEIGHT = 500;
const RES = 5;
const COL = GRID_WIDTH / RES;
const ROW = GRID_HEIGHT / RES;
canvas.width = GRID_WIDTH;
canvas.height = GRID_HEIGHT;
}
다음은 적목을 그리는 것이다.Excel 격자나 Google Sheets 파일의 셀과 같은 2D 배열의 간단한 사각형이 됩니다.행과 열을 수신하는 createGrid () 라는 함수를 만들 것입니다.그러면 함수는 열 수와 같은 길이의 새 빈 배열을 반환하고 배열의 각 위치에 대해 행 수는 같지만 임의로 0 또는 1을 채우는 새 배열을 만듭니다.
function createGrid(cols, rows) {
return new Array(cols)
.fill(null)
.map(() => new Array(rows)
.fill(null)
.map(() => Math.round(Math.random())));
}
let grid = createGrid(COL, ROW); //we will keep the array inside a variable "grid"
이제 1이 채워지고 0이 억제되는 셀 값에 따라 블록을 그릴 수 있습니다.이렇게 하려면 격자, 행, 열 및 블록 해상도/크기를 수신하는 drawGrid()라는 새 함수가 필요합니다.
function drawGrid(grid, cols, rows, reslution) {
ctx.clearRect(0, 0, cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
const cell = grid[i][j];
ctx.fillStyle = cell ? "#5c3ec9" : "#f8f8f2";
ctx.fillRect(i * reslution, j * reslution, reslution, reslution);
}
}
}
});
보시다시피, 칸을 먼저 그리려면Canvas API 본체 함수clearRect () 를 실행해야 합니다. 모든 것을 지우기 전에 회로판을 지워야 합니다.그것은 두 개의 매개 변수에서 세척을 시작하는 초기 좌표를 수신하고, 마지막 두 개의 매개 변수에서 우리는 회로판의 전체 사이즈를 설정해야 하며, 함수는 세척을 중지할 것이다.완료되면 두 번의 순환을 반복해서 전체 진열을 훑어보겠습니다.모든 순환에 대해 우리는 현재 단원을 단원이라고 불리는 상수 안에 유지하고 3원if를 사용하며 단원이 0 또는 1인지 검사할 것이다.
셀의 값이 1이면 fillStyle이라는 다른 Canvas API 네이티브 속성에 #5c3ec9 색상을 적용합니다. 그렇지 않으면 배경의 동일한 색상만 적용합니다. (JS에서 값 1은 진짜/존재, 값 0은 가짜/존재하지 않음을 기억하십시오.)
다음 행은 다른 네이티브 태그이지만 이번에는 함수 fillRect()를 사용하여 다음 4개 매개변수의 사각형을 그립니다.
drawGrid(grid, COL, ROW, RES);
게임 규칙 설명
우리가 계속하기 전에, 우리는 존 콘웨이가 제기한 규칙을 이해해야 한다. 이런 게임은 사실상'자기 게임'이다.
하나의 세포가 살아있는지(우리의 자색/1세포), 죽었는지(우리의 검은색/0세포)를 정의하는 네 가지 간단한 규칙이 있다.규칙은 다음과 같습니다.
1: 두 명의 살아있는 이웃보다 적은 모든 살아있는 세포는 인구가 부족하기 때문에 죽는다.
2: 두 개 또는 세 개의 살아있는 이웃이 있는 모든 살아있는 세포는 다음 세대까지 이어질 것이다.
3: 세 개 이상의 살아있는 이웃의 살아있는 세포는 모두 죽는다. 마치 인구 과잉 때문이다.
4: 세 명의 살아있는 이웃의 죽은 세포는 번식을 통해 살아있는 세포로 변한다.
이 규칙을 따라 이 점을 실현하기 위해 함수를 만듭시다.전체 배열을 옮겨다니며 규칙을 적용하고 drawGrid () 함수로 새 배열을 생성합니다.
이 순환이 반복될 때마다 우리는 새로운 진열이 이전 세대의 조건을 계승하는 차세대 세포라고 생각한다.
이 함수는nexGen () 이라고 불리며, 첫 번째 단계로 마지막 geeration을 상수로 유지할 것입니다.
function nextGen(grid) {
const nextGen = grid.map((arr) => [...arr]);
모르시면 [...arr]
발췌문에서 SPREAD 연산자를 사용합니다. 버전 6에서Javascript에 추가된 것으로 한 번에 더 많은 정보를 저장하기 위해 수조와 대상에 널리 사용됩니다.확장 연산자 대신 .push()
또는 .slice()
함수를 사용할 수도 있습니다. 문제없습니다.다음 단계는 순환을 시작합니다. 순환은 그룹을 통해 게임 규칙을 적용합니다.위에서 말한 바와 같이, 우리는
grid.length
모든 줄을 훑어보고, grid[col].length
모든 열을 훑어보아야 한다. (col 매개 변수는 내가 변수를 제어하기 위해 지정한 이름일 뿐이지만, 평소와 같이 자모 I와 j를 사용할 수 있다.)우리는 이 기회를 이용하여 상수 중의 초기 세포를 포획하고 살아있는 인접 세포의 수량을 계산하는 변수를 만들 것이다.
for (let col = 0; col < grid.length; col++) {
for (let row = 0; row < grid[col].length; row++) {
const currentCell = grid[col][row];
let sumNeighbors = 0;
다음 단계는 각 세포에 대해 8명의 이웃을 검사하고 그들이 살아 있는지 확인하는 것이다.코드를 처음 보면 이해하기 어려울 수도 있지만 화면 캡처 설명은 다음과 같습니다.네, 구글 폼을 사용했지만, 중요한 것은 다음 순환이 이 값들을 두루 훑어보는 것입니다.-1과 1 사이에 있는 활성 이웃의 수를 찾습니다.
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
if (i === 0 && j === 0) {
continue;
}
현재 단원의 위치이기 때문에 이웃의 수량에 추가하고 싶지 않습니다.다음 절에서는 우리 영역의 구석에 대해 토론할 것이다.이렇게 생각해 보면, 만약 하나의 칸이 화포의 왼쪽에 붙어 있다면, 우리는 그 앞줄의 이웃, 즉 가장 왼쪽의 이웃을 방문할 수 없을 것이다. 왜냐하면 그들은 존재하지 않기 때문이다.그래서 우리는 가치를 높여야 한다
if (i === 0 && j === 0)
변수의 좌표가 캔버스 범위 내에 있을 때만 이 변수에 추가할 수 있습니다.const x = col + i
const y = row + j;
if (x >= 0 && y >= 0 && x < COL && y < ROW) {
const currentNeighbor = grid[col + i][row + j];
sumNeighbors += currentNeighbor;
일단 조건이 충족되면sumNeighbors
변수는 그 이전의 값을 받고 활세포의 값을 더한다. 이곳의 사세포가 받은 값이 0이라는 것을 기억하면 총화에 영향을 주지 않는다.완료되면 간단한
sumNeighbors
John Conway 설명 규칙을 적용할 수 있습니다.if (currentCell === 0 && sumNeighbors === 3) {
nextGen[col][row] = 1;
} else if (currentCell === 1 && (sumNeighbors < 2 || sumNeighbors > 3)){
nextGen[col][row] = 0;
}
설명: 첫 번째 조건은 현재 칸이 비어 있는지 테스트합니다. 3개의 인접 칸이 있으면 다음 세대는 같은 위치에서 값 1이나 라이브를 받을 것입니다.두 번째 조건은 다른 규칙을 하나로 합쳐서 현재 단원이 활동 상태에 있는지 테스트한다.이웃이 두 명 미만이면 다음 세대는 0을, 이웃이 세 명 이상이면 다음 세대도 0을 받는다.
마지막으로 다음 세대
if/else
로 돌아가면 함수는 다음과 같습니다.
function nextGen(grid) {
const nextGen = grid.map((arr) => [...arr]); //make a copy of grid with spread operator
for (let col = 0; col < grid.length; col++) {
for (let row = 0; row < grid[col].length; row++) {
const currentCell = grid[col][row];
let sumNeighbors = 0; //to verify the total of neighbors
//Verifying the 8 neigbours of current cell
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
if (i === 0 && j === 0) {
continue; // because this is the current cell's position
}
const x = col + i;
const y = row + j;
if (x >= 0 && y >= 0 && x < COL && y < ROW) {
const currentNeighbor = grid[col + i][row + j];
sumNeighbors += currentNeighbor;
}
}
}
//Aplying rules
if (currentCell === 0 && sumNeighbors === 3) {
nextGen[col][row] = 1;
} else if (
currentCell === 1 &&
(sumNeighbors < 2 || sumNeighbors > 3)
) {
nextGen[col][row] = 0;
}
}
}
return nextGen;
}
이렇게 하면 프로젝트를 거의 완성할 수 있습니다. 다음 단계는 매우 간단합니다. 업데이트()라는 함수를 만들어서 모든 함수를 순서대로 실행할 것입니다. 리퀘스트 Animation Frame () 함수의 원생 자바스크립트를 사용하여 브라우저에서 순환 과정을 반복할 것입니다.requestAnimationFrame(update);
function update() {
grid = nextGen(grid);
drawGrid(grid, COL, ROW, RES);
requestAnimationFrame(update); //running again to repeat the loop
}
자, 이제 모든 것이 준비되었습니다. 당신의 서류는 이렇게 해야 합니다.document.addEventListener("DOMContentLoaded", () => {
const canvas = document.querySelector("#board");
const ctx = canvas.getContext("2d");
const GRID_WIDTH = 500;
const GRID_HEIGHT = 500;
const RES = 5;
const COL = GRID_WIDTH / RES;
const ROW = GRID_HEIGHT / RES;
canvas.width = GRID_WIDTH;
canvas.height = GRID_HEIGHT;
//Making a grid and filling with 0 or 1
function createGrid(cols, rows) {
return new Array(cols)
.fill(null)
.map(() =>
new Array(rows).fill(null).map(() => Math.round(Math.random()))
);
}
let grid = createGrid(COL, ROW);
requestAnimationFrame(update);
function update() {
grid = nextGen(grid);
drawGrid(grid, COL, ROW, RES);
requestAnimationFrame(update);
}
//Generate nex generation
function nextGen(grid) {
const nextGen = grid.map((arr) => [...arr]); //make a copy of grid with spread operator
for (let col = 0; col < grid.length; col++) {
for (let row = 0; row < grid[col].length; row++) {
const currentCell = grid[col][row];
let sumNeighbors = 0; //to verify the total of neighbors
//Verifying the 8 neigbours of current cell
for (let i = -1; i < 2; i++) {
for (let j = -1; j < 2; j++) {
if (i === 0 && j === 0) {
continue; // because this is the current cell's position
}
const x = col + i;
const y = row + j;
if (x >= 0 && y >= 0 && x < COL && y < ROW) {
const currentNeighbor = grid[col + i][row + j];
sumNeighbors += currentNeighbor;
}
}
}
//Aplying rules
if (currentCell === 0 && sumNeighbors === 3) {
nextGen[col][row] = 1;
} else if (
currentCell === 1 &&
(sumNeighbors < 2 || sumNeighbors > 3)
) {
nextGen[col][row] = 0;
}
}
}
return nextGen;
}
//Draw cells on canvas
function drawGrid(grid, cols, rows, reslution) {
ctx.clearRect(0, 0, cols, rows);
for (let i = 0; i < cols; i++) {
for (let j = 0; j < rows; j++) {
const cell = grid[i][j];
ctx.fillStyle = cell ? "#5c3ec9" : "#f8f8f2";
ctx.fillRect(i * reslution, j * reslution, reslution, reslution);
}
}
}
});
이제 HTML 파일만 실행하면 이 점을 볼 수 있습니다. (또는 화면을 녹화할 때 문제가 생겼기 때문에 더 좋습니다.)마지막 고려
이것은 보기에 그리 대단한 것은 아니지만 이 프로젝트는 매우 재미있다. HTML, CSS와 JS의 기본 지식을 훈련할 수 있고 주로 그룹의 조작을 훈련할 수 있다.만약 당신이 흥미가 있다면, 나는 본 게임과 같은 개념을 사용하는 대형 프로젝트를 가리키는 링크를 남길 것입니다.
Excel에서 라이프 스타일 게임 만들기 - https://github.com/asgunzi/JogodaVidaExcel
YouTube 채널 O Programador(PT/BR) - https://youtu.be/qTwqL69PK_Y
나는 네가 그것을 좋아하길 바란다. 네가 아주 멋진 것을 배워서 밥 로스가 한 말을 영원히 기억하길 바란다. "네가 공부하고 있다면, 너는 실패하지 않을 것이다."
아무리 늦어도 계속 걸어라.
안녕히 계세요.✌️
Reference
이 문제에 관하여(HTML, CSS, 자바스크립트 배우기 - 존 콘웨이의 인생 게임 재현), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/akadot_/learning-html-css-and-javascript-vanilla-reproducing-the-john-conways-game-of-life-9pn텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)