116 lines
3.3 KiB
Python
116 lines
3.3 KiB
Python
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 # 可以碰撞
|
|
destroyable = 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, int, int, 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)
|
|
|
|
class BedrockBlock(Block):
|
|
id = 'bedrock'
|
|
color = COLORS.get(id)
|
|
destroyable = False |