fix collision detection issue
This commit is contained in:
parent
3cb2bf4b74
commit
6670715bf2
20
main.py
20
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,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)
|
||||
|
||||
|
@ -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'
|
||||
|
@ -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}
|
||||
|
||||
# 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
|
||||
@ -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
|
Reference in New Issue
Block a user