From: Elijah Cohen Date: Fri, 3 May 2019 17:34:09 +0000 (-0500) Subject: COLLISIONS WORK? I'M ALMOST DONE? X-Git-Url: https://git.eli173.com/?a=commitdiff_plain;h=48c27ecb8bda16fc008c7d0b6e057d7441f68268;p=pong_br COLLISIONS WORK? I'M ALMOST DONE? todo is now get things properly sent for paddles, work on mobile and stuff, and robots. cool --- diff --git a/.gitignore b/.gitignore index 2a43901..18810e9 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,4 @@ server/node_modules/* /web/main.js~ /web/play.html~ /server/collisions.js~ +/server/matrix.js~ diff --git a/server/collisions.js b/server/collisions.js index 324d2a9..d360766 100644 --- a/server/collisions.js +++ b/server/collisions.js @@ -4,6 +4,10 @@ const Coord = require('./coord.js'); const Endpoints = require('./endpoints.js'); // i guess slightly useful here +const Matrix = require('./matrix.js'); + +const Vec = Coord; // hah + /* * okay, game plan: * we look at line segments: the segments from the endpoints, @@ -13,24 +17,6 @@ const Endpoints = require('./endpoints.js'); // i guess slightly useful here * dunno if that part is good or not. i suspect it's okay */ -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) { - // vertical line, undef slope - return new Coord(ep.f.x, c.y); - } - if(ep.f.y == ep.s.y) { - // horizontal line, zero slope - return new Coord(c.x, ep.f.y); - } - var sl = (ep.f.y-ep.s.y)/(ep.f.x-ep.s.x); - var sr = 1/sl; - var x_int = (sl*ep.f.x - sr*c.x + c.y - ep.f.y)/(sl-sr); - var y_int = sr*(x_int-c.x) + c.y; - return new Coord(x_int, y_int); -} - - var segments_intersect = function(e1, e2) { // takes 2 sets of endpoints for the segments // variables for easier reference, thinking @@ -62,6 +48,12 @@ var segments_intersect = function(e1, e2) { } +Vec.prototype.normalize = function(vec) { + var mag = Math.sqrt(this.x**2 + this.y**2); + this.x = this.x/mag; + this.y = this.y/mag; +} + var handleWalls = function(ball, walls) { // returns true if there's a collision // modifies ball's velocity if it encounters an actual collision @@ -70,27 +62,20 @@ var handleWalls = function(ball, walls) { var next_spot = new Coord(ball.coord.x + ball.dx/c.FPS, ball.coord.y + ball.dy/c.FPS); // the next spot if(segments_intersect(wall, new Endpoints(ball.coord, next_spot))) { //there's a collision - var wall_normal = new Coord((wall.f.x+wall.s.x)/2, (wall.f.y+wall.s.y)/2); // given by the midpoint - var normal_angle = Math.atan2(wall_normal.x, wall_normal.y); - // okay, i understand now, gotta do translations as well as the rotations - // vector for next_spot needs to rotate, then be translated so that current ball spot is taken away, - // putting vector with tail at the origin. then i do the reflection, and translate back, then rotate back, - // and i might be good from there - var ball_spot = new Coord(ball.coord.x, ball.coord.y); - console.log("-------------------------------------"); - console.log(next_spot); - ball_spot.rotate(-normal_angle); - next_spot.rotate(-normal_angle); - console.log(next_spot); - next_spot.translate(-ball_spot.x, -ball_spot.y); // now it's a vector with tail at the origin i think - console.log(next_spot); - next_spot.x = -next_spot.x; // next translate back then rotate back then done? - next_spot.translate(ball_spot.x, ball_spot.y); - ball_spot.rotate(normal_angle); - next_spot.rotate(normal_angle); // nope gotta subtract back to get it to be a proper - next_spot.translate(-ball_spot.x, -ball_spot.y); // now i'm good i think - ball.dx = next_spot.x; - ball.dy = next_spot.y; + var wall_normal = new Vec((wall.f.x+wall.s.x)/2, (wall.f.y+wall.s.y)/2); // given by the midpoint + wall_normal.normalize(); + var wall_parallel = new Vec(wall.s.x - wall.f.x, wall.s.y - wall.f.y); + wall_parallel.normalize(); + // there's our basis vectors + var vel = new Vec(ball.dx, ball.dy); + var tr_mat = new Matrix(wall_parallel.x, wall_parallel.y, wall_normal.x, wall_normal.y); + var vel_in_basis = tr_mat.vmul(vel); + // now in the basis this is easy, I just swap the right variable, then transform back, and reassign! + // the x-coord is along the wall, y is along the normal i think, sooo... + vel_in_basis.y = -vel_in_basis.y; + vel = tr_mat.inverse().vmul(vel_in_basis); + ball.dx = vel.x; + ball.dy = vel.y; ball.speed_up(); return true; } @@ -110,22 +95,28 @@ var handlePaddles = function(ball, lzs, paddles) { } var wall = paddle.getPaddlePoints(lz); // - var next_spot = new Coord(ball.coord.x + ball.dx/c.FPS, ball.coord.y + ball.dy/c.FPS); + var next_spot = new Coord(ball.coord.x + ball.dx/c.FPS, ball.coord.y + ball.dy/c.FPS); // the next spot if(segments_intersect(wall, new Endpoints(ball.coord, next_spot))) { //there's a collision - var wall_normal = new Coord((wall.f.x+wall.s.x)/2, (wall.f.y+wall.s.y)/2); // given by the midpoint - var normal_angle = Math.atan2(wall_normal.x, wall_normal.y); - // okay, i understand now. I have to do the vector addition and translation thing - var vel_vec = new Coord(ball.dx, ball.dy); - vel_vec.rotate(-normal_angle); - vel_vec.x = -vel_vec.x; // i'm fairly certain it's x... + var wall_normal = new Vec((wall.f.x+wall.s.x)/2, (wall.f.y+wall.s.y)/2); // given by the midpoint + wall_normal.normalize(); + var wall_parallel = new Vec(wall.s.x - wall.f.x, wall.s.y - wall.f.y); + wall_parallel.normalize(); + // there's our basis vectors + var vel = new Vec(ball.dx, ball.dy); + var tr_mat = new Matrix(wall_parallel.x, wall_parallel.y, wall_normal.x, wall_normal.y); + var vel_in_basis = tr_mat.vmul(vel); + // now in the basis this is easy, I just swap the right variable, then transform back, and reassign! + // the x-coord is along the wall, y is along the normal i think, sooo... + vel_in_basis.y = -vel_in_basis.y; + // do the paddle bonus here too if(paddle.direction == 'u') - vel_vec.y += c.PADDLE_MVT_BONUS; + vel_in_basis.x += c.PADDLE_MVT_BONUS; else if(paddle.direction == 'd') - vel_vec.y -= c.PADDLE_MVT_BONUS; - vel_vec.rotate(normal_angle); - ball.dx = vel_vec.x; - ball.dy = vel_vec.y; + vel_in_basis.x -= c.PADDLE_MVT_BONUS; + vel = tr_mat.inverse().vmul(vel_in_basis); + ball.dx = vel.x; + ball.dy = vel.y; ball.speed_up(); return true; } diff --git a/server/matrix.js b/server/matrix.js new file mode 100644 index 0000000..f7cc19a --- /dev/null +++ b/server/matrix.js @@ -0,0 +1,29 @@ + +const Vec = require('./coord.js'); + +var Matrix = function(a,b,c,d) { + this.a = a; + this.b = b; + this.c = c; + this.d = d; +} + +Matrix.prototype.inverse = function() { + var recip = 1/(this.a*this.d-this.b*this.c); + return new Matrix(this.d*recip, -this.b*recip, -this.c*recip, this.a*recip); +} + +Matrix.prototype.mmul = function(m) { + var a = this.a*m.a + this.b*m.c; + var b = this.a*m.b + this.b*m.d; + var c = this.c*m.a + this.d*m.c; + var d = this.c*m.b + this.d*m.d; + return new Matrix(a,b,c,d); +} +Matrix.prototype.vmul = function(v) { + var x = this.a*v.x + this.b*v.y; + var y = this.c*v.x + this.d*v.y; + return new Vec(x,y); +} + +module.exports= Matrix;