from module import COLORS, BLOCK_SIZE, PLAYER_SIZE from typing import TYPE_CHECKING # 解决循环导入 if TYPE_CHECKING: from module.player import Player class Block: id = '' color = '' flowable = False # 可流动 fallible = False # 可下坠 collision = True # 可以碰撞 def __init__(self, x: int, y: int): self.x = x self.y = y def get_screen_x(self) -> int: return self.x * BLOCK_SIZE def get_screen_y(self) -> int: return self.y * BLOCK_SIZE def check_collision(self, player: 'Player') -> bool: # 将玩家的碰撞体积看作为一个正方形,其形心坐标为 (player.x, player.y) # 方块的坐标,即其的 (x, y) 是在 world 中的下标,需要将其转换为坐标 # 由于 下标*边长 计算得到的是这个方块左上角的坐标,所以要添加偏移量 # 计算得到形心坐标,偏移量是方块大小的一半 real_x = self.x * BLOCK_SIZE + BLOCK_SIZE / 2 real_y = self.y * BLOCK_SIZE + BLOCK_SIZE / 2 # 判断其是否碰撞仅需看其两形心间的距离,如果玩家的形心落在了方块碰撞 # 区域内,则发生碰撞,否则不发生碰撞。方块碰撞检测区域位于同形心坐标 # 边长为 PLAYER_SIZE + BLOCK_SIZE 的矩形区域 # 定界: left = real_x - (PLAYER_SIZE + BLOCK_SIZE) / 2 right = real_x + (PLAYER_SIZE + BLOCK_SIZE) / 2 top = real_y - (PLAYER_SIZE + BLOCK_SIZE) / 2 bottom = real_y + (PLAYER_SIZE + BLOCK_SIZE) / 2 # 判碰撞: return left < player.x < right and top < player.y < bottom def get_collision_surface(self) -> tuple[int]: # 获得方块表面界限(碰撞面) # 上、右、下、左 real_x = self.x * BLOCK_SIZE + BLOCK_SIZE / 2 real_y = self.y * BLOCK_SIZE + BLOCK_SIZE / 2 top = real_y - BLOCK_SIZE / 2 bottom = real_y + BLOCK_SIZE / 2 left = real_x - BLOCK_SIZE / 2 right = real_x + BLOCK_SIZE / 2 return top, right, bottom, left def get_center_vector(self): return self.x * BLOCK_SIZE + BLOCK_SIZE / 2, self.y * BLOCK_SIZE + BLOCK_SIZE / 2 class GrassBlock(Block): id = 'grass' color = COLORS.get(id) def __init__(self, x: int, y: int): super().__init__(x, y) class DirtBlock(Block): id = 'dirt' color = COLORS.get(id) def __init__(self, x: int, y: int): super().__init__(x, y) class SandBlock(Block): id = 'sand' color = COLORS.get(id) flowable = True def __init__(self, x: int, y: int): super().__init__(x, y) class StoneBlock(Block): id = 'stone' color = COLORS.get(id) def __init__(self, x: int, y: int): super().__init__(x, y) class AirBlock(Block): id = 'air' color = COLORS.get(id) collision = False def __init__(self, x: int, y: int): super().__init__(x, y) class WaterBlock(Block): id = 'water' color = COLORS.get(id) flowable = True collision = False def __init__(self, x: int, y: int): super().__init__(x, y)