Snake-app-snake.js code
import { getSnakeDirection } from './snake-app-input.js'
export let SNAKE_SPEED = 4 /* how many moves per second*/
snakeSpeedControl()
const field = document.querySelector('#snake-field')
export const fieldSize =
getComputedStyle(field).getPropertyValue('--field-size')
export const snakeBody = [
{
x: Math.round(fieldSize / 2),
y: Math.round(fieldSize / 2),
},
]
let newSnakeParts = 0
export function updateSnake() {
addSnakeParts()
const snakeDirection = getSnakeDirection()
const headDirection = snakeDirection.head
let newX = snakeBody[0].x + snakeDirection.x
let newY = snakeBody[0].y + snakeDirection.y
if (newX === 0) newX = +fieldSize
if (newX === +fieldSize + 1) newX = 1
if (newY === 0) newY = +fieldSize
if (newY === +fieldSize + 1) newY = 1
const newSnakeHead = { x: newX, y: newY, head: headDirection }
snakeBody.unshift(newSnakeHead)
snakeBody.pop()
getSnakeShape(snakeBody)
}
export function drawSnake(snakeField, { brownColor = false } = {}) {
snakeBody.forEach(segment => appendSnakePart(segment, snakeField, brownColor))
}
export function snakeGrowth(amount) {
newSnakeParts += amount
}
export function eatedOrOnSnake(mouse, { ignoreHead = false } = {}) {
return snakeBody.some((snakePart, index) => {
if (ignoreHead && index === 0) return false
return comparePositions(snakePart, mouse)
})
}
export function snakeIntersection() {
return eatedOrOnSnake(snakeBody[0], { ignoreHead: true })
}
export function brownSnake(snakeField) {
drawSnake(snakeField, { brownColor: true })
}
// --- Additional functions ---
function appendSnakePart(segment, snakeField, brownColor) {
const snakePart = document.createElement('div')
snakePart.style.gridColumnStart = segment.x
snakePart.style.gridRowStart = segment.y
const shape = segment.shape
snakePart.classList.add(shape)
if (brownColor) snakePart.classList.add('brown-snake')
snakeField.append(snakePart)
}
function getSnakeShape(snakeBody) {
snakeBody[0].shape = snakeBody[0].head
const snakeLength = snakeBody.length
if (snakeLength === 1) return
// --- Tail shape: ---
if (snakeBody[snakeLength - 1].x > snakeBody[snakeLength - 2].x)
snakeBody[snakeLength - 1].shape = 'tail-right'
if (snakeBody[snakeLength - 1].x < snakeBody[snakeLength - 2].x)
snakeBody[snakeLength - 1].shape = 'tail-left'
if (snakeBody[snakeLength - 1].y > snakeBody[snakeLength - 2].y)
snakeBody[snakeLength - 1].shape = 'tail-down'
if (snakeBody[snakeLength - 1].y < snakeBody[snakeLength - 2].y)
snakeBody[snakeLength - 1].shape = 'tail-up'
if (snakeLength === 2) return
// --- Body Shape: ---
for (let segment = 1; segment < snakeLength - 1; segment++) {
// if x(i-1) = x(i) = x(i+1) или y(i-1) = yi = y(i+1), then the second element – N;
if (
snakeBody[segment - 1].x === snakeBody[segment].x &&
snakeBody[segment].x === snakeBody[segment + 1].x
) {
snakeBody[segment].shape = 'snake-body-N'
return
}
if (
snakeBody[segment - 1].y === snakeBody[segment].y &&
snakeBody[segment].y === snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-N'
return
}
// if x(i-1) = xi и y(i-1) > yi и xi < x(i+1) и yi = y(i+1), then the second element – UL;
if (
snakeBody[segment - 1].x === snakeBody[segment].x &&
snakeBody[segment - 1].y > snakeBody[segment].y &&
snakeBody[segment].x < snakeBody[segment + 1].x &&
snakeBody[segment].y === snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-UL'
return
}
// if x(i-1) > xi и y(i-1) = yi и xi = x(i+1) и yi < y(i+1), then the second element – UL;
if (
snakeBody[segment - 1].x > snakeBody[segment].x &&
snakeBody[segment - 1].y === snakeBody[segment].y &&
snakeBody[segment].x === snakeBody[segment + 1].x &&
snakeBody[segment].y < snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-UL'
return
}
// if x(i-1) < xi и y(i-1) = yi и xi = x(i+1) и yi < y(i+1), then the second element – UR;
if (
snakeBody[segment - 1].x < snakeBody[segment].x &&
snakeBody[segment - 1].y === snakeBody[segment].y &&
snakeBody[segment].x === snakeBody[segment + 1].x &&
snakeBody[segment].y < snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-UR'
return
}
// if x(i-1) = xi и y(i-1) > yi и xi > x(i+1) и yi = y(i+2), then the second element – UR;
if (
snakeBody[segment - 1].x === snakeBody[segment].x &&
snakeBody[segment - 1].y > snakeBody[segment].y &&
snakeBody[segment].x > snakeBody[segment + 1].x &&
snakeBody[segment].y === snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-UR'
return
}
// if x(i-1) < xi и y(i-1) = yi и xi = x(i+1) и yi > y(i+1), then the second element – BR;
if (
snakeBody[segment - 1].x < snakeBody[segment].x &&
snakeBody[segment - 1].y === snakeBody[segment].y &&
snakeBody[segment].x === snakeBody[segment + 1].x &&
snakeBody[segment].y > snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-BR'
return
}
// if x(i-1) = xi и y(i-1) < yi и xi > x(i+1) и yi = y(i+1), then the second element – BR;
if (
snakeBody[segment - 1].x === snakeBody[segment].x &&
snakeBody[segment - 1].y < snakeBody[segment].y &&
snakeBody[segment].x > snakeBody[segment + 1].x &&
snakeBody[segment].y === snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-BR'
return
}
// if x(i-1) = xi и y(i-1) < yi и xi < x(i+1) и yi = y(i+1), then the second element – BL;
if (
snakeBody[segment - 1].x === snakeBody[segment].x &&
snakeBody[segment - 1].y < snakeBody[segment].y &&
snakeBody[segment].x < snakeBody[segment + 1].x &&
snakeBody[segment].y === snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-BL'
return
}
// if x(i-1) > xi и y(i-1) = yi и xi = x(i+1) и yi > y(i+1), then the second element – BL;
if (
snakeBody[segment - 1].x > snakeBody[segment].x &&
snakeBody[segment - 1].y === snakeBody[segment].y &&
snakeBody[segment].x === snakeBody[segment + 1].x &&
snakeBody[segment].y > snakeBody[segment + 1].y
) {
snakeBody[segment].shape = 'snake-body-BL'
return
}
snakeBody[segment].shape = 'snake-body-N'
}
console.table(snakeBody)
}
function comparePositions(snakePart, mouse) {
return snakePart.x === mouse.x && snakePart.y === mouse.y
}
function addSnakeParts() {
for (let i = 0; i < newSnakeParts; i++) {
snakeBody.push({ ...snakeBody[snakeBody.length - 1] })
}
newSnakeParts = 0
}
function snakeSpeedControl() {
document.addEventListener('keydown', e => {
switch (e.key) {
case '+':
SNAKE_SPEED += 0.1
console.log(SNAKE_SPEED)
break
}
switch (e.key) {
case '-':
SNAKE_SPEED -= 0.1
console.log(SNAKE_SPEED)
break
}
})
}