feat: Collider

This commit is contained in:
cha0s 2019-04-08 16:20:28 -04:00
parent 8bdd0f27b6
commit b227b69855
3 changed files with 89 additions and 0 deletions

View File

@ -0,0 +1,51 @@
import {compose} from '@avocado/core';
import {StateProperty, Trait} from '../trait';
const decorate = compose(
StateProperty('isCheckingCollisions'),
);
export class Collider extends decorate(Trait) {
static defaultParams() {
return {
collidesWithGroups: [
'default',
],
collisionGroup: 'default',
}
}
static defaultState() {
return {
isCheckingCollisions: true,
}
}
initialize() {
this._collisionGroup = this.params.get('collisionGroup');
this._collidesWithGroups = this.params.get('collidesWithGroups').toJS();
}
get collisionGroup() {
return this._collisionGroup;
}
get collidesWithGroups() {
return this._collidesWithGroups;
}
methods() {
return {
collidesWith: (entity) => {
if (!entity.is('collider')) {
return false;
}
const collisionGroup = entity.collisionGroup();
return -1 !== this._collidesWithGroups.indexOf(collisionGroup);
},
};
}
}

View File

@ -39,6 +39,7 @@ export class Physical extends decorate(Trait) {
if (world) {
const body = world.createBody(this.entity.shape);
world.associateBodyWithEntity(body, this.entity);
body.setCollisionForEntity(this.entity);
world.addBody(body);
this._body = body;
if (this.entity.container) {

View File

@ -8,6 +8,20 @@ import { Rectangle } from '../../math';
export class Body extends AbstractBody {
static collisionCategory(group) {
if (!('filterCategoryBit' in this)) {
this.filterCategoryBit = 0;
}
if (!('filterCategories' in this)) {
this.filterCategories = {};
}
if (!this.filterCategories[group]) {
this.filterCategories[group] = 1 << this.filterCategoryBit;
this.filterCategoryBit += 1;
}
return this.filterCategories[group];
}
static lookupBody(matterBody) {
if (this.bodies) {
return this.bodies.get(matterBody);
@ -98,6 +112,29 @@ export class Body extends AbstractBody {
});
}
setCollision(category, mask, group = 0) {
MatterBody.set(this.matterBody, 'collisionFilter', {
category,
group,
mask,
});
}
setCollisionForEntity(entity) {
if (entity.is('collider')) {
const ctor = this.constructor;
const category = ctor.collisionCategory(entity.collisionGroup);
let mask = 0;
for (const group of entity.collidesWithGroups) {
mask = mask | ctor.collisionCategory(group);
}
this.setCollision(category, mask);
}
else {
this.setCollision(0, 0, -1);
}
}
get static() {
return this.matterBody.isStatic;
}