update chess to use moth
Some checks failed
Build and Deploy / build-macos (push) Failing after 7s
Build and Deploy / build-windows (CLANG64) (push) Has been cancelled
Build and Deploy / package-dist (push) Has been cancelled
Build and Deploy / deploy-itch (push) Has been cancelled
Build and Deploy / deploy-gitea (push) Has been cancelled
Build and Deploy / build-linux (push) Has been cancelled

This commit is contained in:
2025-05-28 17:49:37 -05:00
parent 4eb592b740
commit 09f48d08b9
8 changed files with 88 additions and 214 deletions

View File

@@ -1,22 +1,18 @@
/* main.js runs the demo with your prototype-based grid */
var moth = use('moth', $_.delay)
var json = use('json')
var os = use('os')
var draw2d = use('draw2d')
var res = 160
var internal_res = 480
var input = use('input')
moth.initialize({ width:res, height:res, resolution_x:internal_res, resolution_y:internal_res, mode:'letterbox' });
var os = use('os');
var draw2d = use('draw2d');
var gfx = use('graphics');
input.watch($_)
/*──── import our pieces + systems ───────────────────────────────────*/
var Grid = use('grid'); // your new ctor
var MovementSystem = use('movement').MovementSystem;
var startingPos = use('pieces').startingPosition;
var rules = use('rules');
var Grid = use('examples/chess/grid'); // your new ctor
var MovementSystem = use('examples/chess/movement').MovementSystem;
var startingPos = use('examples/chess/pieces').startingPosition;
var rules = use('examples/chess/rules');
/*──── build board ───────────────────────────────────────────────────*/
var grid = new Grid(8, 8);
@@ -55,7 +51,7 @@ function updateTitle() {
break;
}
prosperon.window.title = title
console.log(title)
}
// Initialize title
@@ -70,7 +66,7 @@ var opponentMousePos = null;
var opponentHoldingPiece = false;
var opponentSelectPos = null;
prosperon.on('mouse_button_down', function(e) {
function handleMouseButtonDown(e) {
if (e.which !== 0) return;
// Don't allow piece selection unless we have an opponent
@@ -96,9 +92,9 @@ prosperon.on('mouse_button_down', function(e) {
} else {
selectPos = null;
}
})
}
prosperon.on('mouse_button_up', function(e) {
function handleMouseButtonUp(e) {
if (e.which !== 0 || !holdingPiece || !selectPos) return;
// Don't allow moves unless we have an opponent and it's our turn
@@ -139,9 +135,9 @@ prosperon.on('mouse_button_up', function(e) {
type: 'piece_drop'
});
}
})
}
prosperon.on('mouse_motion', function(e) {
function handleMouseMotion(e) {
var mx = e.pos.x;
var my = e.pos.y;
@@ -162,7 +158,18 @@ prosperon.on('mouse_motion', function(e) {
selectPos: selectPos
});
}
})
}
function handleKeyDown(e) {
// S key - start server
if (e.scancode === 22 && gameState === 'waiting') { // S key
startServer();
}
// J key - join server
else if (e.scancode === 13 && gameState === 'waiting') { // J key
joinServer();
}
}
/*──── drawing helpers ───────────────────────────────────────────────*/
/* ── constants ─────────────────────────────────────────────────── */
@@ -193,7 +200,8 @@ function drawBoard() {
draw2d.rectangle(
{ x: x*S, y: y*S, width: S, height: S },
{ thickness: 0, color: color }
{ thickness: 0 },
{ color: color }
);
}
}
@@ -235,7 +243,7 @@ function drawPieces() {
var r = { x: piece.coord[0]*S, y: piece.coord[1]*S,
width:S, height:S };
draw2d.image(piece.sprite, r, 0, [0,0], [0,0], {mode:"nearest"});
draw2d.image(piece.sprite, r);
});
// Draw the held piece at the mouse position if we're holding one
@@ -245,7 +253,7 @@ function drawPieces() {
var r = { x: hoverPos[0]*S, y: hoverPos[1]*S,
width:S, height:S };
draw2d.image(piece.sprite, r, 0, [0,0], [0,0], {mode:"nearest"});
draw2d.image(piece.sprite, r);
}
}
@@ -257,29 +265,25 @@ function drawPieces() {
width:S, height:S };
// Draw with slight transparency to show it's the opponent's piece
draw2d.image(opponentPiece.sprite, r, 0, [0,0], [0,0], {mode:"nearest", color: [1, 1, 1, 0.7]});
draw2d.image(opponentPiece.sprite, r);
}
}
}
var graphics = use('graphics')
function update(dt)
{
return {}
}
prosperon.on('draw', function() {
function draw()
{
draw2d.clear()
drawBoard()
drawPieces()
draw2d.text("HELL", [100,100])
})
draw2d.text("HELL", {x: 100, y: 100}, 'fonts/c64.ttf', 16, [1,1,1,1])
return draw2d.get_commands()
}
prosperon.on('key_down', function(e) {
// S key - start server
if (e.scancode === 22 && gameState === 'waiting') { // S key
startServer();
}
// J key - join server
else if (e.scancode === 13 && gameState === 'waiting') { // J key
joinServer();
}
})
function startServer() {
gameState = 'server_waiting';
@@ -327,17 +331,12 @@ function joinServer() {
var os = use('os')
var sdl = use('sdl')
var ioguy = sdl.ioguy()
send(ioguy, {
type: "subscribe",
actor: $_
});
$_.receiver(e => {
if (e.type === 'game_start' || e.type === 'move' || e.type === 'greet')
if (e.kind == 'update')
send(e, update(e.dt))
else if (e.kind == 'draw')
send(e, draw())
else if (e.type === 'game_start' || e.type === 'move' || e.type === 'greet')
console.log("Receiver got message:", e.type, e);
if (e.type === 'quit') os.exit()
@@ -392,7 +391,13 @@ $_.receiver(e => {
// Opponent dropped their piece
opponentHoldingPiece = false;
opponentSelectPos = null;
} else if (e.type === 'mouse_button_down') {
handleMouseButtonDown(e)
} else if (e.type === 'mouse_button_up') {
handleMouseButtonUp(e)
} else if (e.type === 'mouse_motion') {
handleMouseMotion(e)
} else if (e.type === 'key_down') {
handleKeyDown(e)
}
prosperon.dispatch(e.type, e)
})

View File

@@ -572,6 +572,9 @@ cmd.process(prosperon.argv.slice())
if (!prosperon.args.id) prosperon.id = util.guid()
else prosperon.id = prosperon.args.id
// Make remaining arguments available as global 'args' variable
globalThis.args = prosperon.args.remaining || []
$_.__ACTORDATA__.id = prosperon.id
function turn(msg)

View File

@@ -162,6 +162,27 @@ Cmdline.register_order(
prosperon.args = parse_args(argv)
if (!prosperon.args.cwd) prosperon.args.cwd = '.'
io.mount(prosperon.args.cwd)
// Store all remaining non-flag arguments
var remaining_args = []
var skip_next = false
for (var i = 0; i < argv.length; i++) {
if (skip_next) {
skip_next = false
continue
}
if (argv[i].startsWith("--")) {
// Check if this flag has a value
if (i + 1 < argv.length && !argv[i + 1].startsWith("--")) {
skip_next = true
}
continue
}
remaining_args.push(argv[i])
}
// Add remaining arguments to prosperon.args
prosperon.args.remaining = remaining_args
if (!prosperon.args.program)
os.exit()

View File

@@ -1,138 +0,0 @@
/**
* 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 {}

View File

@@ -55,11 +55,6 @@ var camera = {
var util = use('util')
var cammy = util.camera_globals(camera)
console.log(cammy)
var sq = {x:50,y:30,height:300,width:100}
console.log(json.encode(sq))
console.log(json.encode(worldToScreenRect(sq, camera, 500, 500)))
var graphics
@@ -68,11 +63,20 @@ var render
var gameactor
var dir = args[0]
if (!io.exists(args[0] + '/main.js'))
throw Error(`No main.js found in ${args[0]}`)
console.log('starting game in ' + dir)
io.mount(dir)
$_.start(e => {
if (gameactor) return
gameactor = e.actor
loop()
}, 'tests/prosperon.js')
}, args[0] + "/main.js")
send(video_actor, {
kind: "window",
@@ -254,8 +258,6 @@ function loop()
var dt = now - last
last = now
// camera.pos = camera.pos.map(x => x += 5*dt)
// Update the game
send(gameactor, {kind:'update', dt:dt}, e => {
// Get draw commands from game

View File

@@ -667,8 +667,6 @@ void script_startup(prosperon_rt *prt, void (*hook)(JSContext*))
JS_AddIntrinsicRegExp(js);
JS_AddIntrinsicJSON(js);
JS_AddIntrinsicMapSet(js);
JS_AddIntrinsicTypedArrays(js);
JS_AddIntrinsicWeakRef(js);
JS_AddIntrinsicProxy(js);
JS_SetContextOpaque(js, prt);

View File

@@ -170,17 +170,6 @@ static JSValue js_os_version(JSContext *js, JSValue self, int argc, JSValue *arg
return ret;
}
JSValue js_os_get_trace(JSContext *js, JSValue self)
{
return JS_NewBool(js, trace);
}
JSValue js_os_set_trace(JSContext *js, JSValue self, JSValue value)
{
trace = JS_ToBool(js, value);
return JS_UNDEFINED;
}
JSC_CCALL(os_on,
prosperon_rt *rt = JS_GetContextOpaque(js);
JS_FreeValue(js, rt->on_exception);
@@ -301,7 +290,6 @@ static const JSCFunctionListEntry js_os_funcs[] = {
MIST_FUNC_DEF(os, freemem, 0),
MIST_FUNC_DEF(os, hostname, 0),
MIST_FUNC_DEF(os, version, 0),
JS_CGETSET_DEF("trace", js_os_get_trace, js_os_set_trace),
MIST_FUNC_DEF(os, exit, 1),
MIST_FUNC_DEF(os, now, 0),
MIST_FUNC_DEF(os, power_state, 0),

View File

@@ -115,11 +115,6 @@ static const JSCFunctionListEntry js_input_funcs[] = {
JSValue js_input_use(JSContext *js) {
JSValue mod = JS_NewObject(js);
JS_SetPropertyFunctionList(js,mod,js_input_funcs,countof(js_input_funcs));
// Initialize SDL cursor class (no functions)
JSValue c_types = JS_GetPropertyStr(js, JS_GetGlobalObject(js), "c_types");
JS_FreeValue(js, c_types);
return mod;
}