feat: collision scripts
This commit is contained in:
parent
86a3367efa
commit
30033fd8e4
|
@ -11,7 +11,7 @@ export default function createEcs(Ecs) {
|
|||
'PlantGrowth',
|
||||
'FollowCamera',
|
||||
'VisibleAabbs',
|
||||
'Collliders',
|
||||
'Colliders',
|
||||
'ControlDirection',
|
||||
'SpriteDirection',
|
||||
'RunAnimations',
|
||||
|
|
|
@ -5,7 +5,7 @@ export default async function createHomestead(Ecs) {
|
|||
const area = {x: 100, y: 60};
|
||||
await ecs.create({
|
||||
AreaSize: {x: area.x * 16, y: area.y * 16},
|
||||
Engine: {},
|
||||
Ticking: {},
|
||||
TileLayers: {
|
||||
layers: [
|
||||
{
|
||||
|
@ -19,6 +19,17 @@ export default async function createHomestead(Ecs) {
|
|||
Water: {water: {}},
|
||||
});
|
||||
await ecs.create({
|
||||
Collider: {
|
||||
bodies: [
|
||||
[
|
||||
{x: -36, y: -16},
|
||||
{x: -21, y: -16},
|
||||
{x: -36, y: -1},
|
||||
{x: -21, y: -1},
|
||||
],
|
||||
],
|
||||
collisionStartScript: '/assets/shit-shack/collision-start.js',
|
||||
},
|
||||
Position: {x: 100, y: 100},
|
||||
Sprite: {
|
||||
anchor: {x: 0.5, y: 0.8},
|
||||
|
|
21
app/create-house.js
Normal file
21
app/create-house.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import createEcs from './create-ecs.js';
|
||||
|
||||
export default async function createHouse(Ecs) {
|
||||
const ecs = createEcs(Ecs);
|
||||
const area = {x: 20, y: 20};
|
||||
await ecs.create({
|
||||
AreaSize: {x: area.x * 16, y: area.y * 16},
|
||||
Ticking: {},
|
||||
TileLayers: {
|
||||
layers: [
|
||||
{
|
||||
area,
|
||||
data: Array(area.x * area.y).fill(0).map(() => 5 + Math.floor(Math.random() * 2)),
|
||||
source: '/assets/tileset.json',
|
||||
tileSize: {x: 16, y: 16},
|
||||
}
|
||||
],
|
||||
},
|
||||
});
|
||||
return ecs;
|
||||
}
|
|
@ -1,6 +1,16 @@
|
|||
export default async function createPlayer(id) {
|
||||
const player = {
|
||||
Camera: {},
|
||||
Collider: {
|
||||
bodies: [
|
||||
[
|
||||
{x: -8, y: -8},
|
||||
{x: 7, y: -8},
|
||||
{x: -8, y: 7},
|
||||
{x: 7, y: 7},
|
||||
],
|
||||
],
|
||||
},
|
||||
Controlled: {},
|
||||
Direction: {direction: 2},
|
||||
Ecs: {path: ['homesteads', `${id}`].join('/')},
|
||||
|
@ -28,7 +38,7 @@ export default async function createPlayer(id) {
|
|||
},
|
||||
},
|
||||
Health: {health: 100},
|
||||
Position: {x: 368, y: 368},
|
||||
Position: {x: 128, y: 128},
|
||||
Speed: {speed: 100},
|
||||
Sound: {},
|
||||
Sprite: {
|
||||
|
|
|
@ -7,6 +7,7 @@ export default class Collider extends Component {
|
|||
instanceFromSchema() {
|
||||
const {ecs} = this;
|
||||
return class ColliderInstance extends super.instanceFromSchema() {
|
||||
collidingWith = {};
|
||||
isCollidingWith(other) {
|
||||
const {aabb, aabbs} = this;
|
||||
const {aabb: otherAabb, aabbs: otherAabbs} = other;
|
||||
|
@ -63,6 +64,26 @@ export default class Collider extends Component {
|
|||
}
|
||||
}
|
||||
}
|
||||
async load(instance) {
|
||||
// heavy handed...
|
||||
if ('undefined' !== typeof window) {
|
||||
return;
|
||||
}
|
||||
instance.collisionEndScriptInstance = await this.ecs.readScript(
|
||||
instance.collisionEndScript,
|
||||
{
|
||||
ecs: this.ecs,
|
||||
entity: this.ecs.get(instance.entity),
|
||||
},
|
||||
);
|
||||
instance.collisionStartScriptInstance = await this.ecs.readScript(
|
||||
instance.collisionStartScript,
|
||||
{
|
||||
ecs: this.ecs,
|
||||
entity: this.ecs.get(instance.entity),
|
||||
},
|
||||
);
|
||||
}
|
||||
static properties = {
|
||||
bodies: {
|
||||
type: 'array',
|
||||
|
@ -71,5 +92,7 @@ export default class Collider extends Component {
|
|||
subtype: vector2d('int16'),
|
||||
},
|
||||
},
|
||||
collisionEndScript: {type: 'string'},
|
||||
collisionStartScript: {type: 'string'},
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
import Component from '@/ecs/component.js';
|
||||
|
||||
export default class Engine extends Component {}
|
|
@ -39,6 +39,7 @@ export default class Colliders extends System {
|
|||
}
|
||||
|
||||
tick() {
|
||||
const {Ticking} = this.ecs.get(1);
|
||||
const seen = {};
|
||||
for (const entity of this.ecs.changed(['Position'])) {
|
||||
if (seen[entity.id]) {
|
||||
|
@ -48,6 +49,8 @@ export default class Colliders extends System {
|
|||
if (!entity.Collider) {
|
||||
continue;
|
||||
}
|
||||
const {collidingWith: wasCollidingWith} = entity.Collider;
|
||||
entity.Collider.collidingWith = {};
|
||||
this.updateHash(entity);
|
||||
for (const other of this.within(entity.Collider.aabb)) {
|
||||
if (seen[other.id]) {
|
||||
|
@ -57,8 +60,33 @@ export default class Colliders extends System {
|
|||
if (!other.Collider) {
|
||||
continue;
|
||||
}
|
||||
delete other.Collider.collidingWith[entity.id];
|
||||
if (entity.Collider.isCollidingWith(other.Collider)) {
|
||||
console.log('collide', entity, other);
|
||||
entity.Collider.collidingWith[other.id] = true;
|
||||
other.Collider.collidingWith[entity.id] = true;
|
||||
if (!wasCollidingWith[other.id]) {
|
||||
if (entity.Collider.collisionStartScriptInstance) {
|
||||
entity.Collider.collisionStartScriptInstance.context.other = other;
|
||||
Ticking.addTickingPromise(entity.Collider.collisionStartScriptInstance.tickingPromise());
|
||||
}
|
||||
if (other.Collider.collisionStartScriptInstance) {
|
||||
other.Collider.collisionStartScriptInstance.context.other = entity;
|
||||
Ticking.addTickingPromise(other.Collider.collisionStartScriptInstance.tickingPromise());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const otherId in wasCollidingWith) {
|
||||
if (!entity.Collider.collidingWith[otherId]) {
|
||||
const other = this.ecs.get(otherId);
|
||||
if (entity.Collider.collisionEndScriptInstance) {
|
||||
entity.Collider.collisionEndScriptInstance.context.other = other;
|
||||
Ticking.addTickingPromise(entity.Collider.collisionEndScriptInstance.tickingPromise());
|
||||
}
|
||||
if (other.Collider.collisionEndScriptInstance) {
|
||||
other.Collider.collisionEndScriptInstance.context.other = entity;
|
||||
Ticking.addTickingPromise(other.Collider.collisionEndScriptInstance.tickingPromise());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import Script from '@/util/script.js';
|
|||
|
||||
import createEcs from './create-ecs.js';
|
||||
import createHomestead from './create-homestead.js';
|
||||
import createHouse from './create-house.js';
|
||||
import createPlayer from './create-player.js';
|
||||
|
||||
export default class Engine {
|
||||
|
@ -42,6 +43,9 @@ export default class Engine {
|
|||
return chars.byteLength > 0 ? JSON.parse((new TextDecoder()).decode(chars)) : {};
|
||||
}
|
||||
async readScript(uri, context) {
|
||||
if (!uri) {
|
||||
return undefined;
|
||||
}
|
||||
const code = await this.readAsset(uri);
|
||||
if (code.byteLength > 0) {
|
||||
return Script.fromCode((new TextDecoder()).decode(code), context);
|
||||
|
@ -160,6 +164,10 @@ export default class Engine {
|
|||
['homesteads', `${id}`].join('/'),
|
||||
await createHomestead(this.Ecs),
|
||||
);
|
||||
await this.saveEcs(
|
||||
['houses', `${id}`].join('/'),
|
||||
await createHouse(this.Ecs),
|
||||
);
|
||||
buffer = await createPlayer(id);
|
||||
await this.server.writeData(
|
||||
['players', `${id}`].join('/'),
|
||||
|
|
1
public/assets/shit-shack/collision-start.js
Normal file
1
public/assets/shit-shack/collision-start.js
Normal file
|
@ -0,0 +1 @@
|
|||
console.log("I'ma warp yo azz")
|
Loading…
Reference in New Issue
Block a user