-Pretty close to done. I want to do all input management in the same separate file (incl. mobile &c). Should be nice to compartmentalize that way. I don't need to do all that much for the input, just do key handling, and also try to get an easy touch overlay down.
+OKAY
+
+have an intro page, and then let the 'play' page I already have up be the whole thing.
+
+I should check referrers, so that if someone links to/goes straight to the 'play' page they get sent back to the page beforehand. Also, this lets me make the 'play' page the whole webapp, which makes for very easy reverse proxy load balancing shenanigans. Plus this kinda enforces a pleasant splash page with directions and whatever.
+
+At this point it's cleaning and polish. I also /need/ to get the out-of-bounds detection going much better. I think a simple algorithm that just detects the inside of a (convex) polygon (or distance to one) will be good enough, as that's really all there is to this game (and yes, it is always convex).
+
+Writing this on a plane, so most of this work will be left for later I guess. I can do some nice error checking and game ending and so forth now.
+
+Oh shit, I have to figure out how to count how many games are ongoing. I'll just use a global variable? Or did I want to do player connections? Actually a global for current games might be pretty reasonable.
state.id = i;
this.players[i].send_data(JSON.stringify(state));
}
+
+ // check for life and death
+ var dead_ids = state.dead.map(d => d.id);
+ if(dead_ids.length == state.n-1) {
+ // game over! tell everyone and end the cycle
+ clearInterval(this.timeout);
+ var sum = dead_ids.reduce((x,y) => x+y);
+ var winner = state.n*(state.n-1)/2 - sum; // note the minus is bc we start at zero yeah?
+ for(var i=0; i<this.players.length;i++) {
+ var tosend = (i==winner) ? 'w' : 'l';
+ this.players[i].send_data(tosend); // w for winner, l for loser cuz why not?
+ }
+ }
}
const Paddle = require('./paddles.js');
const collisions = require('./collisions.js');
-function Dead(id) {
+function Dead(id, pl) {
this.id = id;
+ this.place = pl;
this.time = c.DYING_TIME_IN_FRAMES;
}
if((ab > a1) && (ab < a2)) {
// check if not already dead (in case multi balls out at same time etc)
if(!this.dead.some(x => x.id == ang.id)) {
- this.dead.push(new Dead(ang.id));
+ var place = this.numPlayers - this.dead.length;
+ this.dead.push(new Dead(ang.id, place));
/* TODO: socket cleanup for dead player */
}
}
var thedead = this.dead;
var totnum = this.numPlayers;
var theobject = {n: totnum, dead: thedead, paddles: newpads, balls: newballs};
+ // maybe a proper constructor would be good here...
return theobject;
}
-
+// oh can I just trash this? yeah totally todo
function nearest_point_on_line(c, ep) {
// finds the point on the line defined by ep closest to center c
if(ep.f.x == ep.s.x) {
pcolor = 'rgb(0,0,200)';
bcolor = 'rgb(100,100,100)';
xcolor = 'rgb(200,0,200)';
+playercolor = 'rgb(0,100,200)';
+var latest_theta = 0;
+
// main function, given everything from the game state, draws on the given context
var draw = function(state, ctx) {
clearCanvas(ctx);
-
+
// okay, gotta get the endpoints, then draw the walls,
// then draw the balls,
// then finally the hard part is the paddles
- //console.log(state);
var endpoints = genAllEndpoints(state.n, state.dead);
+
+ // set rotation
+ // check for dead first
+ var isDead = state.dead.some(d => d.id==state.id);
+ if(!isDead) {
+ var rot_ep = endpoints.find(e => e.id == state.id); // has to have smth right? yeah if alive i guess?
+ var rot_mp = new Coord((rot_ep.f.x+rot_ep.s.x)/2, (rot_ep.f.y+rot_ep.s.y)/2);
+ var rot_th = Math.atan2(rot_mp.y, rot_mp.x) + Math.PI;
+ latest_theta = rot_th;
+ }
+ ctx.transform(Math.cos(latest_theta),-Math.sin(latest_theta),Math.sin(latest_theta),Math.cos(latest_theta),0,0) // this is to rotate it so that the player paddle is in the right place
+
var livingzones = endpoints.filter(e => (e.id != -1) && (!state.dead.some(d=>(d.id==e.id))));
var walls = endpoints.filter(e => (e.id==-1) || state.dead.some(d=>(d.id==e.id)));
//draw walls
var pps = getPaddlePoints(paddle, eps);
drawLine(ctx, pcolor, pps.f, pps.s);
}
+ if(isDead) {
+ drawOverlay(ctx, state.dead.find(d => d.id == state.id).place);
+ }
}
ctx.stroke();
ctx.restore();
}
+
+var drawOverlay = function(ctx, place) {
+
+}
+
var clearCanvas = function(ctx) {
ctx.save();
function keypressHandler(evt, isdn) {
// "is down" (is a keydown)
var thekey = 'x';
- if(evt.keyCode == '87') // 'w'
+ // small but significant note: everything here is rotated by a half circle, so everything is upside-down
+ if(evt.keyCode == '83') // 's'
thekey = 'u';
- else if(evt.keyCode == '83') // 's'
+ else if(evt.keyCode == '87') // 'w'
thekey = 'd';
if(!isdn && thekey==keystate) {
}
}
+
+function touchHandler(evt) {
+ // deals with touch events on the canvas, todo when I can get my hands on documentation lol
+}
+
+
+
+
function keySender(ws) {
if(keystate != 'x')
ws.send(keystate);
-var prefixurl = "ws://localhost:6789";
+const prefixurl = "ws://localhost:6789";
-theSocket = null;
+var theSocket = null;
+var is_dead = false;
var module = {};
// change the 1's to zoom in i think.. todo
ctx.setTransform(10, 0, 0, 10, ctx.canvas.width/2, ctx.canvas.height/2); // change to setTransform?
ctx.lineWidth = ctx.lineWidth/5;
+ if(e.data == "w") {
+ console.log("winner");
+ return;
+ }
+ else if(e.data == "l") {
+ console.log("loser");
+ return;
+ }
+ var state = JSON.parse(e.data);
- draw(JSON.parse(e.data), ctx);
+ if(!is_dead) {
+ // check for deadness
+
+ var status = state.dead.some(e => e.id == state.id);
+ if(status) {
+ // add event listener if dead
+ canvas.onclick = function(e) {location.reload()} // okay, outside of 'input' file...
+ }
+ }
+
+ draw(state, ctx);
}
document.onkeydown = function(e) {keypressHandler(e, true);};
<script type="text/javascript" src="endpoints.js"></script>
<script type="text/javascript" src="input.js"></script>
<style type="text/css">
- body { background-color: black; }
+ body { background-color: blue; }
#c {
width: 100%;
height: 100%;
border: 1px solid red;
+ background-color: black;
}
</style>
</head>