Complete Cocos Creator port with level bundles, themes, and tooling.

Adds level prefabs, theme assets, audio, extensions, and deployment scripts for the Unity WebGL migration.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-06-16 15:30:58 +08:00
parent cba5105908
commit d393302388
6248 changed files with 17322729 additions and 11036 deletions

View File

@@ -0,0 +1,171 @@
'use strict';
/** 各主题推荐贴图路径resources 相对路径,无 .png供编辑器「从主题填充」 */
/** Prop_kuai1 → nProp_kuai1Prop → nProp */
function propToGroundPath(blockPath) {
if (!blockPath) return '';
const norm = String(blockPath).trim().replace(/\\/g, '/');
const slash = norm.lastIndexOf('/');
const dir = slash >= 0 ? norm.slice(0, slash + 1) : '';
const file = slash >= 0 ? norm.slice(slash + 1) : norm;
if (file.startsWith('Prop_')) return `${dir}n${file}`;
if (file === 'Prop') return `${dir}nProp`;
if (file.startsWith('nProp')) return norm;
return norm.replace(/\/Prop([^/]*)$/, '/nProp$1');
}
function withPropGround(preset) {
return {
...preset,
propGround: propToGroundPath(preset.prop),
};
}
function vehicleFourWay(folder, prefix) {
const base = `textures/${folder}/${prefix}`;
return {
vehicleNorth: `${base}_N`,
vehicleEast: `${base}_E`,
vehicleSouth: `${base}_S`,
vehicleWest: `${base}_W`,
};
}
const THEME_ENTITY_PRESETS = {
default: withPropGround({
playerFront: 'textures/default/player_F',
playerBack: 'textures/default/player_B',
...vehicleFourWay('default', 'ship'),
prop: 'textures/default/Prop',
}),
silu: withPropGround({
playerFront: 'textures/silu/skin/待机正面/1',
playerBack: 'textures/silu/skin/待机背面/1',
...vehicleFourWay('silu', 'siluShip'),
prop: 'textures/silu/Prop_kuai1',
}),
chinese: withPropGround({
playerFront: 'textures/chinese/chineseShip_F',
playerBack: 'textures/chinese/chineseShip_B',
...vehicleFourWay('chinese', 'chineseShip'),
prop: 'textures/chinese/Prop_kuai1',
}),
sanxing: withPropGround({
playerFront: 'textures/sanxing/skin/待机正面/1',
playerBack: 'textures/sanxing/skin/待机背面/1',
...vehicleFourWay('sanxing', 'sanxingShip'),
prop: 'textures/sanxing/Prop_kuai1',
}),
snow: withPropGround({
playerFront: 'textures/snow/skin/待机正面/1',
playerBack: 'textures/snow/skin/待机背面/1',
...vehicleFourWay('snow', 'snowShip'),
prop: 'textures/snow/Prop_kuai1',
}),
numMan: withPropGround({
playerFront: 'textures/numMan/skin/待机正面/1',
playerBack: 'textures/numMan/skin/待机背面/1',
...vehicleFourWay('numMan', 'numManShip'),
prop: 'textures/numMan/Prop_kuai11',
}),
redArmy: withPropGround({
playerFront: 'textures/redArmy/skin/待机正面/1',
playerBack: 'textures/redArmy/skin/待机背面/1',
...vehicleFourWay('redArmy', 'redArmyShip'),
prop: 'textures/redArmy/Prop_kuai1',
}),
redarmy: withPropGround({
playerFront: 'textures/redArmy/skin/待机正面/1',
playerBack: 'textures/redArmy/skin/待机背面/1',
...vehicleFourWay('redArmy', 'redArmyShip'),
prop: 'textures/redArmy/Prop_kuai1',
}),
};
const ENTITY_TEXTURE_FIELDS = [
{ key: 'playerFront', label: '角色正面' },
{ key: 'playerBack', label: '角色背面' },
{ key: 'vehicleNorth', label: '载具北' },
{ key: 'vehicleEast', label: '载具东' },
{ key: 'vehicleSouth', label: '载具南' },
{ key: 'vehicleWest', label: '载具西' },
{ key: 'prop', label: '可拾取物(砖块 Prop)' },
{ key: 'propGround', label: '可拾取物(空地 nProp)' },
];
function normalizeTexturePath(raw) {
if (!raw) return '';
let p = String(raw).trim().replace(/\\/g, '/');
if (p.startsWith('assets/resources/')) p = p.slice('assets/resources/'.length);
if (p.startsWith('resources/')) p = p.slice('resources/'.length);
if (p.startsWith('/')) p = p.slice(1);
if (p.endsWith('.png')) p = p.slice(0, -4);
return p;
}
function ensureEntityTextures(state) {
if (!state.config) return null;
if (!state.config.entityTextures || typeof state.config.entityTextures !== 'object') {
state.config.entityTextures = {};
}
return state.config.entityTextures;
}
function presetForTheme(theme) {
return THEME_ENTITY_PRESETS[theme] || THEME_ENTITY_PRESETS.silu;
}
function applyThemePreset(state, theme) {
const et = ensureEntityTextures(state);
if (!et) return false;
const preset = presetForTheme(theme || state.theme || 'silu');
Object.assign(et, { ...preset });
return true;
}
function readEntityTexturesFromPanel(listEl) {
const out = {};
for (const f of ENTITY_TEXTURE_FIELDS) {
const el = listEl?.querySelector(`#entity-tex-${f.key}`);
const v = normalizeTexturePath(el?.value || '');
if (v) out[f.key] = v;
}
return out;
}
function writeEntityTexturesToPanel(listEl, entityTextures) {
const et = entityTextures || {};
for (const f of ENTITY_TEXTURE_FIELDS) {
const el = listEl?.querySelector(`#entity-tex-${f.key}`);
if (el) el.value = et[f.key] || '';
}
}
function pruneEmptyEntityTextures(state) {
const et = state.config?.entityTextures;
if (!et) return;
let hasAny = false;
for (const f of ENTITY_TEXTURE_FIELDS) {
const v = normalizeTexturePath(et[f.key]);
if (v) {
et[f.key] = v;
hasAny = true;
} else {
delete et[f.key];
}
}
if (!hasAny) delete state.config.entityTextures;
}
module.exports = {
THEME_ENTITY_PRESETS,
ENTITY_TEXTURE_FIELDS,
normalizeTexturePath,
ensureEntityTextures,
presetForTheme,
applyThemePreset,
readEntityTexturesFromPanel,
writeEntityTexturesToPanel,
pruneEmptyEntityTextures,
};