-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
252 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Conway's game of life</title> | ||
</head> | ||
<style> | ||
html, | ||
body { | ||
display: flex; | ||
margin: 0; | ||
padding: 0; | ||
border: none; | ||
max-height: 100vh; | ||
height: 100%; | ||
} | ||
</style> | ||
<body> | ||
<canvas id="canvas"></canvas> | ||
|
||
<script> | ||
class Cell { | ||
#isAlive = false; | ||
#neighbors = 0; | ||
|
||
constructor(ctx, x, y, size) { | ||
/** @type {CanvasRenderingContext2D} */ | ||
this.ctx = ctx; | ||
this.x = x; | ||
this.y = y; | ||
this.size = size; | ||
} | ||
|
||
draw() { | ||
if (this.#isAlive) { | ||
this.ctx.fillStyle = `rgba( | ||
${Math.max(50, this.x * 4)}, | ||
${Math.max(100, this.y * 4)}, | ||
${Math.max(200, (this.x + this.y) * 2)}, | ||
1)`; | ||
this.ctx.fillRect( | ||
this.x * this.size, | ||
this.y * this.size, | ||
this.size, | ||
this.size | ||
); | ||
} | ||
} | ||
|
||
nextGeneration() { | ||
if (!this.#isAlive && this.#neighbors === 3) { | ||
this.#isAlive = true; | ||
} else { | ||
this.#isAlive = | ||
this.#isAlive && (this.#neighbors === 2 || this.#neighbors === 3); | ||
} | ||
|
||
this.draw(); | ||
} | ||
|
||
get isAlive() { | ||
return this.#isAlive; | ||
} | ||
|
||
set isAlive(isAlive) { | ||
this.#isAlive = isAlive; | ||
} | ||
|
||
set neighbors(count) { | ||
this.#neighbors = count; | ||
} | ||
|
||
get neighbors() { | ||
return this.#neighbors; | ||
} | ||
} | ||
|
||
class Game { | ||
#cellSize = 10; | ||
/** @type {Cell[][]} */ #cells = []; | ||
|
||
constructor(/** @type {HTMLCanvasElement} */ canvas) { | ||
this.canvas = canvas; | ||
this.ctx = this.canvas.getContext("2d"); | ||
this.canvas.width = document.documentElement.offsetWidth; | ||
this.canvas.height = document.documentElement.offsetHeight; | ||
} | ||
|
||
get size() { | ||
return { | ||
rows: Math.ceil(this.canvas.width / this.#cellSize), | ||
cols: Math.ceil(this.canvas.height / this.#cellSize), | ||
cellSize: this.#cellSize, | ||
}; | ||
} | ||
|
||
drawBoard() { | ||
this.ctx.fillStyle = "rgba(0,0,0,1)"; | ||
this.ctx.fillRect(0, 0, this.canvas.width, this.canvas.height); | ||
} | ||
|
||
generateCells() { | ||
for (let i = 0; i < this.size.rows; i++) { | ||
this.#cells[i] = []; | ||
|
||
for (let j = 0; j < this.size.cols; j++) { | ||
this.#cells[i][j] = new Cell(this.ctx, i, j, this.size.cellSize); | ||
this.#cells[i][j].isAlive = Math.random() > 0.9; | ||
this.#cells[i][j].draw(); | ||
} | ||
} | ||
} | ||
|
||
updateNeighborCells(x, y) { | ||
let count = 0; | ||
|
||
const neighborCoordinates = [ | ||
[x, y + 1], | ||
[x, y - 1], | ||
[x - 1, y - 1], | ||
[x + 1, y - 1], | ||
[x - 1, y], | ||
[x + 1, y], | ||
[x - 1, y + 1], | ||
[x + 1, y + 1], | ||
]; | ||
|
||
for (let [x, y] of neighborCoordinates) { | ||
const xOutOfBound = x < 0 || x >= this.size.rows; | ||
const yOutOfBound = y < 0 || y >= this.size.cols; | ||
|
||
if (x < 0) { | ||
x = this.size.rows - 1; | ||
} | ||
|
||
if (y < 0) { | ||
y = this.size.cols - 1; | ||
} | ||
|
||
if (x >= this.size.rows) { | ||
x = 0; | ||
} | ||
|
||
if (y >= this.size.cols) { | ||
y = 0; | ||
} | ||
|
||
if (this.#cells[x][y].isAlive) { | ||
count++; | ||
} | ||
} | ||
|
||
this.#cells[x][y].neighbors = count; | ||
} | ||
|
||
updateCells() { | ||
for (let i = 0; i < this.size.rows; i++) { | ||
for (let j = 0; j < this.size.cols; j++) { | ||
this.updateNeighborCells(i, j); | ||
} | ||
} | ||
|
||
for (let i = 0; i < this.size.rows; i++) { | ||
for (let j = 0; j < this.size.cols; j++) { | ||
this.#cells[i][j].nextGeneration(); | ||
} | ||
} | ||
} | ||
|
||
run() { | ||
this.drawBoard(); | ||
this.updateCells(); | ||
|
||
setTimeout(() => { | ||
requestAnimationFrame(() => { | ||
this.run(); | ||
}); | ||
}, 1000 / 60); | ||
} | ||
|
||
init() { | ||
this.drawBoard(); | ||
this.generateCells(); | ||
|
||
this.run(); | ||
} | ||
} | ||
const game = new Game(document.getElementById("canvas")); | ||
game.init(); | ||
</script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,64 +1,64 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Main page of pet projects</title> | ||
<link rel="icon" href="./favicon.ico" type="image/x-icon" /> | ||
<style> | ||
.container { | ||
display: flex; | ||
justify-content: flex-start; | ||
flex-wrap: wrap; | ||
padding: 20px 40px; | ||
} | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Main page of pet projects</title> | ||
<link rel="icon" href="./favicon.ico" type="image/x-icon" /> | ||
<style> | ||
.container { | ||
display: flex; | ||
justify-content: flex-start; | ||
flex-wrap: wrap; | ||
padding: 20px 40px; | ||
} | ||
|
||
.container a { | ||
text-decoration: none; | ||
padding: 10px 15px; | ||
font-family: Arial, Helvetica, sans-serif; | ||
font-size: 16px; | ||
margin: 10px; | ||
border: 0px solid; | ||
border-radius: 10px; | ||
display: block; | ||
color: #fff; | ||
background-color: #3b9aff; | ||
transition: all 0.2s ease-in-out; | ||
} | ||
.container a { | ||
text-decoration: none; | ||
padding: 10px 15px; | ||
font-family: Arial, Helvetica, sans-serif; | ||
font-size: 16px; | ||
margin: 10px; | ||
border: 0px solid; | ||
border-radius: 10px; | ||
display: block; | ||
color: #fff; | ||
background-color: #3b9aff; | ||
transition: all 0.2s ease-in-out; | ||
} | ||
|
||
.container a:hover { | ||
background-color: #6eb3f8; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<a href="./full-screen-video-background/index.html" | ||
>Full screen video background</a | ||
> | ||
<a href="./Multiplejs Inspiration/index.html" target="_blank" | ||
>Multiplejs inspiration</a | ||
> | ||
<a href="./One Page Wedding/index.html" target="_blank" | ||
>One Page Wedding</a | ||
> | ||
<a href="./typeEffect/index.html" target="_blank"> | ||
Simple Typing Effect</a | ||
> | ||
<a href="./Slide Transition/index.html" target="_blank"> | ||
Slice Transition</a | ||
> | ||
<a href="./Blurry Overlay/index.html" target="_blank"> Blurry Overlay</a> | ||
<a href="./MineweeperJS/index.html" target="_blank"> | ||
Mineweeper With JS</a | ||
> | ||
<a href="./Breath and relax web app/index.html" target="_blank" | ||
>Breath and relax</a | ||
> | ||
<a href="./Pyramid/index.html" target="_blank">Pyramid</a> | ||
<a href="./2048/index.html" target="_blank">2048 </a> | ||
<a href="./elastic/index.html" target="_blank">Elastic</a> | ||
</div> | ||
</body> | ||
.container a:hover { | ||
background-color: #6eb3f8; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<div class="container"> | ||
<a href="./full-screen-video-background/index.html" | ||
>Full screen video background</a | ||
> | ||
<a href="./Multiplejs Inspiration/index.html" target="_blank" | ||
>Multiplejs inspiration</a | ||
> | ||
<a href="./One Page Wedding/index.html" target="_blank" | ||
>One Page Wedding</a | ||
> | ||
<a href="./typeEffect/index.html" target="_blank"> | ||
Simple Typing Effect</a | ||
> | ||
<a href="./Slide Transition/index.html" target="_blank"> | ||
Slice Transition</a | ||
> | ||
<a href="./Blurry Overlay/index.html" target="_blank"> Blurry Overlay</a> | ||
<a href="./MineweeperJS/index.html" target="_blank"> | ||
Mineweeper With JS</a | ||
> | ||
<a href="./Breath and relax web app/index.html" target="_blank" | ||
>Breath and relax</a | ||
> | ||
<a href="./Pyramid/index.html" target="_blank">Pyramid</a> | ||
<a href="./2048/index.html" target="_blank">2048 </a> | ||
<a href="./game-of-life/index.html" target="_blank">Game of life: base</a> | ||
</div> | ||
</body> | ||
</html> |