(Heads up I literally started programming like 1 week ago)
So I'm trying to use node.js and socket.io to make a simple multiplayer snake game. I also wanted to use my custom domain (https://trononline.tech (it has a snake game, but not the one I want)), but I cant do that without this console error: https://ibb.co/RhpHK5H
It's really annoying and no matter what I try it doesn't seem to change.
My code:
//server.js
const io = require('socket.io')();
const { initGame, gameLoop, getUpdatedVelocity} = require('./game');
const { FRAME_RATE } = require('./constants');
const{ makeid } = require('./utils')
const state = {};
const clientRooms = {};
io.on('connection', client => {
const state = initGame;
client.on('keydown', handleKeydown);
client.on('newGame', handleNewGame);
client.on('joinGame', handleJoinGame);
function handleJoinGame(gameCode) {
const room = io.sockets.adapter.rooms[gameCode];
let allUsers;
if (room) {
allUsers = room.sockets;
}
let numClients = 0;
if (allUsers) {
numClients = Object.keys(allUsers).length;
}
if (numClients === 0) {
client.emit('unknownGame');
return;
} else if (numClients > 1) {
client.emit('tooManyPlayers');
return;
}
clientRooms[client.id] = gameCode;
client.join(gameCode);
client.number = 2;
client.emit('init', 2);
startGameInterval(gameCode);
}
function handleNewGame() {
let roomName = makeid(5);
clientRooms[client.id] = roomName;
client.emit('gameCode', roomName);
state[roomName] = initGame();
client.join(roomName)
client.number = 1;
client.emit('init', 1);
}
function handleKeydown(keyCode) {
const roomName = clientRooms[client.id];
if (!roomName) {
return;
}
try {
keyCode = parseInt(keyCode);
} catch(e) {
console.error(e);
return;
}
const vel = getUpdatedVelocity(keyCode);
if (vel) {
state[roomName].players[client.number - 1].vel = vel;
}
}
startGameInterval(client, state);
});
function startGameInterval (roomName) {
const intervalId = setInterval(() => {
const winner = gameLoop(state[roomName]);
if(!winner) {
emitGameState('roomName', state[roomName]);
} else {
emitGameOver(roomName, winner);
state[roomName] = null;
clearInterval(intervalId);
}
}, 1000 / FRAME_RATE);
}
function emitGameState(roomName, state) {
io.sockets.in(roomName)
.emit('gameState', JSON.stringify(state));
}
function emitGameOver(roomName, winner) {
io.sockets.in(roomName)
.emit('gameOver', JSON.stringify({ winner }))
}
//index.js
const FOOD_COLOUR = '#FF0000';
const socket = io("https://trononline.tech/snake");
socket.on('init', handleInit);
socket.on('gameState', handleGameState);
socket.on('gameOver', handleGameOver);
socket.on ('gameCode', handleGameCode);
socket.on('unknownGame', handleUnknownGame);
socket.on('tooManyPlayers', handleTooManyPlayers);
const gameScreen = document.getElementById('gameScreen');
const initialScreen = document.getElementById('initialScreen');
const newGameButton = document.getElementById('newGameButton');
const joinGameButton = document.getElementById('joinGameButton');
const gameCodeInput = document.getElementById('gameCodeInput');
const gameCodeDisplay = document.getElementById('gameCodeDisplay')
newGameButton.addEventListener('click', newGame);
joinGameButton.addEventListener('click', joinGame);
function newGame() {
socket.emit('newGame');
init();
}
function joinGame() {
const code = gameCodeInput.value;
socket.emit('joinGame', code);
init();
}
let canvas, ctx;
let playerNumber
let gameActive = false;
function init() {
initialScreen.style.display = "none";
gameScreen.style.display = "block";
canvas = document.getElementById('canvas');
ctx = canvas.getContext('2d')
canvas.width = canvas.height = 600;
ctx.fillStyle = BG_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
document.addEventListener('keydown', keydown);
gameActive = true;
}
function keydown (e) {
socket.emit('keydown', e.keyCode);
}
function paintGame(state) {
ctx.fillStyle = BG_COLOUR;
ctx.fillRect(0, 0, canvas.width, canvas.height);
const food = state.food;
const gridSize = state.gridSize;
const size = canvas.width / gridSize;
ctx.fillStyle = FOOD_COLOUR;
ctx.fillRect(food.x * size, food.y * size, size, size);
paintPlayer(state.players[0], size, SNAKE1_COLOUR);
paintPlayer(state.players[1], size, SNAKE2_COLOUR);
}
function paintPlayer(playerState, size, colour) {
const snake = playerState.snake;
ctx.fillStyle = colour;
for (let cell of snake) {
ctx.fillRect(cell.x * size, cell.y * size, size, size);
}
}
function handleInit (number) {
playerNumber = number;
}
function handleGameState(gameState) {
if (!gameActive) {
return;
}
gameState = JSON.parse(gameState);
requestAnimationFrame(() => paintGame(gameState));
}
function handleGameOver(data) {
if (!gameActive) {
return;
}
data = JSON.parse(data);
if (data.winner === playerNumber) {
alert("You win! :^)");
} else {
alert("You lose. :^(")
}
gameActive = false;
}
function handleGameCode(gameCode) {
gameCodeDisplay.textContent = gameCode;
}
function handleUnknownGame() {
reset();
alert("Unknown game code")
}
function handleTooManyPlayers() {
reset();
alert("This game is already in progress");
}
function reset() {
playerNumber = null;
gameCodeInput.value = "";
initialScreen.style.display = "block";
gameScreen.style.display = "none";
}
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>MultiPlayer Snake</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
<style>
#gameScreen {
display: none;
}
</style>
</head>
<body>
<section class="vh-100">
<div class="container h-100">
<div id="initialScreen" class="h-100">
<div class="d-flex flex-column align-items-center justify-content-center h-100">
<h1>Multiplayer Snake</h1>
<button
type="submit"
class="btn btn-success"
id="newGameButton"
>
Create New Game
</button>
<div>OR</div>
<div class="form-group">
<label for="gameCodeInput"></label><input type="text" placeholder="Enter Game Code" id="gameCodeInput"/>
</div>
<button
type="submit"
class="btn btn-success"
id="joinGameButton"
>
Join Game
</button>
</div>
</div>
<div id="gameScreen" class="h-100">
<div class="d-flex flex-column align-items-center justify-content-center h-100">
<h1>Your game code is: <span id="gameCodeDisplay"></span></h1>
<canvas id="canvas"></canvas>
</div>
</div>
</div>
</section>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script src="index.js"></script>
</body>
</html>
To be honest I don't know what I've tried yet because they were mostly just minor tweaks that resulted in nothing.
Any help is greatly appreciated!