refactor: particle physics
This commit is contained in:
parent
308131449d
commit
aaba818802
|
@ -1,102 +0,0 @@
|
|||
import {Proton, TextNode} from '@avocado/graphics';
|
||||
|
||||
class DamageTextNode extends TextNode {
|
||||
|
||||
constructor(damage) {
|
||||
const {amount} = damage;
|
||||
super(amount);
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
sizeInPx() {
|
||||
const {amount} = this.damage;
|
||||
// Big numbers are literally big.
|
||||
if (amount > 999) {
|
||||
return 12;
|
||||
}
|
||||
else if (amount > 99) {
|
||||
return 10;
|
||||
}
|
||||
else if (amount > 9) {
|
||||
return 8;
|
||||
}
|
||||
else {
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
spanClassName() {
|
||||
const {damageSpec, isDamage} = this.damage;
|
||||
let className = super.spanClassName();
|
||||
className += ' affinity-' + damageSpec.affinity;
|
||||
if (isDamage) {
|
||||
className += ' is-damage';
|
||||
}
|
||||
else {
|
||||
className += ' is-healing';
|
||||
}
|
||||
return className;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export class DamageEmitter {
|
||||
|
||||
constructor() {
|
||||
const proton = new Proton();
|
||||
const emitter = new Proton.Emitter();
|
||||
proton.addEmitter(emitter);
|
||||
this.emitter = emitter;
|
||||
this.proton = proton;
|
||||
}
|
||||
|
||||
addRenderer(renderer) {
|
||||
this.renderer = renderer;
|
||||
this.proton.addRender(this.renderer);
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.proton.destroy();
|
||||
}
|
||||
|
||||
emit(position, damage) {
|
||||
// BUGS
|
||||
const pz = new Proton.PointZone();
|
||||
pz.x = position[0];
|
||||
pz.y = -position[1];
|
||||
const initializers = [
|
||||
new Proton.Body(new DamageTextNode(damage)),
|
||||
new Proton.Position(pz),
|
||||
new Proton.Mass(1),
|
||||
new Proton.Life(2),
|
||||
new Proton.Velocity(
|
||||
new Proton.Span(50, 90),
|
||||
new Proton.Vector3D(0, 5, 0),
|
||||
27.5
|
||||
),
|
||||
];
|
||||
// Heh, bugs.
|
||||
const rot = new Proton.Rotate(0, 0, 0);
|
||||
rot.a = new Proton.Span(-.006, .006);
|
||||
const behaviors = [
|
||||
new Proton.Alpha(1, .25),
|
||||
new Proton.Scale(.8, 1.2),
|
||||
new Proton.Force(0, -0.5, 0),
|
||||
rot,
|
||||
];
|
||||
this.emitter.createParticle(initializers, behaviors);
|
||||
}
|
||||
|
||||
hasParticles() {
|
||||
return this.particleCount > 0;
|
||||
}
|
||||
|
||||
get particleCount() {
|
||||
return this.emitter.particles.length;
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
this.proton.tick(elapsed);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +1,3 @@
|
|||
import * as I from 'immutable';
|
||||
|
||||
import {Trait} from '@avocado/entity';
|
||||
import {
|
||||
behaviorItemFromJSON,
|
||||
|
@ -8,16 +6,14 @@ import {
|
|||
Context,
|
||||
} from '@avocado/behavior';
|
||||
import {hasGraphics, TextNodeRenderer} from '@avocado/graphics';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {randomNumber, Vector} from '@avocado/math';
|
||||
|
||||
import {DamagePacket} from './damage.packet';
|
||||
import {DamageEmitter} from './emitter';
|
||||
|
||||
export class Vulnerable extends Trait {
|
||||
|
||||
static defaultParams() {
|
||||
const emitDamage = buildInvoke(['entity', 'emitParticle'], [
|
||||
'damage',
|
||||
const emitDamage = buildInvoke(['entity', 'emitDamageParticle'], [
|
||||
buildTraversal(['entity', 'position']),
|
||||
buildTraversal(['damage']),
|
||||
]);
|
||||
|
@ -45,9 +41,6 @@ export class Vulnerable extends Trait {
|
|||
this.damageId = 0;
|
||||
this.damageTickingPromises = [];
|
||||
this.damages = [];
|
||||
this._hasAddedEmitter = false;
|
||||
this._hasAddedEmitterRenderer = false;
|
||||
this._isHydrating = false;
|
||||
this._isInvulnerable = false;
|
||||
this.locks = new Map();
|
||||
this._tookDamageActions = behaviorItemFromJSON(
|
||||
|
@ -60,14 +53,6 @@ export class Vulnerable extends Trait {
|
|||
this.damageTickingPromises = [];
|
||||
}
|
||||
|
||||
hydrate() {
|
||||
if (AVOCADO_CLIENT) {
|
||||
this._isHydrating = true;
|
||||
this.addEmitter();
|
||||
this.addEmitterRenderer();
|
||||
}
|
||||
}
|
||||
|
||||
acceptDamage(damage) {
|
||||
const context = new Context({
|
||||
damage,
|
||||
|
@ -95,42 +80,28 @@ export class Vulnerable extends Trait {
|
|||
}
|
||||
}
|
||||
|
||||
addEmitter() {
|
||||
if (!this._isHydrating) {
|
||||
return;
|
||||
}
|
||||
if (this._hasAddedEmitter) {
|
||||
return;
|
||||
}
|
||||
if (!this.entity.is('emitter')) {
|
||||
return;
|
||||
}
|
||||
this.entity.addEmitter('damage', new DamageEmitter());
|
||||
this._hasAddedEmitter = true;
|
||||
}
|
||||
|
||||
addEmitterRenderer() {
|
||||
if (!this._isHydrating) {
|
||||
return;
|
||||
}
|
||||
if (this._hasAddedEmitterRenderer) {
|
||||
return;
|
||||
}
|
||||
if (!this.entity.is('emitter')) {
|
||||
return;
|
||||
}
|
||||
if (!this.entity.is('staged') || !this.entity.stage) {
|
||||
return;
|
||||
}
|
||||
const renderer = new TextNodeRenderer('.damage', this.entity.stage);
|
||||
this.entity.addEmitterRenderer('damage', renderer);
|
||||
this._hasAddedEmitterRenderer = true;
|
||||
}
|
||||
|
||||
cleanPackets() {
|
||||
this.damages = [];
|
||||
}
|
||||
|
||||
damageTextSize(amount) {
|
||||
const biggest = 16;
|
||||
const smallest = biggest / 2;
|
||||
const step = biggest / 6;
|
||||
if (amount > 999) {
|
||||
return biggest;
|
||||
}
|
||||
else if (amount > 99) {
|
||||
return smallest + (step * 2);
|
||||
}
|
||||
else if (amount > 9) {
|
||||
return smallest + step;
|
||||
}
|
||||
else {
|
||||
return smallest;
|
||||
}
|
||||
}
|
||||
|
||||
get isInvulnerable() {
|
||||
return this._isInvulnerable;
|
||||
}
|
||||
|
@ -152,10 +123,6 @@ export class Vulnerable extends Trait {
|
|||
this._isInvulnerable = isDying;
|
||||
},
|
||||
|
||||
stageChanged: () => {
|
||||
this.addEmitterRenderer();
|
||||
},
|
||||
|
||||
tookDamage: (damage) => {
|
||||
if (AVOCADO_SERVER) {
|
||||
this.damages.push(damage);
|
||||
|
@ -163,17 +130,75 @@ export class Vulnerable extends Trait {
|
|||
}
|
||||
},
|
||||
|
||||
traitsChanged: () => {
|
||||
this.addEmitter();
|
||||
this.addEmitterRenderer();
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
methods() {
|
||||
return {
|
||||
|
||||
emitDamageParticle: (position, damage) => {
|
||||
const {amount, damageSpec, isDamage} = damage;
|
||||
const fill = isDamage ? '#FF0000' : '#00FF77';
|
||||
|
||||
this.entity.emitParticleJson({
|
||||
traits: {
|
||||
darkened: {
|
||||
params: {
|
||||
isDarkened: false,
|
||||
},
|
||||
},
|
||||
emitted: {
|
||||
params: {
|
||||
alpha: {
|
||||
start: 1,
|
||||
end: 0,
|
||||
},
|
||||
force: [0, 1],
|
||||
velocity: [
|
||||
randomNumber(-0.5, 0.5),
|
||||
randomNumber(-1.25, -0.75)
|
||||
],
|
||||
position,
|
||||
rotation: {
|
||||
start: 0,
|
||||
add: {
|
||||
min: -0.5,
|
||||
max: 0.5,
|
||||
},
|
||||
},
|
||||
scale: {
|
||||
start: 1,
|
||||
end: 1.25,
|
||||
},
|
||||
},
|
||||
},
|
||||
existent: {},
|
||||
layered: {},
|
||||
listed: {},
|
||||
positioned: {},
|
||||
roomed: {},
|
||||
textual: {
|
||||
state: {
|
||||
text: amount,
|
||||
textStyle: {
|
||||
fill,
|
||||
fontFamily: 'joystix',
|
||||
fontSize: this.damageTextSize(amount),
|
||||
strokeThickness: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
visible: {
|
||||
state: {
|
||||
zIndex: 65535,
|
||||
}
|
||||
},
|
||||
},
|
||||
}).then((particle) => {
|
||||
this.entity.list.addEntity(particle);
|
||||
});
|
||||
},
|
||||
|
||||
takeDamageFrom: (entity) => {
|
||||
const damageSpecs = entity.damageSpecs;
|
||||
for (let i = 0; i < damageSpecs.length; ++i) {
|
||||
|
|
Loading…
Reference in New Issue
Block a user