ajhahn.de
← Theria commits

Commit

Theria

feat: draw the arena map and entities in the client

ajhahnde · Jun 2026 · e58ce53935e7438b81334ce9f52de5e0d183964f · parent: 76f2839 · view on GitHub →

modified scenes/main.tscn
@@ -6,3 +6,4 @@
script = ExtResource("1_main")
[node name="Camera2D" type="Camera2D" parent="."]
zoom = Vector2(0.16, 0.16)
modified src/client/main.gd
@@ -4,30 +4,40 @@ extends Node2D
## It owns a SimCore and advances it one tick per physics frame (physics is
## pinned to the simulation's 60 Hz in project.godot). All authority lives in
## the simulation; this layer only samples local input, asks the bot for its
## command, and draws the resulting state. Swapping this for a networked driver
## later does not touch the simulation.
## command, and draws the resulting state — the static map geometry plus the
## live entities. Swapping this for a networked driver later does not touch the
## simulation.
const HERO_SPEED := 320.0
const BOT_SPEED := 300.0
const HERO_TEAM := 0
const BOT_TEAM := 1
const MARKER_SIZE := Vector2(28.0, 28.0)
const HERO_COLOR := Color(0.36, 0.66, 1.0)
const BOT_COLOR := Color(1.0, 0.42, 0.38)
const ENTITY_RADIUS := 44.0
## Map debug-draw styling. World-unit sizes, tuned to read at the camera's
## zoomed-out framing of the whole arena.
const FIELD_COLOR := Color(0.114, 0.125, 0.145)
const BOUNDS_COLOR := Color(0.3, 0.32, 0.36)
const BOUNDS_WIDTH := 8.0
const LANE_COLOR := Color(0.5, 0.5, 0.55, 0.7)
const LANE_WIDTH := 28.0
const CAMP_COLOR := Color(0.45, 0.7, 0.45)
const CAMP_RADIUS := 60.0
const NEXUS_SIZE := Vector2(140.0, 140.0)
var _sim := SimCore.new()
var _bot := BotController.new()
var _hero_id: int = 0
var _bot_id: int = 0
var _markers: Dictionary = {}
func _ready() -> void:
_hero_id = _sim.add_entity(HERO_TEAM, MapData.spawn_for_team(HERO_TEAM), HERO_SPEED)
_bot_id = _sim.add_entity(BOT_TEAM, MapData.spawn_for_team(BOT_TEAM), BOT_SPEED)
_markers[_hero_id] = _make_marker(HERO_COLOR)
_markers[_bot_id] = _make_marker(BOT_COLOR)
_sync_markers()
queue_redraw()
func _physics_process(_delta: float) -> void:
@@ -36,7 +46,35 @@ func _physics_process(_delta: float) -> void:
_bot_id: _bot.decide(_sim.state, _bot_id),
}
_sim.step(inputs)
_sync_markers()
queue_redraw()
func _draw() -> void:
_draw_map()
_draw_entities()
func _draw_map() -> void:
draw_rect(MapData.BOUNDS, FIELD_COLOR, true)
draw_rect(MapData.BOUNDS, BOUNDS_COLOR, false, BOUNDS_WIDTH)
for lane in MapData.lane_count():
draw_polyline(MapData.lane_path(lane, HERO_TEAM), LANE_COLOR, LANE_WIDTH)
for camp in MapData.JUNGLE_CAMPS:
draw_circle(camp, CAMP_RADIUS, CAMP_COLOR)
for team in MapData.NEXUS_POSITIONS.size():
var centre := MapData.nexus_for_team(team)
var rect := Rect2(centre - NEXUS_SIZE * 0.5, NEXUS_SIZE)
draw_rect(rect, _team_color(team), true)
func _draw_entities() -> void:
for id in _sim.state.entities:
var entity: SimEntity = _sim.state.entities[id]
draw_circle(entity.position, ENTITY_RADIUS, _team_color(entity.team))
func _team_color(team: int) -> Color:
return HERO_COLOR if team == HERO_TEAM else BOT_COLOR
func _sample_player_input() -> InputCommand:
@@ -52,18 +90,3 @@ func _sample_player_input() -> InputCommand:
dir.x += 1.0
command.move_dir = dir
return command
func _make_marker(color: Color) -> ColorRect:
var rect := ColorRect.new()
rect.color = color
rect.size = MARKER_SIZE
add_child(rect)
return rect
func _sync_markers() -> void:
for id in _markers:
var entity: SimEntity = _sim.state.get_entity(id)
var marker: ColorRect = _markers[id]
marker.position = entity.position - MARKER_SIZE * 0.5