Починен зелёный экран: все узлы были не на том слое
nodeCreate кладёт узел на слой DEFAULT, а камера Canvas рисует только UI_2D. Поэтому сборка показывала цвет очистки камеры и больше ничего. В редакторе это не видно вообще: камера вида сцены рисует все слои, так что сцена выглядит правильной, а билд — пустым. - 45 узлов в обеих сценах и префабе переведены на слой UI_2D - scripts/check-scenes.mjs: headless-проверка сцен и префабов — слои, наличие камеры у Canvas, видимость UI_2D у камеры, незаполненные ссылки в наших компонентах. Проверено, что она действительно падает на подсунутом неверном слое - npm run check — всё разом (чистота core, сцены, типы, тесты) - Bootstrap теперь докладывает каждый шаг в лейбл и в консоль и через 10 секунд уходит в лобби даже если арт не догрузился: молча висящий загрузчик — худший вид бага в отчёте - ловушка со слоями описана в docs/CODE_MODE_SETUP.md Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,42 +1,81 @@
|
||||
import { _decorator, Component, director, game, resources, SpriteFrame } from 'cc';
|
||||
import { _decorator, Component, director, game, Label, resources, SpriteFrame } from 'cc';
|
||||
import { App } from './App';
|
||||
import { CARDS_DIR } from '../ui/game/CardLibrary';
|
||||
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** If the art has not arrived by then, open the lobby anyway rather than hang. */
|
||||
const PRELOAD_TIMEOUT = 10;
|
||||
|
||||
/**
|
||||
* The loader scene, per ARCHITECTURE.md: bring the modules up, then hand over
|
||||
* to the lobby. Everything that must exist before any gameplay runs belongs
|
||||
* here, and nowhere else.
|
||||
*
|
||||
* Every step reports itself to the on-screen label and to the console, because
|
||||
* a loader that stalls silently is the hardest kind of bug to diagnose from a
|
||||
* bug report — "it shows a green screen" should never again be all we know.
|
||||
*/
|
||||
@ccclass('Bootstrap')
|
||||
export class Bootstrap extends Component {
|
||||
@property({ tooltip: 'Scene to open once the modules are ready.' })
|
||||
nextScene = 'lobby';
|
||||
|
||||
@property({ type: Label, tooltip: 'Shows what the loader is doing.' })
|
||||
statusLabel: Label | null = null;
|
||||
|
||||
private _handedOver = false;
|
||||
|
||||
start(): void {
|
||||
// A phone that throttles to 30 fps makes the card animations stutter;
|
||||
// asking for 60 up front is cheap and the engine falls back on its own.
|
||||
game.frameRate = 60;
|
||||
|
||||
this._report('starting modules');
|
||||
App.create();
|
||||
|
||||
// Warm the card art here rather than on the first deal: thirty-seven
|
||||
// sprites are the only sizeable load in the game, and a loader scene is
|
||||
// exactly where a player expects to wait for it.
|
||||
resources.loadDir(CARDS_DIR, SpriteFrame, (error) => {
|
||||
this._report('loading cards');
|
||||
resources.loadDir(CARDS_DIR, SpriteFrame, (error, frames) => {
|
||||
if (error) {
|
||||
console.error('[bootstrap] could not preload the card art', error);
|
||||
} else {
|
||||
console.log(`[bootstrap] ${frames.length} card sprites ready`);
|
||||
}
|
||||
this._openLobby();
|
||||
});
|
||||
|
||||
// A failed bundle can leave that callback unfired. The lobby does not
|
||||
// need the art to show, so never let the loader be a dead end.
|
||||
this.scheduleOnce(() => {
|
||||
if (!this._handedOver) {
|
||||
console.warn('[bootstrap] card art did not arrive in time, opening the lobby anyway');
|
||||
this._openLobby();
|
||||
}
|
||||
}, PRELOAD_TIMEOUT);
|
||||
}
|
||||
|
||||
private _openLobby(): void {
|
||||
if (this._handedOver) {
|
||||
return;
|
||||
}
|
||||
this._handedOver = true;
|
||||
|
||||
this._report('opening lobby');
|
||||
director.loadScene(this.nextScene, (error) => {
|
||||
if (error) {
|
||||
console.error(`[bootstrap] could not open '${this.nextScene}'`, error);
|
||||
this._report(`could not open ${this.nextScene}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _report(what: string): void {
|
||||
console.log(`[bootstrap] ${what}`);
|
||||
if (this.statusLabel) {
|
||||
this.statusLabel.string = what;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user