Archived
1
0
Fork 0
This repository has been archived on 2019-02-05. You can view files and clone it, but cannot push or open issues or pull requests.
Pong/index.js

348 lines
9.4 KiB
JavaScript

var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
/** Parameters **/
var clients = [], // List of all conected clients
players = [], // Store Player 1 and Player 2 in Array {Player1 == players[0]}
gameState = 0, // Game-Controler Variable
width, height, // Final Width + Height of Game-Window
startinterval, // Interval for Counting down (cancelable)
calcPos,
score = [0,0];
/** Game-Config **/
var cube_width = 50,
cube_height = 200,
cube_speed = 7; // Depending on 'tickrate' [cube_speed*tickrate == acutal Speed]
/** 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,
ball_VX = 0,
ball_VY = 0,
ball_maxAngle = 5*Math.PI/12;
/** ########## **/
/** 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;
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 //
clients[clientkey].width = w;
clients[clientkey].height = h;
if(clients.length > 1 && gameState == 0) setUp(socket);
});
if(gameState > 0) socket.emit('size', width, height);
/** #### **/
/** Ping **/
/** ### **/
socket.on('appping', function(fn){
fn(Date.now());
});
/** ######### **/
/** Ballshoot **/
/** ######### **/
socket.on('ballshoot', function(y){
// shottball event obsolet
// socket.emit('shootball', y);
// socket.broadcast.emit('shootball', y);
console.log('### Ball shoot event ###');
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;
console.log('owner: right - at:' + players[1].y);
}
ball_owner = 0;
});
/** ################ **/
/** Paddel V-Change **/
/** ############## **/
socket.on('vchange', function(pos, val, y, timestamp){
var timediff = Date.now()-timestamp;
// console.log('INTERPOLATING...');
// var diff = ((players[pos-1].speed/tickrate)*timediff);
// if(players[pos-1].vY == 0){ // Lag from Sender (accel)
// if(val > 0)
// players[pos-1].y -= diff;
// if(val < 0)
// players[pos-1].y += diff;
// }
// if(players[pos-1].vY == 1){
// if(val == 0)
// players[pos-1].y += diff;
// }
// if(players[pos-1].vY == -1){
// if(val == 0)
// players[pos-1].y -= diff;
// }
players[pos-1].vY = val;
// console.log('Diff:' + diff);
// console.log('Got: ' + y + ' @ ' + timestamp);
// console.log('Expected:' + players[pos-1].y + ' @ ' + Date.now());
socket.emit('changeV', pos, val, players[pos-1].y);
socket.broadcast.emit('changeV', pos, val, players[pos-1].y);
});
/** ########## **/
/** DISCONNECT **/
/** ########## **/
socket.on('disconnect', function(){
var index;
clients.forEach(function(sock, ind){
if (sock.socket == socket){
index = ind;
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('test', 'player_left'); //TODO win-event
console.log('Only one Player left. Sending win-event');
// Debug Restart:
gameState = 0;
clearInterval(startinterval);
broadcastGameState(socket);
return;
}
else if(clients.length == 0){
console.log('All Players left. Reseting lobby...');
gameState = 0;
id = 0;
return;
}
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;
}
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
/** Sync all settings to client and start the game **/
function setUp(socket){
gameState = 1;
broadcastGameState(socket);
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(calcPos == null) // Start tick Server only once
tickServer();
socket.emit('size', width, height);
socket.broadcast.emit('size', width, height);
var i = 5;
startinterval = setInterval(function(){
i--;
socket.emit('countdown', i);
socket.broadcast.emit('countdown', i);
if(i == 0){
resetPlayers();
clearInterval(startinterval);
gameState = 2;
broadcastGameState(socket);
socket.emit('start');
socket.broadcast.emit('start');
}
}, 1000);
}
/** Broadcast GameState to all clients **/
function broadcastGameState(socket){
socket.emit('gamestate', gameState);
socket.broadcast.emit('gamestate', gameState);
}
function tickServer(){
calcPos = setInterval(function(){
calculatePlayerPosition();
calculateBallPosition();
}, tickrate);
}
function calculatePlayerPosition(){
players.forEach(function(player){
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('changeV', player.id, player.vY, player.y);
player.socket.broadcast.emit('changeV', player.id, player.vY, player.y);
});
}
function calculateBallPosition(){
/** Move Ball with Paddle if owned by owner (@roundstart) **/
if(ball_owner == 1){
ballX = cube_width+ball_size,
ballY = players[0].y+cube_height/2;
}
else if(ball_owner == 2){
ballX = width-cube_width-ball_size,
ballY = players[1].y+cube_height/2;
}
/** ############ **/
/** Ball Physics **/
/** ############ **/
ballX += ball_VX;
ballY += ball_VY;
/** Collide with right Paddle or get point and respawn **/
if(ballX > width - cube_width){
if(ballY < players[1].y || ballY > players[1].y+cube_height){
console.log('Point for Left');
changeScore(1, score[0]+1);
ball_VX = 0;
ball_VY = 0;
ball_owner = 1;
} else {
var intersect = ((players[1].y+cube_height/2)-ballY)/(cube_height/2);
console.log('Intersect with right at:');
console.log(intersect);
console.log('###########################');
ball_VX = -ball_speed*Math.cos(intersect*ball_maxAngle);
ball_VY = -ball_speed*Math.sin(intersect*ball_maxAngle);
}
}
/** Collide with left Paddle or get point and respawn **/
if(ballX < cube_width){
if(ballY < players[0].y || ballY > players[0].y+cube_height){
console.log('Point for Right');
changeScore(2, score[1]+1);
ball_VX = 0;
ball_VY = 0;
ball_owner = 2;
} else {
var intersect = ((players[0].y+cube_height/2)-ballY)/(cube_height/2);
console.log('Intersect with left at:');
console.log(intersect);
console.log('###########################');
ball_VX = ball_speed*Math.cos(intersect*ball_maxAngle);
ball_VY = ball_speed*Math.sin(intersect*ball_maxAngle);
}
}
/** TODO INCREASE SPEED ON PADDLE HIT (weiter außen = schneller) **/
/** Collide with walls **/
if(ballY <= 0 || ballY >= height-ball_size){
ball_VY = -ball_VY;
console.log(ballX + ' : ' + ballY);
}
var data = {
x : ballX,
y : ballY,
vx : ball_VX,
vy : ball_VY,
speed : ball_speed,
owner : ball_owner
};
players[0].socket.emit('ballpos', data);
players[0].socket.broadcast.emit('ballpos', data);
}
function changeScore(id, val){
score[id-1] = val;
players[0].socket.emit('scoreChange', score);
players[0].socket.broadcast.emit('scoreChange', score);
}
function resetPlayers(){
players.forEach(function(player){
player.speed = cube_speed;
player.width = cube_width;
player.height = cube_height;
player.y = 0;
player.vY = 0;
changeScore(player.id-1, 0);
});
}
function resetServer(){
// TODO
}
function Client(id, socket){
this.id = id;
this.socket = socket;
this.width = 0;
this.height = 0;
}
function Player(id, socket){
this.id = id;
this.socket = socket;
this.speed = cube_speed;
this.width = cube_width;
this.height = cube_height;
this.y = 0;
this.vY = 0;
}