"""LityPy Demo - 3D 开放世界 RPG""" from lity import * scene = Scene("LityPy RPG Demo", 1280, 720) camera = Camera() # 地面 ground = create_ground(scene, 60, Color(0.25, 0.5, 0.2)) # 玩家 player = scene.create("hero", "cube", pos=Vec3(0, 0.5, 0), color=Color.GREEN) player.speed = 5.0 player.add_rigidbody() player.add_collider(size=Vec3(0.5, 1, 0.5)) # 村庄建筑 walls = [ create_building(scene, -5, -5, 2, 2, 2, Color.RED, Color.GRAY), create_building(scene, 3, -6, 2.5, 2.5, 2, Color.BLUE, Color.GRAY), create_building(scene, -2, -8, 1.8, 1.8, 1.8, Color.YELLOW, Color(0.45, 0.28, 0.15)), create_building(scene, 6, -3, 2, 3, 2, Color.ORANGE, Color.GRAY), ] # NPC npc1 = scene.create("merchant", "cube", pos=Vec3(1, 0.4, -4), color=Color.CYAN, tags=["npc"]) npc1.dialog = "欢迎来到村庄!" npc2 = scene.create("guard", "cube", pos=Vec3(-4, 0.4, -3), color=Color.MAGENTA, tags=["npc"]) npc2.dialog = "小心森林里的怪物!" # 树木 for i in range(25): x, z = rand(-25, 25), rand(-25, 25) if abs(x) < 8 and abs(z) < 10: continue create_tree(scene, x, z) # 岩石 for i in range(10): x, z = rand(-25, 25), rand(-25, 25) scene.create(f"rock_{i}", "sphere", pos=Vec3(x, 0.3, z), scale=Vec3(rand(0.3, 0.8), rand(0.2, 0.5), rand(0.3, 0.8)), color=Color(0.5, 0.5, 0.5)) # 花 for i in range(15): x, z = rand(-10, 10), rand(-10, 10) c = Color(rand(0.6, 1), rand(0.1, 0.5), rand(0.1, 0.5)) scene.create(f"flower_{i}", "sphere", pos=Vec3(x, 0.15, z), scale=Vec3(0.1, 0.1, 0.1), color=c) # 水塘 scene.create("water", "plane", pos=Vec3(-8, 0.05, -3), scale=Vec3(4, 1, 4), color=Color(0.15, 0.3, 0.6, 0.8)) # 远山 for i, (x, z, sx, sy, sz) in enumerate([ (-20, 15, 8, 3, 8), (22, 12, 10, 4, 10), (0, 25, 12, 3, 8) ]): scene.create(f"hill_{i}", "sphere", pos=Vec3(x, -0.5, z), scale=Vec3(sx, sy, sz), color=Color(0.2, 0.4, 0.18)) # 敌人 enemies = [] for i in range(8): x, z = rand(-20, 20), rand(5, 20) e = scene.create(f"enemy_{i}", "sphere", pos=Vec3(x, 0.5, z), color=Color(0.8, 0.2, 0.1), tags=["enemy"]) e.hp = 100 e.speed = 2.0 e.patrol_center = Vec3(x, 0.5, z) enemies.append(e) # ===== 游戏逻辑 ===== score = 0 hp = 100 @scene.on_frame def update(dt): global score, hp camera.follow(player, offset=Vec3(0, 4, -8), smooth=3.0 * dt) for e in enemies: d = e.pos.distance(player.pos) if d < 15: to_player = (player.pos - e.pos).normalize() e.pos = e.pos + to_player * e.speed * dt e.rot = Vec3(0, math.atan2(to_player.x, to_player.z), 0) if d < 8: e.pos = e.pos.lerp(e.patrol_center, dt * 0.5) # 导出场景 export_scene_ly(scene, "rpg_scene.ly") scene.save("rpg_scene.json") print(f"\n=== LityPy RPG Demo ===") print(f"场景: {len(scene.entities)} 个实体") print(f"玩家: {player.pos}") print(f"敌人: {len(enemies)} 个") print(f"建筑: {len(walls)} 栋") print(f"\n特性展示:") print(f" Vec3: {Vec3(1,2,3) + Vec3(4,5,6)}") print(f" Color.from_hex: {Color.from_hex('#FF5500')}") print(f" lerp: {lerp(0, 10, 0.3)}") print(f" rand: {rand(0, 100):.2f}") print(f" sin: {math.sin(time_s()):.4f}") print(f"\n引擎 API 已就绪,需要编译 C 端集成。")