ç½é¡µç¶
1. 环境要求¶
- Node.js 18+
- npm 或 yarn
- 现代浏览器(支持ES2020+、WebGL 2.0、Web Audio API)
- 支持File System Access API的浏览器(推荐Chrome/Edge)
- 网页版地址是 ra2web.com,下面的项目是源码
2. 安装步骤¶
-
克隆项目
-
安装依赖
-
启动开发服务器
-
访问应用 打开浏览器访问
http://localhost:3000 - 调试模式:
http://localhost:3000?test=glsl- GLSL着色器测试http://localhost:3000?debug=true- 启用调试模式
3. 问题解决¶
3.1 网页打开报错¶
使用以下patch,以下内容复制成patch文件,然后patch -p1 < ~/diff.patch
Diff
diff --git a/src/data/vfs/VirtualFileSystem.ts b/src/data/vfs/VirtualFileSystem.ts
index 8215b89..6c8b8fd 100644
--- a/src/data/vfs/VirtualFileSystem.ts
+++ b/src/data/vfs/VirtualFileSystem.ts
@@ -7,7 +7,7 @@ import { pad } from "../../util/string";
import { FileNotFoundError } from "./FileNotFoundError";
import { MemArchive } from "./MemArchive";
import type { VirtualFile } from "./VirtualFile";
-import AppLogger from "../../util/Logger"; // Import the default export
+import AppLogger from "../../util/logger"; // Import the default export
import type { RealFileSystem } from "./RealFileSystem"; // Assuming RFS interface/type
// Define a generic interface for archive types for better type safety
diff --git a/src/engine/Engine.ts b/src/engine/Engine.ts
index 0e45e88..e998139 100644
--- a/src/engine/Engine.ts
+++ b/src/engine/Engine.ts
@@ -20,7 +20,7 @@ import * as stringUtils from '../util/string';
import { MapList } from './MapList';
import { HvaFile } from '../data/HvaFile';
import { MixinRulesType } from '../game/ini/MixinRulesType';
-import type { AppLogger as AppLoggerType } from '../util/Logger'; // Changed to lowercase, aliased for clarity
+import type { AppLogger as AppLoggerType } from '../util/logger'; // Changed to lowercase, aliased for clarity
import type { DataStream } from '../data/DataStream'; // For VFS openFile result stream
export enum EngineType {
diff --git a/src/engine/gameRes/GameRes.ts b/src/engine/gameRes/GameRes.ts
index 83f8cc4..ecd2582 100644
--- a/src/engine/gameRes/GameRes.ts
+++ b/src/engine/gameRes/GameRes.ts
@@ -5,7 +5,7 @@ import { VirtualFileSystem } from '../../data/vfs/VirtualFileSystem';
import { Engine, EngineType } from '../Engine';
import { ResourceLoader, LoaderResult } from '../ResourceLoader';
import { DownloadError } from '../../network/HttpRequest';
-import { AppLogger } from '../../util/Logger'; // Assuming AppLogger is exported or can be typed
+import { AppLogger } from '../../util/logger'; // Assuming AppLogger is exported or can be typed
import { GameResConfig } from './GameResConfig';
import { ChecksumError } from './importError/ChecksumError';
import { FileNotFoundError as GameResFileNotFoundError } from './importError/FileNotFoundError'; // Alias to avoid clash
diff --git a/src/engine/gfx/batch/MergedSpriteMesh.ts b/src/engine/gfx/batch/MergedSpriteMesh.ts
index 386e432..7137c2c 100644
--- a/src/engine/gfx/batch/MergedSpriteMesh.ts
+++ b/src/engine/gfx/batch/MergedSpriteMesh.ts
@@ -1,5 +1,5 @@
import * as THREE from 'three';
-import * as arrayUtils from '../../../util/Array';
+import * as arrayUtils from '../../../util/array';
import { PaletteBasicMaterial } from '../material/PaletteBasicMaterial';
// 临时向量,用于位置计算
diff --git a/src/engine/renderable/entity/WaypointLines.ts b/src/engine/renderable/entity/WaypointLines.ts
index 27271fb..f3344dc 100644
--- a/src/engine/renderable/entity/WaypointLines.ts
+++ b/src/engine/renderable/entity/WaypointLines.ts
@@ -1,6 +1,6 @@
import { Coords } from "@/game/Coords";
import { TargetLinesConfig, configHasTarget } from "@/game/gameobject/task/system/TargetLinesConfig";
-import { equals } from "@/util/Array";
+import { equals } from "@/util/array";
import { WaypointLine } from "@/engine/renderable/entity/WaypointLine";
import * as THREE from "three";
diff --git a/src/game/BotManager.ts b/src/game/BotManager.ts
index 18a528c..42c4f7b 100644
--- a/src/game/BotManager.ts
+++ b/src/game/BotManager.ts
@@ -1,5 +1,5 @@
import { CompositeDisposable } from '../util/disposable/CompositeDisposable';
-import { AppLogger } from '@/util/Logger';
+import { AppLogger } from '@/util/logger';
import { ActionQueue } from './action/ActionQueue';
import { ActionsApi } from './api/ActionsApi';
import { EventsApi } from './api/EventsApi';
diff --git a/src/game/api/LoggerApi.ts b/src/game/api/LoggerApi.ts
index 637ac1b..701001f 100644
--- a/src/game/api/LoggerApi.ts
+++ b/src/game/api/LoggerApi.ts
@@ -1,5 +1,5 @@
import { formatTimeDuration } from '@/util/format';
-import { AppLogger } from '@/util/Logger';
+import { AppLogger } from '@/util/logger';
export class LoggerApi {
private logger: typeof AppLogger;
diff --git a/src/game/gameobject/task/move/MoveTask.ts b/src/game/gameobject/task/move/MoveTask.ts
index f1a470b..ada6eb3 100644
--- a/src/game/gameobject/task/move/MoveTask.ts
+++ b/src/game/gameobject/task/move/MoveTask.ts
@@ -1,7 +1,7 @@
import { Task } from "@/game/gameobject/task/system/Task";
import { Infantry } from "@/game/gameobject/Infantry";
import { MovementZone } from "@/game/type/MovementZone";
-import { findIndexReverse, findReverse } from "@/util/Array";
+import { findIndexReverse, findReverse } from "@/util/array";
import { SpeedType } from "@/game/type/SpeedType";
import { MoveState, CollisionState, MoveResult, MoveTrait } from "@/game/gameobject/trait/MoveTrait";
import { WaitTicksTask } from "@/game/gameobject/task/system/WaitTicksTask";
@@ -9,7 +9,8 @@ import { MoveAsideTask } from "@/game/gameobject/task/move/MoveAsideTask";
import { MovePositionHelper } from "@/game/gameobject/unit/MovePositionHelper";
import { RadialTileFinder } from "@/game/map/tileFinder/RadialTileFinder";
import { RangeHelper } from "@/game/gameobject/unit/RangeHelper";
-import { AppLogger, Logger } from "@/util/Logger";
+import { AppLogger } from "@/util/logger";
+import type { ILogger } from 'js-logger';
import { Coords } from "@/game/Coords";
import { TaskStatus } from "@/game/gameobject/task/system/TaskStatus";
import { ZoneType } from "@/game/gameobject/unit/ZoneType";
@@ -80,7 +81,7 @@ export class MoveTask extends Task {
private toBridge: boolean;
private options?: MoveOptions;
public preventOpportunityFire = false;
- private logger: Logger;
+ private logger: ILogger;
private destinationLeptons: Vector2;
private currentWaypointLeptons: Vector2;
private needsPathUpdate = false;
diff --git a/src/gui/PointerEvents.ts b/src/gui/PointerEvents.ts
index 19d94bb..65afd79 100644
--- a/src/gui/PointerEvents.ts
+++ b/src/gui/PointerEvents.ts
@@ -1,6 +1,6 @@
-import { CompositeDisposable } from '../util/disposable/CompositeDisposable';
-import { equals } from '../util/Array';
-import { clamp } from '../util/math';
+import { CompositeDisposable } from "../util/disposable/CompositeDisposable";
+import { equals } from '../util/array';
+import { clamp } from "../util/math";
import * as THREE from 'three';
// 类型定义
diff --git a/src/gui/component/GameResourcesViewer.tsx b/src/gui/component/GameResourcesViewer.tsx
index 887e22c..d09a13b 100644
--- a/src/gui/component/GameResourcesViewer.tsx
+++ b/src/gui/component/GameResourcesViewer.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import { Engine } from '../../engine/Engine';
-import AppLogger from '../../util/Logger';
+import AppLogger from '../../util/logger';
// Global types are defined in src/types/global.d.ts
diff --git a/src/gui/screen/game/component/hud/SidebarPower.ts b/src/gui/screen/game/component/hud/SidebarPower.ts
index c314a1d..bda041d 100644
--- a/src/gui/screen/game/component/hud/SidebarPower.ts
+++ b/src/gui/screen/game/component/hud/SidebarPower.ts
@@ -9,7 +9,7 @@ import { clamp } from "@/util/math";
import { TextureUtils } from "@/engine/gfx/TextureUtils";
import { HighlightAnimRunner } from "@/engine/renderable/entity/HighlightAnimRunner";
import { BoxedVar } from "@/util/BoxedVar";
-import { findReverse } from "@/util/Array";
+import { findReverse } from "@/util/array";
import { PaletteBasicMaterial } from "@/engine/gfx/material/PaletteBasicMaterial";
type SidebarPowerModel = {
diff --git a/src/gui/screen/mainMenu/lobby/SkirmishScreen.ts b/src/gui/screen/mainMenu/lobby/SkirmishScreen.ts
index c1fd1c3..5d83d87 100644
--- a/src/gui/screen/mainMenu/lobby/SkirmishScreen.ts
+++ b/src/gui/screen/mainMenu/lobby/SkirmishScreen.ts
@@ -25,7 +25,7 @@ import { HtmlView } from "@/gui/jsx/HtmlView";
// DownloadError - 暂时注释,使用any类型替代
// import { CancellationTokenSource, OperationCanceledError } from "@puzzl/core/lib/async/cancellation"; // 未使用
import { MapPreviewRenderer } from "@/gui/screen/mainMenu/lobby/MapPreviewRenderer";
-import { findIndexReverse } from "@/util/Array";
+import { findIndexReverse } from "@/util/array";
import { StorageKey } from "@/LocalPrefs";
import { isNotNullOrUndefined } from "@/util/typeGuard";
import { PreferredHostOpts } from "./PreferredHostOpts";
diff --git a/src/gui/screen/options/component/StorageExplorer.tsx b/src/gui/screen/options/component/StorageExplorer.tsx
index 33cb019..ffaefee 100644
--- a/src/gui/screen/options/component/StorageExplorer.tsx
+++ b/src/gui/screen/options/component/StorageExplorer.tsx
@@ -1,6 +1,6 @@
import React, { useEffect, useRef, useState } from 'react';
import { Engine } from '../../../../engine/Engine';
-import AppLogger from '../../../../util/Logger';
+import AppLogger from '../../../../util/logger';
import { Strings } from '../../../../data/Strings';
import { MessageBoxApi } from '../../../component/MessageBoxApi';
diff --git a/vite.config.ts b/vite.config.ts
index a74a036..13db9ff 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -6,6 +6,9 @@ export default defineConfig({
plugins: [react()],
server: {
port: 3000, // 您可以根据需要更改端口
+ host: 'localhost', // 明确指定 host
+ // 注意:这些 CORS 头部需要在生产环境中启用以支持 SharedArrayBuffer
+ // 如果遇到跨域问题,请临时注释掉
headers: {
'Cross-Origin-Embedder-Policy': 'require-corp',
'Cross-Origin-Opener-Policy': 'same-origin',
3.2 缺少资源文件¶
下载 https://download.ra2web.com/full-pack.7z ,网页中选择此打包文件,或者选择解压出来的文件夹。