
# ==============================================
# 图片同款！2D我的世界 完美复刻版
# 还原：底部物品栏格子、选中白框、原版方块画风
# 适配海龟编辑器 无任何报错
# ==============================================
import pygame
import random
import math

pygame.init()

# 窗口设置
WIDTH = 1200
HEIGHT = 600
TILE_SIZE = 32
FPS = 60

# ==================== 颜色复刻（完全图片同款）====================
SKY_COLOR = (115, 175, 255)
GRASS_TOP = (38, 150, 38)
GRASS_SIDE = (30, 120, 30)
DIRT_COLOR = (135, 85, 40)
STONE_COLOR = (105, 105, 105)
WOOD_COLOR = (145, 90, 45)
LEAF_COLOR = (25, 110, 25)

WHITE = (255,255,255)
BLACK = (0,0,0)
GRAY = (50,50,50)
HOVER_WHITE = (220,220,220)

# 方块ID
AIR = 0
GRASS = 1
DIRT = 2
STONE = 3
WOOD = 4
LEAF = 5

# 物品栏顺序（图片同款）
BLOCK_LIST = [GRASS, DIRT, STONE, WOOD, LEAF]
BLOCK_NAME = ["草方块","泥土","石头","木头","树叶"]
BLOCK_COL = [GRASS_TOP, DIRT_COLOR, STONE_COLOR, WOOD_COLOR, LEAF_COLOR]



# ==================== 世界地形（图片同款自然地形）====================
class World:
    def __init__(self):
        self.blocks = {}
        self.gen_world()

    def gen_world(self):
        for x in range(-80,80):
            h = int(16 + math.sin(x*0.12)*5 + random.randint(-1,1))
            # 草方块表层
            self.blocks[(x,h)] = GRASS
            # 泥土层
            for y in range(h+1, h+5):
                self.blocks[(x,y)] = DIRT
            # 石头底层
            for y in range(h+5, h+12):
                self.blocks[(x,y)] = STONE

            # 图片同款树木
            if random.random() < 0.14:
                th = random.randint(4,6)
                for ty in range(h-th, h):
                    self.blocks[(x,ty)] = WOOD
                # 树冠
                for ox in range(-2,3):
                    for oy in range(-3,-1):
                        if random.random()<0.7:
                            self.blocks[(x+ox, h+oy-th)] = LEAF

    def get_block(self,x,y):
        return self.blocks.get((int(x),int(y)),AIR)

    def set_block(self,x,y,bid):
        pos = (int(x),int(y))
        if bid == AIR:
            if pos in self.blocks:
                del self.blocks[pos]
        else:
            self.blocks[pos] = bid

# ==================== 玩家物理系统 ====================
class Player:
    def __init__(self):
        self.x = 0
        self.y = -250
        self.vx = 0
        self.vy = 0
        self.speed = 4.2
        self.jump_pow = 11.5
        self.gravity = 0.58
        self.on_ground = True
        self.slot = 0 # 物品栏选中下标

    def update(self,world):
        keys = pygame.key.get_pressed()
        self.vx = 0
        if keys[pygame.K_a]:self.vx = -self.speed
        if keys[pygame.K_d]:self.vx = self.speed

        if keys[pygame.K_SPACE] and self.on_ground:
            self.vy = -self.jump_pow

        self.vy += self.gravity
        if self.vy > 16:
            self.vy = 16

        # X碰撞
        self.x += self.vx
        if self.collide(world):
            self.x -= self.vx

        # Y碰撞
        self.y += self.vy
        self.on_ground = False
        if self.collide(world):
            self.y -= self.vy
            self.vy = 0
            self.on_ground = True

    def collide(self,world):
        w,h = 13,30
        points = [
            (self.x-w, self.y+2),
            (self.x+w, self.y+2),
            (self.x-w, self.y+h),
            (self.x+w, self.y+h)
        ]
        for px,py in points:
            if world.get_block(px//TILE_SIZE, py//TILE_SIZE) != AIR:
                return True
        return False

# ==================== 主游戏（重点：图片同款UI）====================
class Game:
    def __init__(self):
        self.screen = pygame.display.set_mode((WIDTH,HEIGHT))
        pygame.display.set_caption("2D我的世界 图片复刻版")
        self.clock = pygame.time.Clock()
        self.running = True

        self.world = World()
        self.player = Player()

    def draw_ui(self):
        # 底部黑色半透明物品栏背景（和图片一致）
        ui_y = HEIGHT - 55
        pygame.draw.rect(self.screen, (20,20,20), (WIDTH/2 - 160, ui_y, 320, 50))

        # 绘制物品格子 + 选中白框（图片同款）
        for i in range(5):
            sx = WIDTH/2 - 150 + i*62
            # 格子底色
            pygame.draw.rect(self.screen, GRAY, (sx, ui_y+5, 55, 40))
            # 方块预览
            pygame.draw.rect(self.screen, BLOCK_COL[i], (sx+5, ui_y+8, 45, 30))
            # 选中高亮白框
            if self.player.slot == i:
                pygame.draw.rect(self.screen, HOVER_WHITE, (sx, ui_y+5, 55, 40), 3)



    def render(self):
        # 天空底色（图片同款浅蓝）
        self.screen.fill(SKY_COLOR)

        # 相机跟随
        cam_x = self.player.x - WIDTH//2
        cam_y = self.player.y - HEIGHT//2

        # 渲染所有方块
        for (wx,wy), bid in self.world.blocks.items():
            sx = wx * TILE_SIZE - cam_x
            sy = wy * TILE_SIZE - cam_y
            if -TILE_SIZE < sx < WIDTH+TILE_SIZE and -TILE_SIZE < sy < HEIGHT+TILE_SIZE:
                # 方块细节复刻
                if bid == GRASS:
                    pygame.draw.rect(self.screen, GRASS_SIDE, (sx,sy,TILE_SIZE-1,TILE_SIZE-1))
                    pygame.draw.rect(self.screen, GRASS_TOP, (sx,sy,TILE_SIZE-1,6))
                else:
                    pygame.draw.rect(self.screen, BLOCK_COL[bid-1], (sx,sy,TILE_SIZE-1,TILE_SIZE-1))

        # 绘制玩家
        px = self.player.x - cam_x
        py = self.player.y - cam_y
        pygame.draw.rect(self.screen, (25,90,200), (px-13, py, 26, 30))
        pygame.draw.circle(self.screen, (255,220,180), (px, py+10), 11)

        # 鼠标准星
        mx,my = pygame.mouse.get_pos()
        pygame.draw.circle(self.screen, WHITE, (mx,my), 5, 1)

        # 绘制底部物品栏UI
        self.draw_ui()

    def event_loop(self):
        for e in pygame.event.get():
            if e.type == pygame.QUIT:
                self.running = False
            if e.type == pygame.KEYDOWN:
                if e.key == pygame.K_ESCAPE:
                    self.running = False
                # 1-5切换物品栏
                if pygame.K_1 <= e.key <= pygame.K_5:
                    self.player.slot = e.key - pygame.K_1

            # 鼠标操作
            if e.type == pygame.MOUSEBUTTONDOWN:
                mx,my = pygame.mouse.get_pos()
                c_x = self.player.x - WIDTH//2
                c_y = self.player.y - HEIGHT//2
                tx = (mx + c_x) // TILE_SIZE
                ty = (my + c_y) // TILE_SIZE

                if e.button == 1:
                    self.world.set_block(tx,ty,AIR)
                if e.button == 3:
                    sel_block = BLOCK_LIST[self.player.slot]
                    self.world.set_block(tx,ty,sel_block)

    def run(self):
        while self.running:
            self.event_loop()
            self.player.update(self.world)
            self.render()
            pygame.display.flip()
            self.clock.tick(FPS)
        pygame.quit()

if __name__ == "__main__":
    g = Game()
    g.run()
