2017-01-20 22:42:49 +00:00
|
|
|
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');
|
|
|
|
});
|
|
|
|
|
2017-01-21 23:11:01 +00:00
|
|
|
/** 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,
|
2017-01-25 17:58:05 +00:00
|
|
|
wincount : 5
|
2017-01-21 23:11:01 +00:00
|
|
|
}
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
/** 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,
|
2017-01-21 23:11:01 +00:00
|
|
|
score = [0,0],
|
|
|
|
id = 0;
|
2017-01-20 22:42:49 +00:00
|
|
|
|
|
|
|
/** Game-Config **/
|
2017-01-21 23:11:01 +00:00
|
|
|
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;
|
2017-01-21 17:58:44 +00:00
|
|
|
|
|
|
|
/** Networking-Config **/
|
|
|
|
var tickrate = 20;
|
|
|
|
|
|
|
|
/** Ball-Config **/
|
2017-01-21 23:11:01 +00:00
|
|
|
var ball_size = Configuration.ball_size,
|
|
|
|
ball_speed = Configuration.ball_speed,
|
|
|
|
ball_owner = Configuration.ball_owner,
|
|
|
|
ball_maxAngle = Configuration.ball_maxAngle,
|
2017-01-21 17:58:44 +00:00
|
|
|
ball_VX = 0,
|
|
|
|
ball_VY = 0,
|
2017-01-21 23:11:01 +00:00
|
|
|
ballX,
|
|
|
|
ballY;
|
2017-01-20 22:42:49 +00:00
|
|
|
|
|
|
|
/** ########## **/
|
|
|
|
/** CONNECTION **/
|
|
|
|
/** ########## **/
|
|
|
|
io.on('connection', function(socket){
|
2017-01-21 17:58:44 +00:00
|
|
|
/** Set ID for User **/
|
2017-01-21 23:11:01 +00:00
|
|
|
id++;
|
2017-01-21 17:58:44 +00:00
|
|
|
var clientkey = clients.push(new Client(id, socket)) - 1;
|
2017-01-20 22:42:49 +00:00
|
|
|
console.log('Client connected. ID=' + id);
|
|
|
|
|
|
|
|
/** ######### **/
|
|
|
|
/** HANDSHAKE **/
|
|
|
|
/** ######### **/
|
2017-01-21 23:11:01 +00:00
|
|
|
socket.emit('handshake', id, gameState, cube_width, cube_height, cube_speed, score, function(w, h){ // Callback function for Client to set screen size //
|
2017-01-21 17:58:44 +00:00
|
|
|
clients[clientkey].width = w;
|
|
|
|
clients[clientkey].height = h;
|
2017-01-21 23:11:01 +00:00
|
|
|
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();
|
2017-01-20 22:42:49 +00:00
|
|
|
});
|
|
|
|
|
2017-01-21 23:11:01 +00:00
|
|
|
/** If game was already started send Window-Detials **/
|
2017-01-20 22:42:49 +00:00
|
|
|
if(gameState > 0) socket.emit('size', width, height);
|
2017-01-21 23:11:01 +00:00
|
|
|
|
|
|
|
|
2017-01-20 22:42:49 +00:00
|
|
|
/** #### **/
|
|
|
|
/** Ping **/
|
|
|
|
/** ### **/
|
|
|
|
socket.on('appping', function(fn){
|
|
|
|
fn(Date.now());
|
|
|
|
});
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
/** ######### **/
|
2017-01-21 00:01:23 +00:00
|
|
|
/** Ballshoot **/
|
2017-01-21 17:58:44 +00:00
|
|
|
/** ######### **/
|
2017-01-21 00:01:23 +00:00
|
|
|
socket.on('ballshoot', function(y){
|
2017-01-21 17:58:44 +00:00
|
|
|
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;
|
2017-01-20 22:42:49 +00:00
|
|
|
});
|
2017-01-20 23:50:32 +00:00
|
|
|
|
|
|
|
/** ################ **/
|
|
|
|
/** Paddel V-Change **/
|
|
|
|
/** ############## **/
|
2017-01-21 17:58:44 +00:00
|
|
|
socket.on('vchange', function(pos, val, y, timestamp){
|
2017-01-21 23:11:01 +00:00
|
|
|
try{
|
2017-01-21 18:49:50 +00:00
|
|
|
players[pos-1].vY = val;
|
2017-01-21 23:11:01 +00:00
|
|
|
} catch (err) {
|
|
|
|
console.log('Error in vChange: ' + err.message);
|
|
|
|
}
|
2017-01-21 17:58:44 +00:00
|
|
|
|
2017-01-21 18:49:50 +00:00
|
|
|
// NOTE Interpolation not needed
|
2017-01-21 17:58:44 +00:00
|
|
|
// 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;
|
|
|
|
// }
|
|
|
|
// console.log('Diff:' + diff);
|
|
|
|
// console.log('Got: ' + y + ' @ ' + timestamp);
|
|
|
|
// console.log('Expected:' + players[pos-1].y + ' @ ' + Date.now());
|
2017-01-21 18:23:47 +00:00
|
|
|
// socket.emit('changeV', pos, val, players[pos-1].y);
|
|
|
|
// socket.broadcast.emit('changeV', pos, val, players[pos-1].y);
|
2017-01-20 22:42:49 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
/** ########## **/
|
|
|
|
/** DISCONNECT **/
|
|
|
|
/** ########## **/
|
|
|
|
socket.on('disconnect', function(){
|
2017-01-21 23:11:01 +00:00
|
|
|
var cid, key; // Client ID
|
|
|
|
clients.forEach(function(cl, k){
|
|
|
|
if(cl.socket == socket){
|
|
|
|
cid = cl.id;
|
|
|
|
key = k;
|
|
|
|
return;
|
2017-01-20 22:42:49 +00:00
|
|
|
}
|
|
|
|
});
|
2017-01-21 23:11:01 +00:00
|
|
|
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();
|
2017-01-20 22:42:49 +00:00
|
|
|
return;
|
|
|
|
}
|
2017-01-21 23:11:01 +00:00
|
|
|
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.');
|
2017-01-20 22:42:49 +00:00
|
|
|
}
|
2017-01-21 23:11:01 +00:00
|
|
|
if(pid == 2){
|
|
|
|
clients[0].socket.emit('win', 1, 'Player 2 left.');
|
|
|
|
clients[0].socket.broadcast.emit('win', 1, 'Player 2 left.');
|
2017-01-20 22:42:49 +00:00
|
|
|
}
|
2017-01-21 23:11:01 +00:00
|
|
|
resetServer();
|
|
|
|
console.log('Reseting...');
|
2017-01-20 22:42:49 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
http.listen(3000, function(){
|
|
|
|
console.log('listening on *:3000');
|
|
|
|
});
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
|
|
|
|
/** Sync all settings to client and start the game **/
|
2017-01-21 23:11:01 +00:00
|
|
|
function setUp(){
|
2017-01-20 22:42:49 +00:00
|
|
|
gameState = 1;
|
2017-01-21 23:11:01 +00:00
|
|
|
broadcastGameState();
|
2017-01-20 22:42:49 +00:00
|
|
|
console.log('Starting SetUp...');
|
|
|
|
/** Select smalest screensize and set for all clients **/
|
2017-01-21 23:11:01 +00:00
|
|
|
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;
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
if(calcPos == null) // Start tick Server only once
|
|
|
|
tickServer();
|
2017-01-21 23:11:01 +00:00
|
|
|
clients[0].socket.emit('size', width, height);
|
|
|
|
clients[0].socket.broadcast.emit('size', width, height);
|
2017-01-20 22:42:49 +00:00
|
|
|
var i = 5;
|
2017-01-20 23:50:32 +00:00
|
|
|
startinterval = setInterval(function(){
|
2017-01-21 23:11:01 +00:00
|
|
|
if(gameState == 3) clearInterval(startinterval);
|
2017-01-20 22:42:49 +00:00
|
|
|
i--;
|
2017-01-21 23:11:01 +00:00
|
|
|
clients[0].socket.emit('countdown', i);
|
|
|
|
clients[0].socket.broadcast.emit('countdown', i);
|
2017-01-20 22:42:49 +00:00
|
|
|
if(i == 0){
|
2017-01-21 17:58:44 +00:00
|
|
|
resetPlayers();
|
2017-01-20 23:50:32 +00:00
|
|
|
clearInterval(startinterval);
|
2017-01-20 22:42:49 +00:00
|
|
|
gameState = 2;
|
2017-01-21 23:11:01 +00:00
|
|
|
broadcastGameState();
|
2017-01-20 22:42:49 +00:00
|
|
|
}
|
|
|
|
}, 1000);
|
|
|
|
}
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
/** Broadcast GameState to all clients **/
|
2017-01-21 23:11:01 +00:00
|
|
|
function broadcastGameState(){
|
|
|
|
clients[0].socket.emit('gamestate', gameState);
|
|
|
|
clients[0].socket.broadcast.emit('gamestate', gameState);
|
2017-01-20 22:42:49 +00:00
|
|
|
}
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
function tickServer(){
|
|
|
|
calcPos = setInterval(function(){
|
2017-01-21 23:11:01 +00:00
|
|
|
try {
|
|
|
|
calculatePlayerPosition();
|
|
|
|
calculateBallPosition();
|
|
|
|
} catch (err){
|
|
|
|
console.log('Error in ServerTick: ' + err.message);
|
|
|
|
}
|
|
|
|
|
2017-01-21 17:58:44 +00:00
|
|
|
}, tickrate);
|
|
|
|
}
|
|
|
|
|
|
|
|
function calculatePlayerPosition(){
|
2017-01-21 23:11:01 +00:00
|
|
|
players.forEach(function(player, k){
|
2017-01-21 17:58:44 +00:00
|
|
|
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;
|
2017-01-21 23:11:01 +00:00
|
|
|
player.socket.emit('paddlepos', k+1, player.vY, player.y);
|
|
|
|
player.socket.broadcast.emit('paddlepos', k+1, player.vY, player.y);
|
2017-01-21 17:58:44 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
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);
|
2017-01-25 17:58:05 +00:00
|
|
|
ball_VY = -ball_speed*Math.sin(intersect*ball_maxAngle);
|
2017-01-21 17:58:44 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/** 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;
|
2017-01-21 23:11:01 +00:00
|
|
|
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();
|
|
|
|
}
|
2017-01-21 17:58:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function resetPlayers(){
|
2017-01-21 23:11:01 +00:00
|
|
|
ball_owner = Math.round(Math.random()) + 1;
|
|
|
|
ball_VX = 0;
|
|
|
|
ball_VY = 0;
|
|
|
|
players.forEach(function(player, k){
|
2017-01-21 17:58:44 +00:00
|
|
|
player.speed = cube_speed;
|
|
|
|
player.width = cube_width;
|
|
|
|
player.height = cube_height;
|
|
|
|
player.y = 0;
|
|
|
|
player.vY = 0;
|
2017-01-21 23:11:01 +00:00
|
|
|
changeScore(k, 0);
|
2017-01-21 17:58:44 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function resetServer(){
|
2017-01-21 23:11:01 +00:00
|
|
|
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 = [];
|
2017-01-21 17:58:44 +00:00
|
|
|
}
|
|
|
|
|
2017-01-20 22:42:49 +00:00
|
|
|
function Client(id, socket){
|
|
|
|
this.id = id;
|
|
|
|
this.socket = socket;
|
|
|
|
this.width = 0;
|
|
|
|
this.height = 0;
|
|
|
|
}
|
2017-01-21 17:58:44 +00:00
|
|
|
|
2017-01-21 23:11:01 +00:00
|
|
|
function Player(id, socket, window_width, window_height){
|
2017-01-21 17:58:44 +00:00
|
|
|
this.id = id;
|
|
|
|
this.socket = socket;
|
2017-01-21 23:11:01 +00:00
|
|
|
this.window_width = window_width;
|
|
|
|
this.window_height = window_height;
|
2017-01-21 17:58:44 +00:00
|
|
|
this.speed = cube_speed;
|
|
|
|
this.width = cube_width;
|
|
|
|
this.height = cube_height;
|
|
|
|
this.y = 0;
|
|
|
|
this.vY = 0;
|
|
|
|
}
|