[Python] 纯文本查看 复制代码
import pygame
import random
import sys
# 初始化 Pygame
pygame.init()
# 屏幕大小
WIDTH, HEIGHT = 800, 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption("我的世界 - 特定方块行为")
# 颜色
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
GREEN = (0, 255, 0)
BROWN = (139, 69, 19)
SKY_BLUE = (135, 206, 250)
GRAY = (100, 100, 100)
WOOD = (160, 82, 45)
SAND = (237, 201, 175)
WATER = (64, 164, 223)
GLASS = (173, 216, 230)
# 方块大小
BLOCK_SIZE = 40
# 世界大小
WORLD_WIDTH = WIDTH // BLOCK_SIZE
WORLD_HEIGHT = HEIGHT // BLOCK_SIZE
# 定义方块类型
BLOCK_TYPES = {
"grass": GREEN,
"stone": GRAY,
"wood": WOOD,
"sand": SAND,
"water": WATER,
"glass": GLASS,
}
block_type_keys = list(BLOCK_TYPES.keys())
current_block_index = 0 # 当前方块类型索引
# 方块类
class Block(pygame.sprite.Sprite):
def __init__(self, x, y, color, block_type):
super().__init__()
self.image = pygame.Surface((BLOCK_SIZE, BLOCK_SIZE))
self.image.fill(color)
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.block_type = block_type # 方块类型
def update(self, tiles):
# 如果是沙子,模拟重力
if self.block_type == "sand":
below = self.rect.y + BLOCK_SIZE
if below < HEIGHT:
if not any(tile.rect.collidepoint(self.rect.x, below) for tile in tiles):
self.rect.y += BLOCK_SIZE
# 如果是水,模拟扩散
elif self.block_type == "water":
below = self.rect.y + BLOCK_SIZE
left = self.rect.x - BLOCK_SIZE
right = self.rect.x + BLOCK_SIZE
if below < HEIGHT:
# 向下扩散
if not any(tile.rect.collidepoint(self.rect.x, below) for tile in tiles):
self.rect.y += BLOCK_SIZE
# 向左扩散
elif left >= 0 and not any(tile.rect.collidepoint(left, self.rect.y) for tile in tiles):
self.rect.x -= BLOCK_SIZE
# 向右扩散
elif right < WIDTH and not any(tile.rect.collidepoint(right, self.rect.y) for tile in tiles):
self.rect.x += BLOCK_SIZE
# 玩家类
class Player(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((BLOCK_SIZE // 2, BLOCK_SIZE))
self.image.fill((255, 0, 0)) # 红色玩家
self.rect = self.image.get_rect()
self.rect.x = x
self.rect.y = y
self.speed_x = 0
self.speed_y = 0
self.gravity = 1
self.jump_power = -15
self.on_ground = False
def update(self, tiles):
# 重力
self.speed_y += self.gravity
self.rect.x += self.speed_x
self.rect.y += self.speed_y
# 碰撞检测
self.on_ground = False
for tile in tiles:
if self.rect.colliderect(tile.rect):
# 垂直碰撞
if self.speed_y > 0: # 下落时
self.rect.bottom = tile.rect.top
self.speed_y = 0
self.on_ground = True
elif self.speed_y < 0: # 上升时
self.rect.top = tile.rect.bottom
self.speed_y = 0
# 水平碰撞
if self.speed_x > 0: # 向右移动
self.rect.right = tile.rect.left
elif self.speed_x < 0: # 向左移动
self.rect.left = tile.rect.right
# 防止玩家移出屏幕
if self.rect.left < 0:
self.rect.left = 0
if self.rect.right > WIDTH:
self.rect.right = WIDTH
if self.rect.bottom > HEIGHT:
self.rect.bottom = HEIGHT
self.on_ground = True
def jump(self):
if self.on_ground:
self.speed_y = self.jump_power
# 生成世界
def generate_world():
tiles = pygame.sprite.Group()
for x in range(WORLD_WIDTH):
for y in range(WORLD_HEIGHT):
if y > WORLD_HEIGHT // 2: # 地面以下
if y > WORLD_HEIGHT // 2 + 2: # 更深层为石头
color = GRAY
block_type = "stone"
else: # 地面附近为泥土或沙子
block_type = "sand" if random.random() > 0.7 else "grass"
color = BLOCK_TYPES[block_type]
block = Block(x * BLOCK_SIZE, y *
BLOCK_SIZE, color, block_type)
tiles.add(block)
elif y == WORLD_HEIGHT // 2: # 地面
block = Block(x * BLOCK_SIZE, y * BLOCK_SIZE, GREEN, "grass")
tiles.add(block)
elif y == WORLD_HEIGHT // 2 - 1: # 水面
if random.random() > 0.8:
block = Block(x * BLOCK_SIZE, y *
BLOCK_SIZE, WATER, "water")
tiles.add(block)
return tiles
# 初始化玩家和方块
player = Player(WIDTH // 2, HEIGHT // 2)
tiles = generate_world()
# 精灵组
all_sprites = pygame.sprite.Group()
all_sprites.add(player)
# 主循环
clock = pygame.time.Clock()
running = True
while running:
screen.fill(SKY_BLUE) # 天空背景
clock.tick(60)
# 事件处理
for event in pygame.event.get():
if event.type == pygame.QUIT:
running = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
player.speed_x = -5
if event.key == pygame.K_RIGHT:
player.speed_x = 5
if event.key == pygame.K_SPACE:
player.jump()
# 切换方块类型
if event.key == pygame.K_TAB:
current_block_index = (
current_block_index + 1) % len(block_type_keys)
if event.type == pygame.KEYUP:
if event.key in (pygame.K_LEFT, pygame.K_RIGHT):
player.speed_x = 0
# 鼠标事件 - 放置和移除方块
if event.type == pygame.MOUSEBUTTONDOWN:
mouse_x, mouse_y = pygame.mouse.get_pos()
grid_x = mouse_x // BLOCK_SIZE * BLOCK_SIZE
grid_y = mouse_y // BLOCK_SIZE * BLOCK_SIZE
if event.button == 1: # 左键放置方块
block_type = block_type_keys[current_block_index]
block = Block(grid_x, grid_y,
BLOCK_TYPES[block_type], block_type)
tiles.add(block)
elif event.button == 3: # 右键移除方块
for tile in tiles:
if tile.rect.collidepoint(mouse_x, mouse_y):
tiles.remove(tile)
# 更新
for tile in tiles:
tile.update(tiles)
player.update(tiles)
# 绘制
tiles.draw(screen)
all_sprites.draw(screen)
# 显示当前方块类型
font = pygame.font.Font(None, 36)
block_type_text = f"当前方块: {block_type_keys[current_block_index]}"
text_surface = font.render(block_type_text, True, BLACK)
screen.blit(text_surface, (10, 10))
# 刷新屏幕
pygame.display.flip()
pygame.quit()
sys.exit()