From aaba81880219c4241f3015a24c2674f9812e2414 Mon Sep 17 00:00:00 2001 From: cha0s Date: Sun, 3 Nov 2019 10:43:05 -0600 Subject: [PATCH] refactor: particle physics --- common/combat/emitter.js | 102 --------------------- common/combat/vulnerable.trait.js | 141 ++++++++++++++++++------------ 2 files changed, 83 insertions(+), 160 deletions(-) delete mode 100644 common/combat/emitter.js diff --git a/common/combat/emitter.js b/common/combat/emitter.js deleted file mode 100644 index c71d206..0000000 --- a/common/combat/emitter.js +++ /dev/null @@ -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); - } - -} diff --git a/common/combat/vulnerable.trait.js b/common/combat/vulnerable.trait.js index 68abd54..b19f7bb 100644 --- a/common/combat/vulnerable.trait.js +++ b/common/combat/vulnerable.trait.js @@ -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) {