找回密码
 中文实名注册
搜索
查看: 643|回复: 0

我的世界

[复制链接]

17

主题

21

回帖

1630

积分

金牌会员

积分
1630
发表于 2025-6-28 15:30:13 | 显示全部楼层 |阅读模式
[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()

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 中文实名注册

本版积分规则

快速回复 返回顶部 返回列表