From 77fff585d2afe92a2768d6f19de375e5d429abb2 Mon Sep 17 00:00:00 2001 From: TorgaW Date: Sat, 13 Apr 2024 20:41:01 +0300 Subject: [PATCH] NPC implementation. part I --- public/assets/images/characters/char0.png | Bin 0 -> 181 bytes .../images/world/world_terrain_atlas.png | Bin 630 -> 692 bytes src/Game/AssetsLoader/AssetsLoader.js | 6 +- src/Game/Game.js | 9 ++- src/Game/GlobalVariables/GlobalVariables.js | 8 ++ src/Game/NPC/NPC.js | 69 ++++++++++++++++++ src/Game/Utils/DataTypes.utils.js | 21 +++--- src/Game/WorldChunk/WorldChunk.js | 2 + src/Game/WorldGeneration/WorldGeneration.js | 14 ++-- 9 files changed, 111 insertions(+), 18 deletions(-) create mode 100644 public/assets/images/characters/char0.png create mode 100644 src/Game/NPC/NPC.js diff --git a/public/assets/images/characters/char0.png b/public/assets/images/characters/char0.png new file mode 100644 index 0000000000000000000000000000000000000000..a251d44a99b1556f0b3b07e382142243d274e0b0 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`HJ&bxAr`%BCpB^%P~dRcyYc`3 zRQJY&<%^Q7Ih1xipL#0%;Gb1h3m7sEvB}3oGNiXf?>@)z;7rFVdQ&MBb@0OX5E0{{R3 literal 0 HcmV?d00001 diff --git a/public/assets/images/world/world_terrain_atlas.png b/public/assets/images/world/world_terrain_atlas.png index cc53d21aeec8a9c6993f97c1254b8f8888b7ab23..20683e7e44d76baca433e19d2773c7e044df4778 100644 GIT binary patch literal 692 zcmV;l0!#ggP)lIas%g38qsc5fSrpgh4y|qtOvM-m*t#d?RN0YOy6Rwl)ZEu8|;hmo8ljiO( zmZ}>^{wk)oq%%1Viu{13_6!;ob=suF-2y127si*N3K+ zv&lhZBio8#wT1!$#sVw?0{|D70G_R00Dvu$HsxSkFa{`9BsCli03fTeWq8BUdju4d zfZTIzFM_|zsfc1yCG?$adQZjZlvS__dJ~8V)q%;=p{X7zY#br^P0b0Tr?J@f4DOhBwD5uv7xvNmrTC{R{i@>~|!r}#NZV`L$ zOzgJQvUL?J0ZzS^^cs-%_8Q%I0JBSL+%mLvLzXM;@X7VwmJa-wn*BPfpNh)fHFmr z!@&RmG8#JyXE=;UK(P%V_grT${eG8K5yhlR=sVf;j*8JKt6&xMCvagajLFlXt(Cyz z#0_?6FNNUzrJm{~SSu|ytW2!v&eC`yJP)iswk3^rkXC2)_PCxS+cu$ zd3)N{o6G!`=EcLubBr;|vYG3fb@S1?oZ09dfy9nJe`)U*ZR<@knVDmZ=F8XyGvhVr z-_~?vR{zp|Mdg^p5c+gx4k3tpqB0Ypu`-i^GJ&hfyrABqGQSXicJzsd6_wL8z%?|M z0B|cR1%*Yp-ZM`Y;3p}r=^n#Etg=0%( zd$pi|0u6+38?=)YXgtw&31!E3(s9JT{?QgCZPBKQMFUzGB`u^w9P=o61*>q|Ie_ml z!3dHbGYZ56Gj7sjmcaXt(F30!Lw_P+EX>3W6qp1}Y3Ow$ies9xACUMaVP6n|Q;5XA`^;2Ii3aD*!aF6EU9z%8?W zw;k?)poN>N)NXzrI_NrmALz{&=ISVd&^E1Oh$0~f`BFHxM7B2{-Ukc%HV~<{sd|-Y z7#-R!pr+S^)0D?&eXO5zrfOTpr;LdH0phzUOWPeL Qvj6}907*qoM6N<$g3iqyb^rhX diff --git a/src/Game/AssetsLoader/AssetsLoader.js b/src/Game/AssetsLoader/AssetsLoader.js index 1456eb9..8d35864 100644 --- a/src/Game/AssetsLoader/AssetsLoader.js +++ b/src/Game/AssetsLoader/AssetsLoader.js @@ -4,7 +4,7 @@ import { loadPixelAsset } from "../Utils/Assets.utils"; export async function loadGameAssets() { UIAssetsLoaderInfoPipe.update((s)=>{ - s.totalToDownload = 4; + s.totalToDownload = 5; s.downloaded = 0; }); // await loadPixelAsset("assets/images/amogus.png"); @@ -31,6 +31,10 @@ export async function loadGameAssets() UIAssetsLoaderInfoPipe.update((s)=>{ s.downloaded += 1; }); + await loadPixelAsset("assets/images/characters/char0.png"); + UIAssetsLoaderInfoPipe.update((s)=>{ + s.downloaded += 1; + }); await loadPixelAsset("assets/images/buildings/buildings.png"); UIAssetsLoaderInfoPipe.update((s)=>{ s.downloaded += 1; diff --git a/src/Game/Game.js b/src/Game/Game.js index bdd317f..29e1b84 100644 --- a/src/Game/Game.js +++ b/src/Game/Game.js @@ -4,7 +4,7 @@ import { UICameraInfo, UIGameProfilerPipe, UIMainPipe, UIObtainedResourcesPipe, import { getSpriteFromAtlas } from "./Utils/Sprites.utils"; import { profileFPS } from "./Profiler/Profiler"; import { createKeyboardBinding, inputControllerTick } from "./InputController/InputController"; -import { BC_APP, BC_BUILDING_PLACEHOLDERS, BC_CAMERA, BC_SPRITES_SETTINGS, BC_VIEWPORT, BC_WORLD, PRNG, setBC_APP, setBC_SELECTION, setBC_VIEWPORT, setBC_WORLD } from "./GlobalVariables/GlobalVariables"; +import { BC_APP, BC_BUILDING_PLACEHOLDERS, BC_CAMERA, BC_SPRITES_SETTINGS, BC_VIEWPORT, BC_WORLD, PRNG, setBC_APP, setBC_NPC_LAYER, setBC_SELECTION, setBC_VIEWPORT, setBC_WORLD } from "./GlobalVariables/GlobalVariables"; import { clampNumber, interpolate, } from "./Utils/Math.utils"; import { calculateViewportFromCamera, moveHorizontally, moveVertically, screenToWorldCoordinates } from "./Camera/Camera"; @@ -24,6 +24,7 @@ import { handleBuildingsIncome, incBuildingCount } from "./Buildings/Buildings"; import { handleDayNightCycle } from "./World/DayNightCycle"; import { ambientDay, ambientMusic, ambientNight, handleSounds } from "./Sound/Sound"; import { handleChunkFilling } from "./WorldGeneration/ChunkFillQueue"; +import { addNPCToWorld } from "./NPC/NPC"; export function generateWorld() { @@ -234,10 +235,15 @@ export async function initGame() { let world = new PIXI.Container(); let viewport = new PIXI.Container(); + let NPCLayer = new PIXI.Container(); world.addChild(viewport); + viewport.addChild(NPCLayer); setBC_VIEWPORT(viewport); setBC_WORLD(world); + setBC_NPC_LAYER(NPCLayer); + NPCLayer.zIndex = 100; viewport.isRenderGroup = true; + NPCLayer.isRenderGroup = true; app.stage.addChild(world); // world.tint = 0x00ffff; @@ -270,4 +276,5 @@ function startGame() { ambientDay.play(); ambientNight.play(); ambientMusic.play(); + addNPCToWorld(BC_CAMERA.position.x, BC_CAMERA.position.y, {type: "slave"}); } diff --git a/src/Game/GlobalVariables/GlobalVariables.js b/src/Game/GlobalVariables/GlobalVariables.js index ddb9fd8..ebf9a64 100644 --- a/src/Game/GlobalVariables/GlobalVariables.js +++ b/src/Game/GlobalVariables/GlobalVariables.js @@ -30,6 +30,14 @@ export function setBC_SELECTION(selection) { BC_SELECTION = selection; }; +/** + * {PIXI.Container} + */ +export let BC_NPC_LAYER; +export function setBC_NPC_LAYER(npc_layer) { + BC_NPC_LAYER = npc_layer; +}; + // export let BC_TERRAIN; export let BC_TERRAIN_SETTINGS = { tileSize: 16, diff --git a/src/Game/NPC/NPC.js b/src/Game/NPC/NPC.js new file mode 100644 index 0000000..bd10520 --- /dev/null +++ b/src/Game/NPC/NPC.js @@ -0,0 +1,69 @@ +import { BC_NPC_LAYER, BC_SPRITES_SETTINGS } from "../GlobalVariables/GlobalVariables"; +import { Vault } from "../Utils/DataTypes.utils"; +import { getSpriteFromAtlas } from "../Utils/Sprites.utils"; +import { WORLD_CHUNKS, worldCoordinatesToChunkIndex, worldCoordinatesToChunkIndexesCoordinates } from "../WorldGeneration/WorldGeneration"; +import * as PIXI from "../../pixi/pixi.mjs"; +import { addToViewport } from "../Utils/World.utils"; + +export const NPCVault = new Vault(); +let lastNPCId = -1; + +export class NPC +{ + /** + * + * @param {Position} param0 + * @param {Position} param1 + * @param {NPCProps} props + */ + constructor(x, y, x_c, y_c, spriteRef, id, props = {}) + { + this.position = {x, y}; + this.ceiledPosition = {x_c, y_c}; + // this.spriteRef = spriteRef; + // this.id = id; + this.props = {spriteRef, id, classRef: this, ...props}; + } + + setProps(props) + { + this.props = {...this.props, ...props}; + } + + tick(ticker) + { + + } +}; + +export class NPCProps +{ + constructor({type}) + { + this.type = type; + } +}; + +/** + * + * @param {Number} x + * @param {Number} y + * @param {NPCProps} props + */ +export function addNPCToWorld(x, y, props={}) { + let pos = worldCoordinatesToChunkIndexesCoordinates(x, y); + let sprite = getSpriteFromAtlas("assets/images/characters/char0.png", new PIXI.Rectangle(0,0,16,16)); + sprite.position.set(pos.x *BC_SPRITES_SETTINGS.defaultSize *BC_SPRITES_SETTINGS.scale, pos.y *BC_SPRITES_SETTINGS.defaultSize *BC_SPRITES_SETTINGS.scale); + sprite.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale); + sprite.zIndex = 100; + // addToViewport(sprite); + lastNPCId++; + let npc = new NPC(x, y, pos.x, pos.y, sprite, lastNPCId, props); + NPCVault.set(lastNPCId, npc); + BC_NPC_LAYER.addChild(sprite); + console.log(BC_NPC_LAYER); +} + +export function npcTickHandler(ticker) +{ +} \ No newline at end of file diff --git a/src/Game/Utils/DataTypes.utils.js b/src/Game/Utils/DataTypes.utils.js index 39ec34e..03b99c2 100644 --- a/src/Game/Utils/DataTypes.utils.js +++ b/src/Game/Utils/DataTypes.utils.js @@ -6,14 +6,14 @@ import { clampNumber, interpolateWith, mapRange } from "./Math.utils"; export class Vault { constructor(name = "") { this.name = name; - this.storage = {}; + this.storage = new Map(); /** * set key-value pair in storage * @param {String} key * @param {*} value */ this.set = (key, value) => { - this.storage[key] = value; + this.storage.set(key, value); }; /** * return element from storage @@ -21,7 +21,7 @@ export class Vault { * @returns element (ref) or undefined */ this.get = (key) => { - return this.storage[key]; + return this.storage.get(key); }; /** @@ -30,7 +30,8 @@ export class Vault { * @returns true/false */ this.existsKey = (key) => { - return Object.keys(this.storage).includes(key); + // return Object.keys(this.storage).includes(key); + return [...this.storage.keys()].includes(key); }; /** @@ -39,14 +40,14 @@ export class Vault { * @returns true/false */ this.del = (key) => { - return delete this.storage[key]; + return this.storage.delete(key); }; /** * clears storage */ this.clear = () => { - this.storage = {}; + this.storage.clear(); }; /** @@ -55,9 +56,9 @@ export class Vault { * @returns found value (ref) or false */ this.find = (value) => { - let t = Object.keys(this.storage); + let t = [...this.storage.keys()]; for (const i of t) { - if (this.storage[i] === value) return this.storage[i]; + if (this.storage.get(i) === value) return this.storage.get(i); } return false; }; @@ -67,9 +68,9 @@ export class Vault { * @param {Function} fn */ this.forAll = (fn) => { - let keys = Object.keys(this.storage); + let keys = [...this.storage.keys()]; for (const i of keys) { - fn(this.storage[i]); + fn(this.storage.get(i)); } }; } diff --git a/src/Game/WorldChunk/WorldChunk.js b/src/Game/WorldChunk/WorldChunk.js index 406de22..2557afd 100644 --- a/src/Game/WorldChunk/WorldChunk.js +++ b/src/Game/WorldChunk/WorldChunk.js @@ -6,9 +6,11 @@ export function createWorldChunkContainer() { let terrainLayer = new PIXI.Container(); let vegetationLayer = new PIXI.Container(); let buildingsLayer = new PIXI.Container(); + // let NPCLayer = new PIXI.Container(); chunk.addChild(terrainLayer); chunk.addChild(vegetationLayer); chunk.addChild(buildingsLayer); + // chunk.addChild(NPCLayer); return chunk; } diff --git a/src/Game/WorldGeneration/WorldGeneration.js b/src/Game/WorldGeneration/WorldGeneration.js index 5c29149..6c228dd 100644 --- a/src/Game/WorldGeneration/WorldGeneration.js +++ b/src/Game/WorldGeneration/WorldGeneration.js @@ -11,10 +11,10 @@ import { addChunkToFillQueue } from "./ChunkFillQueue"; // import {WorldChunk} from "../Types/WorldGenerationTypes"; const terrainSpriteList = { - 0: { x: 1, y: 1 }, //water - 1: { x: 0, y: 1 }, //sand - 2: { x: 0, y: 0 }, //grass - 3: { x: 1, y: 0 }, //stone + 0: { x: 21, y: 21 }, //water + 1: { x: 2, y: 21 }, //sand + 2: { x: 2, y: 2 }, //grass + 3: { x: 21, y: 2 }, //stone }; const terrainTypeList = { 0: "ter_water", //water @@ -91,7 +91,7 @@ const stoneVegResourcesList = { 2: { type: "stone", num: 5 / 5 }, }; -const WORLD_CHUNKS = new Vault(); +export const WORLD_CHUNKS = new Vault(); let VISIBLE_CHUNKS = new Vault(); export function worldCoordinatesToChunkIndex(x, y) { @@ -170,6 +170,7 @@ export function updateChunksVisibility() { newChunk.getChildAt(0), newChunk.getChildAt(1), newChunk.getChildAt(2), + // newChunk.getChildAt(3), new Vault("terrain"), new Vault("vegetation"), new Vault("buildings") @@ -343,6 +344,7 @@ export function createFirstWorldChunks() { chunkRef.getChildAt(0), chunkRef.getChildAt(1), chunkRef.getChildAt(2), + // chunkRef.getChildAt(3), new Vault("terrain"), new Vault("vegetation"), new Vault("buildings") @@ -400,7 +402,7 @@ export function fillChunk(chunk, x, y) { res = Math.floor(terrainCue.getValueAt(res)); let sprite = getSpriteFromAtlas( "assets/images/world/world_terrain_atlas.png", - new PIXI.Rectangle(16 * terrainSpriteList[res].x, 16 * terrainSpriteList[res].y, 16, 16) + new PIXI.Rectangle(terrainSpriteList[res].x, terrainSpriteList[res].y, 16, 16) ); sprite.position.set(16 * BC_SPRITES_SETTINGS.scale * ii, 16 * BC_SPRITES_SETTINGS.scale * jj); sprite.scale.set(BC_SPRITES_SETTINGS.scale, BC_SPRITES_SETTINGS.scale);