import pygame
import random

# -------------------------- 初始化设置 --------------------------
pygame.init()
SCREEN_WIDTH = 1000
SCREEN_HEIGHT = 600
screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
pygame.display.set_caption("开放世界沙盒游戏")
clock = pygame.time.Clock()
FPS = 60

# 颜色定义
WHITE = (255, 255, 255)
GRASS = (60, 180, 60)
TREE = (30, 100, 30)
STONE = (120, 120, 120)
PLAYER_COLOR = (255, 80, 80)
BUILD_COLOR = (160, 110, 60)

# 世界地图大小（开放世界，单位：格子）
TILE_SIZE = 40
WORLD_WIDTH = 80
WORLD_HEIGHT = 80

# 生成世界地图 0=草地 1=树(障碍) 2=石头(障碍)
world_map = []
for y in range(WORLD_HEIGHT):
    row = []
    for x in range(WORLD_WIDTH):
        r = random.random()
        if r < 0.08:
            row.append(1)
        elif r < 0.12:
            row.append(2)
        else:
            row.append(0)
    world_map.append(row)

# 玩家属性
player_x = WORLD_WIDTH // 2 * TILE_SIZE
player_y = WORLD_HEIGHT // 2 * TILE_SIZE
player_speed = 5
player_w = 30
player_h = 30

# 相机偏移
camera_x = 0
camera_y = 0

# 玩家放置的建筑方块列表
build_blocks = []

# -------------------------- 游戏循环 --------------------------
running = True
while running:
    # 事件监听
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        # 鼠标左键放置方块
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                mx, my = pygame.mouse.get_pos()
                world_px = mx + camera_x
                world_py = my + camera_y
                bx = (world_px // TILE_SIZE) * TILE_SIZE
                by = (world_py // TILE_SIZE) * TILE_SIZE
                build_blocks.append((bx, by))

    # 按键移动
    keys = pygame.key.get_pressed()
    dx, dy = 0, 0
    if keys[pygame.K_a]:
        dx = -player_speed
    if keys[pygame.K_d]:
        dx = player_speed
    if keys[pygame.K_w]:
        dy = -player_speed
    if keys[pygame.K_s]:
        dy = player_speed

    # 碰撞检测函数
    def can_move(new_x, new_y):
        rect = pygame.Rect(new_x, new_y, player_w, player_h)
        # 地图障碍物检测
        tile_x1 = int(new_x // TILE_SIZE)
        tile_y1 = int(new_y // TILE_SIZE)
        tile_x2 = int((new_x + player_w) // TILE_SIZE)
        tile_y2 = int((new_y + player_h) // TILE_SIZE)
        for ty in range(tile_y1, tile_y2 + 1):
            for tx in range(tile_x1, tile_x2 + 1):
                if 0 <= tx < WORLD_WIDTH and 0 <= ty < WORLD_HEIGHT:
                    tile = world_map[ty][tx]
                    if tile == 1 or tile == 2:
                        tile_rect = pygame.Rect(tx*TILE_SIZE, ty*TILE_SIZE, TILE_SIZE, TILE_SIZE)
                        if rect.colliderect(tile_rect):
                            return False
        # 检测自建方块碰撞
        for (bx, by) in build_blocks:
            b_rect = pygame.Rect(bx, by, TILE_SIZE, TILE_SIZE)
            if rect.colliderect(b_rect):
                return False
        return True

    # X方向移动
    if can_move(player_x + dx, player_y):
        player_x += dx
    # Y方向移动
    if can_move(player_x, player_y + dy):
        player_y += dy

    # 边界限制，不让玩家走出世界
    player_x = max(0, min(player_x, WORLD_WIDTH*TILE_SIZE - player_w))
    player_y = max(0, min(player_y, WORLD_HEIGHT*TILE_SIZE - player_h))

    # 更新相机（跟随玩家）
    camera_x = player_x - SCREEN_WIDTH//2 + player_w//2
    camera_y = player_y - SCREEN_HEIGHT//2 + player_h//2

    # ----------- 渲染画面 -----------
    screen.fill((20, 20, 20))

    # 计算可视范围的格子
    start_tile_x = int(camera_x // TILE_SIZE) - 1
    start_tile_y = int(camera_y // TILE_SIZE) - 1
    end_tile_x = start_tile_x + SCREEN_WIDTH // TILE_SIZE + 3
    end_tile_y = start_tile_y + SCREEN_HEIGHT // TILE_SIZE + 3

    # 绘制地图地块
    for y in range(start_tile_y, end_tile_y):
        for x in range(start_tile_x, end_tile_x):
            if 0 <= x < WORLD_WIDTH and 0 <= y < WORLD_HEIGHT:
                tile = world_map[y][x]
                draw_x = x*TILE_SIZE - camera_x
                draw_y = y*TILE_SIZE - camera_y
                if tile == 0:
                    color = GRASS
                elif tile == 1:
                    color = TREE
                elif tile == 2:
                    color = STONE
                pygame.draw.rect(screen, color, (draw_x, draw_y, TILE_SIZE-1, TILE_SIZE-1))

    # 绘制玩家放置的方块
    for (bx, by) in build_blocks:
        draw_x = bx - camera_x
        draw_y = by - camera_y
        pygame.draw.rect(screen, BUILD_COLOR, (draw_x, draw_y, TILE_SIZE-1, TILE_SIZE-1))

    # 绘制玩家角色
    player_draw_x = player_x - camera_x
    player_draw_y = player_y - camera_y
    pygame.draw.rect(screen, PLAYER_COLOR, (player_draw_x, player_draw_y, player_w, player_h))

    pygame.display.flip()
    clock.tick(FPS)

pygame.quit()
