]> git.eli173.com Git - pong_br/commitdiff
potentially done with drawing code? untested
authorElijah Cohen <eli@eli173.com>
Mon, 29 Apr 2019 23:07:43 +0000 (18:07 -0500)
committerElijah Cohen <eli@eli173.com>
Mon, 29 Apr 2019 23:07:43 +0000 (18:07 -0500)
.gitignore
server/gamestate.js
web/constants.js [new file with mode: 0644]
web/coord.js [new file with mode: 0644]
web/draw.js [new file with mode: 0644]
web/drawing.js [deleted file]
web/endpoints.js [new file with mode: 0644]
web/field.js [new file with mode: 0644]
web/main.js [new file with mode: 0644]
web/play.html [new file with mode: 0644]

index 5bb3fe9dfbd80d6162240eb141dcc1094c4d969c..40198b0957accba40be3826a84a6983da9b70b8a 100644 (file)
@@ -29,3 +29,9 @@ server/node_modules/*
 /server/coord.js~
 /server/endpoints.js~
 /server/constants.js~
+/web/field.js~
+/web/endpoints.js~
+/web/coord.js~
+/web/draw.js~
+/web/main.js~
+/web/play.html~
index a9225c47dfd1211678e7414a6b191fd3a72fc7b5..5648bee4d3b69fd4ed3cd9069aa68d07e79ba7a3 100644 (file)
@@ -164,7 +164,9 @@ GameState.prototype.getState = function() {
     // dead don't need changing, all info is necessary
     var newballs = this.balls.map(b => b.reduce());
     var newpads = this.paddles.map(p => p.reduce());
-    var theobject = {dead: this.dead, paddles: newpads, balls: newballs};
+    var thedead = this.dead;
+    var totnum = this.numPlayers;
+    var theobject = {n: totnum, dead: thedead, paddles: newpads, balls: newballs};
     return theobject;
 }
 
diff --git a/web/constants.js b/web/constants.js
new file mode 100644 (file)
index 0000000..b67c956
--- /dev/null
@@ -0,0 +1,29 @@
+
+
+var c = {
+    // matchmaker
+    WS_PORT: 6789,
+    NUM_PLAYERS: 3,
+    MS_PER_FRAME: 500,
+    WAIT_TIME: 60000, // 1 minute
+    MAX_GAMES: 5, // the most games allowed to go on at once, to be tweaked as needed for purposes
+    // gamestate
+    DYING_TIME_IN_FRAMES: 100,
+    BOARD_RADIUS: 10,
+    OOB_THRESH: 1, // out-of-bounds threshold
+    ANGLE_THRESH: 0.2, //radians, needs to acct for various rotatings going on... can prolly wing it
+    PADDLE_MVT_BONUS: 0.1, // why this value? who knows. the extra speed from paddles in motion
+    // ball
+    MIN_INIT: 3,
+    MAX_INIT: 5, // initial speed constraints
+    BALL_RADIUS: 0.5,
+    MAX_SPEED: 15,
+    SPEED_BUMP: 0.2,
+    // field
+    BOARD_RADIUS: 10, // completely arbitrary actually...
+    // paddle
+    DPADDLE: 0.1,
+    WIDTH_RATIO: 0.1, // paddle is 1/10th of gap rn
+}
+
+
diff --git a/web/coord.js b/web/coord.js
new file mode 100644 (file)
index 0000000..0d4a6c5
--- /dev/null
@@ -0,0 +1,25 @@
+
+
+
+
+
+var Coord = function(x,y) {
+    this.x = x;
+    this.y = y;
+}
+
+
+Coord.prototype.dist2 = function(c2) {
+    // returns square of the distance
+    var dx = this.x-c2.x;
+    var dy = this.y-c2.y;
+    return dx*dx + dy*dy;
+}
+
+Coord.prototype.rotate = function(th) {
+    // rotates about angle, returns new value
+    var new_x = this.x*Math.cos(th) - this.y*Math.sin(th);
+    var new_y = this.x*Math.sin(th) + this.y*Math.cos(th);
+    this.x = new_x;
+    this.y = new_y;
+}
diff --git a/web/draw.js b/web/draw.js
new file mode 100644 (file)
index 0000000..5de5506
--- /dev/null
@@ -0,0 +1,92 @@
+
+
+// contains the routines needed to actually get the stuff drawn
+
+dwallcolor = 'rgb(200,0,0)';
+wallcolor = 'rgb(100,100,0)';
+pcolor = 'rgb(0,0,200)';
+bcolor = 'rgb(100,100,100)';
+
+
+// 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
+    var theEndpoints = genEndpoints(state.n, state.dead);
+    var negatives = endpointNegatives(theEndpoints);
+
+    // dead walls
+    for(var ep of theEndpoints) {
+       var deadOption = state.dead.find(d => (d.id==ep.id));
+       if((deadOption !== undefined) && (deadOption.time > 0)) {
+           drawLine(ctx, dwallcolor, ep.f, ep.s);
+       }
+    }
+    // walls
+    for(var ep of negatives) {
+       drawLine(ctx, wallcolor, ep.f, ep.s);
+    }
+    // balls
+    for(var b of state.balls) {
+       drawBall(ctx, bcolor, b);
+    }
+    // finally the paddles...
+    for(var ep of endpoints) {
+       var paddleOption = state.paddles.find(p => (p.id == ep.id));
+       if(paddleOption !== undefined) {
+           // should probably make sure it's not dead?
+           if(!state.dead.some(d => (d.id == ep.id))) {
+               var pps = getPaddlePoints(paddleOption, ep);
+               drawLine(ctx, pcolor, pps.f, pps.s);
+           }
+       }
+    }
+}
+
+var getPaddlePoints = function(paddle, enclosing) {
+    // returns an endpoints object for the paddle
+    // given the desired width of said paddle and the enclosing endpoints
+    var encl_len = dist(enclosing.f, enclosing.s);
+    var pspace_len = encl_len - (2*c.WIDTH_RATIO*encl_len);
+    var place_on_pspace = pspace_len*(paddle.position+1)/2;
+    var above_f = pspace_len + c.WIDTH_RATIO;  // distance above the first enclosing point (takes advantage of the increasing in angle thing to determine orientations)
+    var overall_proportion = above_f/encl_len;
+    var vector = [enclosing.s.x-enclosing.f.x, enclosing.s.y-enclosing.f.y];
+    var d = overall_proportion-c.WIDTH_RATIO;
+    var first = new Coord(vector[0]*d, vector[1]*d);
+    d = overall_proportion+c.WIDTH_RATIO;
+    var second = new Coord(vector[0]*d, vector[1]*d);
+    return new Endpoints(first, second, paddle.id);
+}
+
+
+
+var drawBall(ctx, color, c) {
+    ctx.save();
+    ctx.fillStyle = bcolor;
+    ctx.beginPath();
+    ctx.arc(c.x, c.y, BALL_RADIUS, 0, 2*Math.PI, false);
+    ctx.fill();
+    ctx.restore();
+}
+
+var drawLine(ctx, color, c1, c2) {
+    // draws a line from c1 to c2 in color
+    ctx.save();
+    ctx.strokeStyle = color;
+    ctx.beginPath();
+    ctx.moveTo(c1.x, c1.y);
+    ctx.lineTo(c2.x, c2.y);
+    ctx.closePath();
+    ctx.stroke();
+    ctx.restore();
+}
+
+var clearCanvas = function(ctx) {
+    ctx.save();
+    ctx.transform(1,0,0,1,0,0);
+    ctx.clearRect(0,0,cxt.canvas.width, ctx.canvas.height);
+    ctx.restore();
+}
diff --git a/web/drawing.js b/web/drawing.js
deleted file mode 100644 (file)
index 7af6248..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-function drawngon(n,r) {
-    var cvs = document.getElementById('game');
-    var ctx = cvs.getContext('2d');
-    var angleper = 2*Math.PI/n;
-    var center = {x:cvs.width/2, y:cvs.height/2};
-
-    ctx.beginPath();
-    ctx.moveTo(center.x+r, center.y);
-    var start = {x: center.x+r, y:center.y};
-    for(var i=1; i<n; i++) {
-       var next = rotate(start, center, angleper*i);
-       ctx.lineTo(next.x, next.y);
-    }
-    ctx.closePath();
-    ctx.stroke();
-}
-
-
-function rotate(p,c,t) {
-    // rotates p around c by t
-    var d = {x:p.x-c.x, y:p.y-c.y};
-    var r = {x:d.x*Math.cos(t)-d.y*Math.sin(t), y:d.x*Math.sin(t)+d.y*Math.cos(t)};
-    var f = {x:r.x+c.x, y:r.y+c.y};
-    return f;
-}
diff --git a/web/endpoints.js b/web/endpoints.js
new file mode 100644 (file)
index 0000000..4df3ed4
--- /dev/null
@@ -0,0 +1,12 @@
+
+
+var Endpoints = function(f,s,id) {
+    // f,s are first, second coordinates, in increasing angle
+    // id corresponds to a player, or -1 or smth if n/a
+    // these endpoints enclose a paddle
+    this.f = f;
+    this.s = s;
+    this.id = id;
+}
+
+
diff --git a/web/field.js b/web/field.js
new file mode 100644 (file)
index 0000000..b6e2910
--- /dev/null
@@ -0,0 +1,90 @@
+
+// for generating/using the actual playing field of the game, I guess it'll be newly generated on each frame? the math is simple enough...
+
+
+
+var genEndpoints = function(n ,dead) {
+    /**
+       /* takes the number of players total (that the game started with, should be NUM_PLAYERS),
+       /* and the array of the dead and dying
+       /* does id's in a bad but expectable way
+    */
+    // so i'll start from a radius out a zero radians
+    var endpoints = [];
+    var players_length = n - dead.length;
+    for(var d of dead) {
+       players_length += d.time/c.DYING_TIME_IN_FRAMES;
+    }
+    var theta = 0;
+    var dtheta = players_length/(2*Math.PI);
+    var coord = new Coord(c.BOARD_RADIUS,0);
+    for(var i=0; i<n; i++) {
+       var deadStatus = dead.find(e=>(e.id==i));
+       if((deadStatus !== undefined) && (deadStatus.time > 0)) {
+           var r = c.BOARD_RADIUS;
+           theta += (deadStatus.time/c.DYING_TIME_IN_FRAMES)/2;
+           var pt1 = new Coord(r*Math.cos(theta), r*Math.sin(theta));
+           theta += (deadStatus.time/c.DYING_TIME_IN_FRAMES)/2;
+           var pt2 = new Coord(r*Math.cos(theta), r*Math.sin(theta));
+           endpoints.push(new Endpoints(pt1, pt2, n));
+       }
+       else {
+           theta += dtheta/2;
+           var pt1 = new Coord(r*Math.cos(theta), r*Math.sin(theta));
+           theta += dtheta/2;
+           var pt2 = new Coord(r*Math.cos(theta), r*Math.sin(theta));
+           endpoints.push(new Endpoints(pt1, pt2, n));
+       }
+    }
+    return endpoints;
+}
+
+var endpointNegatives = function(endpoints) {
+    // generates the opposite of genEndpoints
+    // i.e. genEndpoints gives the spaces where the paddles live,
+    // and this gives the endpoints enclosing walls
+    var newpoints = [];
+    newpoints.push(new Endpoints(endpoints[endpoints.length-1].s, endpoints[0].f,  -1));
+    for(var i=1;i<endpoints.length;i++) {
+       newpoints.push(new Endpoints(endpoints[i-1].s, endpoints[i].f, -1));
+    }
+    return newpoints;
+}
+
+var AnglePair = function(f,s,id) {
+    this.f = f;
+    this.s = s;
+    this.id = id;
+}
+var angles = function(n, dead, thresh) {
+    // gives angle pairs for the thresholds and whatnot.
+    var angs = [];
+    var players_length = n - dead.length;
+    for(var d of dead) {
+       players_length += d.time/c.DYING_TIME_IN_FRAMES;
+    }
+    var theta = 0;
+    var dtheta = players_length/(2*Math.PI);
+    var coord = new Coord(c.BOARD_RADIUS,0);
+    for(var i=0; i<n; i++) {
+       var deadStatus = dead.find(e=>(e.id==i));
+       if((deadStatus !== undefined) && (deadStatus.time > 0)) {
+           var r = c.BOARD_RADIUS;
+           theta += (deadStatus.time/c.DYING_TIME_IN_FRAMES)/2;
+           var t1 = theta;
+           theta += (deadStatus.time/c.DYING_TIME_IN_FRAMES)/2;
+           var t2 = theta
+           angs.push(new AnglePair(t1, t2, n));
+       }
+       else {
+           theta += dtheta/2;
+           var t1 = theta;
+           theta += dtheta/2;
+           var t2 = theta;
+           angs.push(new AnglePair(t1, t2, n));
+       }
+    }
+    return angs;
+}
+
+module.exports = {angles: angles, genEndpoints: genEndpoints, endpointNegatives: endpointNegatives};
diff --git a/web/main.js b/web/main.js
new file mode 100644 (file)
index 0000000..8fc137d
--- /dev/null
@@ -0,0 +1,27 @@
+
+var prefixurl = "ws://localhost:6789";
+
+theSocket = null;
+
+
+var main = function() { // starts everything, gets us going, setup ish
+    var canvas = document.getElementById('c');
+    if(!canvas.getContext) {
+       alert("Sorry, this game requires support for the <canvas> element");
+       return;
+    }
+    canvas.width = window.innerWidth;
+    canvas.height = window.innerHeight;
+    ctx = canvas.getContext('2d');
+    // change the 1's to zoom in i think.. todo
+    ctx.transform(1, 0, 0, 1, ctx.width/2, ctx.height/2);
+
+    
+    theSocket = new WebSocket(prefixurl);
+    theSocket.onmessage = function(e) {
+       draw(JSON.parse(e.data), ctx);
+    }
+}
+
+
+window.addEventListener("DOMContentLoaded", e => main());
diff --git a/web/play.html b/web/play.html
new file mode 100644 (file)
index 0000000..9adec06
--- /dev/null
@@ -0,0 +1,21 @@
+<!doctype html>
+<html>
+  <head>
+    <title>Pong Battle Royale</title>
+    <script type="text/javascript" src="main.js"></script>
+    <script type="text/javascript" src="draw.js"></script>
+    <script type="text/javascript" src="coord.js"></script>
+    <script type="text/javascript" src="constants.js"></script>
+    <style type="text/css">
+      body { background-color: black; }
+      #c {
+         width: 100%;
+         height: 100%;
+         border: 1px solid red;
+      }
+    </style>
+  </head>
+  <body>
+    <canvas id="c">Sorry, you need to have Javascript enabled for this!</canvas>
+  </body>
+</html>