mirror of
https://github.com/tobspr/shapez.io.git
synced 2025-06-13 13:04:03 +00:00
[WIP] Add mode menu. Add factory-based gameMode creation
This commit is contained in:
parent
5ccb2dbd0a
commit
6f0a32f054
@ -5,6 +5,7 @@ import { Factory } from "./factory";
|
|||||||
* @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed
|
* @typedef {import("../game/time/base_game_speed").BaseGameSpeed} BaseGameSpeed
|
||||||
* @typedef {import("../game/component").Component} Component
|
* @typedef {import("../game/component").Component} Component
|
||||||
* @typedef {import("../game/base_item").BaseItem} BaseItem
|
* @typedef {import("../game/base_item").BaseItem} BaseItem
|
||||||
|
* @typedef {import("../game/game_mode").GameMode} GameMode
|
||||||
* @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding
|
* @typedef {import("../game/meta_building").MetaBuilding} MetaBuilding
|
||||||
|
|
||||||
|
|
||||||
@ -19,6 +20,9 @@ export let gBuildingsByCategory = null;
|
|||||||
/** @type {FactoryTemplate<Component>} */
|
/** @type {FactoryTemplate<Component>} */
|
||||||
export let gComponentRegistry = new Factory("component");
|
export let gComponentRegistry = new Factory("component");
|
||||||
|
|
||||||
|
/** @type {FactoryTemplate<GameMode>} */
|
||||||
|
export let gGameModeRegistry = new Factory("gameMode");
|
||||||
|
|
||||||
/** @type {FactoryTemplate<BaseGameSpeed>} */
|
/** @type {FactoryTemplate<BaseGameSpeed>} */
|
||||||
export let gGameSpeedRegistry = new Factory("gamespeed");
|
export let gGameSpeedRegistry = new Factory("gamespeed");
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import {
|
|||||||
registerCanvas,
|
registerCanvas,
|
||||||
} from "../core/buffer_utils";
|
} from "../core/buffer_utils";
|
||||||
import { globalConfig } from "../core/config";
|
import { globalConfig } from "../core/config";
|
||||||
|
import { gGameModeRegistry } from "./game_mode_registry";
|
||||||
import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
|
import { getDeviceDPI, resizeHighDPICanvas } from "../core/dpi_manager";
|
||||||
import { DrawParameters } from "../core/draw_parameters";
|
import { DrawParameters } from "../core/draw_parameters";
|
||||||
import { gMetaBuildingRegistry } from "../core/global_registries";
|
import { gMetaBuildingRegistry } from "../core/global_registries";
|
||||||
@ -31,7 +32,7 @@ import { KeyActionMapper } from "./key_action_mapper";
|
|||||||
import { GameLogic } from "./logic";
|
import { GameLogic } from "./logic";
|
||||||
import { MapView } from "./map_view";
|
import { MapView } from "./map_view";
|
||||||
import { defaultBuildingVariant } from "./meta_building";
|
import { defaultBuildingVariant } from "./meta_building";
|
||||||
import { RegularGameMode } from "./modes/regular";
|
import { GameMode } from "./game_mode";
|
||||||
import { ProductionAnalytics } from "./production_analytics";
|
import { ProductionAnalytics } from "./production_analytics";
|
||||||
import { GameRoot } from "./root";
|
import { GameRoot } from "./root";
|
||||||
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
import { ShapeDefinitionManager } from "./shape_definition_manager";
|
||||||
@ -104,7 +105,7 @@ export class GameCore {
|
|||||||
root.dynamicTickrate = new DynamicTickrate(root);
|
root.dynamicTickrate = new DynamicTickrate(root);
|
||||||
|
|
||||||
// Init game mode
|
// Init game mode
|
||||||
root.gameMode = new RegularGameMode(root);
|
root.gameMode = GameMode.create(root);
|
||||||
|
|
||||||
// Init classes
|
// Init classes
|
||||||
root.camera = new Camera(root);
|
root.camera = new Camera(root);
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
/* typehints:start */
|
/* typehints:start */
|
||||||
import { enumHubGoalRewards } from "./tutorial_goals";
|
import { enumHubGoalRewards } from "./tutorial_goals";
|
||||||
|
import { GameRoot } from "./root";
|
||||||
/* typehints:end */
|
/* typehints:end */
|
||||||
|
|
||||||
import { GameRoot } from "./root";
|
import { gGameModeRegistry } from "../core/global_registries";
|
||||||
|
import { types, BasicSerializableObject } from "../savegame/serialization";
|
||||||
|
|
||||||
/** @typedef {{
|
/** @typedef {{
|
||||||
* shape: string,
|
* shape: string,
|
||||||
@ -24,13 +26,43 @@ import { GameRoot } from "./root";
|
|||||||
* throughputOnly?: boolean
|
* throughputOnly?: boolean
|
||||||
* }} LevelDefinition */
|
* }} LevelDefinition */
|
||||||
|
|
||||||
export class GameMode {
|
export class GameMode extends BasicSerializableObject {
|
||||||
/**
|
/** @returns {string} */
|
||||||
*
|
static getId() {
|
||||||
* @param {GameRoot} root
|
abstract;
|
||||||
*/
|
return "unknown-mode";
|
||||||
|
}
|
||||||
|
|
||||||
|
static getSchema() {
|
||||||
|
return {
|
||||||
|
id: types.string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static create (root) {
|
||||||
|
let id;
|
||||||
|
|
||||||
|
if (!root.savegame.gameMode || !root.savegame.gameMode.id) {
|
||||||
|
id = "Regular";
|
||||||
|
} else {
|
||||||
|
id = root.savegame.gameMode.id
|
||||||
|
}
|
||||||
|
|
||||||
|
const Mode = gGameModeRegistry.findById(id);
|
||||||
|
|
||||||
|
return new Mode(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @param {GameRoot} root */
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
|
super();
|
||||||
this.root = root;
|
this.root = root;
|
||||||
|
this.id = this.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
getId() {
|
||||||
|
// @ts-ignore
|
||||||
|
return this.constructor.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
10
src/js/game/game_mode_registry.js
Normal file
10
src/js/game/game_mode_registry.js
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { gGameModeRegistry } from "../core/global_registries";
|
||||||
|
import { PuzzleEditGameMode } from "./modes/puzzle_edit";
|
||||||
|
import { PuzzlePlayGameMode } from "./modes/puzzle_play";
|
||||||
|
import { RegularGameMode } from "./modes/regular";
|
||||||
|
|
||||||
|
export function initGameModeRegistry() {
|
||||||
|
gGameModeRegistry.register(PuzzleEditGameMode);
|
||||||
|
gGameModeRegistry.register(PuzzlePlayGameMode);
|
||||||
|
gGameModeRegistry.register(RegularGameMode);
|
||||||
|
}
|
11
src/js/game/modes/puzzle_edit.js
Normal file
11
src/js/game/modes/puzzle_edit.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { GameMode } from "../game_mode";
|
||||||
|
|
||||||
|
export class PuzzleEditGameMode extends GameMode {
|
||||||
|
static getId() {
|
||||||
|
return "PuzzleEdit";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(root) {
|
||||||
|
super(root);
|
||||||
|
}
|
||||||
|
}
|
11
src/js/game/modes/puzzle_play.js
Normal file
11
src/js/game/modes/puzzle_play.js
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { GameMode } from "../game_mode";
|
||||||
|
|
||||||
|
export class PuzzlePlayGameMode extends GameMode {
|
||||||
|
static getId() {
|
||||||
|
return "PuzzlePlay";
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(root) {
|
||||||
|
super(root);
|
||||||
|
}
|
||||||
|
}
|
@ -454,6 +454,10 @@ const fullVersionLevels = generateLevelDefinitions(false);
|
|||||||
const demoVersionLevels = generateLevelDefinitions(true);
|
const demoVersionLevels = generateLevelDefinitions(true);
|
||||||
|
|
||||||
export class RegularGameMode extends GameMode {
|
export class RegularGameMode extends GameMode {
|
||||||
|
static getId() {
|
||||||
|
return "Regular";
|
||||||
|
}
|
||||||
|
|
||||||
constructor(root) {
|
constructor(root) {
|
||||||
super(root);
|
super(root);
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ import { initComponentRegistry } from "./game/component_registry";
|
|||||||
import { initDrawUtils } from "./core/draw_utils";
|
import { initDrawUtils } from "./core/draw_utils";
|
||||||
import { initItemRegistry } from "./game/item_registry";
|
import { initItemRegistry } from "./game/item_registry";
|
||||||
import { initMetaBuildingRegistry } from "./game/meta_building_registry";
|
import { initMetaBuildingRegistry } from "./game/meta_building_registry";
|
||||||
|
import { initGameModeRegistry } from "./game/game_mode_registry";
|
||||||
import { initGameSpeedRegistry } from "./game/game_speed_registry";
|
import { initGameSpeedRegistry } from "./game/game_speed_registry";
|
||||||
|
|
||||||
const logger = createLogger("main");
|
const logger = createLogger("main");
|
||||||
@ -81,6 +82,7 @@ initDrawUtils();
|
|||||||
initComponentRegistry();
|
initComponentRegistry();
|
||||||
initItemRegistry();
|
initItemRegistry();
|
||||||
initMetaBuildingRegistry();
|
initMetaBuildingRegistry();
|
||||||
|
initGameModeRegistry();
|
||||||
initGameSpeedRegistry();
|
initGameSpeedRegistry();
|
||||||
|
|
||||||
let app = null;
|
let app = null;
|
||||||
|
@ -33,6 +33,7 @@ export class SavegameSerializer {
|
|||||||
camera: root.camera.serialize(),
|
camera: root.camera.serialize(),
|
||||||
time: root.time.serialize(),
|
time: root.time.serialize(),
|
||||||
map: root.map.serialize(),
|
map: root.map.serialize(),
|
||||||
|
gameMode: root.gameMode.serialize(),
|
||||||
entityMgr: root.entityMgr.serialize(),
|
entityMgr: root.entityMgr.serialize(),
|
||||||
hubGoals: root.hubGoals.serialize(),
|
hubGoals: root.hubGoals.serialize(),
|
||||||
pinnedShapes: root.hud.parts.pinnedShapes.serialize(),
|
pinnedShapes: root.hud.parts.pinnedShapes.serialize(),
|
||||||
|
@ -207,6 +207,11 @@ export class MainMenuState extends GameState {
|
|||||||
const qs = this.htmlElement.querySelector.bind(this.htmlElement);
|
const qs = this.htmlElement.querySelector.bind(this.htmlElement);
|
||||||
|
|
||||||
if (G_IS_DEV && globalConfig.debug.fastGameEnter) {
|
if (G_IS_DEV && globalConfig.debug.fastGameEnter) {
|
||||||
|
if (globalConfig.debug.testPuzzleMode) {
|
||||||
|
this.onPuzzlePlayButtonClicked();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
const games = this.app.savegameMgr.getSavegamesMetaData();
|
const games = this.app.savegameMgr.getSavegamesMetaData();
|
||||||
if (games.length > 0 && globalConfig.debug.resumeGameOnFastEnter) {
|
if (games.length > 0 && globalConfig.debug.resumeGameOnFastEnter) {
|
||||||
this.resumeGame(games[0]);
|
this.resumeGame(games[0]);
|
||||||
@ -308,21 +313,65 @@ export class MainMenuState extends GameState {
|
|||||||
buttonContainer.appendChild(importButtonElement);
|
buttonContainer.appendChild(importButtonElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
const modeButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
const bottomButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
||||||
removeAllChildren(modeButtonContainer);
|
removeAllChildren(bottomButtonContainer);
|
||||||
|
|
||||||
const puzzleModeButton = makeButton(
|
const puzzleModeButton = makeButton(
|
||||||
modeButtonContainer,
|
bottomButtonContainer,
|
||||||
["styledButton"],
|
["styledButton"],
|
||||||
T.mainMenu.puzzleMode
|
T.mainMenu.puzzleMode
|
||||||
);
|
);
|
||||||
|
|
||||||
modeButtonContainer.appendChild(puzzleModeButton);
|
bottomButtonContainer.appendChild(puzzleModeButton);
|
||||||
this.trackClicks(puzzleModeButton, this.onPuzzleModeButtonClicked);
|
this.trackClicks(puzzleModeButton, this.onPuzzleModeButtonClicked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
renderPuzzleModeMenu() {
|
||||||
|
const savegames = this.htmlElement.querySelector(".mainContainer .savegames");
|
||||||
|
|
||||||
|
if (savegames) {
|
||||||
|
savegames.remove();
|
||||||
|
}
|
||||||
|
|
||||||
|
const buttonContainer = this.htmlElement.querySelector(".mainContainer .buttons");
|
||||||
|
removeAllChildren(buttonContainer);
|
||||||
|
|
||||||
|
const playButtonElement = makeButtonElement(
|
||||||
|
["playButton", "styledButton"],
|
||||||
|
T.mainMenu.play
|
||||||
|
);
|
||||||
|
|
||||||
|
buttonContainer.appendChild(playButtonElement);
|
||||||
|
this.trackClicks(playButtonElement, this.onPuzzlePlayButtonClicked);
|
||||||
|
|
||||||
|
const bottomButtonContainer = this.htmlElement.querySelector(".bottomContainer .buttons");
|
||||||
|
removeAllChildren(bottomButtonContainer);
|
||||||
|
|
||||||
|
const backButton = makeButton(
|
||||||
|
bottomButtonContainer,
|
||||||
|
["styledButton"],
|
||||||
|
T.mainMenu.back
|
||||||
|
);
|
||||||
|
|
||||||
|
bottomButtonContainer.appendChild(backButton);
|
||||||
|
this.trackClicks(backButton, this.onBackButtonClicked);
|
||||||
|
}
|
||||||
|
|
||||||
|
onPuzzlePlayButtonClicked() {
|
||||||
|
const savegame = this.app.savegameMgr.createNewSavegame();
|
||||||
|
|
||||||
|
this.moveToState("InGameState", {
|
||||||
|
savegame,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
onPuzzleModeButtonClicked() {
|
onPuzzleModeButtonClicked() {
|
||||||
this.moveToState("InGameState");
|
this.renderPuzzleModeMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
onBackButtonClicked() {
|
||||||
|
this.renderMainMenu();
|
||||||
|
this.renderSavegames();
|
||||||
}
|
}
|
||||||
|
|
||||||
onSteamLinkClicked() {
|
onSteamLinkClicked() {
|
||||||
|
@ -117,6 +117,7 @@ mainMenu:
|
|||||||
savegameLevelUnknown: Unknown Level
|
savegameLevelUnknown: Unknown Level
|
||||||
savegameUnnamed: Unnamed
|
savegameUnnamed: Unnamed
|
||||||
puzzleMode: Puzzle Mode
|
puzzleMode: Puzzle Mode
|
||||||
|
back: Back
|
||||||
|
|
||||||
dialogs:
|
dialogs:
|
||||||
buttons:
|
buttons:
|
||||||
|
Loading…
Reference in New Issue
Block a user