

我想移植一个游戏到网页上,搞到了c语言源码和exe文件,并用emscripten编译了源码,得到了一个html,一个js,一个wasm。后来我发现源码里没有data目录,就从exe文件里找了个data.bin,看类型是zip,我就解压了,解压后还打开看了一眼,都是正常的。我把data目录放进html文件所在的文件夹,运行python -m http.server后就出现如图所示的报错,可是我明明有data文件啊?我开了无痕浏览,所以不是缓存问题。求解


晚上好🌙🌙🌙
本答案参考通义千问
你遇到的问题是关于 Emscripten 编译后游戏在网页上运行时提示找不到 data 目录。虽然你已经将 data 文件夹放到了 HTML 文件所在的目录中,但仍然报错,这可能是因为 Emscripten 的文件系统加载方式 和你的本地文件结构不匹配。
Emscripten 默认使用虚拟文件系统(FS)
Emscripten 在编译时会将一些资源(如 data 文件)打包进 .wasm 或 .js 文件中,或者通过 预加载机制 加载外部文件。
data.bin 是 ZIP 格式,可能是资源包
你从 .exe 中提取的 data.bin 实际上是一个 ZIP 压缩包,里面包含了游戏所需的资源文件(图片、声音等),但 它并不是一个“目录”,而是一个压缩文件。
HTML 文件和 data 目录不在同一个路径下
虽然你把 data 放到了 HTML 所在的目录,但 Emscripten 可能期望的是 相对路径或特定的加载方式,而不是简单的文件夹。
没有正确配置 Emscripten 的资源加载路径
如果你在编译时没有设置正确的路径,或者没有使用 --preload-file 参数,那么 Emscripten 无法自动加载 data 目录。
data.bin 的用途data.bin,确认其中是否包含游戏资源。data.zip 并放在 HTML 同级目录中。--preload-file 参数重新编译如果你还没有用 --preload-file 预加载 data.zip,请重新编译源码:
emcc -O3 -s WASM=1 -s EXPORTED_FUNCTIONS="['_main']" -s EXPORTED_RUNTIME_METHODS="['cwrap', 'getValue', 'Pointer_stringify']" \
-s "MODULARIZE=1" -s "EXPORT_NAME='Game'"\
-s "PRELOAD_FILE=data.zip:/" \
your_source.c -o game.html
注意:
-s PRELOAD_FILE=data.zip:/表示将data.zip作为根目录/加载到虚拟文件系统中。
确保 HTML 文件中引用了正确的路径。例如:
<script src="game.js"></script>
并确保 data.zip 与 game.js 在同一目录下。
打开浏览器的开发者工具(F12),查看控制台是否有以下错误:
Failed to load resource: the server responded with a 404Uncaught Error: Could not find data fileFile not found in FS: /data/...这些信息可以帮助你定位具体缺失的文件或路径。
fetch 动态加载资源(可选)如果上述方法仍无效,可以尝试手动加载 data.zip,并在 JS 中解压它:
// game.js
const fs = require('fs');
const path = require('path');
function loadZip() {
fetch('data.zip')
.then(res => res.arrayBuffer())
.then(data => {
const zip = new JSZip();
zip.loadAsync(data).then(zip => {
zip.forEach((relativePath, file) => {
file.async('blob').then(blob => {
// 将文件写入虚拟文件系统
FS.createDataFile('/', relativePath, blob, true, true);
});
});
});
});
}
// 在 Game 初始化前调用
loadZip();
注意:这段代码需要配合
JSZip库使用,并且要确保在 Emscripten 的 JS 中引入。
| 步骤 | 内容 |
|------|------|
| 1 | 确认 data.bin 是否为 ZIP 文件,必要时重命名 |
| 2 | 使用 --preload-file=data.zip:/ 重新编译 |
| 3 | 确保 data.zip 与 game.js 在同一目录 |
| 4 | 检查浏览器控制台错误信息 |
| 5 | 如需动态加载,可使用 fetch + JSZip 方式加载 ZIP 文件 |
FILE *fp = fopen("/data/somefile.dat", "rb");
如有更多细节(比如你使用的 Emscripten 版本、源码结构、报错截图等),我可以进一步帮你调试!