From 0227aad47d837ba2a86f359ac64dd2179af60d4d Mon Sep 17 00:00:00 2001 From: Axel Meyer Date: Tue, 9 Jun 2026 14:13:17 +0000 Subject: [PATCH] feat(0.3.0): Player als Actor-Entity (Phase A.6) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Refactor spine-prototype für player_control v0.2.0 + actor: - composition.define_template{id="player", properties={position, movement_speed, sprite_color, sprite_w, sprite_h}, tags={"renderable"}} - actor.create instanziiert Player bei map-center - player_control.update(player, dt) ersetzt player.update(dt) - camera.set_target / interaction.update lesen via actor.position(player) (Lua-multi-return) - Manueller draw_rect für Player raus — Player wird via render.draw_entities{tag="renderable"} zusammen mit Sign gezeichnet - Draw-order: stones zuerst, dann Entities (Sign + Player). Stones-vs- Player-Overlay-Issue in der Praxis nicht relevant (Positionen kollidieren nicht) PLAYER_R/G/B Konstanten entfernt (Color jetzt im Template). Bumps: 0.2.0 → 0.3.0; +actor v0.1.0; player_control 0.1.0 → 0.2.0. Co-Authored-By: Claude Opus 4.7 (1M context) --- init.lua | 78 +++++++++++++++++++++++++++++-------------------- manifest.module | 5 ++-- 2 files changed, 49 insertions(+), 34 deletions(-) diff --git a/init.lua b/init.lua index d974861..c4b6161 100644 --- a/init.lua +++ b/init.lua @@ -1,12 +1,13 @@ -local maps = require("lib-core.maps") -local r_lib = require("lib-core.render") -local camera = require("lib-core.camera") -local input = require("lib-core.input") -local player = require("lib-core.player_control") -local interaction = require("lib-core.interaction") -local selection = require("lib-core.selection") -local command = require("lib-core.command") -local composition = require("lib-core.composition") +local maps = require("lib-core.maps") +local r_lib = require("lib-core.render") +local camera = require("lib-core.camera") +local input = require("lib-core.input") +local player_control = require("lib-core.player_control") +local interaction = require("lib-core.interaction") +local selection = require("lib-core.selection") +local command = require("lib-core.command") +local composition = require("lib-core.composition") +local actor = require("lib-core.actor") local demo_map = maps.load("maps/demo.map.json") maps.set_current(demo_map) @@ -57,12 +58,29 @@ camera.enable_pan_edge() -- unsichtbar in follow-mode wegen set_target-override jeden Frame). camera.set_pan_enabled("keys", false) --- Configure player: defaults are 24x24 + 200 px/sec; place at map-center -local p_size = player.size() -player.set_position(map_center_x - p_size.w / 2, map_center_y - p_size.h / 2) -player.bind_movement("move_left", "move_right", "move_up", "move_down") +-- Player-Template (Phase A.5/A.6 — Actor + composition). +-- position is the visual CENTER per render.draw_entities convention. +composition.define_template{ + id = "player", + properties = { + position = {x = 0, y = 0}, + movement_speed = 200, + sprite_color = engine.render.rgb(200, 60, 80), + sprite_w = 24, + sprite_h = 24, + }, + tags = {"renderable"}, +} -local PLAYER_R, PLAYER_G, PLAYER_B = 200, 60, 80 +-- Spawn the player at map-center; bind WASD movement. +local player = actor.create{ + template = "player", + properties = { + position = {x = map_center_x, y = map_center_y}, + movement_speed = 200, + }, +} +player_control.bind_movement("move_left", "move_right", "move_up", "move_down") -- Sign-Template (Phase A.1 — composition + Inactive-Entity-Pattern). -- Position-Property is the visual CENTER per render.draw_entities convention. @@ -116,10 +134,11 @@ function init(ctx) local t = camera.target() engine.print(string.format("camera: target=(%d,%d) zoom=%.2f", t.x, t.y, camera.zoom())) engine.print(string.format("input: %d actions bound", input.action_count())) - local p = player.position() - local s = player.size() + local px, py = actor.position(player) + local sw = player:get_property("sprite_w") + local sh = player:get_property("sprite_h") engine.print(string.format("player: pos=(%d,%d) size=%dx%d speed=%d", - p.x, p.y, s.w, s.h, player.speed())) + px, py, sw, sh, actor.movement_speed(player))) -- Position + text are read once at registration; the sign is stationary -- in v0.1 so a snapshot is correct. If it ever moves, the interaction- @@ -154,18 +173,17 @@ function render(ctx) engine.render.clear_color(engine.render.rgb(20, 20, 30)) camera.begin() maps.draw_map_pre_entities() - -- draw all renderable entities (Phase A.2: tag-based render) - r_lib.draw_entities{ tag = "renderable" } - -- P.3.6: draw stones + -- P.3.6: draw stones (still Lua-tables; future-slice makes them + -- entities too) for _, s in ipairs(stones) do engine.render.draw_rect(s.x, s.y, s.w, s.h, engine.render.rgb(s.color[1], s.color[2], s.color[3])) end - -- draw player on top of map/stones - local p = player.position() - local sz = player.size() - engine.render.draw_rect(p.x, p.y, sz.w, sz.h, - engine.render.rgb(PLAYER_R, PLAYER_G, PLAYER_B)) + -- Draw all renderable entities (Sign + Player). Drawn AFTER + -- stones so the Player visually overlays stone-occlusions — + -- in practice positions don't collide, but the layering + -- intent is preserved. + r_lib.draw_entities{ tag = "renderable" } -- P.3.6: highlights over selected entities (world-space) selection.render_highlights() maps.draw_map_post_entities() @@ -189,10 +207,8 @@ function update(ctx, dt) -- Player + interaction nur in follow-mode (in free-cam ist player pausiert). if not free_cam_mode then - player.update(dt) - local p = player.position() - local s = player.size() - interaction.update(p.x + s.w / 2, p.y + s.h / 2) + player_control.update(player, dt) + interaction.update(actor.position(player)) end -- Pan-Summation jeden Frame (keys nur wenn enabled; drag + edge always-on). @@ -202,9 +218,7 @@ function update(ctx, dt) if not free_cam_mode then -- Follow-cam: set_target jeden Frame -> drag/edge "drift" wird unsichtbar. - local p = player.position() - local s = player.size() - camera.set_target(p.x + s.w / 2, p.y + s.h / 2) + camera.set_target(actor.position(player)) end -- CI-conditional self-exit (unverändert aus P.0): diff --git a/manifest.module b/manifest.module index f538c7c..b7968f9 100644 --- a/manifest.module +++ b/manifest.module @@ -1,6 +1,6 @@ { "id": "spine-prototype", - "version": "0.2.0", + "version": "0.3.0", "kind": "module", "api": "^0.1", "ci_frames": 30, @@ -14,7 +14,8 @@ {"id":"lib-core.camera","version":"0.3.0"}, {"id":"lib-core.selection","version":"0.1.0"}, {"id":"lib-core.input","version":"0.4.0"}, - {"id":"lib-core.player_control","version":"0.1.0"}, + {"id":"lib-core.player_control","version":"0.2.0"}, + {"id":"lib-core.actor","version":"0.1.0"}, {"id":"lib-core.interaction","version":"0.1.0"}, {"id":"lib-core.command","version":"0.1.0"}, {"id":"lib-core.composition","version":"0.1.0"},