This commit is contained in:
Bastian Wagner 2025-10-09 20:45:16 +02:00
parent 8704e6aac7
commit 5fa7e77ba4
13 changed files with 216 additions and 10 deletions

BIN
public/assets/house.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 67 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
public/assets/storage.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

View File

@ -12,14 +12,19 @@ export class BuildingRenderer {
/** Wird aufgerufen, wenn ein neues Gebäude entsteht */ /** Wird aufgerufen, wenn ein neues Gebäude entsteht */
addBuilding(building: Building) { addBuilding(building: Building) {
let textureKey = 'default'; let textureKey = 'lumberhut';
switch (building.constructor) { console.log(building.constructor)
case LumberHut: switch (building.type) {
case 'lumberjack':
textureKey = 'lumberhut'; textureKey = 'lumberhut';
break; break;
case Storage: case 'storage':
console.log("storage")
textureKey = 'storage'; textureKey = 'storage';
break; break;
case 'house':
textureKey = 'house';
break;
default: default:
textureKey = 'default'; textureKey = 'default';
} }

View File

@ -1,5 +1,7 @@
import { Building, BuildingType } from "./building/building"; import { Building, BuildingType } from "./building/building";
import { House } from "./building/house-building";
import { LumberHut } from "./building/lumber-building"; import { LumberHut } from "./building/lumber-building";
import { Market } from "./building/market-building";
import { StorageBuilding } from "./building/storage.building"; import { StorageBuilding } from "./building/storage.building";
import { GameMap } from "./game-map"; import { GameMap } from "./game-map";
import { ResourceManager, ResourceType } from "./resource-manager"; import { ResourceManager, ResourceType } from "./resource-manager";
@ -41,6 +43,15 @@ export class BuildingSystem {
const w = new Worker(x,y); const w = new Worker(x,y);
b.assignWorker(w); b.assignWorker(w);
return b; 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; return null;
} }

View File

@ -1,6 +1,6 @@
import { GameMap } from "../game-map"; import { GameMap } from "../game-map";
export type BuildingType = 'house' | 'lumberjack' | 'quarry' | 'storage'; export type BuildingType = 'house' | 'lumberjack' | 'quarry' | 'storage' | 'market';
export abstract class Building { export abstract class Building {
type: BuildingType = 'house'; type: BuildingType = 'house';

View File

@ -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<ResourceType, number> = {
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;
}
}

View File

@ -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<ResourceType, number> = {
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;
}
}

View File

@ -1,5 +1,6 @@
import { GameMap } from "../game-map"; import { GameMap } from "../game-map";
import { CollectMaterialJob } from "../job/collect-material.job"; import { CollectMaterialJob } from "../job/collect-material.job";
import { ResourceType } from "../resource-manager";
import { Worker } from "../worker"; import { Worker } from "../worker";
import { Building } from "./building"; import { Building } from "./building";
import { ProductionBuilding } from "./production-building"; import { ProductionBuilding } from "./production-building";
@ -24,7 +25,6 @@ export class StorageBuilding extends ResouceBuilding {
const target = this.findNearestProdBuilding(); const target = this.findNearestProdBuilding();
if (!target) { if (!target) {
console.log("Not Target found");
return; return;
} }
@ -40,4 +40,11 @@ export class StorageBuilding extends ResouceBuilding {
return b; 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;
}
} }

View File

@ -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;
}
}
}

View File

@ -55,7 +55,6 @@ export class Worker {
} }
get idle(): boolean { get idle(): boolean {
console.log(this.job == null)
return this.job == null; return this.job == null;
} }
} }

View File

@ -34,10 +34,12 @@ export class GameScene extends Phaser.Scene {
preload() { preload() {
this.load.image('lumberhut', 'assets/lumberhut.png'); this.load.image('lumberhut', 'assets/lumberhut.png');
this.load.image('storage', 'assets/storage.png');
this.load.image('house', 'assets/house.png');
} }
create() { create() {
this.map = new GameMap(19, 10, 123); this.map = new GameMap(50, 50, 123);
this.gfx = this.add.graphics(); this.gfx = this.add.graphics();
// Highlight-Layer (separate Graphics) // Highlight-Layer (separate Graphics)
@ -47,9 +49,10 @@ export class GameScene extends Phaser.Scene {
// 📸 Kamera einstellen // 📸 Kamera einstellen
const cam = this.cameras.main; const cam = this.cameras.main;
cam.setZoom(this.zoom);
cam.setBounds(0, 0, this.map.width * this.tileSize, this.map.height * this.tileSize); 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.centerOn(this.map.width * this.tileSize / 2, this.map.height * this.tileSize / 2);
cam.setZoom(this.zoom);
// 🕹️ Steuerung // 🕹️ Steuerung
this.setupCameraControls(); this.setupCameraControls();
@ -62,7 +65,7 @@ export class GameScene extends Phaser.Scene {
// Testweise standardmäßig Haus als Werkzeug // 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}`); console.log(`Tile [${tile.x}, ${tile.y}] → ${tile.type}`);
if (this.selectedBuilding != null) { if (this.selectedBuilding != null) {
const succ = this.buildingSystem.tryPlaceBuilding(tile.x, tile.y, this.selectedBuilding); const succ = this.buildingSystem.tryPlaceBuilding(tile.x, tile.y, this.selectedBuilding);
console.log(succ)
if (succ) { if (succ) {
this.buildingRenderer.addBuilding(succ) this.buildingRenderer.addBuilding(succ)
} }
@ -232,4 +236,20 @@ export class GameScene extends Phaser.Scene {
// case 'water': return 0x244b6b; // 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)}
}
} }