Cocos2d-x VS 工程配置:Win32 输出目录与资源自动复制

背景

做 Cocos2d-x 游戏经常要给策划和测试打包 Win32 版本。每次手动复制资源太麻烦了,这篇文章分享如何配置 VS 的输出目录和生成后事件,实现资源自动复制。

配置目标

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
项目目录
├── proj.win32/
│ ├── 项目名.sln
│ └── 项目名.vcxproj
├── Resources/ # 游戏资源目录
│ ├── images/
│ ├── sounds/
│ └── config/
├── Debug.win32/ # Debug 输出目录
│ ├── 项目名.exe
│ ├── images/ # 自动复制
│ ├── sounds/ # 自动复制
│ └── config/ # 自动复制
└── Release.win32/ # Release 输出目录
├── 项目名.exe
└── ...

配置步骤

1. 配置输出目录

位置: 项目属性 → 配置属性 → 常规 → 输出目录

配置值:

1
$(SolutionDir)$(Configuration).win32\

说明:

宏变量 含义
$(SolutionDir) 解决方案目录(以 \ 结尾)
$(Configuration) 当前配置(Debug 或 Release)

效果:

  • Debug 配置:项目目录/Debug.win32/
  • Release 配置:项目目录/Release.win32/

2. 配置中间文件目录

位置: 项目属性 → 配置属性 → 常规 → 中间目录

配置值:

1
$(Configuration).win32\\$(ProjectName).tlog\

3. 配置附加库目录

位置: 项目属性 → 链接器 → 常规 → 附加库目录

配置值:

1
$(SolutionDir)$(Configuration).win32

说明:

  • 设置链接器查找库文件的目录
  • 与输出目录保持一致

4. 配置生成后事件(自动复制资源)

位置: 项目属性 → 生成事件 → 生成后事件 → 命令行

添加命令:

1
2
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y

命令详解:

参数 说明
/D 仅复制新文件(根据日期判断)
/E 复制子目录,包括空目录
/I 如果目标目录不存在则创建
/F 显示复制的完整文件名
/Y 自动覆盖不提示

第一条命令: 复制 Resources 目录到输出目录

1
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
  • $(ProjectDir):项目文件目录
  • ..\Resources:项目目录的 Resources 文件夹
  • $(OutDir):输出目录(即前面配置的 $(Configuration).win32)

第二条命令: 复制 DLL 文件到输出目录

1
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
  • 复制 Cocos2d-x 引擎的 DLL 文件
  • 确保运行时可以找到依赖库

完整配置示例

.vcxproj 文件中的配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
<?xml version="1.0" encoding="utf-8"?>
<Project>
<!-- ... 其他配置 ... -->

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<!-- 输出目录 -->
<OutDir>$(SolutionDir)$(Configuration).win32\</OutDir>
<IntDir>$(Configuration).win32\$(ProjectName).tlog\</IntDir>

<!-- 生成后事件 -->
<PostBuildEvent>
<Command>
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
</Command>
</PostBuildEvent>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>$(SolutionDir)$(Configuration).win32\</OutDir>
<IntDir>$(Configuration).win32\$(ProjectName).tlog\</IntDir>

<PostBuildEvent>
<Command>
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
</Command>
</PostBuildEvent>
</PropertyGroup>

<!-- 链接器配置 -->
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Link>
<!-- 附加库目录 -->
<AdditionalLibraryDirectories>
$(SolutionDir)$(Configuration).win32
</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>

<!-- ... -->
</Project>

常见问题和解决方案

1. xcopy 命令失败

错误信息:

1
'xcopy' 不是内部或外部命令

解决方案:

1
2
3
4
<!-- 使用完整路径 -->
<Command>
"C:\Windows\System32\xcopy.exe" "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
</Command>

或者使用 robocopy(更现代的复制工具):

1
robocopy "$(ProjectDir)..\Resources" "$(OutDir)\Resources" /E /MIR

2. 路径包含空格导致失败

解决方案: 使用引号包裹路径

1
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y

3. 复制速度慢

优化方案: 只复制有变更的文件

1
2
<!-- 添加 /D 参数,只复制新文件 -->
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y

4. 排除特定文件

创建排除列表:

1
2
<!-- 使用 /EXCLUDE 参数 -->
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y /EXCLUDE:exclude.txt

exclude.txt 内容:

1
2
3
4
*.tmp
*.log
.svn\
.git\

5. 条件复制(Debug/Release 不同)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<PostBuildEvent>
<Command>
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
xcopy "$(ProjectDir)..\Resources-Debug" "$(OutDir)" /D /E /I /F /Y
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
</Command>
</PostBuildEvent>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<PostBuildEvent>
<Command>
xcopy "$(ProjectDir)..\Resources" "$(OutDir)" /D /E /I /F /Y
xcopy "$(ProjectDir)..\Resources-Release" "$(OutDir)" /D /E /I /F /Y
xcopy "$(OutDir)..\*.dll" "$(OutDir)" /D /Y
</Command>
</PostBuildEvent>
</PropertyGroup>

高级配置

使用 PowerShell 脚本

更灵活的资源复制方案:

1
2
3
4
5
<PostBuildEvent>
<Command>
powershell -ExecutionPolicy Bypass -Command "&amp; '$(ProjectDir)..\tools\copy-resources.ps1' -Source '$(ProjectDir)..\Resources' -Destination '$(OutDir)'"
</Command>
</PostBuildEvent>

copy-resources.ps1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
param(
[string]$Source,
[string]$Destination
)

# 确保目标目录存在
if (!(Test-Path $Destination)) {
New-Item -ItemType Directory -Path $Destination -Force
}

# 复制资源
Copy-Item -Path "$Source\*" -Destination $Destination -Recurse -Force

# 输出日志
Write-Host "Resources copied from $Source to $Destination"

# 可选:压缩资源
# Compress-Archive -Path "$Destination\*" -DestinationPath "$Destination\..\resources.zip" -Force

多平台资源管理

1
2
3
4
5
Resources/
├── common/ # 通用资源
├── win32/ # Win32 特有
├── android/ # Android 特有
└── ios/ # iOS 特有
1
2
3
4
5
<!-- 复制通用资源 -->
xcopy "$(ProjectDir)..\Resources\common" "$(OutDir)" /D /E /I /F /Y

<!-- 复制平台特有资源 -->
xcopy "$(ProjectDir)..\Resources\win32" "$(OutDir)" /D /E /I /F /Y

最佳实践

  1. 版本控制: 不要将输出目录(Debug.win32/Release.win32)提交到版本控制

  2. .gitignore 配置:

1
2
3
4
5
6
7
# Cocos2d-x Win32
Debug.win32/
Release.win32/
*.suo
*.user
*.tlog
ipch/
  1. 定期清理: 资源文件变更频繁时,定期清理输出目录

  2. 自动化测试: 结合 CI/CD 流程,自动执行构建和资源复制

小结

通过配置 VS 的输出目录和生成后事件,可以实现:

  • 清晰的目录结构
  • 自动的资源复制
  • 方便的测试分发
  • 高效的开发流程

配置要点:

  1. 输出目录:$(SolutionDir)$(Configuration).win32\
  2. 库目录:$(SolutionDir)$(Configuration).win32
  3. 生成后事件:使用 xcopy 自动复制资源和 DLL

搞定这些配置后,给测试发包就方便多了。