Skip to content

Commit f8b6208

Browse files
authored
Add files via upload
0 parents  commit f8b6208

File tree

6 files changed

+217
-0
lines changed

6 files changed

+217
-0
lines changed

food.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { onSnake, expandSnake } from './snake.js'
2+
import { randomGridPosition } from './grid.js'
3+
4+
let food = getRandomFoodPosition()
5+
const EXPANSION_RATE = 5
6+
7+
export function update() {
8+
if (onSnake(food)) {
9+
expandSnake(EXPANSION_RATE)
10+
food = getRandomFoodPosition()
11+
}
12+
}
13+
14+
export function draw(gameBoard) {
15+
const foodElement = document.createElement('div')
16+
foodElement.style.gridRowStart = food.y
17+
foodElement.style.gridColumnStart = food.x
18+
foodElement.classList.add('food')
19+
gameBoard.appendChild(foodElement)
20+
}
21+
22+
function getRandomFoodPosition() {
23+
let newFoodPosition
24+
while (newFoodPosition == null || onSnake(newFoodPosition)) {
25+
newFoodPosition = randomGridPosition()
26+
}
27+
return newFoodPosition
28+
}

game.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { update as updateSnake, draw as drawSnake, SNAKE_SPEED, getSnakeHead, snakeIntersection } from './snake.js'
2+
import { update as updateFood, draw as drawFood } from './food.js'
3+
import { outsideGrid } from './grid.js'
4+
5+
let lastRenderTime = 0
6+
let gameOver = false
7+
const gameBoard = document.getElementById('game-board')
8+
9+
function main(currentTime) {
10+
if (gameOver) {
11+
if (confirm('You lost. Press ok to restart.')) {
12+
window.location = '/'
13+
}
14+
return
15+
}
16+
17+
18+
window.requestAnimationFrame(main)
19+
const secondsSinceLastRender = (currentTime - lastRenderTime) / 1000
20+
if (secondsSinceLastRender < 1 / SNAKE_SPEED) return
21+
22+
23+
lastRenderTime = currentTime
24+
25+
update()
26+
draw()
27+
}
28+
29+
window.requestAnimationFrame(main)
30+
31+
function update() {
32+
updateSnake()
33+
updateFood()
34+
checkDeath()
35+
}
36+
37+
function draw() {
38+
gameBoard.innerHTML = ''
39+
drawSnake(gameBoard)
40+
drawFood(gameBoard)
41+
}
42+
43+
function checkDeath() {
44+
gameOver = outsideGrid(getSnakeHead()) || snakeIntersection()
45+
}

grid.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
const GRID_SIZE = 21
2+
3+
export function randomGridPosition() {
4+
return {
5+
x: Math.floor(Math.random() * GRID_SIZE) + 1,
6+
y: Math.floor(Math.random() * GRID_SIZE) + 1
7+
}
8+
}
9+
10+
export function outsideGrid(position) {
11+
return (
12+
position.x < 1 || position.x > GRID_SIZE ||
13+
position.y < 1 || position.y > GRID_SIZE
14+
)
15+
}

index.html

+43
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
7+
<title>Snake</title>
8+
<style>
9+
body {
10+
height: 100vh;
11+
width: 100vw;
12+
display: flex;
13+
justify-content: center;
14+
align-items: center;
15+
margin: 0;
16+
background-color: black;
17+
}
18+
19+
#game-board {
20+
background-color: #CCC;
21+
width: 100vmin;
22+
height: 100vmin;
23+
display: grid;
24+
grid-template-rows: repeat(21, 1fr);
25+
grid-template-columns: repeat(21, 1fr);
26+
}
27+
28+
.snake {
29+
background-color: hsl(200, 100%, 50%);
30+
border: .25vmin solid black;
31+
}
32+
33+
.food {
34+
background-color: hsl(50, 100%, 50%);
35+
border: .25vmin solid black;
36+
}
37+
</style>
38+
<script src="game.js" defer type="module"></script>
39+
</head>
40+
<body>
41+
<div id="game-board"></div>
42+
</body>
43+
</html>

input.js

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
let inputDirection = { x: 0, y: 0 }
2+
let lastInputDirection = { x: 0, y: 0 }
3+
4+
window.addEventListener('keydown', e => {
5+
switch (e.key) {
6+
case 'ArrowUp':
7+
if (lastInputDirection.y !== 0) break
8+
inputDirection = { x: 0, y: -1 }
9+
break
10+
case 'ArrowDown':
11+
if (lastInputDirection.y !== 0) break
12+
inputDirection = { x: 0, y: 1 }
13+
break
14+
case 'ArrowLeft':
15+
if (lastInputDirection.x !== 0) break
16+
inputDirection = { x: -1, y: 0 }
17+
break
18+
case 'ArrowRight':
19+
if (lastInputDirection.x !== 0) break
20+
inputDirection = { x: 1, y: 0 }
21+
break
22+
}
23+
})
24+
25+
export function getInputDirection() {
26+
lastInputDirection = inputDirection
27+
return inputDirection
28+
}

snake.js

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import { getInputDirection } from "./input.js"
2+
3+
export const SNAKE_SPEED = 5
4+
const snakeBody = [{ x: 11, y: 11 }]
5+
let newSegments = 0
6+
7+
export function update() {
8+
addSegments()
9+
10+
const inputDirection = getInputDirection()
11+
for (let i = snakeBody.length - 2; i >= 0; i--) {
12+
snakeBody[i + 1] = { ...snakeBody[i] }
13+
}
14+
15+
snakeBody[0].x += inputDirection.x
16+
snakeBody[0].y += inputDirection.y
17+
}
18+
19+
export function draw(gameBoard) {
20+
snakeBody.forEach(segment => {
21+
const snakeElement = document.createElement('div')
22+
snakeElement.style.gridRowStart = segment.y
23+
snakeElement.style.gridColumnStart = segment.x
24+
snakeElement.classList.add('snake')
25+
gameBoard.appendChild(snakeElement)
26+
})
27+
}
28+
29+
export function expandSnake(amount) {
30+
newSegments += amount
31+
}
32+
33+
export function onSnake(position, { ignoreHead = false } = {}) {
34+
return snakeBody.some((segment, index) => {
35+
if (ignoreHead && index === 0) return false
36+
return equalPositions(segment, position)
37+
})
38+
}
39+
40+
export function getSnakeHead() {
41+
return snakeBody[0]
42+
}
43+
44+
export function snakeIntersection() {
45+
return onSnake(snakeBody[0], { ignoreHead: true })
46+
}
47+
48+
function equalPositions(pos1, pos2) {
49+
return pos1.x === pos2.x && pos1.y === pos2.y
50+
}
51+
52+
function addSegments() {
53+
for (let i = 0; i < newSegments; i++) {
54+
snakeBody.push({ ...snakeBody[snakeBody.length - 1] })
55+
}
56+
57+
newSegments = 0
58+
}

0 commit comments

Comments
 (0)