Bug fixes to engine across all HWs, event data for tweens

This commit is contained in:
ZGrandison 2022-03-31 19:03:21 -04:00
parent 82699642ca
commit b901612c3c
6 changed files with 96 additions and 83 deletions

View File

@ -24,7 +24,6 @@ export default class GoapActionPlanner {
//Build tree from 0 to 1 //Build tree from 0 to 1
this.buildTree(0, goal, possibleActions, currentStatus); this.buildTree(0, goal, possibleActions, currentStatus);
console.log(this.graph.toString());
//Run djikstra to find shortest path //Run djikstra to find shortest path
this.path = GraphUtils.djikstra(this.graph, 0); this.path = GraphUtils.djikstra(this.graph, 0);
@ -34,7 +33,6 @@ export default class GoapActionPlanner {
let i = 1; let i = 1;
while(this.path[i] !== -1){ while(this.path[i] !== -1){
console.log(this.path[i]);
if (this.path[i] !== 0){ if (this.path[i] !== 0){
plan.push(<GoapAction>this.mapping.get(this.path[i])); plan.push(<GoapAction>this.mapping.get(this.path[i]));
} }
@ -47,9 +45,6 @@ export default class GoapActionPlanner {
buildTree(root: number, goal:string, possibleActions: Array<GoapAction>, currentStatus: Array<string>): void { buildTree(root: number, goal:string, possibleActions: Array<GoapAction>, currentStatus: Array<string>): void {
//For each possible action //For each possible action
possibleActions.forEach(action => { possibleActions.forEach(action => {
console.log("root:" + root + ",action precons:" + action.preconditions.toString()
+ ", action effects:" + action.effects.toString() + ", current Status:" + currentStatus.toString())
//Can it be performed? //Can it be performed?
if (action.checkPreconditions(currentStatus)){ if (action.checkPreconditions(currentStatus)){
//This action can be performed //This action can be performed
@ -59,7 +54,6 @@ export default class GoapActionPlanner {
//Check if the new node is the goal //Check if the new node is the goal
if (newStatus.includes(goal)){ if (newStatus.includes(goal)){
console.log("AT GOAL");
let newNode = this.graph.addNode() - 1; let newNode = this.graph.addNode() - 1;
this.mapping.set(newNode, action); this.mapping.set(newNode, action);
this.graph.addEdge(root, newNode, action.cost); this.graph.addEdge(root, newNode, action.cost);
@ -73,7 +67,6 @@ export default class GoapActionPlanner {
this.graph.addEdge(root, newNode, action.cost); this.graph.addEdge(root, newNode, action.cost);
//Recursive call //Recursive call
console.log(possibleActions.indexOf(action))
let newActions = possibleActions.filter(act => act !== action) let newActions = possibleActions.filter(act => act !== action)
this.buildTree(newNode, goal, newActions, action.effects); this.buildTree(newNode, goal, newActions, action.effects);
} }

View File

@ -86,8 +86,8 @@ export default class OrthogonalTilemap extends Tilemap {
let row = Math.floor(index / this.numCols); let row = Math.floor(index / this.numCols);
// Get the world position // Get the world position
let x = col * this.tileSize.x; let x = col * this.tileSize.x * this.scale.x;
let y = row * this.tileSize.y; let y = row * this.tileSize.y * this.scale.y;
return new Vec2(x, y); return new Vec2(x, y);
} }

View File

@ -264,7 +264,7 @@ export default class BasicPhysicsManager extends PhysicsManager {
// Also check for triggers // Also check for triggers
for(let overlap of overlaps){ for(let overlap of overlaps){
// Check for a trigger. If we care about the trigger, react // Check for a trigger. If we care about the trigger, react
if(overlap.other.isTrigger && (overlap.other.triggerMask & node.group)){ if(overlap.other.isTrigger && (overlap.other.triggerMask & node.group) && node.group != -1){
// Get the bit that this group is represented by // Get the bit that this group is represented by
let index = Math.floor(Math.log2(node.group)); let index = Math.floor(Math.log2(node.group));

View File

@ -49,6 +49,9 @@ export class TweenData {
loop: boolean; loop: boolean;
/** The name of the event to send (if any) when the tween finishes playing */ /** The name of the event to send (if any) when the tween finishes playing */
onEnd: string onEnd: string
/** Extra data to be sent when the onEnd event is fired. Keys with the name 'key' or 'node' are reserved and can't be used as names for your extra data */
onEndData: Record<string, any>;
// Members for management by the tween manager // Members for management by the tween manager
/** The progress of this tween through its effects */ /** The progress of this tween through its effects */

View File

@ -6,65 +6,97 @@ import Scene from "../../Scene/Scene";
import Timer from "../../Timing/Timer"; import Timer from "../../Timing/Timer";
import Color from "../../Utils/Color"; import Color from "../../Utils/Color";
import { EaseFunctionType } from "../../Utils/EaseFunctions"; import { EaseFunctionType } from "../../Utils/EaseFunctions";
import MathUtils from "../../Utils/MathUtils";
import RandUtils from "../../Utils/RandUtils"; import RandUtils from "../../Utils/RandUtils";
import ParticleSystemManager from "./ParticleSystemManager"; import ParticleSystemManager from "./ParticleSystemManager";
/*
-Move particle system to HW#4, particle class and particle manager(object pool), source, randomized period of decay,
semi-randomized approach for spawning, should be general purpose
and load some settings from a json (location, states, colors, randomization).
Should be effect when balloon is popped
*/
export default class ParticleSystem implements Updateable { export default class ParticleSystem implements Updateable {
/** Pool for all particles */
protected particlePool: Array<Particle>; protected particlePool: Array<Particle>;
/** Lifetime for each particle */
protected lifetime: number; protected lifetime: number;
protected liveParticles: number;
protected maxLiveParticles: number;
protected sourcePoint: Vec2; protected sourcePoint: Vec2;
protected particleSize: Vec2; protected particleSize: Vec2;
/** Timer for how long a particle system lasts before being turned off */
protected systemLifetime: Timer; protected systemLifetime: Timer;
protected systemRunning: boolean; protected systemRunning: boolean;
protected color: Color = new Color(255, 0, 0); protected color: Color = new Color(255, 0, 0);
constructor(poolSize: number, sourcePoint: Vec2, lifetime: number, size: number, maxParticles: number) { /** Particles that can be rendered per frame */
protected particlesPerFrame: number;
/** Total number of particles to render, this will be incremented overtime by particlesPerFrame */
protected particlesToRender: number;
protected particleMass: number;
/**
* Construct a particle system
*
* @param poolSize The pool size, i.e the total number of particles that will be created
* @param sourcePoint The initial source point each particle will start at when the system is running, can be changed
* @param lifetime Lifetime of each particle before they are set inactive
* @param size Size of each particle
* @param mass Initial mass of each particle, can be changed
* @param maxParticlesPerFrame Total number of particles that can be created during a given frame.
*/
constructor(poolSize: number, sourcePoint: Vec2, lifetime: number, size: number, mass: number, maxParticlesPerFrame: number) {
this.particlePool = new Array(poolSize); this.particlePool = new Array(poolSize);
this.sourcePoint = sourcePoint; this.sourcePoint = sourcePoint;
this.lifetime = lifetime; this.lifetime = lifetime;
this.particleSize = new Vec2(size, size); this.particleSize = new Vec2(size, size);
this.maxLiveParticles = maxParticles;
this.systemRunning = false; this.systemRunning = false;
this.particlesPerFrame = maxParticlesPerFrame;
this.particlesToRender = this.particlesPerFrame;
this.particleMass = mass;
ParticleSystemManager.getInstance().registerParticleSystem(this); ParticleSystemManager.getInstance().registerParticleSystem(this);
} }
initalizePool(scene: Scene, layer: string, type: ParticleSystemType, mass: number) { /** Initialize the pool of all particles, creating the assets in advance */
initializePool(scene: Scene, layer: string) {
for (let i = 0; i < this.particlePool.length; i++) { for (let i = 0; i < this.particlePool.length; i++) {
this.particlePool[i] = <Particle>scene.add.graphic(GraphicType.PARTICLE, layer, this.particlePool[i] = <Particle>scene.add.graphic(GraphicType.PARTICLE, layer,
{ position: this.sourcePoint.clone(), size: this.particleSize.clone(), mass: mass }); { position: this.sourcePoint.clone(), size: this.particleSize.clone(), mass: this.particleMass });
this.particlePool[i].addPhysics(); this.particlePool[i].addPhysics();
this.particlePool[i].isCollidable = false; this.particlePool[i].isCollidable = false;
this.particlePool[i].visible = false; this.particlePool[i].visible = false;
} }
} }
startSystem(time: number, startPoint?: Vec2) { /**
* Start up the particle system to run for a set amount of time
* @param time Time for the particle systme to run
* @param mass Optional change of mass for each particle
* @param startPoint Optional change of start position for each particle
*/
startSystem(time: number, mass?: number, startPoint?: Vec2) {
//Stop the system to reset all particles
this.stopSystem();
//Set the timer
this.systemLifetime = new Timer(time); this.systemLifetime = new Timer(time);
//Update optional parameters
if (mass !== undefined)
this.particleMass = mass;
if (startPoint !== undefined)
this.sourcePoint = startPoint;
//Start the timer, set flags, and give the initial amount of particles to render
this.systemLifetime.start(); this.systemLifetime.start();
this.systemRunning = true; this.systemRunning = true;
this.sourcePoint = startPoint; this.particlesToRender = this.particlesPerFrame;
} }
stopSystem() { stopSystem() {
console.log(this);
this.systemRunning = false; this.systemRunning = false;
for (let particle of this.particlePool) { for (let particle of this.particlePool) {
if (particle.inUse) { if (particle.inUse) {
@ -77,15 +109,35 @@ export default class ParticleSystem implements Updateable {
this.color = color; this.color = color;
} }
/**
* Default implementation of setParticleAnimation, no tween animations occur, but each particle is given a random
* velocity. It's encouraged for you to override this function and implement your own tween animations.
*
* @param particle
*/
setParticleAnimation(particle: Particle) {
particle.vel = RandUtils.randVec(-50, 50, -100, 100);
particle.tweens.add("active", {
startDelay: 0,
duration: this.lifetime,
effects: []
});
}
update(deltaT: number) { update(deltaT: number) {
// Exit if the system isn't currently running
if (!this.systemRunning) { if (!this.systemRunning) {
return; return;
} }
// Stop the system if our timer is up
if (this.systemLifetime.isStopped()) { if (this.systemLifetime.isStopped()) {
this.stopSystem(); this.stopSystem();
} }
else { else {
for (let particle of this.particlePool) { for (let i = 0; i < this.particlesToRender; i++) {
let particle = this.particlePool[i];
// If a particle is in use, decrease it's age and update it's velocity, if it has one
if (particle.inUse) { if (particle.inUse) {
particle.decrementAge(deltaT * 1000); particle.decrementAge(deltaT * 1000);
@ -93,71 +145,27 @@ export default class ParticleSystem implements Updateable {
particle.setParticleInactive(); particle.setParticleInactive();
} }
//particle.vel.y += 200*deltaT;
particle.move(particle.vel.scaled(deltaT)); particle.move(particle.vel.scaled(deltaT));
} }
else { else {
// Set the particle to active
particle.setParticleActive(this.lifetime, this.sourcePoint.clone()); particle.setParticleActive(this.lifetime, this.sourcePoint.clone());
// Update particle color, mass, and alpha
particle.color = this.color; particle.color = this.color;
particle.alpha = 1; particle.alpha = 1;
//particle.size.set(1) particle.mass = this.particleMass;
particle.vel = RandUtils.randVec(-50, 50, -100, 100);
// Give particle tween animations
particle.tweens.add("active", { this.setParticleAnimation(particle);
startDelay: 0,
duration: 2000,
effects: [
{
property: "alpha",
resetOnComplete: true,
start: 1,
end: 0,
ease: EaseFunctionType.IN_OUT_SINE
},
/*{
property: "colorR",
resetOnComplete: true,
start: particle.color.r,
end: 255,
ease: EaseFunctionType.IN_OUT_SINE
},
{
property: "colorG",
resetOnComplete: true,
start: particle.color.g,
end: 255,
ease: EaseFunctionType.IN_OUT_SINE
},
{
property: "colorB",
resetOnComplete: true,
start: particle.color.b,
end: 255,
ease: EaseFunctionType.IN_OUT_SINE
},*/
{
property: "velY",
resetOnComplete: true,
start: particle.vel.y,
end: particle.vel.y + ((this.lifetime * particle.mass)/2),
ease: EaseFunctionType.IN_OUT_SINE
}
]
});
particle.tweens.play("active"); particle.tweens.play("active");
//particle.vel = RandUtils.randVec(-150, 150, -100, 100);
//console.log(particle.vel.toString());
} }
} }
// Update the amount of particles that can be rendered based on the particles per frame, clamping if we go over the total number
// of particles in our pool
this.particlesToRender = MathUtils.clamp(this.particlesToRender+this.particlesPerFrame, 0, this.particlePool.length);
} }
} }
} }
export enum ParticleSystemType {
emitter = "emitter",
burst = "burst"
}

View File

@ -143,7 +143,16 @@ export default class TweenController {
// If it has an onEnd, send an event // If it has an onEnd, send an event
if(tween.onEnd){ if(tween.onEnd){
this.emitter.fireEvent(tween.onEnd, {key: key, node: this.owner.id}); let data: Record<string, any> = {key: key, node: this.owner.id}
// If it has onEnd event data, add each entry, as long as the key is not named 'key' or 'node'
if (tween.onEndData) {
Object.keys(tween.onEndData).forEach(key => {
if (key !== "key" && key !== "node") {
data[key] = tween.onEndData[key];
}
})
}
this.emitter.fireEvent(tween.onEnd, data);
} }
} }
} }