diff --git a/src/app/app.component.html b/src/app/app.component.html index 0673847..1c9adfa 100644 --- a/src/app/app.component.html +++ b/src/app/app.component.html @@ -1,5 +1,7 @@
- +@if (gameService.showShipInfo) { + +} @if (gameService.showPlanetInfo) { } \ No newline at end of file diff --git a/src/app/components/dialog/ship-dialog/ship-dialog.component.html b/src/app/components/dialog/ship-dialog/ship-dialog.component.html index e69de29..39d2e2e 100644 --- a/src/app/components/dialog/ship-dialog/ship-dialog.component.html +++ b/src/app/components/dialog/ship-dialog/ship-dialog.component.html @@ -0,0 +1,66 @@ +
+ +
+
+
{{ ship.name }}
+
+ +
+ +
+ @if (ship.status == 'traveling') { +
Fliegt nach {{ destination }}
+ } @else if (ship.status == 'loading') { +
Lädt Waren
+ } @else if (ship.status == 'unloading') { +
Entlädt Waren
+ } @else if (ship.status == 'waiting') { +
Wartet auf Abfertigung
+ } @else { +
Untätig
+ } + +
+ +
+
    +
  • +
    Geschwindigkeit:
    +
    {{ ship.maxSpeed | number:'0.0-0' }} km/s
    +
  • +
  • +
    Beschleunigung:
    +
    {{ ship.acceleration | number:'0.0-0' }}
    +
  • +
  • +
    Frachtraum:
    +
    {{ ship.cargoSize | number:'0.0-0' }} t
    +
  • +
  • +
    Ladegeschwindigkeit:
    +
    {{ ship.loadingSpeed | number:'0.0-2' }} t/s
    +
  • +
+
+ +
+
+ +
+
📦 Fracht:
+
    + @for (item of cargo; track $index) { +
  • {{ item.type }}: {{ item.amount | number:'0.0-0' }}
  • + } +
+
+ +
+ + + +
+
+ + +
\ No newline at end of file diff --git a/src/app/components/dialog/ship-dialog/ship-dialog.component.scss b/src/app/components/dialog/ship-dialog/ship-dialog.component.scss index 3c3bec3..8d7606f 100644 --- a/src/app/components/dialog/ship-dialog/ship-dialog.component.scss +++ b/src/app/components/dialog/ship-dialog/ship-dialog.component.scss @@ -8,4 +8,9 @@ // height: 240px; // background-color: var(--background-color); // color: var(--primary-color); +} + +img { + width: 92px; + height: 92px; } \ No newline at end of file diff --git a/src/app/components/dialog/ship-dialog/ship-dialog.component.ts b/src/app/components/dialog/ship-dialog/ship-dialog.component.ts index 7a450a4..e78d5d0 100644 --- a/src/app/components/dialog/ship-dialog/ship-dialog.component.ts +++ b/src/app/components/dialog/ship-dialog/ship-dialog.component.ts @@ -1,5 +1,9 @@ import { CommonModule } from '@angular/common'; -import { Component } from '@angular/core'; +import { Component, inject } from '@angular/core'; +import { GameService } from '../../../service/game.service'; +import { Ship } from '../../../model/ships/ship.model'; +import { Good } from '../../../model/goods/good.interface'; +import { TradeInstance } from '../../../model/planet.model'; @Component({ selector: 'app-ship-dialog', @@ -8,5 +12,25 @@ import { Component } from '@angular/core'; styleUrl: './ship-dialog.component.scss' }) export class ShipDialogComponent { + public gameService: GameService = inject(GameService); + get ship(): Ship { + return this.gameService.showShipInfo!; + } + + + close() { + this.gameService.showShipInfo = undefined; + } + + get cargo(): TradeInstance[] { + return this.ship.cargoSpace.filter(c => c.amount); + } + + get destination(): string { + if (this.ship.route) { + return this.ship.route.nextPlanetName; + } + return '' + } } diff --git a/src/app/model/planet.model.ts b/src/app/model/planet.model.ts index 8954d30..89950d4 100644 --- a/src/app/model/planet.model.ts +++ b/src/app/model/planet.model.ts @@ -102,23 +102,6 @@ export class Planet { } - deliver(ship: Ship) { - if (!ship || ship.cargoSpace.length == 0) { return; } - - const requests = this.requestedGoods; - if (requests.length == 0) { return; } - for (let request of requests) { - const offer = ship.cargoSpace.find(cargo => cargo.type == request?.type); - if (!offer) { continue; } - const transfer = Math.min(offer.amount, request.amount); - const good = this.getGood(request.type); - if (!good) { continue; } - good.amount += transfer; - offer.amount -= transfer; - console.log(`Ausgeladen: ${good.type}: ${transfer}`) - } - } - /** * Gets a list of goods that the planet needs to import * @returns Array of goods with their type and requested amount diff --git a/src/app/model/ship.ts b/src/app/model/ship.ts index e5444ec..2c68fc0 100644 --- a/src/app/model/ship.ts +++ b/src/app/model/ship.ts @@ -1,6 +1,6 @@ import { MapScene } from "../scene/map.scene"; +import { GameService } from "../service/game.service"; import { PlanetUi } from "../ui/planet.ui"; -import { GoodType } from "./goods/good-type.enum"; import { TradeInstance } from "./planet.model"; import { Ship } from "./ships/ship.model"; @@ -9,11 +9,11 @@ export class ShipUi extends Phaser.Physics.Arcade.Sprite { private target: PlanetUi | null = null; private targetVector: Phaser.Math.Vector2 | null = null; // Später Planet! public model: Ship = new Ship(); + public gameService: GameService; - - constructor(scene: MapScene, x: number, y: number) { + constructor(scene: MapScene, x: number, y: number, gameService: GameService) { super(scene, x, y, 'ship'); - + this.gameService = gameService; scene.add.existing(this); @@ -27,14 +27,21 @@ export class ShipUi extends Phaser.Physics.Arcade.Sprite { } this.setInteractive(conf) this.activateRoute(); + + this.on('pointerdown', (pointer: Phaser.Input.Pointer) => { + if (pointer.button == Phaser.Input.MOUSE_DOWN) { + this.gameService.showShip(this.model); + } else if (pointer.button == Phaser.Input.MOUSE_UP) { + + } + }); } moveTo(target: PlanetUi | undefined) { if (!target) { return; } this.target = target; this.targetVector = new Phaser.Math.Vector2(target.getWorldPoint().x, target.getWorldPoint().y); - const angle = Phaser.Math.Angle.Between(this.getWorldPoint().x, this.getWorldPoint().y, target.getWorldPoint().x, target.getWorldPoint().y); - // this.setRotation(angle); // Zeigt Schiff zur Zielrichtung + this.model.status = 'traveling'; if (!this.body) { return; } } @@ -75,8 +82,8 @@ export class ShipUi extends Phaser.Physics.Arcade.Sprite { } - targetReached(target: PlanetUi) { - this.model.exchangeGoods(target.model) + async targetReached(target: PlanetUi) { + await this.model.exchangeGoods(target.model) if (this.model.route) { this.model.route.routePointReached(); const target = (this.scene as MapScene).getPlanetUiByName(this.model.route.nextPlanetName); diff --git a/src/app/model/ships/ship.model.ts b/src/app/model/ships/ship.model.ts index 88713d3..458033d 100644 --- a/src/app/model/ships/ship.model.ts +++ b/src/app/model/ships/ship.model.ts @@ -9,17 +9,55 @@ export class Ship { public cargoSize = 100; cargoSpace: TradeInstance[] = []; public route: TradeRoute | undefined = new TradeRoute([]) + public name = "Pioneer-01"; + public loadingSpeed = 1.5; - exchangeGoods(planet: Planet) { - if (!this.route) { return; } + public status: 'loading' | 'unloading' | 'waiting' | 'idle' | 'traveling' = 'idle' - planet.deliver(this); + async exchangeGoods(planet: Planet) { + if (!this.route) { + return Promise.resolve(null) + } - console.log(`\n[${planet.name}] Starting new Trade. Free cargospace: ${this.freeCargoSpace.toFixed(2)}`) + await this.unloadGoods(planet); + await this.loadGoods(planet); + return Promise.resolve(null); + + } + + private async unloadGoods(planet: Planet) { + if (!planet || this.cargoSpace.length == 0) { return Promise.resolve(null); } + + const planetRequests = planet.requestedGoods; + if (planetRequests.length == 0) { return Promise.resolve(null); } + this.status = 'unloading'; + + for (const request of planetRequests) { + const offer = this.cargoSpace.find(cargo => cargo.type == request.type); + if (!offer) { continue; } + + const transfer = Math.min(offer.amount, request.amount); + const good = planet.getGood(offer.type); + if (!good) { continue; } + await this.removeFromCargoSpace({type: offer.type, amount: transfer}); + good.amount += transfer; + + } + this.cargoSpace = this.cargoSpace.filter(c => c.amount != 0) + return Promise.resolve(null); + + } + + private async loadGoods(planet: Planet) { + if (!this.route) { + return Promise.resolve(null) + } + this.status = 'loading'; const demands = this.route.getTradeRouteDemands(); - if (demands.length == 0) { return; } - console.log(JSON.parse(JSON.stringify(demands))) + if (demands.length == 0) { + return Promise.resolve(null) + } for (let demand of demands) { // requested amount: demand - storage @@ -27,26 +65,59 @@ export class Ship { if (stored) { demand.amount -= stored.amount; }; demand.amount = Math.min(demand.amount, this.freeCargoSpace); demand.amount = Math.max(demand.amount, 0) - if (demand.amount > 0) { console.log(`[${planet.name}] Requesting ${demand.amount.toFixed(2)} ${demand.type}`); } if (demand.amount == 0) { continue; } const received = planet.request(demand); - this.addToCargoSpace({type: demand.type, amount: received}) + await this.addToCargoSpace({type: demand.type, amount: received}) } - console.log(`Cargo: ${this.cargoSpace.map(c => `${c.type}: ${c.amount.toFixed(2)}`).join(', ')}`); + return Promise.resolve(null) } get freeCargoSpace(): number { return this.cargoSize - this.cargoSpace.reduce((acc, succ) => acc + succ.amount, 0) } - addToCargoSpace(cargo: TradeInstance) { - const existing = this.cargoSpace.find(c => c.type == cargo.type); + private async removeFromCargoSpace(cargo: TradeInstance) { + const steps = Math.ceil(cargo.amount) - if (existing) { - existing.amount += cargo.amount; - } else { - this.cargoSpace.push(cargo); + for (let i = 1; i <= steps; i++) { + const existing = this.cargoSpace.find(c => c.type == cargo.type); + if (existing) { + existing.amount -= (cargo.amount / steps); + } + await this.waitForLoading(1) } + + return Promise.resolve(null) + } + + private async addToCargoSpace(cargo: TradeInstance) { + + const steps = Math.ceil(cargo.amount) + + for (let i = 1; i <= steps; i++) { + const existing = this.cargoSpace.find(c => c.type == cargo.type); + if (existing) { + existing.amount += (cargo.amount / steps); + } else { + this.cargoSpace.push({ + type: cargo.type, + amount: cargo.amount / steps + }); + + } + await this.waitForLoading(1) + } + + return Promise.resolve(null) + + } + + async waitForLoading(amount: number) { + return new Promise(resolve => { + setTimeout(() => { + resolve(null); + }, amount * 1000 / this.loadingSpeed) + }) } } \ No newline at end of file diff --git a/src/app/scene/map.scene.ts b/src/app/scene/map.scene.ts index 48f014a..1494127 100644 --- a/src/app/scene/map.scene.ts +++ b/src/app/scene/map.scene.ts @@ -93,7 +93,7 @@ export class MapScene extends Phaser.Scene { }); setTimeout(() => { - const s = new ShipUi(this, 100, 100); + const s = new ShipUi(this, 100, 100, this.gameService); s.model.route = new TradeRoute(this.planets.filter(planet => ['Terra Nova', 'Aqualis'].includes(planet.model.name)).map(planet => planet.model)) this.ships.push(s) this.physics.world.enable(s); diff --git a/src/app/service/game.service.ts b/src/app/service/game.service.ts index 97064e9..0fb6865 100644 --- a/src/app/service/game.service.ts +++ b/src/app/service/game.service.ts @@ -2,12 +2,14 @@ import { inject, Injectable } from "@angular/core"; import { MatDialog, MatDialogRef } from "@angular/material/dialog"; import { PlanetDialogComponent } from "../components/dialog/planet-dialog/planet-dialog.component"; import { Planet } from "../model/planet.model"; +import { Ship } from "../model/ships/ship.model"; @Injectable({ providedIn: 'root', }) export class GameService { public showPlanetInfo: Planet | undefined; + public showShipInfo: Ship | undefined; constructor() {} @@ -15,6 +17,10 @@ export class GameService { this.showPlanetInfo = planet; } + showShip(ship: Ship) { + this.showShipInfo = ship; + } + get canDrag(): boolean { return true; } diff --git a/src/styles/_ui.scss b/src/styles/_ui.scss index 888717c..f19ec23 100644 --- a/src/styles/_ui.scss +++ b/src/styles/_ui.scss @@ -108,4 +108,9 @@ $font-size-base: 14px; margin-right: 8px; margin-top: 8px; } +} + +.flex { + display: flex; + justify-content: space-between; } \ No newline at end of file