diff --git a/public/assets/house.png b/public/assets/house.png new file mode 100644 index 0000000..0b91db5 Binary files /dev/null and b/public/assets/house.png differ diff --git a/public/assets/original/house.png b/public/assets/original/house.png new file mode 100644 index 0000000..7fdb7cd Binary files /dev/null and b/public/assets/original/house.png differ diff --git a/public/assets/original/storage.png b/public/assets/original/storage.png new file mode 100644 index 0000000..8f7fb6a Binary files /dev/null and b/public/assets/original/storage.png differ diff --git a/public/assets/storage.png b/public/assets/storage.png new file mode 100644 index 0000000..0c5ef33 Binary files /dev/null and b/public/assets/storage.png differ diff --git a/src/app/game/core/building-renderer.ts b/src/app/game/core/building-renderer.ts index 723c9f7..306b2a9 100644 --- a/src/app/game/core/building-renderer.ts +++ b/src/app/game/core/building-renderer.ts @@ -12,14 +12,19 @@ export class BuildingRenderer { /** Wird aufgerufen, wenn ein neues Gebäude entsteht */ addBuilding(building: Building) { - let textureKey = 'default'; - switch (building.constructor) { - case LumberHut: + let textureKey = 'lumberhut'; + console.log(building.constructor) + switch (building.type) { + case 'lumberjack': textureKey = 'lumberhut'; break; - case Storage: + case 'storage': + console.log("storage") textureKey = 'storage'; break; + case 'house': + textureKey = 'house'; + break; default: textureKey = 'default'; } diff --git a/src/app/game/core/building-system.ts b/src/app/game/core/building-system.ts index 68cccc1..3aa3252 100644 --- a/src/app/game/core/building-system.ts +++ b/src/app/game/core/building-system.ts @@ -1,5 +1,7 @@ import { Building, BuildingType } from "./building/building"; +import { House } from "./building/house-building"; import { LumberHut } from "./building/lumber-building"; +import { Market } from "./building/market-building"; import { StorageBuilding } from "./building/storage.building"; import { GameMap } from "./game-map"; import { ResourceManager, ResourceType } from "./resource-manager"; @@ -41,6 +43,15 @@ export class BuildingSystem { const w = new Worker(x,y); b.assignWorker(w); return b; + } else if (type == 'house') { + const b = new House(this.map, x, y, this.buildings); + this.buildings.push(b); + return b; + } else if (type == 'market') { + const b = new Market(this.map, x, y, this.buildings); + const w = new Worker(x,y); + b.assignWorker(w); + this.buildings.push(b); } return null; } diff --git a/src/app/game/core/building/building.ts b/src/app/game/core/building/building.ts index 99be90d..2bd7ce6 100644 --- a/src/app/game/core/building/building.ts +++ b/src/app/game/core/building/building.ts @@ -1,6 +1,6 @@ import { GameMap } from "../game-map"; -export type BuildingType = 'house' | 'lumberjack' | 'quarry' | 'storage'; +export type BuildingType = 'house' | 'lumberjack' | 'quarry' | 'storage' | 'market'; export abstract class Building { type: BuildingType = 'house'; diff --git a/src/app/game/core/building/house-building.ts b/src/app/game/core/building/house-building.ts new file mode 100644 index 0000000..849de10 --- /dev/null +++ b/src/app/game/core/building/house-building.ts @@ -0,0 +1,40 @@ +import { ResourceType } from "../resource-manager"; +import { Building, BuildingType } from "./building"; + +export class House extends Building { + residents = 2; + maxResidents = 2; + override type: BuildingType = 'house'; + + public stored: Record = { + food: 0, + wood: 5, + gold: 0, + stone: 0 + }; + + // wie oft Holz verbraucht wird (Sekunden) + private woodConsumptionInterval = 10; + private woodTimer = 0; + + update(dt: number): void { + this.woodTimer += dt; + + // 🔸 Holz verbrennen + if (this.woodTimer >= this.woodConsumptionInterval) { + this.woodTimer = 0; + this.consumeWood(); + } + } + + private consumeWood() { + if (this.stored.wood <= 0) { return; } + this.stored.wood --; + console.log("Hold:", this.stored.wood) + } + + get needsWoodDelivery(): boolean { + return true; + } + +} \ No newline at end of file diff --git a/src/app/game/core/building/market-building.ts b/src/app/game/core/building/market-building.ts new file mode 100644 index 0000000..97bb2f5 --- /dev/null +++ b/src/app/game/core/building/market-building.ts @@ -0,0 +1,66 @@ +import { SupplyJob } from "../job/supply-job"; +import { ResourceType } from "../resource-manager"; +import { Worker } from "../worker"; +import { BuildingType } from "./building"; +import { House } from "./house-building"; +import { ResouceBuilding } from "./resource-building"; +import { StorageBuilding } from "./storage.building"; + +export class Market extends ResouceBuilding { + + override type: BuildingType = 'market'; + radius = 15; // Versorgungsreichweite in Tiles + transferRate = 2; // Holz pro Tick + + public override stored: Record = { + food: 0, + gold: 0, + stone: 0, + wood: 0, + }; + + + override assignWorker(worker: Worker): void { + this.assignedWorker = worker; + + } + + + override update(dt: number): void { + super.update(dt); + // 🔸 beliefert Häuser im Umkreis + const houses = this.buildings.filter(b => b instanceof House) as House[]; + + for (const h of houses) { + const dist = Math.sqrt((h.x - this.x) ** 2 + (h.y - this.y) ** 2); + if (dist > this.radius) continue; + this.distributeWood(h); + } + + // get Goods + if (!this.assignedWorker || !this.assignedWorker.idle) { return; } + const storages: StorageBuilding[] = this.buildings.filter(b => b.type == 'storage') as StorageBuilding[]; + const storage = storages.find(b => b.stored.wood && b.stored.wood > 0); + if (!storage) { return; } + + this.assignedWorker.setJob(new SupplyJob(this.map, this.assignedWorker, storage, this, 'wood', 5)) + } + + private distributeWood(house: House): void { + const available = this.stored.wood + console.log("AV:", available) + if (available < this.transferRate) return; + + // wie viel Holz das Haus gerade braucht + const need = Math.max(0, house.residents - (house.stored['wood'] ?? 0)) * 2; + if (need <= 0) return; + + const transfer = Math.min(need, this.transferRate, available); + this.stored.wood -= transfer; + house.stored['wood'] = (house.stored['wood'] ?? 0) + transfer; + } + + addResource(good: ResourceType, amount: number) { + this.stored[good] += amount; + } +} \ No newline at end of file diff --git a/src/app/game/core/building/storage.building.ts b/src/app/game/core/building/storage.building.ts index 8296243..1e332f0 100644 --- a/src/app/game/core/building/storage.building.ts +++ b/src/app/game/core/building/storage.building.ts @@ -1,5 +1,6 @@ import { GameMap } from "../game-map"; import { CollectMaterialJob } from "../job/collect-material.job"; +import { ResourceType } from "../resource-manager"; import { Worker } from "../worker"; import { Building } from "./building"; import { ProductionBuilding } from "./production-building"; @@ -24,7 +25,6 @@ export class StorageBuilding extends ResouceBuilding { const target = this.findNearestProdBuilding(); if (!target) { - console.log("Not Target found"); return; } @@ -40,4 +40,11 @@ export class StorageBuilding extends ResouceBuilding { return b; } + + removeResource(good: ResourceType, amount: number): number { + if (!this.stored[good]) { return 0 } + const a = Math.min(amount, this.stored[good]); + this.stored[good] -= a; + return a; + } } \ No newline at end of file diff --git a/src/app/game/core/job/supply-job.ts b/src/app/game/core/job/supply-job.ts new file mode 100644 index 0000000..1a8a20c --- /dev/null +++ b/src/app/game/core/job/supply-job.ts @@ -0,0 +1,58 @@ +import { Market } from "../building/market-building"; +import { StorageBuilding } from "../building/storage.building"; +import { GameMap } from "../game-map"; +import { findPath } from "../pathfinding"; +import { Job } from "./base-job"; +import { Worker } from "../worker"; +import { ResourceType } from "../resource-manager"; + +export class SupplyJob extends Job { + + constructor( + map: GameMap, + worker: Worker, + private target: StorageBuilding, + private home: Market, + private goodToGet: ResourceType, + private amountToGet: number + ) { + super(map, worker); + this.workDuration = 1; // 4 Sekunden Hackzeit + } + + + override start(): void { + const start = this.map.getTile(Math.floor(this.worker.x), Math.floor(this.worker.y))!; + const goal = this.map.getTile(this.target.x, this.target.y)!; + const path = findPath(this.map, start, goal); + this.worker.setPath(path); + this.state = 'walking'; + } + + update(dt: number): void { + switch (this.state) { + case 'walking': + if (this.worker.followPath(dt)) { + const taken = this.target.removeResource(this.goodToGet, this.amountToGet); + this.worker.carrying = taken; + + const goalTile = this.map.getTile(this.home.x, this.home.y)!; + const start = this.map.getTile(Math.floor(this.worker.x), Math.floor(this.worker.y))!; + this.worker.setPath(findPath(this.map, start, goalTile)); + this.state = 'returning'; + } + break; + + case 'returning': + if (this.worker.followPath(dt)) { + this.home.addResource(this.goodToGet, this.worker.carrying); + console.log(`📦 ${this.worker.carrying} ${this.goodToGet} geliefert an Markt (${this.home.x},${this.home.y})`); + this.worker.carrying = 0; + this.state = 'done'; + } + break; + } + } + + +} \ No newline at end of file diff --git a/src/app/game/core/worker.ts b/src/app/game/core/worker.ts index 23430e7..0e61366 100644 --- a/src/app/game/core/worker.ts +++ b/src/app/game/core/worker.ts @@ -55,7 +55,6 @@ export class Worker { } get idle(): boolean { - console.log(this.job == null) return this.job == null; } } \ No newline at end of file diff --git a/src/app/game/scenes/game.scene.ts b/src/app/game/scenes/game.scene.ts index c0ca04d..d25e6af 100644 --- a/src/app/game/scenes/game.scene.ts +++ b/src/app/game/scenes/game.scene.ts @@ -34,10 +34,12 @@ export class GameScene extends Phaser.Scene { preload() { this.load.image('lumberhut', 'assets/lumberhut.png'); + this.load.image('storage', 'assets/storage.png'); + this.load.image('house', 'assets/house.png'); } create() { - this.map = new GameMap(19, 10, 123); + this.map = new GameMap(50, 50, 123); this.gfx = this.add.graphics(); // Highlight-Layer (separate Graphics) @@ -47,9 +49,10 @@ export class GameScene extends Phaser.Scene { // 📸 Kamera einstellen const cam = this.cameras.main; + cam.setZoom(this.zoom); cam.setBounds(0, 0, this.map.width * this.tileSize, this.map.height * this.tileSize); cam.centerOn(this.map.width * this.tileSize / 2, this.map.height * this.tileSize / 2); - cam.setZoom(this.zoom); + // 🕹️ Steuerung this.setupCameraControls(); @@ -62,7 +65,7 @@ export class GameScene extends Phaser.Scene { // Testweise standardmäßig Haus als Werkzeug - this.selectedBuilding = 'lumberjack'; + this.selectedBuilding = 'house'; @@ -134,6 +137,7 @@ export class GameScene extends Phaser.Scene { console.log(`Tile [${tile.x}, ${tile.y}] → ${tile.type}`); if (this.selectedBuilding != null) { const succ = this.buildingSystem.tryPlaceBuilding(tile.x, tile.y, this.selectedBuilding); + console.log(succ) if (succ) { this.buildingRenderer.addBuilding(succ) } @@ -232,4 +236,20 @@ export class GameScene extends Phaser.Scene { // case 'water': return 0x244b6b; // } // } + + dev() { + let a = this.buildingSystem.tryPlaceBuilding(4, 4, 'house'); + if (a) { + this.buildingRenderer.addBuilding(a) + } + + let b = this.buildingSystem.tryPlaceBuilding(5, 9, 'lumberjack'); + if (b) { this.buildingRenderer.addBuilding(b)} + + let c = this.buildingSystem.tryPlaceBuilding(5, 6, 'storage'); + if (c) { this.buildingRenderer.addBuilding(c)} + + let d = this.buildingSystem.tryPlaceBuilding(11, 11, 'market'); + if (d) { this.buildingRenderer.addBuilding(d)} + } } \ No newline at end of file