Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add basic collision resolution #65

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions lib/systems/resolve-collisions.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
"use strict";

/**
* System that looks for an entity with the {@link Components.collisons}, {@link Components.velocity}, {@link Components.lastPosition}, {@link Components.position}, and {@link Components.size} components.
* Every frame the resolveCollisions system will check to see if any applicable entities are intersecting with an entity with the component {@link Components.body}, and if they are it will reset them to previous position either left, right, above, or below the other each other appropriately.
* @memberof Systems
* @alias resolveCollisions
* @requires Systems.lastPosition
* @see [addEach]{@link https://github.com/ericlathrop/entity-component-system#addeachsystem-search}
* @see [registerSearch]{@link https://github.com/ericlathrop/entity-component-system#registersearchsearch-components}
*/

function wasLeft(entityLastPosition, entitySize, otherPosition) {
return entityLastPosition.x + entitySize.width <= otherPosition.x;
}
function wasRight(entityLastPosition, otherPosition, otherSize) {
return entityLastPosition.x >= otherPosition.x + otherSize.width;
}
function wasAbove(entityLastPosition, entitySize, otherPosition) {
return entityLastPosition.y + entitySize.height <= otherPosition.y;
}
function wasBelow(entityLastPosition, otherPosition, otherSize) {
return entityLastPosition.y >= otherPosition.y + otherSize.height;
}

module.exports = function(ecs, game) { // eslint-disable-line no-unused-vars
game.entities.registerSearch("resolveCollisionsSearch", ["collisions","velocity","lastPosition","position","size"]);
ecs.addEach(function resolveCollisions(entity, elapsed) { // eslint-disable-line no-unused-vars
var entityCollisions = game.entities.get(entity, "collisions");
var entityPosition = game.entities.get(entity, "position");
var entitySize = game.entities.get(entity, "size");
var entityVelocity = game.entities.get(entity, "velocity");
var entityLastPosition = game.entities.get(entity, "lastPosition");

for (var i = 0; i < entityCollisions.length; i++) {
var other = entityCollisions[i];
if (game.entities.get(other, "body")) {
var otherPosition = game.entities.get(other, "position");
var otherSize = game.entities.get(other, "size");

if (wasLeft(entityLastPosition, entitySize, otherPosition)) {
entityPosition.x = otherPosition.x - entitySize.width;
entityVelocity.x = 0;
}
if (wasRight(entityLastPosition, otherPosition, otherSize)) {
entityPosition.x = otherPosition.x + otherSize.width;
entityVelocity.x = 0;
}
if (wasAbove(entityLastPosition, entitySize, otherPosition)) {
entityPosition.y = otherPosition.y - entitySize.height;
entityVelocity.y = 0;
}
if (wasBelow(entityLastPosition, otherPosition, otherSize)) {
entityPosition.y = otherPosition.y + otherSize.height;
entityVelocity.y = 0;
}
}
}
}, "resolveCollisionsSearch");

};
18 changes: 18 additions & 0 deletions lib/systems/track-last-position.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
"use strict";

/**
* System that looks for an entity with the {@link Components.collisions}, {@link Components.position}, and {@link Components.size} components.
* Every frame the trasckLastPosition system will store the current position in a temporary component named "lastPosition". This is required for using the system resolveCollisions.
* @memberof Systems
* @alias trackLastPosition
* @see [addEach]{@link https://github.com/ericlathrop/entity-component-system#addeachsystem-search}
* @see [registerSearch]{@link https://github.com/ericlathrop/entity-component-system#registersearchsearch-components}
*/

module.exports = function(ecs, game) { // eslint-disable-line no-unused-vars
game.entities.registerSearch("trackLastPositionSearch",["collisions", "position", "size"]);
ecs.addEach(function trackLastPosition(entity, elapsed) { // eslint-disable-line no-unused-vars
var position = game.entities.get(entity, "position");
game.entities.set(entity, "lastPosition", { x: position.x, y: position.y });
}, "trackLastPositionSearch");
};