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.html
2017-01-21 00:50:32 +01:00

373 lines
11 KiB
HTML

<!doctype html>
<html>
<head>
<title>🏓 Pong</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { height: 100vh; width: 100vw; overflow: hidden; }
canvas {border: black solid 1px; top:-1px; left:-1px; position: absolute;}
div { position: fixed; top: 0; right: 0; width: 130px; height: 60px; background: rgba(0, 0, 0, .5); color: white; padding: 5px; font-family: monospace; z-index: 100; }
</style>
</head>
<body>
<div id="debug">FPS: &nbsp;<fps>...</fps><br/>Ping: <ping>...</ping><br />ID: &nbsp;&nbsp;<id>...</id></div>
<canvas id="test"></canvas>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io();
var pid;
socket.on('handshake', function(id, state, c_width, c_height, sp, fn){
$('id').text(id);
pid = id;
gameState = state;
cube_width = c_width;
cube_height = c_height;
speed = sp;
fn($(window).width(), $(window).height());
});
socket.on('size', function(w, h){
width = w;
height = h;
c.width = w;
c.height = h;
text = 'Starting in 5';
});
socket.on('gamestate', function(state){
gameState = state;
});
socket.on('shootball', function(){
shootBall();
});
/** Make Countdown serversided No cheating possible **/
socket.on('countdown', function(i){
text = 'Starting in ' + i;
});
socket.on('start', function(){
leftOr = 'none';
rightOr = 'none';
leftY = 0;
rightY = 0;
leftV = 0;
rightV = 0;
ballX = cube_width+ball_size;
ballY = cube_height/2;
ball_owner = 1;
ball_VX = 0;
ball_VY = 0;
gameState = 2;
});
socket.on('changeV', function(pos, val, y){
if(pos == 1){
leftV = val;
leftY = y;
}
if(pos == 2){
rightV = val;
rightY = y;
}
console.log(leftY);
});
socket.on('test', function(arg){
console.log(arg);
});
/** Initialize Canvas **/
var c = document.getElementById("test");
var ctx = c.getContext("2d");
c.width = $(window).width();
c.height = $(window).height();
var leftY = 0;
var rightY = 0;
var leftV = 0;
var rightV = 0;
var leftColor = 'red';
var rightColor = 'blue';
var gameState = 0; // 0 == Waiting for Players, 1 == Countdown, 2 == inGame, 3 == ??Win??
/** FPS Vars **/
var lastCalledTime,
lastFPSshown,
fps;
/** Global Configuration **/
var localcoop = false, // Local Coop in 1 window
width = $(window).width(),
height = $(window).height();
/** Prop-Config **/
var cube_width = 50,
cube_height = 200,
speed = 7,
ball_size = 15,
ball_speed = 8,
ballX = cube_width+ball_size,
ballY = cube_height/2,
ball_owner = 1,
ball_VX = 0,
ball_VY = 0,
ball_maxAngle = 5*Math.PI/12;
/** Messaure Ping and show **/
setInterval(function(){
var connTime = Date.now();
socket.emit('appping', function(data){
$('ping').text(Date.now()-connTime + 'ms');
});
}, 1000);
var texti = 0,
nativtext = 'Waiting for Players',
text = nativtext;
function draw() {
/** FPS Calculation **/
if(!lastCalledTime) {
lastCalledTime = Date.now();
fps = 0;
}
delta = (Date.now() - lastCalledTime)/1000;
lastCalledTime = Date.now();
fps = 1/delta;
/** Show FPS in Debug-Window **/
if(!lastFPSshown) {
lastFPSshown = Date.now();
$('fps').text('...');
}
if(lastFPSshown+1000 < Date.now()) {
lastFPSshown = Date.now();
$('fps').text(Math.round(fps));
/** Use this timer for displaying loading indicator **/
if(gameState == 0)
switch(texti){
case 0: text = nativtext; texti++; break;
case 1 :
case 2 : text+='.'; texti++; break;
case 3 : text+='.'; texti = 0; break;
}
}
/** Clear Drawing-Region **/
ctx.fillStyle = 'white';
ctx.fillRect(0, 0, width, height);
if(gameState < 2){
ctx.fillStyle = 'black';
ctx.font = '30px monospace';
ctx.fillText(text, width/2-text.length*8, height/2-30);
}
if(gameState == 2 && pid > 2){
var specstr = "Spectator-Mode"
ctx.fillStyle = 'black';
ctx.font = '15px monospace';
ctx.fillText(specstr, width/2-specstr.length*8, 50);
}
if(leftY > height-cube_height || leftY < 0)
leftV = 0;
if(rightY > height-cube_height || rightY < 0)
rightV = 0;
if(leftY < 0 ) leftY = 0;
if(rightY < 0 ) rightY = 0;
if(leftY > height-cube_height) leftY = height-cube_height;
if(rightY > height-cube_height) rightY = height-cube_height;
/** Draw Cube **/
/** Note: Get position by multiplying it with the "Render-Delta" - for same speed on every system **/
leftY -= leftV*Math.round((1*delta)*60*speed);
rightY -= rightV*Math.round((1*delta)*60*speed);
ctx.fillStyle = leftColor;
ctx.fillRect(0, leftY, cube_width, cube_height);
ctx.fillStyle = rightColor;
ctx.fillRect(width-cube_width, rightY, cube_width, cube_height);
/** Move Ball with Paddle if owned by owner (@roundstart) **/
if(ball_owner == 1){
ballX = cube_width+ball_size,
ballY = leftY+cube_height/2;
}
else if(ball_owner == 2){
ballX = width-cube_width-ball_size,
ballY = rightY+cube_height/2;
}
/** ############ **/
/** Ball Physics **/
/** ############ **/
/** Collide with right Paddle or get point and respawn **/
if(ballX > width - cube_width){
if(ballY < rightY || ballY > rightY+cube_height){
console.log('Point for Left');
ball_VX = 0;
ball_VY = 0;
ball_owner = 1;
} else {
var intersect = ((rightY+cube_height/2)-ballY)/(cube_height/2);
console.log(intersect);
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 < leftY || ballY > leftY+cube_height){
console.log('Point for Right');
ball_VX = 0;
ball_VY = 0;
ball_owner = 2;
} else {
var intersect = ((leftY+cube_height/2)-ballY)/(cube_height/2);
console.log(intersect);
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;
}
/** Draw Ball **/
ctx.fillStyle = 'black';
ballX += Math.round((1*delta)*60)*ball_VX;
ballY += Math.round((1*delta)*60)*ball_VY;
ctx.beginPath();
ctx.arc(ballX, ballY, ball_size, 0, 2*Math.PI);
ctx.fill();
}
/** ############## **/
/** Input Handlers **/
/** ############## **/
$(window).on('keydown', function(e) {
if(localcoop){
switch(e.keyCode) {
case 38 : if(leftY <= 0) break; setV(1, 1); break;
case 40 : if(leftY >= height-cube_height) break; setV(1, -1); break;
case 87 : if(rightY <= 0) break; setV(2, 1); break;
case 83 : if(rightY >= height-cube_height) break; setV(2, -1); break;
case 37 :
case 39 : if(ball_owner != 1) break; shootBall(); break;
case 65 :
case 68 : if(ball_owner != 2) break; shootBall(); break;
}
} else if(pid == 1 || pid == 2){
switch(e.keyCode) {
case 38 :
case 87 : if(pid == 1){
if(leftY <= 0) break; setV(1, 1);
} else if(pid == 2) {
if(rightY <= 0) break; setV(2, 1);
}
break;
case 40 :
case 83 : if(pid == 1){
if(leftY >= height-cube_height) break; setV(1, -1);
} else if(pid == 2){
if(rightY >= height-cube_height) break; setV(2, -1);
}
break;
case 37 :
case 39 :
case 65 :
case 68 : if(ball_owner != pid)break; socket.emit('ballshoot'); shootBall(); break;
}
}
});
$(window).on('keyup', function(e) {
if(localcoop){
switch(e.keyCode) {
case 38 :
case 40 :
//TODO (maybe) add Smooth stopping to Paddles
// case 40 : var i = 100;
// var interval = setInterval(function(){
// i--;
// leftV = i/100*(0,002-i/100);
// if(i == 0) clearInterval(interval);
// }, Math.round((1*delta)*60)*10);
setV(1, 0);
break;
case 87 :
case 83 : setV(2, 0); break;
}
}else if(pid == 1 || pid == 2){
switch(e.keyCode) {
case 38 :
case 87 : if(pid == 1){
setV(1, 0);
} else if(pid == 2) {
setV(2, 0);
}
break;
case 40 :
case 83 : if(pid == 1){
setV(1, 0);
} else if(pid == 2){
setV(2, 0);
}
break;
}
}
});
function setV(pos, val){
console.log(leftY);
if(pos == 1){
leftV = val;
if(!localcoop)
socket.emit('vchange', pos, val, leftY);
}
if(pos == 2){
rightV = val;
if(!localcoop)
socket.emit('vchange', pos, val, rightY);
}
}
function shootBall() {
/** TODO Tewak and Add MAX_Speed **/
if(ball_owner == 1)
ball_VX = ball_speed;
else if(ball_owner == 2)
ball_VX = -ball_speed;
ball_owner = 0;
}
function animloop() {
draw();
window.requestAnimationFrame(animloop);
}
animloop();
</script>
</body>
</html>