This repository has been archived by the owner on Oct 5, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
game.ts
126 lines (104 loc) · 3.57 KB
/
game.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
import { GameState, KeysState, BLOCK_SIZE, Move, Cor , STATE_INITIAL, Bait, MAX_BITE_SIZE} from './models';
const SIZE = 32;
export function tick(deltaTime: number, gameState: GameState, keysState: KeysState): GameState {
const head = gameState.tail[0];
let move = getMove(keysState, gameState.move) || gameState.move;
let nextTail = gameState.tail;
const nextHead = getCellNextCord(move, head, deltaTime, (0.6 * Math.log(gameState.tail.length + 148)) - 2);
// border
// if(nextHead.x >= BLOCK_SIZE * (SIZE - 1) || nextHead.y < 0 || nextHead.y >= BLOCK_SIZE * (SIZE - 1)){
// return STATE_INITIAL;
// }
if(move === Move.Left && nextHead.x <= 0) {
nextHead.x = BLOCK_SIZE * (SIZE - 1);
}
if(move === Move.Up && nextHead.y < 0) {
nextHead.y = BLOCK_SIZE * (SIZE - 1);
}
if(move === Move.Right && nextHead.x >= BLOCK_SIZE * (SIZE - 1)) {
nextHead.x = 0;
}
if(move === Move.Down && nextHead.y >= BLOCK_SIZE * (SIZE - 1)) {
nextHead.y = 0;
}
// eating
if(gameState.bait && collideWithBait(nextHead, gameState.bait)) {
gameState.mealSize = gameState.mealSize + gameState.bait.size;
gameState.bait = getRandomBait();
} else {
if(gameState.mealSize > 0) {
gameState.mealSize = gameState.mealSize - 1;
} else {
nextTail = nextTail.slice(0, gameState.tail.length -1);
}
}
// self
for(let i = 10; i < nextTail.length; i++) {
if(collide(nextHead, nextTail[i])){
return STATE_INITIAL
}
}
const nextGameState: GameState = {
...gameState,
tail: [
nextHead,
...nextTail,
],
move,
};
return nextGameState;
}
// TODO: move to utils
const getCellNextCord = (move: Move, cell: Cor, deltaTime: number, blocksPerSeconds = 1): Cor => {
const speed = blocksPerSeconds * BLOCK_SIZE * deltaTime;
const step = BLOCK_SIZE * speed;
switch(move){
case Move.Up:
return {
x: cell.x,
y: cell.y - step,
};
case Move.Right:
return {
x: cell.x + step,
y: cell.y,
};
case Move.Down:
return {
x: cell.x,
y: cell.y + step,
};
case Move.Left:
return {
x: cell.x - step,
y: cell.y,
};
default:
throw new Error('bad Move');
}
}
const getMove = (keysState: KeysState, currentMove: Move): Move => {
if(keysState.ArrowUp && currentMove !== Move.Up && currentMove !== Move.Down) return Move.Up;
if(keysState.ArrowRight && currentMove !== Move.Right && currentMove !== Move.Left) return Move.Right;
if(keysState.ArrowDown && currentMove !== Move.Down && currentMove !== Move.Up) return Move.Down;
if(keysState.ArrowLeft && currentMove !== Move.Left && currentMove !== Move.Right) return Move.Left;
return currentMove;
}
const cellIsOutOfTheArea = (cell: Cor) => {
return cell != null && (cell.x < 0 || cell.y < 0);
}
const getDistance = (a: Cor, b: Cor): number => Math.sqrt((a.x - b.x)**2 + (a.y - b.y)**2);
const collide = (cellA: Cor, cellB: Cor): boolean => {
return getDistance(cellA, cellB) < BLOCK_SIZE;
}
const collideWithBait = (cellA: Cor, bait: Bait): boolean => {
return getDistance(cellA, {x: bait.x, y: bait.y}) <= (bait.size / MAX_BITE_SIZE) * BLOCK_SIZE + 8;
}
const getRandomBait = (): Bait => {
const generatePoint = () => Math.floor(((Math.random() * (SIZE - 1) * BLOCK_SIZE)/ BLOCK_SIZE)) * BLOCK_SIZE;
return {
x: generatePoint(),
y: generatePoint(),
size: Math.floor(Math.random() * MAX_BITE_SIZE) + 2,
}
}