Files
rrttm/src/gamestates/overworld.py
2026-10-14 12:38:05 +02:00

153 lines
4.3 KiB
Python

import assets
import arcade
import controls
import gamestate
import math
from objects import BalthasarRenderer, OverworldMap, TestObject, DIR_UP, DIR_LEFT, DIR_DOWN, DIR_RIGHT, B_SPRITE_HEIGHT
WALK_SPEED = 48
balthasar = BalthasarRenderer()
overworld = OverworldMap()
objects = [
TestObject(0,16),
balthasar
]
btrans_active = False
btrans_timer = 0
btrans_sound = None
BTRANS_PULSE_DUR = 0.25
BTRANS_DURATION = 0.75
def aabb_check(left1, bottom1, right1, top1,
left2, bottom2, right2, top2):
return (
left1 < right2 and
right1 > left2 and
bottom1 < top2 and
top1 > bottom2
)
def get_feet_aabb(world_x, world_y, width, height):
"""Returns the world-space AABB of the feet collision box."""
feet_offset_y = (B_SPRITE_HEIGHT - height) / 2
box_center_y = world_y - feet_offset_y
left = world_x - (width / 2)
right = world_x + (width / 2) - 1
bottom = box_center_y - (height / 2)
top = box_center_y + (height / 2) - 1
return left, bottom, right, top
def start_battle(battle_id):
global btrans_active, btrans_timer, btrans_sound
gamestate.gamestates["battle"].battle_id = battle_id
btrans_sound = assets.sounds["sfx_encounter"].play()
btrans_active = True
btrans_timer = 0
def switch(game):
in_battle_transition = False
# !!! CHATGPT !!!
def update(game, dt):
global btrans_active, btrans_timer
if btrans_active:
btrans_timer += dt
if btrans_timer >= BTRANS_DURATION:
game.mos_enabled = False
btrans_active = False
btrans_sound.stop()
gamestate.switch_gamestate(game, "battle")
game.mos_enabled = True
cycle_progress = (btrans_timer % BTRANS_PULSE_DUR) / BTRANS_PULSE_DUR
game.mosaic = max(1, math.floor(cycle_progress * 16))
return
balthasar.update()
if controls.is_control_pressed(4): # DEBUG: battle
start_battle(0)
if controls.is_control_pressed(0): # Fel
balthasar.set_direction(DIR_UP)
elif controls.is_control_pressed(1): # Le
balthasar.set_direction(DIR_DOWN)
elif controls.is_control_pressed(2): # Bal
balthasar.set_direction(DIR_LEFT)
elif controls.is_control_pressed(3): # Jobb
balthasar.set_direction(DIR_RIGHT)
# Calculate movement delta based on input
dx = 0
dy = 0
walking = False
if controls.is_control_held(0): # Fel (Up)
dy += WALK_SPEED * dt
walking = True
elif controls.is_control_held(1): # Le (Down)
dy -= WALK_SPEED * dt
walking = True
if controls.is_control_held(2): # Bal (Left)
dx -= WALK_SPEED * dt
walking = True
elif controls.is_control_held(3): # Jobb (Right)
dx += WALK_SPEED * dt
walking = True
balthasar.set_walking(walking)
cur_x, cur_y = overworld.get_player_world_pos(game)
balthasar.y = cur_y
if walking:
box_w = 12
box_h = 14
# Test and apply X movement independently (Slide on walls)
if dx != 0:
next_x = cur_x + dx
feet_aabb = get_feet_aabb(next_x, cur_y, box_w, box_h)
can_move = False
if overworld.is_box_walkable(*feet_aabb):
can_move = True
for o in objects:
if aabb_check(*feet_aabb, *o.get_aabb()):
can_move = False
if can_move:
overworld.scroll_x -= dx # Note: scroll moves inverse to world pos change
# Re-fetch current world pos after potential X movement update
cur_x, cur_y = overworld.get_player_world_pos(game)
# Test and apply Y movement independently
if dy != 0:
next_y = cur_y + dy
feet_aabb = get_feet_aabb(cur_x, next_y, box_w, box_h)
can_move = False
if overworld.is_box_walkable(*feet_aabb):
can_move = True
for o in objects:
if aabb_check(*feet_aabb, *o.get_aabb()):
can_move = False
if can_move:
overworld.scroll_y -= dy # Note: scroll moves inverse to world pos change
# !!! CHATGPT VÉGE !!!
def draw(game):
overworld.render(game)
trans = overworld.get_translation(game)
for o in sorted(objects, key=lambda o: o.y, reverse=True):
o.render(game, trans)