diff --git a/main.py b/main.py index 704b486..2bf0b21 100644 --- a/main.py +++ b/main.py @@ -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,9 +67,11 @@ while running: screen.fill(COLORS["air"]) for row in world: for block in row: - if block.id != "air": - rect = pygame.Rect(block.x * BLOCK_SIZE, block.y * BLOCK_SIZE, BLOCK_SIZE, BLOCK_SIZE) - pygame.draw.rect(screen, block.color, rect) + 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) # 绘制玩家 pygame.draw.circle(screen, COLORS["player"], (player.x, player.y), 10) diff --git a/module/block.py b/module/block.py index 24209b6..5b67e58 100644 --- a/module/block.py +++ b/module/block.py @@ -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' diff --git a/module/player.py b/module/player.py index b6e0c7e..656cca4 100644 --- a/module/player.py +++ b/module/player.py @@ -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): - new_x = self.x + dx - new_y = self.y + dy + world_position = {'x': int(self.x) // 20, 'y': int(self.y) // 20} + + # TODO:Need 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 @@ -21,4 +44,15 @@ class Player: def jump(self): if self.on_ground: self.velocity = JUMP_FORCE - self.on_ground = False \ No newline at end of file + 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 \ No newline at end of file