Skip to content

Commit

Permalink
feat(collision-detection): move to web worker
Browse files Browse the repository at this point in the history
  • Loading branch information
Niklas Kiefer committed Mar 22, 2019
1 parent 8ac52da commit f7f2e9a
Show file tree
Hide file tree
Showing 8 changed files with 211 additions and 130 deletions.
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
dist/
node_modules/
lib/jquery/
lib/threadify
coverage/
1 change: 1 addition & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"no-trailing-spaces": ["error", { "skipBlankLines": true }],
"padded-blocks": ["error", "always"],
"no-unused-vars": 0,
"new-cap": 0,
"no-console": "error",
"no-only-tests/no-only-tests": 2
},
Expand Down
57 changes: 0 additions & 57 deletions lib/canvas/canvas.js
Original file line number Diff line number Diff line change
Expand Up @@ -220,63 +220,6 @@ class Canvas {

}

/**
* checks collision between obstacles and bird object
*/
collisionDetection () {

let birdShape = this.bird.shape;
let obstacles = this.obstacles;
let birdWidth = birdShape.x + birdShape.width;

const _hitAction = () => {

if (typeof this.onClear === 'function') {

this.onClear();

}

};

obstacles.forEach(obstacle => {

let obstacleShape = obstacle.shape;
let obstacleHeight = obstacleShape.y + obstacleShape.height;
let obstacleWidth = obstacleShape.x + obstacleShape.width;

if (
(birdShape.x >= obstacleShape.x && birdWidth <= obstacleWidth) ||
(birdWidth >= obstacleShape.x && birdWidth <= obstacleWidth) ||
(birdShape.x === obstacleWidth) ||
(birdShape.x === obstacleShape.x) ||
(birdWidth === obstacleWidth)
) {

if (obstacleShape.y === 0) { // check upper obstacle

if (birdShape.y <= obstacleHeight) {

_hitAction();

}

} else { // check lower obstacle

if (birdShape.y + birdShape.height >= obstacleShape.y) {

_hitAction();

}

}

}

});

}

/**
* completely deletes canvas and all its shapes
*/
Expand Down
87 changes: 87 additions & 0 deletions lib/collision-detection/collisionDetection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@

/* global threadify */
class CollisionDetection {

/**
* @param {Bird} options.bird
* @param {Array<Obstacle>} options.obstacle
*/
static collisionDetection ({ bird, obstacles }) {

const thread = this;

let birdWidth = bird.x + bird.width;

obstacles.forEach(obstacle => {

let obstacleHeight = obstacle.y + obstacle.height;
let obstacleWidth = obstacle.x + obstacle.width;

if (
(bird.x >= obstacle.x && birdWidth <= obstacleWidth) ||
(birdWidth >= obstacle.x && birdWidth <= obstacleWidth) ||
(bird.x === obstacleWidth) ||
(bird.x === obstacle.x) ||
(birdWidth === obstacleWidth)
) {

if (obstacle.y === 0) { // check upper obstacle

if (bird.y <= obstacleHeight) {

thread.return(true);

}

} else { // check lower obstacle

if (bird.y + bird.height >= obstacle.y) {

thread.return(true);

}

}

}

});

thread.return(false);

}

static wrapped (canvas) {

// cleanup objects for later use
const bird = {
x: canvas.bird.shape.x,
y: canvas.bird.shape.y,
width: canvas.bird.shape.width,
height: canvas.bird.shape.height
};

const obstacles = canvas.obstacles.map(o => {

return {
x: o.shape.x,
y: o.shape.y,
width: o.shape.width,
height: o.shape.height
};

});

const wrappedFn = threadify(this.collisionDetection);

return {
collisionDetection: wrappedFn,
collideCheckObject: {
bird,
obstacles
}
};

}

}
21 changes: 19 additions & 2 deletions lib/main/main.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/* global Canvas, Footer, KeyboardHandler */
/* global Canvas, Footer, KeyboardHandler, CollisionDetection */
let mrflap, canvas, bird;

function appendFooter () {
Expand Down Expand Up @@ -93,7 +93,24 @@ function spawnObstacles () {
setInterval(() => {

canvas.moveObstacles();
canvas.collisionDetection();

// execute collision detection inside web worker
const {
collisionDetection,
collideCheckObject
} = CollisionDetection.wrapped(canvas);

const job = collisionDetection(collideCheckObject);

job.done = (isCollided) => {

if (isCollided) {

canvas.onClear();

}

};

}, 1000 / 30);

Expand Down
1 change: 1 addition & 0 deletions lib/threadify/threadify.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

71 changes: 0 additions & 71 deletions test/canvas/canvasSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -176,75 +176,4 @@ describe('Canvas', function () {

});

describe('#collisionDetection', function () {

let canvas, bird, hitSpy;

beforeEach(function () {

hitSpy = sinon.spy();

canvas = new Canvas({
mrflapDiv: mrflapDiv,
onClear: hitSpy
});

bird = canvas.drawBird();

});

it('should hit lower obstacle', function () {

// given
const {
obstacleBottom
} = canvas.drawObstacle({
heightBottom: 50
});

// when
for (let i = 0; i < 110; i++) {

canvas.moveObstacles();

}

canvas.collisionDetection();

// then
expect(hitSpy).to.have.been.called;

});

it('should hit upper obstacle', function () {

// given
const {
obstacleTop
} = canvas.drawObstacle({
heightBottom: 50
});

bird.moveUp({
speed: 100
});

const originalX = obstacleTop.x;

// when
for (let i = 0; i < 110; i++) {

canvas.moveObstacles();

}

canvas.collisionDetection();

// then
expect(hitSpy).to.have.been.called;

});

});

});
102 changes: 102 additions & 0 deletions test/collision-detection/collisionDetectionSpec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* global it, describe, expect, beforeEach, __html__, Canvas, sinon, CollisionDetection */
/* eslint-disable no-unused-expressions */
describe('CollisionDetection', function () {

let mrflapDiv;

const _initPlayground = function () {

$('body').append('<div class="mrflap-playground"></div>');

};

beforeEach(function () {

document.body.innerHTML = __html__['test.html'];
_initPlayground();
mrflapDiv = $('.mrflap-playground');

});
describe.only('#collisionDetection', function () {

let canvas, bird;

beforeEach(function () {

canvas = new Canvas({
mrflapDiv: mrflapDiv
});

bird = canvas.drawBird();

});

it('should hit lower obstacle', function () {

// given
canvas.drawObstacle({
heightBottom: 50
});

// when
for (let i = 0; i < 110; i++) {

canvas.moveObstacles();

}

// when
const {
collisionDetection,
collideCheckObject
} = CollisionDetection.wrapped(canvas);

const job = collisionDetection(collideCheckObject);

job.done = (isCollided) => {

// then
expect(isCollided).to.be.true;

};

});

it('should hit upper obstacle', function () {

// given
canvas.drawObstacle({
heightBottom: 50
});

bird.moveUp({
speed: 100
});

// when
for (let i = 0; i < 110; i++) {

canvas.moveObstacles();

}

// when
const {
collisionDetection,
collideCheckObject
} = CollisionDetection.wrapped(canvas);

const job = collisionDetection(collideCheckObject);

job.done = (isCollided) => {

// then
expect(isCollided).to.be.true;

};

});

});

});

0 comments on commit f7f2e9a

Please sign in to comment.