204 lines
5.6 KiB
Python
204 lines
5.6 KiB
Python
import assets
|
|
import arcade
|
|
import controls
|
|
import gamestate
|
|
import math
|
|
|
|
from objects import BalthasarRenderer, OverworldMap, BattlePodium, DIR_UP, DIR_LEFT, DIR_DOWN, DIR_RIGHT, B_SPRITE_HEIGHT
|
|
|
|
WALK_SPEED = 48
|
|
|
|
OVERWORLD_MUSIC = "mus_fnafsux"
|
|
music_box = None
|
|
|
|
balthasar = BalthasarRenderer(96,16)
|
|
overworld = OverworldMap()
|
|
objects = [
|
|
BattlePodium( 72, 32, 0),
|
|
BattlePodium( 32, 72, 1),
|
|
BattlePodium(112, 72, 2),
|
|
BattlePodium( 72, 112, 3),
|
|
balthasar
|
|
]
|
|
|
|
|
|
btrans_active = False
|
|
btrans_timer = 0
|
|
btrans_sound = None
|
|
BTRANS_PULSE_DUR = 0.25
|
|
BTRANS_DURATION = 0.75
|
|
|
|
# !!! CHATGPT !!!
|
|
INTERACT_DISTANCE = 10
|
|
INTERACT_WIDTH = 10
|
|
INTERACT_HEIGHT = 10
|
|
|
|
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_interaction_aabb(world_x, world_y, direction):
|
|
left, bottom, right, top = get_feet_aabb(
|
|
world_x,
|
|
world_y,
|
|
INTERACT_WIDTH,
|
|
INTERACT_HEIGHT
|
|
)
|
|
|
|
if direction == DIR_UP:
|
|
bottom += INTERACT_DISTANCE
|
|
top += INTERACT_DISTANCE
|
|
|
|
elif direction == DIR_DOWN:
|
|
bottom -= INTERACT_DISTANCE
|
|
top -= INTERACT_DISTANCE
|
|
|
|
elif direction == DIR_LEFT:
|
|
left -= INTERACT_DISTANCE
|
|
right -= INTERACT_DISTANCE
|
|
|
|
elif direction == DIR_RIGHT:
|
|
left += INTERACT_DISTANCE
|
|
right += INTERACT_DISTANCE
|
|
|
|
return left, bottom, right, top
|
|
|
|
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
|
|
# !!! CHATGPT VÉGE !!!
|
|
|
|
def start_battle(battle_id):
|
|
global btrans_active, btrans_timer, btrans_sound
|
|
gamestate.gamestates["battle"].battle_id = battle_id
|
|
music_box.pause()
|
|
btrans_sound = assets.sounds["sfx_encounter"].play()
|
|
btrans_active = True
|
|
btrans_timer = 0
|
|
|
|
def switch(game):
|
|
global music_box
|
|
in_battle_transition = False
|
|
overworld.set_player_world_pos(game, balthasar.x, balthasar.y)
|
|
if music_box:
|
|
music_box.unpause()
|
|
else:
|
|
music_box = assets.sounds[OVERWORLD_MUSIC].play(loops=True)
|
|
|
|
# !!! CHATGPT !!!
|
|
def update(game, dt):
|
|
global btrans_active, btrans_timer
|
|
if btrans_active:
|
|
btrans_timer += dt
|
|
|
|
if btrans_timer >= BTRANS_DURATION:
|
|
game.mosaic = 1
|
|
btrans_active = False
|
|
btrans_sound.stop()
|
|
gamestate.switch_gamestate(game, "battle")
|
|
|
|
cycle_progress = (btrans_timer % BTRANS_PULSE_DUR) / BTRANS_PULSE_DUR
|
|
game.mosaic = max(1, math.floor(cycle_progress * 8))
|
|
return
|
|
|
|
balthasar.update()
|
|
cur_x, cur_y = overworld.get_player_world_pos(game)
|
|
balthasar.y = cur_y
|
|
|
|
if controls.is_control_pressed(4): # interakció
|
|
int_aabb = get_interaction_aabb(cur_x, cur_y, balthasar.direction)
|
|
|
|
for o in objects:
|
|
if o.interactive and aabb_check(*int_aabb, *o.get_aabb()):
|
|
o.on_interact(start_battle, lambda o: objects.remove(o))
|
|
|
|
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)
|
|
|
|
|
|
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)
|