This repository has been archived on 2025-02-14. You can view files and clone it, but cannot push or open issues or pull requests.
LXCsGame/module/block.py
2025-02-01 03:52:39 +08:00

110 lines
3.1 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 # 可以碰撞
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)