fun: planties!

This commit is contained in:
cha0s 2024-06-27 15:08:30 -05:00
parent 4bf9b8d891
commit d88135c85f
7 changed files with 128 additions and 0 deletions

View File

@ -0,0 +1,58 @@
import Component from '@/ecs/component.js';
import Script from '@/util/script.js';
export default class Plant extends Component {
instanceFromSchema() {
const {ecs} = this;
const Instance = super.instanceFromSchema();
return class PlantInstance extends Instance {
mayGrow() {
return this.mayGrowScriptInstance.evaluateSync();
}
grow() {
const {Ticking} = ecs.get(this.entity);
Ticking.addTickingPromise(this.growScriptInstance.tickingPromise());
}
};
}
async load(instance) {
// heavy handed...
if ('undefined' !== typeof window) {
return;
}
const {readAsset} = this.ecs;
await readAsset(instance.growScript)
.then(async (code) => {
if (code.byteLength > 0) {
const context = {
ecs: this.ecs,
plant: instance,
};
instance.growScriptInstance = await Script.fromCode((new TextDecoder()).decode(code), context);
}
});
await readAsset(instance.mayGrowScript)
.then(async (code) => {
if (code.byteLength > 0) {
const context = {
ecs: this.ecs,
plant: instance,
};
instance.mayGrowScriptInstance = await Script.fromCode((new TextDecoder()).decode(code), context);
}
});
}
// heavy handed...
markChange() {}
static properties = {
growScript: {type: 'string'},
growth: {type: 'uint16'},
mayGrowScript: {type: 'string'},
stage: {type: 'uint8'},
stages: {
type: 'array',
subtype: {type: 'uint16'},
},
};
}

View File

@ -0,0 +1,27 @@
import {System} from '@/ecs/index.js';
export default class PlantGrowth extends System {
static queries() {
return {
default: ['Plant'],
};
}
tick(elapsed) {
for (const {Plant} of this.select('default')) {
if (65535 === Plant.growth || !Plant.mayGrow()) {
continue;
}
const stage = Math.floor(Plant.stage);
Plant.growth = Math.min(
Plant.growth + (((Math.random() + 0.5) * elapsed) / Plant.stages[stage]) * 65535,
65535,
);
if (65535 === Plant.growth) {
Plant.grow();
}
}
}
}

View File

@ -118,11 +118,39 @@ export default class Engine {
],
},
});
const plant = {
Plant: {
growScript: '/assets/tomato-plant/grow.js',
mayGrowScript: '/assets/tomato-plant/may-grow.js',
stages: [300, 300, 300, 300, 300],
},
Sprite: {
anchor: {x: 0.5, y: 0.75},
animation: 'stage/0',
frame: 0,
frames: 1,
source: '/assets/tomato-plant/tomato-plant.json',
speed: 0,
},
Ticking: {},
VisibleAabb: {},
};
const promises = [];
for (let y = 0; y < 10; ++y) {
for (let x = 0; x < 10; ++x) {
promises.push(ecs.create({
...plant,
Position: {x: 8 + x * 16, y: 8 + y * 16},
}));
}
}
await Promise.all(promises);
const defaultSystems = [
'ResetForces',
'ApplyControlMovement',
'ApplyForces',
'ClampPositions',
'PlantGrowth',
'FollowCamera',
'CalculateAabbs',
'UpdateSpatialHash',

View File

@ -0,0 +1,13 @@
const {Sprite} = ecs.get(plant.entity);
if (plant.stage < 3) {
plant.stage += 1
}
if (4 === plant.stage) {
plant.stage = 3
}
if (3 !== plant.stage) {
plant.growth = 0
}
Sprite.animation = ['stage', plant.stage].join('/')

View File

@ -0,0 +1 @@
3 !== plant.stage

View File

@ -0,0 +1 @@
{"animations":{"stage/0":["tomato-plant/tomato-plant/0"],"stage/1":["tomato-plant/tomato-plant/1"],"stage/2":["tomato-plant/tomato-plant/2"],"stage/3":["tomato-plant/tomato-plant/3"],"stage/4":["tomato-plant/tomato-plant/4"]},"frames":{"tomato-plant/tomato-plant/0":{"frame":{"x":0,"y":0,"w":16,"h":32},"spriteSourceSize":{"x":0,"y":0,"w":16,"h":32},"sourceSize":{"w":16,"h":32}},"tomato-plant/tomato-plant/1":{"frame":{"x":16,"y":0,"w":16,"h":32},"spriteSourceSize":{"x":0,"y":0,"w":16,"h":32},"sourceSize":{"w":16,"h":32}},"tomato-plant/tomato-plant/2":{"frame":{"x":32,"y":0,"w":16,"h":32},"spriteSourceSize":{"x":0,"y":0,"w":16,"h":32},"sourceSize":{"w":16,"h":32}},"tomato-plant/tomato-plant/3":{"frame":{"x":48,"y":0,"w":16,"h":32},"spriteSourceSize":{"x":0,"y":0,"w":16,"h":32},"sourceSize":{"w":16,"h":32}},"tomato-plant/tomato-plant/4":{"frame":{"x":64,"y":0,"w":16,"h":32},"spriteSourceSize":{"x":0,"y":0,"w":16,"h":32},"sourceSize":{"w":16,"h":32}}},"meta":{"format":"RGBA8888","image":"./tomato-plant.png","scale":1,"size":{"w":80,"h":32}}}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB