fix collision detection issue

This commit is contained in:
Jeffrey Hsu 2025-01-31 21:17:10 +08:00
parent 3cb2bf4b74
commit 6670715bf2
3 changed files with 60 additions and 18 deletions

20
main.py
View File

@ -1,7 +1,7 @@
import pygame
from module import WIDTH, HEIGHT, BLOCK_SIZE, PLAYER_SPEED, GRAVITY, COLORS
from module.block import AirBlock, GrassBlock, StoneBlock, SandBlock, WaterBlock
from module.block import GrassBlock, StoneBlock, SandBlock, WaterBlock
from module.player import Player
from module.utils import generate_terrain
@ -11,7 +11,7 @@ screen = pygame.display.set_mode((WIDTH, HEIGHT))
clock = pygame.time.Clock()
world = generate_terrain()
player = Player()
player = Player(world)
# 游戏循环
running = True
@ -28,18 +28,18 @@ while running:
block = world[bx][by]
if event.button == 1: # 左键放置方块
if block.id == "air":
world[bx][by] = player.selected_block(bx, by)
player.put_block(bx, by)
elif event.button == 3: # 右键拆除方块
world[bx][by] = AirBlock(bx, by)
player.put_block(bx, by, 'delete')
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_1:
player.selected_block = GrassBlock
player.select_block(GrassBlock)
elif event.key == pygame.K_2:
player.selected_block = StoneBlock
player.select_block(StoneBlock)
elif event.key == pygame.K_3:
player.selected_block = SandBlock
player.select_block(SandBlock)
elif event.key == pygame.K_4:
player.selected_block = WaterBlock
player.select_block(WaterBlock)
# 玩家移动
keys = pygame.key.get_pressed()
@ -67,7 +67,9 @@ while running:
screen.fill(COLORS["air"])
for row in world:
for block in row:
if block.id != "air":
if block.id == "air":
continue
rect = pygame.Rect(block.x * BLOCK_SIZE, block.y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE)
pygame.draw.rect(screen, block.color, rect)

View File

@ -11,6 +11,12 @@ class Block:
self.x = x
self.y = y
def get_screen_x(self):
return self.x * 20
def get_screen_y(self):
return self.y * 20
class GrassBlock(Block):
id = 'grass'

View File

@ -1,19 +1,42 @@
from typing import Type, Literal
from module import WIDTH, HEIGHT, JUMP_FORCE
from module.block import AirBlock
from module.block import AirBlock, Block
# 玩家类
class Player:
def __init__(self):
self.x = WIDTH // 2
self.y = HEIGHT // 2
def __init__(self, world: list[list[Block]]):
self.x = 100
self.y = 100
self.velocity = 0
self.on_ground = False
self.selected_block = AirBlock
self.world = world
def move(self, dx, dy):
world_position = {'x': int(self.x) // 20, 'y': int(self.y) // 20}
# TODONeed to judgment x and y in order not to raise Index Out Of Range Error
top_block = self.world[world_position['x']][world_position['y'] - 1]
button_block = self.world[world_position['x']][world_position['y'] + 1]
left_block = self.world[world_position['x'] - 1][world_position['y']]
right_block = self.world[world_position['x'] + 1][world_position['y']]
if dx < 0 and left_block.collision:
new_x = left_block.get_screen_x() + 30
elif dx > 0 and right_block.collision:
new_x = right_block.get_screen_x() - 10
else:
new_x = self.x + dx
if dy < 0 and top_block.collision:
new_y = top_block.get_screen_y() + 30
elif dy > 0 and button_block.collision:
new_y = button_block.get_screen_y() - 10
else:
new_y = self.y + dy
if 0 <= new_x < WIDTH and 0 <= new_y < HEIGHT:
self.x = new_x
self.y = new_y
@ -22,3 +45,14 @@ class Player:
if self.on_ground:
self.velocity = JUMP_FORCE
self.on_ground = False
def select_block(self, block: Type[Block]):
self.selected_block = block
def put_block(self, x: int, y: int, action: Literal['create', 'delete'] = 'create'):
if action == 'create':
self.world[x][y] = self.selected_block(x, y)
elif action == 'delete':
self.world[x][y] = AirBlock(x, y)
else:
pass