Files
cell/scripts/modules/moth.js

138 lines
3.0 KiB
JavaScript

/**
* Moth Game Framework
* Higher-level game development framework built on top of Prosperon
*/
// Check if we received the required delay function
if (!arg || arg.length === 0 || typeof arg[0] !== 'function') {
throw new Error("moth module requires $_.delay function as first argument. Usage: use('moth', $_.delay)");
}
// Verify it's actually a delay function by checking if it has the expected behavior
var delay = arg[0];
if (!delay.name || (delay.name !== 'delay' && !delay.name.includes('delay'))) {
console.warn("Warning: The function passed to moth module may not be $_.delay");
}
var os = use('os');
var io = use('io');
var transform = use('transform');
var draw2d
var graphics
var video_actor = use('sdl_video')
var window
var render
var gameConfig = arg[1] || {};
send(video_actor, {
kind: "window",
op:"create",
data: gameConfig
}, e => {
if (e.error) {
console.error(e.error)
os.exit(1)
}
window = e.id
send(video_actor,{
kind:"window",
op:"makeRenderer",
id:window
}, e => {
if (e.error) {
console.error(e.error)
os.exit(1)
}
render = e.id
draw2d = use('draw2d', video_actor, render)
graphics = use('graphics', video_actor, render)
})
})
function loop()
{
}
$_.delay(loop, 1/60)
// Initialize render system
render.initialize({
width: gameConfig.resolution.width,
height: gameConfig.resolution.height,
resolution_x: gameConfig.internal_resolution.width,
resolution_y: gameConfig.internal_resolution.height,
mode: gameConfig.mode || 'letterbox'
});
// Set up default camera
gameConfig.camera = gameConfig.camera || {
size: [gameConfig.internal_resolution.width, gameConfig.internal_resolution.height],
transform: new transform,
fov: 50,
near_z: 0,
far_z: 1000,
surface: undefined,
viewport: {x: 0, y: 0, width: 1, height: 1},
ortho: true,
anchor: [0, 0]
};
// Set window title
prosperon.window.title = gameConfig.title;
startGameLoop();
// Main game loop
function startGameLoop() {
var last = os.now();
var fpsTimer = 0;
var fpsCount = 0;
var targetFrameTime = 1 / gameConfig.fps;
function loop() {
var now = os.now();
var dt = now - last;
last = now;
// Dispatch update event
prosperon.dispatch('update', dt);
// Clear and set up rendering
render.clear(gameConfig.clearColor);
render.camera(gameConfig.camera);
// Dispatch draw event
prosperon.dispatch('draw');
// Present the frame
render.present();
// FPS counter
fpsTimer += dt;
fpsCount++;
if (fpsTimer >= 0.5) {
// Only update if the title wasn't changed by the game
if (prosperon.window.title === gameConfig.title) {
prosperon.window.title = `${gameConfig.title} - FPS ${(fpsCount / fpsTimer).toFixed(1)}`;
}
fpsTimer = fpsCount = 0;
}
// Schedule next frame
delay(loop, Math.max(0, targetFrameTime - (os.now() - now)));
}
loop();
}
// Public API
return {}