added Scene, SceneObject, TickHandler and more. Part II

This commit is contained in:
TorgaW 2024-04-14 17:22:51 +03:00
parent 0f130ad7e5
commit 94f66a2818
9 changed files with 197 additions and 10716 deletions

View File

@ -25,6 +25,8 @@ import { handleDayNightCycle } from "./World/DayNightCycle";
import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound"; import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound";
import { handleChunkFilling } from "./WorldGeneration/ChunkFillQueue"; import { handleChunkFilling } from "./WorldGeneration/ChunkFillQueue";
import { addNPCToWorld } from "./NPC/NPC"; import { addNPCToWorld } from "./NPC/NPC";
import { gameStateObjectsCleaner } from "./GameState/GameState";
import { tickHandler } from "./TickHandler/TickHandler";
export function generateWorld() { export function generateWorld() {
@ -233,18 +235,18 @@ export async function initGame() {
s.loadingAssets = false; s.loadingAssets = false;
}); });
let world = new PIXI.Container(); // let world = new PIXI.Container();
let viewport = new PIXI.Container(); let viewport = new PIXI.Container();
let NPCLayer = new PIXI.Container(); // let NPCLayer = new PIXI.Container();
world.addChild(viewport); // world.addChild(viewport);
viewport.addChild(NPCLayer); // viewport.addChild(NPCLayer);
setBC_VIEWPORT(viewport); setBC_VIEWPORT(viewport);
setBC_WORLD(world); // setBC_WORLD(world);
setBC_NPC_LAYER(NPCLayer); // setBC_NPC_LAYER(NPCLayer);
NPCLayer.zIndex = 100; // NPCLayer.zIndex = 100;
viewport.isRenderGroup = true; viewport.isRenderGroup = true;
NPCLayer.isRenderGroup = true; // NPCLayer.isRenderGroup = true;
app.stage.addChild(world); app.stage.addChild(viewport);
// world.tint = 0x00ffff; // world.tint = 0x00ffff;
BC_CAMERA.position.x = Math.floor(PRNG() * 3242 - 372); BC_CAMERA.position.x = Math.floor(PRNG() * 3242 - 372);
@ -276,5 +278,7 @@ function startGame() {
ambientDay.play(); ambientDay.play();
ambientNight.play(); ambientNight.play();
ambientMusic.play(); ambientMusic.play();
addNPCToWorld(BC_CAMERA.position.x, BC_CAMERA.position.y, {type: "slave"}); // addNPCToWorld(BC_CAMERA.position.x, BC_CAMERA.position.y, {type: "slave"});
BC_APP.ticker.add(gameStateObjectsCleaner);
BC_APP.ticker.add(tickHandler);
} }

View File

@ -1,25 +1,46 @@
import * as PIXI from "../../pixi/pixi.mjs" import * as PIXI from "../../pixi/pixi.mjs"
import { addToCleaningQueue } from "../GameState/GameState";
/** /**
* Base class for all game objects. * Base class for all game objects.
* Contains only necessary functions
*/ */
export class GameObject { export class GameObject {
id = -1; //currently not in use
tickEnabled = true; majorId = -1;
// markedAsWaitingForDestruction = false; //primary game object id
minorId = -1;
#tickEnabled = true;
#markedPendingKill = false;
// markedAsInitialized = false; // markedAsInitialized = false;
/** /**
* GameObject id * GameObject id
* @param {Number} id
* @param {Boolean} tickAble * @param {Boolean} tickAble
*/ */
constructor(id, tickAble) constructor(tickAble = true)
{ {
this.id = id; this.#tickEnabled = tickAble;
this.tickEnabled = tickAble; };
/**
* inits GameObject with id. Without id object will not be added to the scene. id must be unique
*/
init_byGameState(major_id, minor_id)
{
this.majorId = major_id;
this.minorId = minor_id;
};
/**
* Removes object from scene in the next frame and delete it completely after several frames
*/
kill()
{
if(this.#markedPendingKill) return;
this.preDestroy();
this.#markedPendingKill = true;
addToCleaningQueue(this.majorId, this.minorId);
}; };
/** /**
@ -30,16 +51,19 @@ export class GameObject {
/** /**
* called after spawn * called after spawn
*/ */
afterSpawn(){}; onSpawn(){};
/** /**
* called before spawn * called after initialization
*/ */
preSpawn(){}; onInit(){};
/** /**
* called every frame * called every frame
* @param {PIXI.Ticker} ticker * @param {PIXI.Ticker} ticker
*/ */
tick(ticker){}; tick(ticker){};
isTickEnabled(){return this.#tickEnabled;};
isMarkedPendingKill(){return this.#markedPendingKill;};
}; };

View File

@ -0,0 +1,71 @@
import { GameObject } from "../GameObject/GameObject";
/**
* @type Map<Number, GameObject>
*/
let GameObjects = new Map();
/**
* @type Map<Number, GameObject>
*/
let TickGameObjects = new Map();
/**
* @type Array<{major: Number, minor: Number}>
*/
let CleaningQueue = new Array();
let currentMajorId = 0;
let currentMinorId = 0;
function incId() {
currentMinorId++;
if(currentMinorId === Number.MAX_SAFE_INTEGER)
{
currentMinorId = 0;
currentMajorId++;
}
}
/**
* adds game object to game state
* @param {GameObject} gameObject
*/
export function addGameObjectToGameState(gameObject) {
gameObject.init_byGameState(currentMajorId, currentMinorId);
GameObjects.set(currentMinorId, gameObject);
if(gameObject.isTickEnabled())
{
TickGameObjects.set(currentMinorId, gameObject);
}
incId();
gameObject.onInit();
}
export function gameStateObjectsCleaner() {
for (const i of CleaningQueue) {
GameObjects.delete(i.minor);
TickGameObjects.delete(i.minor);
}
}
export function addToCleaningQueue(major_id, minor_id) {
CleaningQueue.push({major: major_id, minor: minor_id});
}
/**
*
* @returns all game objects
*/
export function getGameObjects() {
return GameObjects;
}
/**
*
* @returns all game objects
*/
export function getTickGameObjects() {
return TickGameObjects;
}

View File

@ -1,4 +1,5 @@
import Alea from "alea"; import Alea from "alea";
import { Container } from "../../pixi/pixi.mjs";
export let BC_APP; export let BC_APP;
@ -7,7 +8,7 @@ export function setBC_APP(app) {
}; };
/** /**
* {PIXI.Container} * @type Container
*/ */
export let BC_VIEWPORT; export let BC_VIEWPORT;
export function setBC_VIEWPORT(viewport) { export function setBC_VIEWPORT(viewport) {

44
src/Game/Scene/Scene.js Normal file
View File

@ -0,0 +1,44 @@
import { addGameObjectToGameState } from "../GameState/GameState";
import { BC_VIEWPORT } from "../GlobalVariables/GlobalVariables";
import { SceneObject } from "../SceneObjects/SceneObject";
export class Scene {
/**
* @type Map<Number, SceneObject>
*/
#SceneObjects = new Map();
getObjectById(minor_id) {
return this.#SceneObjects.get(minor_id);
};
/**
* SceneObject must be initialized!
* @param {SceneObject} sceneObject
*/
addObjectToScene(sceneObject) {
this.#SceneObjects.set(sceneObject.minorId, sceneObject);
BC_VIEWPORT.addChild(sceneObject.drawObject);
};
/**
* Uninitialized SceneObject
* @param {SceneObject} sceneObject
*/
addObjectToSceneWithInitialization(sceneObject) {
addGameObjectToGameState(sceneObject);
this.addObjectToScene(sceneObject);
};
/**
* Removes object from render stage and Scene storage
* @param {SceneObject} sceneObject
*/
removeObjectFromScene(sceneObject) {
if(this.#SceneObjects.has(sceneObject.minorId))
{
BC_VIEWPORT.removeChild(sceneObject.drawObject);
this.#SceneObjects.delete(sceneObject.minorId);
}
};
}

View File

@ -0,0 +1,21 @@
import { GameObject } from "../GameObject/GameObject";
import { Container } from "../../pixi/pixi.mjs";
export class SceneObject extends GameObject {
/**
* Pixi container. This container will be added to render stage.
* @type Container
*/
drawObject = new Container();
/**
* Instantly* kills drawObject (by PIXI) and after several ticks kills SceneObject
*
* * not sure about instant killing
*/
kill()
{
super.kill();
this.drawObject.destroy();
}
}

View File

@ -0,0 +1,8 @@
import { getTickGameObjects } from "../GameState/GameState";
export function tickHandler(ticker) {
let gameObjects = getTickGameObjects();
for (const i of gameObjects) {
i[1].tick(ticker);
}
}

View File

@ -1,4 +1,4 @@
import { BC_WORLD, PRNG } from "../GlobalVariables/GlobalVariables"; import { BC_VIEWPORT, BC_WORLD, PRNG } from "../GlobalVariables/GlobalVariables";
import { UIGameTimePipe } from "../UIPipes/UIPipes"; import { UIGameTimePipe } from "../UIPipes/UIPipes";
import { RGBColor, RGBCue } from "../Utils/DataTypes.utils"; import { RGBColor, RGBCue } from "../Utils/DataTypes.utils";
@ -45,7 +45,7 @@ export function handleDayNightCycle(tick) {
// console.log(currentColor.toHex()); // console.log(currentColor.toHex());
// console.log(((Math.floor(timeElapsed) % (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)) / (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay))); // console.log(((Math.floor(timeElapsed) % (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)) / (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)));
// currentColor.multiplyByNumber(((Math.floor(timeElapsed) % (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)) / (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay))); // currentColor.multiplyByNumber(((Math.floor(timeElapsed) % (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)) / (gameSecondsInGameMinute * gameMinutesInGameHour * gameHoursInGameDay)));
BC_WORLD.tint = currentColor.toNumber(); BC_VIEWPORT.tint = currentColor.toNumber();
} }
export function getDayPhase() { export function getDayPhase() {

File diff suppressed because one or more lines are too long