diff --git a/index.html b/index.html index a3c946b..e5d81cc 100644 --- a/index.html +++ b/index.html @@ -45,7 +45,10 @@ ball_maxAngle = 5*Math.PI/12; /** Game Variables **/ - var pid, + var uid, // Unique-ID + pid, // PlayerID 0 == Specator, 1 == Player 1, 2 == Player 2 + pwin = 0, + pwinanim = 0; leftY = 0, rightY = 0, leftV = 0, @@ -57,6 +60,16 @@ loggedkeys = [38, 40, 83, 87], gameState = 0; // 0 == Waiting for Players, 1 == Countdown, 2 == inGame, 3 == ??Win?? + var Localization = { + player : 'Spieler', + spectator : 'Zuschauer', + spectatormode : 'Zuschauer-Modus', + countdown : 'Starte in ', + countdownsuf : ' Sekunden', + waiting : 'Warte auf Spieler', + win : ' hat gewonnen!' + } + /** Initalize Socketio **/ var socket = io(); @@ -65,7 +78,7 @@ /** ############# **/ socket.on('handshake', function(id, state, c_width, c_height, sp, score, fn){ $('id').text(id); - pid = id; + uid = id; gameState = state; cube_width = c_width; cube_height = c_height; @@ -74,15 +87,20 @@ fn($(window).width(), $(window).height()); }); + socket.on('setpid', function(id){ + pid = id; + }); + socket.on('size', function(w, h){ width = w; height = h; c.width = w; c.height = h; - text = 'Starting in 5'; + text = Localization.countdown + 5 + Localization.countdownsuf; }); socket.on('gamestate', function(state){ + // console.log('new GameState: ' + state); gameState = state; }); @@ -92,7 +110,12 @@ /** Serversided Countdown to prevent desync **/ socket.on('countdown', function(i){ - text = 'Starting in ' + i; + text = Localization.countdown + i + Localization.countdownsuf; + }); + + socket.on('win', function(id, data){ + pwin = id; + console.log('Additional Data: ' + data); }); socket.on('paddlepos', function(pos, val, y){ @@ -134,7 +157,7 @@ }, 1000); var texti = 0, - nativtext = 'Waiting for Players', + nativtext = Localization.waiting, text = nativtext; function draw() { @@ -176,12 +199,18 @@ /** Points **/ - var scoretxt = score[0] + ' : ' + score[1]; ctx.fillStyle = 'black'; - ctx.font = '40px monospace'; ctx.textAlign = 'center'; - ctx.fillText(scoretxt, width/2, 70); - + var scoretxt = score[0] + ' : ' + score[1]; + if(pwin != 0 && gameState == 3){ + ctx.font = '80px monospace'; + ctx.fillText(Localization.player + ' ' + pwin + Localization.win, width/2, 310); + ctx.font = '80px monospace'; + ctx.fillText(scoretxt, width/2, 190); + } else { + ctx.font = '40px monospace'; + ctx.fillText(scoretxt, width/2, 70); + } if(gameState < 2){ ctx.fillStyle = 'black'; @@ -190,12 +219,15 @@ ctx.fillText(text, width/2, height/2-30); } - if(gameState == 2 && pid > 2){ - var specstr = "Spectator-Mode" - ctx.fillStyle = 'black'; - ctx.font = '15px monospace'; - ctx.textAlign = 'center'; - ctx.fillText(specstr, width/2, 25); + + ctx.fillStyle = 'black'; + ctx.font = '15px monospace'; + ctx.textAlign = 'center'; + if(gameState == 2 && pid == 0){ + ctx.fillText(Localization.spectatormode, width/2, 25); + } + if(pid == 1 || pid == 2){ + ctx.fillText(Localization.player + ' ' + pid, width/2, 25); } @@ -296,6 +328,7 @@ case 68 : if(ball_owner != 2) break; shootBall(); break; } } else if(pid == 1 || pid == 2){ + if(gameState == 3) return; if(loggedkeys.indexOf(e.keyCode) > -1 && pressedkeys.indexOf(e.keyCode) < 0) pressedkeys.push(e.keyCode); switch(e.keyCode) { @@ -330,9 +363,9 @@ case 83 : setV(2, 0); break; } }else if(pid == 1 || pid == 2){ + if(gameState == 3) return; if(loggedkeys.indexOf(e.keyCode) > -1 && pressedkeys.indexOf(e.keyCode) > -1){ pressedkeys.splice(pressedkeys.indexOf(e.keyCode), 1); - console.log(pressedkeys.length); if(pressedkeys.length == 0) // Only send v=0 if all keys are up setV(pid, 0); } diff --git a/index.js b/index.js index 433e9c1..c5a1a67 100644 --- a/index.js +++ b/index.js @@ -6,6 +6,18 @@ app.get('/', function(req, res){ res.sendFile(__dirname + '/index.html'); }); +/** Config-Values NOTE EDIT HERE **/ +var Configuration = { + cube_width : 50, + cube_height : 200, + cube_speed : 7, + ball_size : 15, + ball_speed : 15, + ball_owner : Math.round(Math.random()) + 1, + ball_maxAngle : 5*Math.PI/12, + wincount : 3 +} + /** Parameters **/ var clients = [], // List of all conected clients players = [], // Store Player 1 and Player 2 in Array {Player1 == players[0]} @@ -13,47 +25,54 @@ var clients = [], // List of all conected clients width, height, // Final Width + Height of Game-Window startinterval, // Interval for Counting down (cancelable) calcPos, - score = [0,0]; + score = [0,0], + id = 0; /** Game-Config **/ -var cube_width = 50, - cube_height = 200, - cube_speed = 7; // Depending on 'tickrate' [cube_speed*tickrate == acutal Speed] +var cube_width = Configuration.cube_width, + cube_height = Configuration.cube_height, + cube_speed = Configuration.cube_speed, // Depending on 'tickrate' [cube_speed*tickrate == acutal Speed] + wincount = Configuration.wincount; /** Networking-Config **/ var tickrate = 20; /** Ball-Config **/ -var ball_size = 15, - ball_speed = 15, - ballX = cube_width+ball_size, - ballY = cube_height/2, - ball_owner = 1, +var ball_size = Configuration.ball_size, + ball_speed = Configuration.ball_speed, + ball_owner = Configuration.ball_owner, + ball_maxAngle = Configuration.ball_maxAngle, ball_VX = 0, ball_VY = 0, - ball_maxAngle = 5*Math.PI/12; + ballX, + ballY; /** ########## **/ /** CONNECTION **/ /** ########## **/ io.on('connection', function(socket){ /** Set ID for User **/ - var id = clients.length + 1; - if(clients.length == 1) - if(clients[0].id == 2) id = 1; + id++; var clientkey = clients.push(new Client(id, socket)) - 1; console.log('Client connected. ID=' + id); /** ######### **/ /** HANDSHAKE **/ /** ######### **/ - socket.emit('handshake', id, gameState, cube_width, cube_height, cube_speed, score, function(w, h){ // Callback function for 1st Client to set screen size // + socket.emit('handshake', id, gameState, cube_width, cube_height, cube_speed, score, function(w, h){ // Callback function for Client to set screen size // clients[clientkey].width = w; clients[clientkey].height = h; - if(clients.length > 1 && gameState == 0) setUp(socket); + var pid = 0; + if(players.length < 2) + pid = players.push(new Player(id, socket, w, h)); + socket.emit('setpid', pid); + if(players.length > 1 && gameState == 0) setUp(); }); +/** If game was already started send Window-Detials **/ if(gameState > 0) socket.emit('size', width, height); + + /** #### **/ /** Ping **/ /** ### **/ @@ -69,7 +88,6 @@ if(gameState > 0) socket.emit('size', width, height); if(ball_owner == 1){ ball_VX = ball_speed; console.log('owner: left - at:' + players[0].y); - } else if(ball_owner == 2){ ball_VX = -ball_speed; @@ -82,7 +100,11 @@ if(gameState > 0) socket.emit('size', width, height); /** Paddel V-Change **/ /** ############## **/ socket.on('vchange', function(pos, val, y, timestamp){ + try{ players[pos-1].vY = val; + } catch (err) { + console.log('Error in vChange: ' + err.message); + } // NOTE Interpolation not needed // console.log('INTERPOLATING...'); @@ -112,40 +134,41 @@ if(gameState > 0) socket.emit('size', width, height); /** DISCONNECT **/ /** ########## **/ socket.on('disconnect', function(){ - var index; - clients.forEach(function(sock, ind){ - if (sock.socket == socket){ - index = ind; - return; + var cid, key; // Client ID + clients.forEach(function(cl, k){ + if(cl.socket == socket){ + cid = cl.id; + key = k; + return; } }); - var oldid = clients[index].id; - clients.splice(index, 1); - console.log('Client disconnected. ID=' + (oldid+1)); - if(clients.length == 1){ - clients[0].socket.emit('debug', 'player_left'); //TODO win-event - console.log('Only one Player left. Sending win-event'); - // Debug Restart: - gameState = 0; - clearInterval(startinterval); - broadcastGameState(socket); + var pid = 0; // 0 == Spectator --- 1 == Player 1 ---- 2 == Player 2 + players.forEach(function(pl, kkey){ + if(pl.socket == socket){ + pid = kkey+1; + return; + } + }); + console.log('Client disconnected. ID=' + cid); + clients.splice(key, 1); + if(clients.length == 0){ + console.log('All Clients disonnected. Reseting...'); + resetServer(); return; } - else if(clients.length == 0){ - console.log('All Players left. Reseting lobby...'); - gameState = 0; - id = 0; - return; + if(pid == 0) return; // Don't do anything if spectator leaves + gameState = 3; + broadcastGameState(); + if(pid == 1){ + clients[0].socket.emit('win', 2, 'Player 1 left.'); + clients[0].socket.broadcast.emit('win', 2, 'Player 1 left.'); } - - var key = 0; - if(clients[0].id == 1 || clients[0].id == 2) key = 1; - switch(oldid){ - case 1 : clients[key].id = 1; clients[key].socket.emit('handshake', 1); console.log('New Player 1 selected.'); setUp(); break; - case 2 : clients[key].id = 2; clients[key].socket.emit('handshake', 2); console.log('New Player 2 selected.'); setUp(); break; - default : console.log('Spectator left. Nothing need to select new Players.'); break; - + if(pid == 2){ + clients[0].socket.emit('win', 1, 'Player 2 left.'); + clients[0].socket.broadcast.emit('win', 1, 'Player 2 left.'); } + resetServer(); + console.log('Reseting...'); }); }); @@ -156,76 +179,69 @@ http.listen(3000, function(){ /** Sync all settings to client and start the game **/ -function setUp(socket){ +function setUp(){ gameState = 1; - broadcastGameState(socket); + broadcastGameState(); console.log('Starting SetUp...'); /** Select smalest screensize and set for all clients **/ - clients.forEach(function(sock){ - broadcastGameState(socket); - if(sock.id == 1){ - players[0] = new Player(sock.id, sock.socket); - clients.forEach(function(sock2){ - if(sock2.id == 2){ - players[1] = new Player(sock2.id, sock2.socket); - if(sock.width < sock2.width) - width = sock.width; - else - width = sock2.width; - if(sock.height < sock2.height) - height = sock.height; - else - height = sock2.height; - } - }); - } - }); + if(players[0].window_width < players[1].window_width) + width = players[0].window_width; + else + width = players[1].window_width; + if(players[0].window_height < players[1].window_height) + height = players[0].window_height; + else + height = players[1].window_height; + if(calcPos == null) // Start tick Server only once tickServer(); - socket.emit('size', width, height); - socket.broadcast.emit('size', width, height); + clients[0].socket.emit('size', width, height); + clients[0].socket.broadcast.emit('size', width, height); var i = 5; startinterval = setInterval(function(){ + if(gameState == 3) clearInterval(startinterval); i--; - socket.emit('countdown', i); - socket.broadcast.emit('countdown', i); + clients[0].socket.emit('countdown', i); + clients[0].socket.broadcast.emit('countdown', i); if(i == 0){ resetPlayers(); clearInterval(startinterval); gameState = 2; - broadcastGameState(socket); - socket.emit('gamestate'); - socket.broadcast.emit('gamestate'); + broadcastGameState(); } }, 1000); } /** Broadcast GameState to all clients **/ -function broadcastGameState(socket){ - socket.emit('gamestate', gameState); - socket.broadcast.emit('gamestate', gameState); +function broadcastGameState(){ + clients[0].socket.emit('gamestate', gameState); + clients[0].socket.broadcast.emit('gamestate', gameState); } function tickServer(){ calcPos = setInterval(function(){ - calculatePlayerPosition(); - calculateBallPosition(); + try { + calculatePlayerPosition(); + calculateBallPosition(); + } catch (err){ + console.log('Error in ServerTick: ' + err.message); + } + }, tickrate); } function calculatePlayerPosition(){ - players.forEach(function(player){ + players.forEach(function(player, k){ player.y -= player.vY*player.speed; if(player.y > height-player.height || player.y < 0) player.vY = 0; if(player.y < 0) player.y = 0; if(player.y > height-player.height) player.y = height-player.height; - player.socket.emit('paddlepos', player.id, player.vY, player.y); - player.socket.broadcast.emit('paddlepos', player.id, player.vY, player.y); + player.socket.emit('paddlepos', k+1, player.vY, player.y); + player.socket.broadcast.emit('paddlepos', k+1, player.vY, player.y); }); } function calculateBallPosition(){ - /** Move Ball with Paddle if owned by owner (@roundstart) **/ if(ball_owner == 1){ ballX = cube_width+ball_size, @@ -299,23 +315,52 @@ function calculateBallPosition(){ function changeScore(id, val){ score[id-1] = val; - players[0].socket.emit('score', score); - players[0].socket.broadcast.emit('score', score); + clients[0].socket.emit('score', score); + clients[0].socket.broadcast.emit('score', score); + + if(val == wincount){ + gameState = 3; + broadcastGameState(); + clients[0].socket.emit('win', id, 'Player ' + id + ' scored needed points first.'); + clients[0].socket.broadcast.emit('win', id, 'Player ' + id + ' scored needed points first.'); + resetServer(); + } } function resetPlayers(){ - players.forEach(function(player){ + ball_owner = Math.round(Math.random()) + 1; + ball_VX = 0; + ball_VY = 0; + players.forEach(function(player, k){ player.speed = cube_speed; player.width = cube_width; player.height = cube_height; player.y = 0; player.vY = 0; - changeScore(player.id-1, 0); + changeScore(k, 0); }); } function resetServer(){ - // TODO + gameState = 0; + clearInterval(calcPos); + calcPos = null; + clearInterval(startinterval); + score = [0,0]; + + cube_width = Configuration.cube_width; + cube_height = Configuration.cube_height; + cube_speed = Configuration.cube_speed; + ball_size = Configuration.ball_size; + ball_speed = Configuration.ball_speed; + ball_owner = Configuration.ball_owner; + ball_maxAngle = Configuration.ball_maxAngle; + ball_VX = 0; + ball_VY = 0; + ballX = Configuration.cube_width; + ballY = Configuration.cube_height/2; + + players = []; } function Client(id, socket){ @@ -325,9 +370,11 @@ function Client(id, socket){ this.height = 0; } -function Player(id, socket){ +function Player(id, socket, window_width, window_height){ this.id = id; this.socket = socket; + this.window_width = window_width; + this.window_height = window_height; this.speed = cube_speed; this.width = cube_width; this.height = cube_height;