Files
DoubleSnake/backend/src/SocketIO/GameManager/Game/Classes/Snake/Snake.js
T
2025-04-11 11:04:31 +02:00

157 lines
4.8 KiB
JavaScript

const SocketUser = require("../../../../Classes/SocketUser");
const Playground = require("../Playground/Playground");
class Snake{
/** @param {SocketUser} player @param {Playground} playground */
constructor(player, playground, color, startTiles, startMovement) {
this.player = player;
this.playground = playground;
this.color = color;
/** @type {Array<Object>} */
this.tiles = [];
this.nextMovement = startMovement;
this.currentMovement = null;
this.directionDegree = new Map([
["right", 0],
["down", 90],
["left", 180],
["up", 270]
]);
this.player.socket.on("movement", (data) => { this.updateNextMovement(data) })
this.setup(startTiles);
}
setup(startTiles){
this.player.socket.emit("color", this.color);
const headX = startTiles.x;
const headY = startTiles.y;
let dx = 0;
let dy = 0;
switch (this.nextMovement) {
case "up": dy = 1; break;
case "down": dy = -1; break;
case "left": dx = 1; break;
case "right": dx = -1; break;
}
for (let i = 0; i < 3; i++) {
let type = null;
switch(i){
case 0:
type = "Head";
break;
case 2:
type = "End";
break;
default:
type = "Straight";
break;
}
this.tiles.push({
class: "Snake",
type: type,
color: this.color,
deg: this.directionDegree.get(this.nextMovement),
x: headX + i * dx,
y: headY + i * dy
});
}
this.drawTiles();
}
movementToAxes(movement){
let num = null;
let axes = null;
switch (movement) {
case "up": num = -1; axes = "y"; break;
case "down": num = 1; axes = "y"; break;
case "left": num = -1; axes = "x"; break;
case "right": num = 1; axes = "x"; break;
}
return {num, axes};
}
move(){
// Aktuelles Movement Klonen nicht das es zwischendurch geändert wird
if(
this.movementToAxes(this.nextMovement).axes
!==
this.movementToAxes(this.currentMovement).axes
){
this.currentMovement = this.nextMovement;
}
// Eine Kopie der aktuellen Tiles erstellen
const tileClone = this.tiles.map(tile => ({ ...tile }));
this.tiles = []
tileClone.forEach((tile, i) => {
const currentTile = { ...tile };
if(i === 0){
const axes = this.movementToAxes(this.currentMovement);
if(axes.axes === "x") currentTile.x += axes.num;
if(axes.axes === "y") currentTile.y += axes.num;
currentTile.deg = this.directionDegree.get(this.currentMovement);
return this.tiles.push(currentTile);
}
let tileBefore = { ...tileClone[i - 1] };
currentTile.deg = tileBefore.deg;
currentTile.x = tileBefore.x;
currentTile.y = tileBefore.y;
this.tiles.push(currentTile);
})
// Ändere nun geraden zu Kurven
this.tiles.forEach((tile, i) => {
if(i === 0 || i === (this.tiles.length - 1)) return;
const before = this.tiles[i - 1];
const after = this.tiles[i + 1];
const dxBefore = tile.x - before.x;
const dyBefore = tile.y - before.y;
const dxAfter = tile.x - after.x;
const dyAfter = tile.y - after.y;
if (dxBefore !== dxAfter && dyBefore !== dyAfter) {
tile.type = "Turn";
if (dxBefore === -1 && dyAfter === -1 || dxAfter === -1 && dyBefore === -1) {
tile.deg = 0;
} else if (dxBefore === 1 && dyAfter === -1 || dxAfter === 1 && dyBefore === -1) {
tile.deg = 90;
} else if (dxBefore === 1 && dyAfter === 1 || dxAfter === 1 && dyBefore === 1) {
tile.deg = 180;
} else if (dxBefore === -1 && dyAfter === 1 || dxAfter === -1 && dyBefore === 1) {
tile.deg = 270;
}
} else {
tile.type = "Straight";
}
})
this.drawTiles();
}
drawTiles(){
this.tiles.forEach(tile => {
this.playground.setTile(tile.x, tile.y, tile);
})
}
updateNextMovement(data){
this.nextMovement = data;
}
}
module.exports = Snake;