From 40fa44f9368254d45bee66b145ab7b89d106df42 Mon Sep 17 00:00:00 2001 From: Jeffrey Hsu Date: Sat, 1 Feb 2025 11:21:20 +0800 Subject: [PATCH] fix gravity simulation bug --- main.py | 5 ----- module/player.py | 28 ++++++++++++++++++++-------- 2 files changed, 20 insertions(+), 13 deletions(-) diff --git a/main.py b/main.py index e31cdef..9f4413c 100644 --- a/main.py +++ b/main.py @@ -31,7 +31,6 @@ while running: player.put_block(bx, by) elif event.button == 3: # 右键拆除方块 player.put_block(bx, by, 'delete') - player.on_ground = False # 不完美解决方法,挖方块时更新状态 elif event.type == pygame.KEYDOWN: if event.key == pygame.K_1: player.select_block(GrassBlock) @@ -61,12 +60,8 @@ while running: player.move(0, player.velocity) # 绘制世界 - screen.fill(COLORS["air"]) for row in world: for block in row: - 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) diff --git a/module/player.py b/module/player.py index c0d9c79..98e25e0 100644 --- a/module/player.py +++ b/module/player.py @@ -18,8 +18,7 @@ class Player: def move(self, dx: float, dy: float): # 仅需检测玩家当前区块的上下左右的方块是否有碰撞体积 - block_x_idx = int(self.x) // BLOCK_SIZE - block_y_idx = int(self.y) // BLOCK_SIZE + block_x_idx, block_y_idx = self.get_pixel_idx() top_block = self.world[block_x_idx][block_y_idx - 1] if block_y_idx > 0 else None bottom_block = self.world[block_x_idx][block_y_idx + 1] if block_y_idx < HEIGHT // 20 - 1 else None @@ -31,7 +30,6 @@ class Player: if dy > 0 and bottom_block is not None and bottom_block.collision: if bottom_block.check_collision(self): new_y = bottom_block.get_collision_surface()[0] - 10 - self.on_ground = True else: new_y = self.y + dy # 向上移动时且上面方块有碰撞体积,与下表面碰撞 @@ -79,12 +77,26 @@ class Player: pass def draw(self, screen: pygame.Surface): - pygame.draw.circle(screen, COLORS["player"], (self.x, self.y), PLAYER_SIZE // 2) self.move(0, 0) - # 绘制玩家所在区块颜色 - if OPTIONS['debug']: - block_x = int(self.x) // BLOCK_SIZE * BLOCK_SIZE - block_y = int(self.y) // BLOCK_SIZE * BLOCK_SIZE + # 重力检测 + block_x_idx, block_y_idx = self.get_pixel_idx() + + bottom_block = self.world[block_x_idx][block_y_idx + 1] if block_y_idx < HEIGHT // 20 - 1 else None + if bottom_block and bottom_block.collision and bottom_block.check_collision(self): + self.on_ground = True + else: + self.on_ground = False + + pygame.draw.circle(screen, COLORS["player"], (self.x, self.y), PLAYER_SIZE // 2) + + if OPTIONS['debug']: + block_x = block_x_idx * BLOCK_SIZE + block_y = block_y_idx * BLOCK_SIZE + + # 绘制玩家所在区块颜色 rect = pygame.Rect(block_x, block_y, BLOCK_SIZE, BLOCK_SIZE) pygame.draw.rect(screen, '#ffd5004d', rect) + + def get_pixel_idx(self) -> tuple[int, int]: + return int(self.x) // BLOCK_SIZE, int(self.y) // BLOCK_SIZE \ No newline at end of file