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

441 lines
12 KiB
JavaScript
Raw Normal View History

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');
});
/** 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-29 22:21:01 +00:00
wincount : 3,
powerupmaxtime : 10
}
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,
score = [0,0],
2017-01-29 22:21:01 +00:00
id = 0,
powerups = [];
/** PowerUps **/
var powerTime = 30;
2017-01-20 22:42:49 +00:00
/** Game-Config **/
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 **/
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,
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 **/
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 **/
/** ######### **/
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;
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
});
/** 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-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){
try{
2017-01-21 18:49:50 +00:00
players[pos-1].vY = val;
} 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(){
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
}
});
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;
}
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
}
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
}
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 **/
function setUp(){
2017-01-20 22:42:49 +00:00
gameState = 1;
broadcastGameState();
2017-01-20 22:42:49 +00:00
console.log('Starting SetUp...');
/** Select smalest screensize and set for all clients **/
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();
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(){
if(gameState == 3) clearInterval(startinterval);
2017-01-20 22:42:49 +00:00
i--;
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;
broadcastGameState();
2017-01-20 22:42:49 +00:00
}
}, 1000);
}
2017-01-21 17:58:44 +00:00
/** Broadcast GameState to all clients **/
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(){
try {
calculatePlayerPosition();
calculateBallPosition();
} catch (err){
console.log('Error in ServerTick: ' + err.message);
}
2017-01-21 17:58:44 +00:00
}, tickrate);
}
2017-01-29 22:21:01 +00:00
function drawPowerUp(){
var key = powerups.push(new PowerUp(1));
console.log(powerups[key-1].x);
console.log(powerups[key-1].y);
players[0].socket.emit('powerup', powerups[key-1].type, powerups[key-1].width, powerups[key-1].height, powerups[key-1].x, powerups[key-1].y);
players[0].socket.broadcast.emit('powerup', powerups[key-1].type, powerups[key-1].width, powerups[key-1].height, powerups[key-1].x, powerups[key-1].y);
}
2017-01-21 17:58:44 +00:00
function calculatePlayerPosition(){
players.forEach(function(player, k){
2017-01-29 22:21:01 +00:00
// console.log(player.powerup.tick);
if(player.powerup.type == 1){
player.speed = Configuration.cube_speed + 10;
player.powerup.tick++;
if(player.powerup.tick == Configuration.powerupmaxtime*(1000/tickrate)){
player.powerup = 0;
}
} else {
player.speed = Configuration.cube_speed;
}
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;
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;
2017-01-29 22:21:01 +00:00
drawPowerUp();
2017-01-21 17:58:44 +00:00
} 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;
2017-01-29 22:21:01 +00:00
// Add PowerUp
drawPowerUp();
2017-01-21 17:58:44 +00:00
} 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);
}
2017-01-29 22:21:01 +00:00
/** Collide with PowerUp **/
powerups.forEach(function(pu, key){
if(!(ballY > pu.y+pu.height || ballY+ball_size*2 < pu.y)){
if(!(ballX > pu.x+pu.width || ballX+ball_size*2 < pu.x)){
if(ball_VX > 0){
players[0].powerup = pu;
} else {
players[1].powerup = pu;
}
console.log('#### KEY####');
console.log(key);
// console.log(pu);
powerups.splice(key, 1);
console.log(powerups.length);
players[0].socket.emit('powerupremove', key);
players[0].socket.broadcast.emit('powerupremove', key);
return;
}
}
});
2017-01-21 17:58:44 +00:00
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;
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(){
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;
changeScore(k, 0);
2017-01-21 17:58:44 +00:00
});
}
function resetServer(){
gameState = 0;
clearInterval(calcPos);
calcPos = null;
clearInterval(startinterval);
score = [0,0];
cube_width = Configuration.cube_width;
cube_height = Configuration.cube_height;
2017-01-29 22:21:01 +00:00
u = 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;
2017-01-29 22:21:01 +00:00
powerups = [];
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
function Player(id, socket, window_width, window_height){
2017-01-21 17:58:44 +00:00
this.id = id;
this.socket = socket;
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;
2017-01-29 22:21:01 +00:00
this.powerup = 0;
}
function PowerUp(type){
this.type = type;
this.tick = 0;
this.width = 50;
this.height = 50;
this.x = Math.random()*(width-Configuration.cube_width*4)+Configuration.cube_width*2;
this.y = Math.random()*(height-50);
2017-01-21 17:58:44 +00:00
}