Note: this code definitely needs cleaned up.
<head> <script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js"></script> <script type="text/javascript" async src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML"> </script> <script type="text/x-mathjax-config"> MathJax.Hub.Config({tex2jax: {inlineMath: [['$','$'], ['\\(','\\)']]}}); </script> <link rel="stylesheet" href="http://mirkwood.cs.edinboro.edu/~bennett/style/hw.css"> </head> <body> <h1>Rectangle Rectangle Collision</h1> <canvas id="squareMove" width="400" height="400" style="border:1px solid #000000;"></canvas> <script type="text/javascript" src="guy.js"></script> <script type="text/javascript" src="squareCode.js"></script> <script type="text/javascript"> canvas = document.getElementById("squareMove"); canvas.tabIndex = 0; canvas.addEventListener("keydown", MyHandler); let columns = new Squares("squareMove", 50, 30); let guy = new Guy("squareMove"); guy.Radius = 10; DrawScene("squareMove", columns, guy); </script> <p> Note: this code definitely needs cleaned up.
"use strict" class Guy { constructor(canvasName, x=0, y=0, r = 20) { this.canvas = document.getElementById(canvasName); this.ctx = canvas.getContext('2d'); this.xpos = x; this.ypos = y; this.radius = r; } get Pos() { return [this.xpos,this.ypos]; } get Radius() { return this.radius; } set Pos(p){ this.xpos = p[0]; this.ypos = p[1]; } set Radius(r){ this.radius = r; } Draw() { let cx, cy; this.ctx.beginPath(); this.ctx.fillStyle = "yellow"; this.ctx.arc(this.xpos, this.ypos, this.radius, 0 , 2*Math.PI); this.ctx.fill(); this.ctx.strokeStyle = "black"; this.ctx.arc(this.xpos, this.ypos, this.radius, 0 , 2*Math.PI); this.ctx.stroke(); } }
"use strict" class Squares { squares = []; all = []; constructor (canvasName, space = 10, count = 100, radius = 50) { this.canvas = document.getElementById(canvasName); this.ctx = canvas.getContext('2d'); let cWidth = this.canvas.width; let cHeight = this.canvas.height; this.count = count; this.minSpace = space; this.radius = radius; var i = 0; var attempt = 0; let x1, y1 let x2, y2; let w, h while (i < this.count && attempt < 1000) { // generate width and height first. w = Math.floor(Math.random()*(radius)); h = Math.floor(Math.random()*(radius)); // I want min dimension of at least 5. w = Math.max(w, 5); h = Math.max(h, 5); // then the position x1 = space + Math.floor(Math.random()*(cWidth - w - 2*space)); y1 = space + Math.floor(Math.random()*(cHeight -h - 2*space)); // other end positions x2 = x1 + w; y2 = y1 + h; if (this.Safe([x1-space,y1-space,x2+space,y2+space,w,h])) { this.squares.push([x1,y1,x2,y2,w,h]); i++; } else { attempt++; } } this.Display(); } get Radius() { return this.radius; } Display() { var i; for(i = 0; i< this.squares.length; i++) { this.ctx.beginPath(); this.ctx.fillStyle = "blue"; this.ctx.rect(this.squares[i][0], this.squares[i][1], this.squares[i][4], this.squares[i][5]); this.ctx.fill(); this.ctx.strokeStyle = "black"; this.ctx.rect(this.squares[i][0], this.squares[i][1], this.squares[i][4], this.squares[i][5]); this.ctx.stroke(); } return; } Between(small, large, pt){ return ( small <= pt && pt <= large); } Inside(x,y, a) { let x0 = a[0]; let y0 = a[1]; let x1 = a[2]; let y1 = a[3]; let insideX = this.Between(x0, x1, x); let insideY = this.Between(y0, y1, y); return (insideX && insideY); } PointInside(a,b) { let x0 = a[0]; let y0 = a[1]; let x1 = a[2]; let y1 = a[3]; // x0, y0 if (this.Inside(x0, y0, b)) { return true; } // x1, y0 if (this.Inside(x1, y0, b)) { return true; } // x0, y1 if (this.Inside(x0, y1, b)) { return true; } // x1, y1 if (this.Inside(x1,y1, b)) { return true; } return false; } Overlap(a,b){ let h1 = this.Between(a[0],a[2], b[0]) || this.Between(a[0],a[2],b[2]); let v1 = this.Between(b[1],b[3], a[1]) || this.Between(b[1],b[3],a[3]); return h1 && v1; } Collide(a,b){ let pointInside = this.PointInside(a,b) || this.PointInside(b,a); let overlap = this.Overlap(a,b) || this.Overlap(b,a); return pointInside || overlap; } Safe(ary) { let i; let ok = true; for(i = 0; i < this.squares.length; i++) { if ( this.Collide( ary, this.squares[i]) ) { ok = false; } } return ok; } Distance(x1, y1, x2, y2) { let dx = x1 - x2; let dy = y1 - y2; return Math.sqrt(dx*dx + dy*dy); } } function DrawScene(canvasName, circles, guy) { let canvas = document.getElementById(canvasName); let ctx = canvas.getContext('2d'); ctx.clearRect(0,0,canvas.width, canvas.height); circles.Display(); guy.Draw(); return; } function Crash(guy, boxes) { let guyRad = guy.Radius; let x1, y1, x2, y2; // find the bounding box "radius" let d = Math.floor(Math.sqrt(2)* guyRad); let pos = guy.Pos; // compute the edges of the bounding box. x1 = guy.Pos[0] - d; y1 = guy.Pos[1] - d; x2 = guy.Pos[0] + d; y2 = guy.Pos[1] + d; return !boxes.Safe([x1,y1,x2,y2]) } function MyHandler(evnt) { let pos; pos = guy.Pos; let x = pos[0]; let y = pos[1]; switch(evnt.key) { case 'w': case 'k': case "ArrowUp": pos[1]--; break; case 's': case 'j': case "ArrowDown": pos[1]++; break; case 'a': case 'h': case "ArrowLeft": pos[0]--; break; case 'd': case 'l': case "ArrowRight": pos[0]++; break; } guy.Pos = pos; if (Crash(guy, columns)) { guy.Pos = [x,y]; } else { DrawScene("squareMove", columns, guy); } return; }