Collision Detect with Polygon & Rect
The blue polygon can be moved and transformed by using the following keys below. Red shapes are can be solid and cannot be passed. Yellow shapes are opaque.
- ArrowKeys - Moves the polygon
- Q - Rotates the polygon
- R - Increases the polygon size
- F - Decreases the polygon size
- C - Resets the polygon
Creating the PolygonObject
constructor(options={}) { options.isMovable = true; options.movementRate = 0.25, super(options); this._shape = new hamonengine.geometry.polygon(); this._shape.addVertex(0, 0); this._shape.addVertex(75, 0); this._shape.addVertex(100, 75/2); this._shape.addVertex(75, 75); this._shape.addVertex(0, 75); this._polygonRotation = 0; this._polygonScale = 1.0; this._rotateHold = 0; this._scaleDirection = 0; this._scaleHoldDown = 0; this._transformedShape = this._shape; }
Creating the Polygons
constructor(options={}) { super(options); //Our main, movable shape. this._object = new hamonengine.demos.actors.polygonObject(); //Create the shape and add the vertices. this._shape3 = new hamonengine.geometry.polygon(); this._shape3.addVertex(0, 0); this._shape3.addVertex(75, 75); this._shape3.addVertex(0, 75); //Create the shape and add the vertices. this._shape2Position = new hamonengine.math.vector2(160, 150); this._shape2 = this._shape3.translate(this._shape2Position); this._rectPosition = new hamonengine.math.vector2(400, 100); this._rect = new hamonengine.geometry.rect(400, 100, 100, 100); }
Rendering the Polygons
renderBasics1(screen, elapsedTimeInMilliseconds) { screen.beginPainting(); screen.drawPolygon(this._shape2, 0, 0, {lineWidth: 1, color: 'red'}); screen.drawPolygon(this._shape3, 300, 25, {lineWidth: 1, color: 'yellow', fill: true, fillColor: 'yellow'}); screen.drawRect(this._rect, 0, 0, {lineWidth: 1, color: 'red'}); this._object.process(screen, elapsedTimeInMilliseconds, [ { shape: this._rect, position: this._rectPosition }, { shape: this._shape2, position: this._shape2Position } ]); //Render the polygon at the specific position that has a line width of 3px and the color is blue with no normals drawn. //The final parameter determines if normals are drawn. this._object.render(screen, elapsedTimeInMilliseconds); screen.endPainting(); }
Collision Detection Logic
process(screen, elapsedTimeInMilliseconds, otherShapes) { //Handle rotation & scale. this._polygonRotation = ((this._polygonRotation + (this._rotateHold * elapsedTimeInMilliseconds / 1000 * Math.PI / 4)) % Math.PI2); this._polygonScale = (this._polygonScale + (this._scaleDirection * elapsedTimeInMilliseconds / 1000 * 0.10)); //Precalculate the movement vector and update it with any collision information. let movementVector = this.calcMove(elapsedTimeInMilliseconds); //Perform the actual rotation & scaling and cache it for rendering. this._transformedShape = this._shape.scale(new hamonengine.math.vector2(this._polygonScale, this._polygonScale)) .rotateAtCenter(this._polygonRotation) .translate(this.position.add(movementVector)); //Handle collisions detection with otherShapes. let hasCollisions = false; let collisionCount = 0; do { //Make note if we have a collision. hasCollisions = false; for (let i = 0; i < otherShapes.length; i++) { //Determine if this shape has collided with another. const mtv = this._transformedShape.isCollision(otherShapes[i].shape); if (mtv.length > 0) { //Determine the position of the two shapes and correct the direction of the MTV based on the position of the two shapes. let distance = otherShapes[i].position.subtract(this.position); if (mtv.dot(distance) >= 0) { mtv = mtv.invert(); } //Adjust the movement vector and shape. movementVector = movementVector.add(mtv); this._transformedShape = this._transformedShape.translate(mtv); hasCollisions = true; } } //If a collision has occurred then we need to recalculate the collision detection again between the shapes. //The MTV generated by one object may force one object to clip into another one, so another round of collision detection is needed. } while (hasCollisions && collisionCount++ <= hamonengine.core.collisionDetection.limit); this.move(elapsedTimeInMilliseconds, movementVector); }