fix emitter

This commit is contained in:
2025-01-24 00:04:55 -06:00
parent d174aa88d6
commit 612111067b
7 changed files with 167 additions and 244 deletions

View File

@@ -2,19 +2,21 @@ var Color = use('color')
var ex = {}
var emitter = {};
emitter.life = 10;
emitter.scale = 1;
emitter.grow_for = 0;
emitter.spawn_timer = 0;
emitter.pps = 0;
emitter.color = Color.white;
ex.emitters = new Set()
emitter.kill = function () {
emitters.remove(this);
};
ex.garbage = function()
{
ex.emitters.delete(this)
}
var std_step = function (p) {
ex.update = function(dt)
{
for (var e of ex.emitters)
try { e.step(dt) } catch(e) { console.error(e) }
}
ex.step_hook = function(p)
{
if (p.time < this.grow_for) {
var s = Math.lerp(0, this.scale, p.time / this.grow_for);
p.transform.scale = s;
@@ -22,40 +24,10 @@ var std_step = function (p) {
var s = Math.lerp(0, this.scale, (p.life - p.time) / this.shrink_for);
p.transform.scale = s;
} else p.transform.scale = [this.scale, this.scale, this.scale];
};
}
emitter.step_hook = std_step;
emitter.spawn = function (t) {
t ??= this.transform;
var par = this.dead.shift();
if (par) {
par.transform.unit();
par.transform.pos = t.pos;
par.transform.scale = this.scale;
this.particles.push(par);
par.time = 0;
this.spawn_hook?.(par);
par.life = this.life;
return;
}
par = {
transform: os.make_transform(),
life: this.life,
time: 0,
color: this.color,
body:{},
};
par.transform.scale = this.scale;
this.particles.push(par);
this.spawn_hook(par);
};
emitter.step = function step(dt) {
ex.step = function(dt)
{
// update spawning particles
if (this.on && this.pps > 0) {
this.spawn_timer += dt;
@@ -75,33 +47,46 @@ emitter.step = function step(dt) {
if (this.kill_hook?.(p) || p.time >= p.life) {
this.die_hook?.(p);
this.dead.push(p);
this.particles.remove(p);
this.particles.delete(p);
}
}
// for (var p of this.particles)
// p.transform.clean();
};
emitter.burst = function (count, t) {
for (var i = 0; i < count; i++) this.spawn(t);
};
var emitters = [];
ex.make = function make_emitter() {
var e = Object.create(emitter);
e.particles = [];
e.dead = [];
emitters.push(e);
return e;
};
ex.update = function update_emitters(dt) {
for (var e of emitters) e.step(dt);
}
ex.stat = function stat_emitters()
ex.burst = function(count,t)
{
for (var i = 0; i < count; i++) this.spawn(t)
}
ex.spawn = function(t)
{
t ??= this.transform
var par = this.dead.shift()
if (par) {
par.transform.unit()
par.transform.pos = t.pos;
par.transform.scale = this.scale;
this.particles.push(par);
par.time = 0;
this.spawn_hook?.(par);
par.life = this.life;
return;
}
par = {
transform: os.make_transform(),
life: this.life,
time: 0,
color: this.color,
body:{},
}
par.transform.scale = this.scale
this.particles.push(par)
this.spawn_hook(par)
}
ex.stat = function()
{
var stat = {};
stat.emitters = emitters.length;
@@ -111,6 +96,20 @@ ex.stat = function stat_emitters()
return stat;
}
ex.all = function all_emitters() { return emitters; }
ex.life = 10
ex.scale = 1
ex.grow_for = 0
ex.spawn_timer = 0
ex.pps = 0
ex.color = Color.white
return ex
---
this.particles = []
this.dead = []
this.transform = this.overling.transform
$.emitters.add(this)

View File

@@ -1,5 +1,4 @@
globalThis.console = os.use('console')
globalThis.prosperon = os.use('prosperon')
globalThis.prosperon = {}
var io = os.use('io')
os.mem_limit.doc = "Set the memory limit of the runtime in bytes.";
@@ -8,6 +7,10 @@ os.max_stacksize.doc = "Set the max stack size in bytes.";
globalThis.Resources = {};
prosperon.SIGINT = function() {
os.exit();
}
Resources.rm_fn = function rm_fn(fn, text) {
var reg = new RegExp(fn.source + "\\s*\\(");
var match;
@@ -31,8 +34,6 @@ Resources.replpath = function replpath(str, path) {
if (!str) return str;
if (str[0] === "/") return str.rm(0);
if (str[0] === "@") return os.prefpath() + "/" + str.rm(0);
if (!path) return str;
var stem = path.dir();
@@ -53,7 +54,7 @@ Resources.replstrs = function replstrs(path) {
var stem = path.dir();
if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script);
// if (!console.enabled) script = Resources.rm_fn(/console\.(spam|info|warn|error)/, script);
/* if (!profile.enabled) script = Resources.rm_fn(/profile\.(cache|frame|endcache|endframe)/, script);
if (!debug.enabled) {
@@ -284,6 +285,7 @@ console.log = function(msg)
}
console.error = function(e) {
console.print(e.message)
if (!e)
e = new Error();

View File

@@ -1,3 +1,10 @@
/*
io path rules. Starts with, meaning:
"@": user path
"/": root game path
"" : relative game path
*/
var io = os.use('io')
var tmpslurp = io.slurp;
@@ -26,10 +33,47 @@ io.glob = function glob(pat) {
return allpaths.filter(str => game.glob(pat,str)).sort();
}
/*var ignore;
if (ignore = io.slurp('.prosperonignore')) {
ignore = ignore.split('\n');
for (var ig of ignore) {
if (!ig) continue;
allpaths = allpaths.filter(x => !x.startsWith(ig));
}
}
*/
io.invalidate = function()
{
allpaths = undefined;
}
io.mkpath = function (dir) {
if (!dir) return;
var mkstack = [];
while (!io.exists(dir)) {
mkstack.push(dir.fromlast("/"));
dir = dir.dir();
}
for (var d of mkstack) {
dir = dir + "/" + d;
say(`making ${dir}`);
io.mkdir(dir);
}
};
io.doc = {
doc: "Functions for filesystem input/output commands.",
exists: "Returns true if a file exists.",
slurp: "Returns the contents of given file as a string.",
slurpbytes: "Return the contents of a file as a byte array.",
slurpwrite: "Write a given string to a given file.",
cp: "Copy file f1 to f2.",
mv: "Rename file f1 to f2.",
rm: "Remove file f.",
mkdir: "Make dir.",
ls: "List contents of the game directory.",
glob: "Glob files in game directory.",
};
return io

View File

@@ -5,6 +5,32 @@ var gizmo = use('gizmos')
var vector = use('vector')
var search = use('search')
var input = use('input')
var appy = {};
appy.inputs = {};
if (os.sys() === "macos") {
appy.inputs["S-q"] = os.exit;
}
appy.inputs.f7 = function () {
debug.meta = !debug.meta;
};
appy.inputs.f8 = function () {
debug.cheat = !debug.cheat;
};
appy.inputs.f9 = function () {
debug.console = !debug.console;
};
appy.inputs.f10 = function () {
debug.show = !debug.show;
};
appy.inputs["M-f4"] = os.exit;
input.player[0].control(appy);
prosperon.window = os.engine_start(config);
var driver = "vulkan"
@@ -870,14 +896,15 @@ render.rectangle = function render_rectangle(rect, color = Color.white, pipeline
render.particles = function render_particles(emitter, pipeline = sprite_pipeline)
{
if (!emitter.diffuse) throw new Error("emitter does not have a proper diffuse");
var diff = graphics.texture(emitter.diffuse)
if (!diff) throw new Error("emitter does not have a proper diffuse");
var mesh = render._main.make_sprite_mesh(emitter.particles);
if (mesh.num_indices === 0) return;
current_queue.push({
type:'geometry',
mesh,
image:emitter.diffuse,
image:diff,
pipeline,
first_index:0,
num_indices:mesh.num_indices
@@ -1157,7 +1184,7 @@ function screen2hud(pos)
* Cameras have a position and rotation. They are not affected by scale.
*/
prosperon.make_camera = function make_camera() {
prosperon.make_camera = function (make_camera) {
return;
/* var cam = world.spawn();
cam.near = 1;
@@ -1281,14 +1308,14 @@ var imgui_fn = function imgui_fn() {
};
var dmon
try {
/*try {
dmon = use('dmon')
} catch (e) {
console.log(`could not use dmon`)
console.error(e)
}
if (dmon) dmon.watch('.');
*/
function dmon_cb(e)
{
io.invalidate();
@@ -1302,7 +1329,7 @@ function dmon_cb(e)
}
var sim = use('sim')
var emitters = use('particle')
var emitter = use('emitter')
var waittime = 1/240;
var last_frame_time = 0;
@@ -1331,7 +1358,7 @@ render.process = function process() {
prosperon.appupdate(dt)
input.procdown()
emitters.update(dt * timescale)
emitter.update(dt * timescale)
os.update_timers(dt * timescale)
prosperon.update(dt*timescale)
@@ -1350,8 +1377,7 @@ render.process = function process() {
current_queue = render_queue;
prosperon.draw()
for (var e of emitters.all())
render.particles(e);
emitter.emitters.forEach(e => render.particles(e))
current_queue = hud_queue;
prosperon.hud()
imgui_fn()

View File

@@ -1,148 +1,6 @@
os.cwd.doc = "Get the absolute path of the current working directory.";
os.env.doc = "Return the value of the environment variable v.";
if (os.sys() === "windows") os.user = os.env("USERNAME");
else os.user = os.env("USER");
var sim = use('sim')
var io = use('io')
var util = use('util')
/*var ignore;
if (ignore = io.slurp('.prosperonignore')) {
ignore = ignore.split('\n');
for (var ig of ignore) {
if (!ig) continue;
allpaths = allpaths.filter(x => !x.startsWith(ig));
}
}
*/
var appy = {};
appy.inputs = {};
if (os.sys() === "macos") {
appy.inputs["S-q"] = os.exit;
}
appy.inputs.f7 = function () {
debug.meta = !debug.meta;
};
appy.inputs.f8 = function () {
debug.cheat = !debug.cheat;
};
appy.inputs.f9 = function () {
debug.console = !debug.console;
};
appy.inputs.f10 = function () {
debug.show = !debug.show;
};
prosperon.toggle_fullscreen = function()
{
prosperon.fullscreen = !prosperon.fullscreen;
game.fullscreen();
console.log(`fullscreen is now ${prosperon.fullscreen}`)
}
appy.inputs.f11 = prosperon.toggle_fullscreen;
appy.inputs.f11.doc = "Toggle window fullscreen.";
appy.inputs.f11.title = "Toggle Fullscreen";
appy.inputs["M-f4"] = os.exit;
var input = use('input')
input.player[0].control(appy);
os.home = os.env("HOME");
/*steam.path = {
windows: `C:/Program Files (x86)/Steam/userdata/${steam.userid}/${steam.appid}`,
macos: `${os.home}/Library/Application Support/Steam/userdata/${steam.userid}/${steam.appid}`,
linux: `${os.home}/.local/share/Steam/userdata/${steam.userid}/${steam.appid}`
};
*/
var otherpath = {
windows: `C:/Users/${os.user}/Saved Games`,
macos: `${os.home}/Library/Application Support`,
linux: `${os.home}/.local/share`,
};
os.prefpath = function () {
return otherpath[os.sys()] + "/" + (game.title ? game.title : "Untitled Prosperon Game");
};
os.openurl = function (url) {
if (os.sys() === "windows") os.system(`start ${url}`);
else os.system(`open ${url}`);
};
io.dumpfolder = ".prosperon";
Resources.texture = {};
Resources.texture.dimensions = function (path) {
texture.dimensions(path);
};
Resources.gif = {};
Resources.gif.frames = function (path) {
return render.gif_frames(path);
};
prosperon.SIGINT = function() {
os.exit();
}
/*
io path rules. Starts with, meaning:
"@": user path
"/": root game path
"" : relative game path
*/
var tmpchm = io.chmod;
io.chmod = function (file, mode) {
return tmpchm(file, parseInt(mode, 8));
};
io.mkpath = function (dir) {
if (!dir) return;
var mkstack = [];
while (!io.exists(dir)) {
mkstack.push(dir.fromlast("/"));
dir = dir.dir();
}
for (var d of mkstack) {
dir = dir + "/" + d;
say(`making ${dir}`);
io.mkdir(dir);
}
};
var tmpslurpw = io.slurpwrite;
io.slurpwrite = function (path, c) {
path = Resources.replpath(path);
// io.mkpath(path.dir());
return tmpslurpw(path, c);
};
var tmprm = io.rm;
io.rm = function (f) {
tmprm(Resources.replpath(f));
};
io.doc = {
doc: "Functions for filesystem input/output commands.",
exists: "Returns true if a file exists.",
slurp: "Returns the contents of given file as a string.",
slurpbytes: "Return the contents of a file as a byte array.",
slurpwrite: "Write a given string to a given file.",
cp: "Copy file f1 to f2.",
mv: "Rename file f1 to f2.",
rm: "Remove file f.",
mkdir: "Make dir.",
ls: "List contents of the game directory.",
glob: "Glob files in game directory.",
};
var dumpfolder = ".prosperon";
var Cmdline = {};
@@ -169,7 +27,6 @@ Cmdline.register_order(
say("No game to edit. Try making one with 'prosperon init'.");
return;
}
sim.pause();
},
"Edit the project in this folder. Give it the name of an UR to edit that specific object.",
"?UR?",
@@ -183,7 +40,7 @@ Cmdline.register_order(
return;
}
io.mkdir(io.dumpfolder);
io.mkdir(dumpfolder);
var project = {};
project.version = prosperon.version;
project.revision = prosperon.revision;

View File

@@ -24,17 +24,17 @@ function test_arrays(ta, tb)
// test_arrays(ta.slice(0,i), ta.slice(0,i));
//}
/*
say(prosperon.guid());
say(prosperon.guid());
say(os.guid());
say(os.guid());
var aa = [];
var ao = {};
var amt = 10000;
profile.cpu(_ => prosperon.guid(), 10000, "guid generation");
profile.cpu(_ => os.guid(), 10000, "guid generation");
profile.cpu(_ => aa.push(1), amt, "add one to array");
profile.cpu(_ => ao[prosperon.guid()] = 1, amt, "add one via guid");
profile.cpu(_ => ao[os.guid()] = 1, amt, "add one via guid");
var aos = Object.keys(ao);

View File

@@ -5449,7 +5449,7 @@ static const JSCFunctionListEntry js_input_funcs[] = {
MIST_FUNC_DEF(input, keymod, 0),
};
JSC_CCALL(prosperon_guid,
JSC_CCALL(os_guid,
char guid[33];
for (int i = 0; i < 4; i++) {
int r = rand();
@@ -5463,12 +5463,12 @@ JSC_CCALL(prosperon_guid,
return JS_NewString(js,guid);
)
JSC_SCALL(prosperon_openurl,
JSC_SCALL(os_openurl,
if (!SDL_OpenURL(str))
ret = JS_ThrowReferenceError(js, "unable to open url %s: %s\n", str, SDL_GetError());
)
JSC_CCALL(prosperon_push_event,
JSC_CCALL(os_push_event,
SDL_UserEvent e;
SDL_zero(e);
e.type = SDL_EVENT_USER;
@@ -5480,12 +5480,6 @@ JSC_CCALL(prosperon_push_event,
SDL_PushEvent(&e);
)
static const JSCFunctionListEntry js_prosperon_funcs[] = {
MIST_FUNC_DEF(prosperon, guid, 0),
MIST_FUNC_DEF(prosperon, openurl, 1),
MIST_FUNC_DEF(prosperon, push_event, 1),
};
JSC_CCALL(time_now,
struct timeval ct;
gettimeofday(&ct, NULL);
@@ -5571,8 +5565,7 @@ JSC_SCALL(io_rm,
if (!PHYSFS_delete(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
)
JSC_SCALL(io_mkdir,
if (!PHYSFS_mkdir(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));
)
if (!PHYSFS_mkdir(str)) ret = JS_ThrowReferenceError(js,"%s", PHYSFS_getErrorByCode(PHYSFS_getLastErrorCode()));)
JSC_SCALL(io_exists, ret = JS_NewBool(js,PHYSFS_exists(str)); )
@@ -7194,9 +7187,7 @@ typedef struct {
static ModuleEntry module_registry[] = {
MISTLINE(io),
MISTLINE(input),
MISTLINE(prosperon),
MISTLINE(time),
MISTLINE(console),
MISTLINE(profile),
MISTLINE(debug),
MISTLINE(vector),
@@ -7263,6 +7254,9 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, system, 1),
MIST_FUNC_DEF(os, exit, 1),
MIST_FUNC_DEF(os, gc, 0),
MIST_FUNC_DEF(os, guid, 0),
MIST_FUNC_DEF(os, openurl, 1),
MIST_FUNC_DEF(os, push_event, 1),
MIST_FUNC_DEF(os, eval, 2),
MIST_FUNC_DEF(os, make_quadtree, 1),
MIST_FUNC_DEF(os, make_rtree, 0),
@@ -7635,6 +7629,7 @@ void ffi_load(JSContext *js) {
QJSCLASSPREP_FUNCS(timer);
QJSGLOBALCLASS(os);
QJSGLOBALCLASS(console);
JSValue jsarray = JS_GetPropertyStr(js,globalThis, "Array");
JSValue array_proto = JS_GetPropertyStr(js,jsarray, "prototype");