Files
mapTools/write_code.py
2025-12-06 17:48:48 +08:00

149 lines
5.3 KiB
Python

import pandas as pd
import os
# 确保文件名与您上传的保持一致
FILE_P = "found_p.xlsx"
FILE_V = "found_v.xlsx"
FILE_COIN = "found_币.xlsx"
OUTPUT_FILE = "Levels90001.cs"
LEVEL_PATH = "Assets/Prefabs/Level/Level{map_id}.prefab" # 假设 levelPath 随 LevelID 变化
# 1. 读取并标准化数据
def load_data():
try:
# Player Data
df_p = pd.read_excel(FILE_P)
df_p.columns = ['MapID', 'X', 'Y', 'Direction']
# Vehicle Data
df_v = pd.read_excel(FILE_V)
df_v.columns = ['MapID', 'X', 'Y', 'Direction']
# Coin Data
df_coin = pd.read_excel(FILE_COIN)
# Coin 文件中没有 Direction 列
df_coin.columns = ['MapID', 'X', 'Y']
return df_p, df_v, df_coin
except FileNotFoundError as e:
print(f"错误:找不到文件 {e.filename}。请确保所有 CSV 文件与脚本在同一目录下。")
return None, None, None
# 2. 生成单个 Spawn() 字符串
def generate_spawn_line(data_row, spawn_type):
map_id = data_row['MapID']
x, y, z = data_row['X'], data_row['Y'], 0 # Z 坐标固定为 0
position_str = f"new Vector3Int({x},{y},{z})"
if spawn_type == 'player':
direction = data_row['Direction']
# 将 CSV 中的 N/S/E/W 转换为 C# 枚举 Direction.North/South/East/West
direction_map = {'N': 'Direction.North', 'S': 'Direction.South', 'E': 'Direction.East', 'W': 'Direction.West'}
dir_enum = direction_map.get(direction, 'Direction.North') # 默认值
return f'new Spawn(){{position = {position_str},path = "Assets/Prefabs/Player.prefab", playerDirection = {dir_enum}}}, // Map {map_id}'
elif spawn_type == 'vehicle':
direction = data_row['Direction']
direction_map = {'N': 'Direction.North', 'S': 'Direction.South', 'E': 'Direction.East', 'W': 'Direction.West'}
dir_enum = direction_map.get(direction, 'Direction.North')
return f'new Spawn(){{position = {position_str},path = "Assets/Prefabs/Vehicle.prefab", vehicleDirection = {dir_enum}}}, // Map {map_id}'
elif spawn_type == 'coin':
# 金币没有方向
return f'new Spawn(){{position = {position_str},path = "Assets/Prefabs/Prop_star.prefab",}},//金币位置{x},{y},z (Map {map_id})'
# 3. 生成完整的 C# Level 代码块
def generate_level_code(map_id, df_p_group, df_v_group, df_coin_group):
# 构建所有 Spawn 行
spawn_lines = []
# Player Spawns
spawn_lines.append('\n\t\t// --- Player Spawns ---')
for _, row in df_p_group.iterrows():
spawn_lines.append('\t\t' + generate_spawn_line(row, 'player'))
# Vehicle Spawns
spawn_lines.append('\n\t\t// --- Vehicle Spawns ---')
for _, row in df_v_group.iterrows():
spawn_lines.append('\t\t' + generate_spawn_line(row, 'vehicle'))
# Coin Spawns
spawn_lines.append('\n\t\t// --- Coin Spawns ---')
for _, row in df_coin_group.iterrows():
spawn_lines.append('\t\t' + generate_spawn_line(row, 'coin'))
spawns_block = '\n'.join(spawn_lines)
# 填充模板
code_template = f"""
\n\t\t// 关卡 {map_id}
\t\t{{ {map_id},new Level(){{LevelID = {map_id},spawns = new List<Spawn>(){{
{spawns_block}
\t\t}},
\t\tboundary = new Vector3Int(20,20,0), // 边界默认值
\t\tlevelPath = "{LEVEL_PATH.format(map_id=map_id)}"}}}},"""
return code_template
# 4. 主执行函数
def main():
df_p, df_v, df_coin = load_data()
if df_p is None:
return
# 获取所有唯一的地图号
all_map_ids = set(df_p['MapID'].unique()) | set(df_v['MapID'].unique()) | set(df_coin['MapID'].unique())
all_map_ids = sorted(list(all_map_ids)) # 按顺序生成
generated_code = []
print(f"发现 {len(all_map_ids)} 个唯一的地图号:{all_map_ids}")
for map_id in all_map_ids:
# 按当前 MapID 过滤数据
p_group = df_p[df_p['MapID'] == map_id] if map_id in df_p['MapID'].values else pd.DataFrame()
v_group = df_v[df_v['MapID'] == map_id] if map_id in df_v['MapID'].values else pd.DataFrame()
coin_group = df_coin[df_coin['MapID'] == map_id] if map_id in df_coin['MapID'].values else pd.DataFrame()
if not p_group.empty or not v_group.empty or not coin_group.empty:
code_block = generate_level_code(map_id, p_group, v_group, coin_group)
generated_code.append(code_block)
print(f"成功生成关卡 {map_id} 的代码块。")
else:
print(f"警告:地图 {map_id} 在所有文件中均无数据,跳过。")
# 将结果写入文件(在循环外,只写一次)
# 把 Levels80212.cs 的第1-10行作为文件头部, 最后3行作为结尾
header = '''using System;
using System.Collections.Generic;
using Platformer.Controller;
using UnityEngine;
using static Platformer.Manager.GameManager;
namespace Platformer.Core
{
public class Levels80001
{
public Dictionary<int, Level> Levels = new Dictionary<int, Level>()
{'''
footer = '''
};
};
}'''
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
f.write(header)
f.write('\t\t'.join(generated_code))
f.write(footer)
print(f"\n--- 所有代码已成功生成并保存到文件:{OUTPUT_FILE} ---")
if __name__ == "__main__":
main()