feat(0.3.0): Player als Actor-Entity (Phase A.6)
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) <noreply@anthropic.com>
This commit is contained in:
78
init.lua
78
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):
|
||||
|
||||
@@ -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"},
|
||||
|
||||
Reference in New Issue
Block a user