Overworld objektumok
This commit is contained in:
@@ -4,12 +4,16 @@ import controls
|
||||
import gamestate
|
||||
import math
|
||||
|
||||
from objects import BalthasarRenderer, OverworldMap, DIR_UP, DIR_LEFT, DIR_DOWN, DIR_RIGHT
|
||||
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
|
||||
@@ -17,6 +21,28 @@ 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
|
||||
@@ -78,19 +104,26 @@ def update(game, dt):
|
||||
walking = True
|
||||
|
||||
balthasar.set_walking(walking)
|
||||
cur_x, cur_y = overworld.get_player_world_pos(game)
|
||||
balthasar.y = cur_y
|
||||
|
||||
if walking:
|
||||
# Get current world position
|
||||
cur_x, cur_y = overworld.get_player_world_pos(game)
|
||||
|
||||
# Define collision box dimensions for Balthasar (e.g., 12 width, 10 height at feet)
|
||||
box_w = 12
|
||||
box_h = 10
|
||||
box_h = 14
|
||||
|
||||
# Test and apply X movement independently (Slide on walls)
|
||||
if dx != 0:
|
||||
next_x = cur_x + dx
|
||||
if overworld.is_box_walkable(next_x, cur_y, box_w, box_h):
|
||||
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
|
||||
@@ -99,10 +132,22 @@ def update(game, dt):
|
||||
# Test and apply Y movement independently
|
||||
if dy != 0:
|
||||
next_y = cur_y + dy
|
||||
if overworld.is_box_walkable(cur_x, next_y, box_w, box_h):
|
||||
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)
|
||||
balthasar.render(game)
|
||||
|
||||
trans = overworld.get_translation(game)
|
||||
for o in sorted(objects, key=lambda o: o.y, reverse=True):
|
||||
o.render(game, trans)
|
||||
@@ -17,6 +17,10 @@ class BalthasarRenderer:
|
||||
self.direction = DIR_UP
|
||||
self.walking = False
|
||||
self.anim_timer = 0
|
||||
self.x = 0
|
||||
self.y = 0
|
||||
self.w = B_SPRITE_WIDHT
|
||||
self.h = B_SPRITE_HEIGHT
|
||||
|
||||
def set_direction(self, direction):
|
||||
self.direction = direction
|
||||
@@ -26,12 +30,15 @@ class BalthasarRenderer:
|
||||
if walking == False:
|
||||
self.anim_timer = 0
|
||||
|
||||
def get_aabb(self):
|
||||
return 0, 0, 0, 0
|
||||
|
||||
def update(self):
|
||||
self.anim_timer += 1
|
||||
if self.anim_timer > 30:
|
||||
self.anim_timer = 0
|
||||
|
||||
def render(self, game):
|
||||
def render(self, game, _):
|
||||
sprite_h = self.direction if self.direction < 3 else 2
|
||||
sprite_v = 1 if (self.walking and self.anim_timer <= 15) else 0
|
||||
flip_h = self.direction == DIR_LEFT
|
||||
@@ -106,22 +113,15 @@ class OverworldMap:
|
||||
return OVERWORLD_MAP[OVERWORLD_HEIGHT - 1 - tile_y][tile_x]
|
||||
return None # Out of bounds / wall
|
||||
|
||||
def is_box_walkable(self, world_x, world_y, width, height):
|
||||
def is_box_walkable(self, left, bottom, right, top):
|
||||
"""Checks if a bounding box (e.g., player's feet) is entirely on walkable tiles."""
|
||||
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
|
||||
|
||||
# Check the four corners of the bounding box
|
||||
corners = [
|
||||
(left, bottom),
|
||||
(right, bottom),
|
||||
(left, top),
|
||||
(right, top)
|
||||
(right, top),
|
||||
]
|
||||
|
||||
for cx, cy in corners:
|
||||
@@ -129,23 +129,43 @@ class OverworldMap:
|
||||
tile_y = int(cy // OVERWORLD_TILE_HEIGHT)
|
||||
|
||||
# Check map bounds
|
||||
if not (0 <= tile_x < OVERWORLD_WIDTH and 0 <= tile_y < OVERWORLD_HEIGHT):
|
||||
if not (
|
||||
0 <= tile_x < OVERWORLD_WIDTH and
|
||||
0 <= tile_y < OVERWORLD_HEIGHT
|
||||
):
|
||||
return False # Out of bounds is a wall
|
||||
|
||||
return True
|
||||
|
||||
|
||||
# !!! CHATGPT VÉGE !!!
|
||||
|
||||
def get_translation(self, game):
|
||||
return (
|
||||
self.scroll_x + (game.screen_width / 2) - ((OVERWORLD_WIDTH * OVERWORLD_TILE_WIDTH) / 2),
|
||||
self.scroll_y + (game.screen_height / 2) - ((OVERWORLD_HEIGHT * OVERWORLD_TILE_HEIGHT) / 2)
|
||||
)
|
||||
def render(self, game):
|
||||
for s in self.sprites:
|
||||
arcade.draw_texture_rect(
|
||||
s[0],
|
||||
s[1].move(
|
||||
self.scroll_x + (game.screen_width / 2) - ((OVERWORLD_WIDTH * OVERWORLD_TILE_WIDTH) / 2),
|
||||
self.scroll_y + (game.screen_height / 2) - ((OVERWORLD_HEIGHT * OVERWORLD_TILE_HEIGHT) / 2)
|
||||
),
|
||||
s[1].move(*self.get_translation(game)),
|
||||
pixelated=True
|
||||
)
|
||||
|
||||
# Teszt objektum
|
||||
|
||||
class TestObject:
|
||||
def __init__(self, x, y):
|
||||
self.x = x
|
||||
self.y = y
|
||||
self.w = 16
|
||||
self.h = 16
|
||||
|
||||
def get_aabb(self):
|
||||
return self.x, self.y, self.x + self.w, self.y + self.h
|
||||
|
||||
def render(self, game, translation):
|
||||
arcade.draw_rect_filled(
|
||||
arcade.LBWH(self.x, self.y, 16, 16).move(*translation),
|
||||
arcade.color.PURPLE,
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user