feat: basic magnetism
This commit is contained in:
parent
766e6b3e0c
commit
2eb97d2723
84
common/traits/magnetic.trait.js
Normal file
84
common/traits/magnetic.trait.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
import {behaviorItemFromJSON, createContext} from '@avocado/behavior';
|
||||||
|
import {compose, Property} from '@avocado/core';
|
||||||
|
import {StateProperty, Trait} from '@avocado/entity';
|
||||||
|
import {Rectangle, Vector} from '@avocado/math';
|
||||||
|
|
||||||
|
import {TraitPlantPacket} from './trait-plant.packet';
|
||||||
|
|
||||||
|
const decorate = compose(
|
||||||
|
StateProperty('attraction', {
|
||||||
|
track: true,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
export class Magnetic extends decorate(Trait) {
|
||||||
|
|
||||||
|
static defaultParams() {
|
||||||
|
return {
|
||||||
|
isAttractor: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static defaultState() {
|
||||||
|
return {
|
||||||
|
attraction: 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static type() {
|
||||||
|
return 'magnetic';
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(entity, params, state) {
|
||||||
|
super(entity, params, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
get isAttracted() {
|
||||||
|
return !this.params.isAttractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
get isAttractor() {
|
||||||
|
return !!this.params.isAttractor;
|
||||||
|
}
|
||||||
|
|
||||||
|
tick(elapsed) {
|
||||||
|
if (!this.params.isAttractor) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const attraction = this.entity.attraction;
|
||||||
|
if (0 === attraction) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const layer = this.entity.layer;
|
||||||
|
if (!layer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const query = Rectangle.compose(
|
||||||
|
Vector.sub(this.entity.position, [32, 32]),
|
||||||
|
[64, 64],
|
||||||
|
);
|
||||||
|
const entities = layer.visibleEntities(query);
|
||||||
|
for (let i = 0; i < entities.length; ++i) {
|
||||||
|
const entity = entities[i];
|
||||||
|
if (!entity.is('magnetic') || !entity.isAttracted) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!entity.is('positioned') || !entity.is('mobile')) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const distance = Vector.distance(
|
||||||
|
this.entity.position,
|
||||||
|
entity.position,
|
||||||
|
);
|
||||||
|
if (distance > attraction) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const difference = Vector.sub(this.entity.position, entity.position);
|
||||||
|
const unit = Vector.normalize(difference);
|
||||||
|
const rdiff = 1 - (distance / attraction);
|
||||||
|
const magnitude = 50 * rdiff;
|
||||||
|
entity.applyMovement(Vector.scale(unit, magnitude));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -47,6 +47,11 @@ export function createEntityForConnection(socket) {
|
||||||
informed: {},
|
informed: {},
|
||||||
layered: {},
|
layered: {},
|
||||||
listed: {},
|
listed: {},
|
||||||
|
magnetic: {
|
||||||
|
params: {
|
||||||
|
isAttractor: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
mobile: {
|
mobile: {
|
||||||
state: {
|
state: {
|
||||||
speed: 100,
|
speed: 100,
|
||||||
|
|
|
@ -61,12 +61,15 @@ export function kittyFireJSON() {
|
||||||
roomJSON.layers[0].entities.push(positionedEntityJSON(uri, position));
|
roomJSON.layers[0].entities.push(positionedEntityJSON(uri, position));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (let i = 0; i < 20; ++i) {
|
||||||
|
addEntityWithRandomPosition('/rock.entity.json');
|
||||||
|
}
|
||||||
// for (let i = 0; i < 20; ++i) {
|
// for (let i = 0; i < 20; ++i) {
|
||||||
// addEntityWithRandomPosition('/flower-barrel.entity.json');
|
// addEntityWithRandomPosition('/flower-barrel.entity.json');
|
||||||
// }
|
// }
|
||||||
for (let i = 0; i < 3; ++i) {
|
// for (let i = 0; i < 3; ++i) {
|
||||||
addEntityWithRandomPosition('/mama-kitty-spawner.entity.json');
|
// addEntityWithRandomPosition('/mama-kitty-spawner.entity.json');
|
||||||
}
|
// }
|
||||||
// for (let i = 0; i < 5; ++i) {
|
// for (let i = 0; i < 5; ++i) {
|
||||||
// addEntityWithRandomPosition('/fire.entity.json');
|
// addEntityWithRandomPosition('/fire.entity.json');
|
||||||
// }
|
// }
|
||||||
|
|
|
@ -30,6 +30,11 @@ export function rockJSON() {
|
||||||
);
|
);
|
||||||
return {
|
return {
|
||||||
traits: {
|
traits: {
|
||||||
|
collider: {
|
||||||
|
params: {
|
||||||
|
isSensor: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
existent: {
|
existent: {
|
||||||
state: {
|
state: {
|
||||||
name: 'Rock',
|
name: 'Rock',
|
||||||
|
@ -51,6 +56,33 @@ export function rockJSON() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
layered: {},
|
||||||
|
listed: {},
|
||||||
|
magnetic: {},
|
||||||
|
mobile: {},
|
||||||
|
physical: {},
|
||||||
|
pictured: {
|
||||||
|
params: {
|
||||||
|
images: {
|
||||||
|
initial: {
|
||||||
|
offset: [0, 0],
|
||||||
|
size: [12, 12], // Derive?
|
||||||
|
uri: '/rock.png',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
positioned: {},
|
||||||
|
roomed: {},
|
||||||
|
shaped: {
|
||||||
|
params: {
|
||||||
|
shape: {
|
||||||
|
type: 'rectangle',
|
||||||
|
position: [0, 0],
|
||||||
|
size: [12, 12],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
spawner: {
|
spawner: {
|
||||||
params: {
|
params: {
|
||||||
spawns: {
|
spawns: {
|
||||||
|
@ -59,7 +91,8 @@ export function rockJSON() {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
},
|
||||||
|
visible: {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user