balancing
@ -3,9 +3,9 @@ version: '3.8'
|
|||||||
services:
|
services:
|
||||||
|
|
||||||
shattered_kingdom_client:
|
shattered_kingdom_client:
|
||||||
image: bastianwagner/stellar_lines_client:latest
|
image: bastianwagner/stellar-lines:latest
|
||||||
pull_policy: always
|
pull_policy: always
|
||||||
container_name: stellar_lines_client
|
container_name: stellar-lines
|
||||||
ports:
|
ports:
|
||||||
- "3900:80"
|
- "3900:80"
|
||||||
|
|
||||||
|
|||||||
BIN
public/sprites/buildings/harbour-1.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
public/sprites/buildings/harbour-old.png
Normal file
|
After Width: | Height: | Size: 909 KiB |
|
Before Width: | Height: | Size: 909 KiB After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/buildings/spaceship-launch-place.png
Normal file
|
After Width: | Height: | Size: 2.0 MiB |
BIN
public/sprites/planets/arboris-old.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
public/sprites/planets/arboris.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
BIN
public/sprites/planets/aurora.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
public/sprites/planets/borealis.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/sprites/planets/celestia.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
public/sprites/planets/crystallia.png
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
public/sprites/planets/draco.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
public/sprites/planets/dryad.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/eclipse.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/flamara.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/ignis-minor.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/sprites/planets/luminis.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/maridia.png
Normal file
|
After Width: | Height: | Size: 1.7 MiB |
BIN
public/sprites/planets/nautilus.png
Normal file
|
After Width: | Height: | Size: 946 KiB |
BIN
public/sprites/planets/solaris.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/titanus.png
Normal file
|
After Width: | Height: | Size: 1.5 MiB |
BIN
public/sprites/planets/umbra.png
Normal file
|
After Width: | Height: | Size: 1.4 MiB |
BIN
public/sprites/planets/vespera.png
Normal file
|
After Width: | Height: | Size: 1.3 MiB |
BIN
public/sprites/planets/zephyra.png
Normal file
|
After Width: | Height: | Size: 1.6 MiB |
@ -15,3 +15,5 @@
|
|||||||
@if (gameService.showTutorial) {
|
@if (gameService.showTutorial) {
|
||||||
<app-welcome (click)="stopPropagation($event)" (mousedown)="stopPropagation($event)" />
|
<app-welcome (click)="stopPropagation($event)" (mousedown)="stopPropagation($event)" />
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<app-trade-route cdkDrag cdkDragBoundary="html" (click)="stopPropagation($event)"/>
|
||||||
@ -13,12 +13,13 @@ import { registerLocaleData } from '@angular/common';
|
|||||||
import localeDe from '@angular/common/locales/de';
|
import localeDe from '@angular/common/locales/de';
|
||||||
import localeDeExtra from '@angular/common/locales/extra/de';
|
import localeDeExtra from '@angular/common/locales/extra/de';
|
||||||
import { WelcomeComponent } from './components/tutorial/welcome/welcome.component';
|
import { WelcomeComponent } from './components/tutorial/welcome/welcome.component';
|
||||||
|
import { TradeRouteComponent } from './components/dialog/trade-route/trade-route.component';
|
||||||
|
|
||||||
registerLocaleData(localeDe, 'de-DE', localeDeExtra);
|
registerLocaleData(localeDe, 'de-DE', localeDeExtra);
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
imports: [MatDialogModule, ShipDialogComponent, PlanetDialogComponent, DragDropModule, StatusBarComponent, BuyComponent, WelcomeComponent],
|
imports: [MatDialogModule, ShipDialogComponent, PlanetDialogComponent, DragDropModule, StatusBarComponent, BuyComponent, WelcomeComponent, TradeRouteComponent],
|
||||||
providers: [{ provide: LOCALE_ID, useValue: 'de-DE' }],
|
providers: [{ provide: LOCALE_ID, useValue: 'de-DE' }],
|
||||||
templateUrl: './app.component.html',
|
templateUrl: './app.component.html',
|
||||||
styleUrl: './app.component.scss'
|
styleUrl: './app.component.scss'
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
<div class="ui-panel">
|
<div class="ui-panel">
|
||||||
<div class="ui-title" cdkDragHandle>
|
<div class="ui-title" cdkDragHandle>
|
||||||
<div class="image"><img [src]="'sprites/planets/sm/'+ planet.image +'.png'" alt=""></div>
|
<div class="image"><img [src]="'sprites/planets/'+ planet.image +'.png'" alt=""></div>
|
||||||
<div>{{ planet.name }}</div>
|
<div>{{ planet.name }}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@ -0,0 +1,54 @@
|
|||||||
|
<div class="ui-panel">
|
||||||
|
|
||||||
|
<div class="ui-title" cdkDragHandle>
|
||||||
|
<div>Handelsrouten</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="ui-body">
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@if (availableRoutes.length > 0) {
|
||||||
|
<div class="ui-section" style="display: flex; flex-direction: column; gap: 4px;">
|
||||||
|
<h4>Routen:</h4>
|
||||||
|
<div class="flex">
|
||||||
|
@for (route of availableRoutes; track $index) {
|
||||||
|
<button (click)="selectRoute(route)" class="button" [class.active-button]="selectedRoute == route">Route {{ $index }}</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div>oder: </div>
|
||||||
|
<button class="button" (click)="newRoute()">Neue Route erstellen</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div class="ui-section">
|
||||||
|
<h4 matTooltip="Füge Planeten durch anklicken zur Route hinzu">Verfügbare Planeten:</h4>
|
||||||
|
<div style="max-height: 100px; overflow: auto;">
|
||||||
|
@for(planet of availablePlanets;track planet.name) {
|
||||||
|
|
||||||
|
<button class="button" (click)="addPlanet(planet)" >{{ planet.name }}</button>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<h4 matTooltip="Die Planeten werden von oben nach unten der Reihe nach angeflogen.">Route:</h4>
|
||||||
|
<div class="ui-section">
|
||||||
|
|
||||||
|
<div cdkDropList (cdkDropListDropped)="drop($event)" class="ui-section" >
|
||||||
|
@for(planet of selectedPlanets; track $index) {
|
||||||
|
<div class="flex">
|
||||||
|
<div cdkDrag>{{ planet.name }}</div>
|
||||||
|
<button class="button" (click)="remove(planet)" >X</button>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="button" (click)="save()">Speichern</button>
|
||||||
|
</div>
|
||||||
@ -0,0 +1,17 @@
|
|||||||
|
:host {
|
||||||
|
position: absolute;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
position: absolute;
|
||||||
|
top: 24px;
|
||||||
|
left: 24px;
|
||||||
|
width: 600px;
|
||||||
|
// height: 240px;
|
||||||
|
// background-color: var(--background-color);
|
||||||
|
// color: var(--primary-color);
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
h4 {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
@ -0,0 +1,23 @@
|
|||||||
|
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||||
|
|
||||||
|
import { TradeRouteComponent } from './trade-route.component';
|
||||||
|
|
||||||
|
describe('TradeRouteComponent', () => {
|
||||||
|
let component: TradeRouteComponent;
|
||||||
|
let fixture: ComponentFixture<TradeRouteComponent>;
|
||||||
|
|
||||||
|
beforeEach(async () => {
|
||||||
|
await TestBed.configureTestingModule({
|
||||||
|
imports: [TradeRouteComponent]
|
||||||
|
})
|
||||||
|
.compileComponents();
|
||||||
|
|
||||||
|
fixture = TestBed.createComponent(TradeRouteComponent);
|
||||||
|
component = fixture.componentInstance;
|
||||||
|
fixture.detectChanges();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should create', () => {
|
||||||
|
expect(component).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
@ -0,0 +1,64 @@
|
|||||||
|
import { CdkDrag, CdkDragDrop, CdkDropList, DragDropModule, moveItemInArray } from '@angular/cdk/drag-drop';
|
||||||
|
import { CommonModule } from '@angular/common';
|
||||||
|
import { Component, inject } from '@angular/core';
|
||||||
|
import { GameService } from '../../../service/game.service';
|
||||||
|
import { Planet } from '../../../model/planet.model';
|
||||||
|
import { TradeRoute } from '../../../model/routes/trade-route.model';
|
||||||
|
import { MatTooltipModule } from '@angular/material/tooltip';
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'app-trade-route',
|
||||||
|
imports: [CommonModule, DragDropModule, CdkDropList, CdkDrag, MatTooltipModule],
|
||||||
|
templateUrl: './trade-route.component.html',
|
||||||
|
styleUrl: './trade-route.component.scss'
|
||||||
|
})
|
||||||
|
export class TradeRouteComponent {
|
||||||
|
|
||||||
|
private gameService: GameService = inject(GameService);
|
||||||
|
|
||||||
|
selectedPlanets: Planet[] = [];
|
||||||
|
|
||||||
|
selectedRoute: TradeRoute = new TradeRoute([]);
|
||||||
|
|
||||||
|
constructor() {}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
get availablePlanets(): Planet[] {
|
||||||
|
return this.gameService.planets.filter(p => p.hasHarbour || true)
|
||||||
|
}
|
||||||
|
|
||||||
|
get availableRoutes(): TradeRoute[] {
|
||||||
|
return this.gameService.tradeRoutes;
|
||||||
|
}
|
||||||
|
|
||||||
|
addPlanet(planet: Planet) {
|
||||||
|
this.selectedPlanets.push(planet);
|
||||||
|
console.log(this.selectedPlanets)
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(planet: Planet) {
|
||||||
|
this.selectedPlanets = this.selectedPlanets.filter(p => p != planet)
|
||||||
|
}
|
||||||
|
|
||||||
|
drop(event: CdkDragDrop<string[]>) {
|
||||||
|
moveItemInArray(this.selectedPlanets, event.previousIndex, event.currentIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectRoute(route: TradeRoute) {
|
||||||
|
this.selectedRoute = route;
|
||||||
|
this.selectedPlanets = route.getPlanets();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
save() {
|
||||||
|
this.selectedRoute.setPlanets(this.selectedPlanets);
|
||||||
|
this.gameService.tradeRoutes.push(this.selectedRoute);
|
||||||
|
this.newRoute();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
newRoute() {
|
||||||
|
this.selectRoute(new TradeRoute([]))
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -12,6 +12,10 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div>🚀 Neues Schiff: {{ selectedShip.name }}</div>
|
<div>🚀 Neues Schiff: {{ selectedShip.name }}</div>
|
||||||
|
<mat-progress-bar
|
||||||
|
class="example-margin"
|
||||||
|
[value]="shipBuildProgress">
|
||||||
|
</mat-progress-bar>
|
||||||
<div style="margin-top: 12px; font-size: 12px;">{{ selectedShip.desciption }}</div>
|
<div style="margin-top: 12px; font-size: 12px;">{{ selectedShip.desciption }}</div>
|
||||||
<ul>
|
<ul>
|
||||||
<li class="flex">
|
<li class="flex">
|
||||||
@ -85,7 +89,7 @@
|
|||||||
<div class="ui-section flex">
|
<div class="ui-section flex">
|
||||||
|
|
||||||
<button class="button"
|
<button class="button"
|
||||||
[disabled]="selectedPlanets.length < 2 || !canAffordShip()"
|
[disabled]="selectedPlanets.length < 2 || !canAffordShip() || shipBuildProgress > 0"
|
||||||
(click)="buyShip()">
|
(click)="buyShip()">
|
||||||
Schiff kaufen
|
Schiff kaufen
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@ -6,10 +6,11 @@ import { Planet } from '../../../model/planet.model';
|
|||||||
import { ShipConfig } from '../../../model/ships/ship.model';
|
import { ShipConfig } from '../../../model/ships/ship.model';
|
||||||
import { FormsModule } from '@angular/forms';
|
import { FormsModule } from '@angular/forms';
|
||||||
import { SHIP_DATA } from '../../../model/ships/ship.type';
|
import { SHIP_DATA } from '../../../model/ships/ship.type';
|
||||||
|
import {MatProgressBarModule} from '@angular/material/progress-bar';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-buy',
|
selector: 'app-buy',
|
||||||
imports: [CommonModule, CdkDropList, CdkDrag, CdkDragHandle, FormsModule],
|
imports: [CommonModule, CdkDropList, CdkDrag, CdkDragHandle, FormsModule, MatProgressBarModule],
|
||||||
templateUrl: './buy.component.html',
|
templateUrl: './buy.component.html',
|
||||||
styleUrl: './buy.component.scss'
|
styleUrl: './buy.component.scss'
|
||||||
})
|
})
|
||||||
@ -50,13 +51,16 @@ export class BuyComponent {
|
|||||||
return this.gameService.money >= this.config.buyCost;
|
return this.gameService.money >= this.config.buyCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get shipBuildProgress(): number {
|
||||||
|
return this.gameService.planets.find(p => p.spaceShipLauncher != undefined)?.spaceShipLauncher?.buildProcess ?? 0;
|
||||||
|
}
|
||||||
|
|
||||||
buyShip() {
|
buyShip() {
|
||||||
if (!this.canAffordShip()) return;
|
if (!this.canAffordShip()) return;
|
||||||
this.gameService.createShip({
|
this.gameService.createShip({
|
||||||
...this.selectedShip,
|
...this.selectedShip,
|
||||||
planetRoute: this.selectedPlanets
|
planetRoute: this.selectedPlanets
|
||||||
})
|
})
|
||||||
this.close();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
|||||||
@ -1,97 +1,135 @@
|
|||||||
import { GoodType } from "../model/goods/good-type.enum";
|
import { GoodType } from "../model/goods/good-type.enum";
|
||||||
import { PlanetInit } from "../model/planet.model";
|
import { PlanetInit } from "../model/planet.model";
|
||||||
|
|
||||||
export const PLANETCONFIGS: { x: number, y: number, texture: string, config: PlanetInit}[] = [
|
export const PLANETCONFIGS: { x: number, y: number, texture: string, config: PlanetInit }[] = [
|
||||||
{
|
// Kernzone
|
||||||
x: 900,
|
{ x: 10000, y: 10000, texture: 'terra-nova', config: { name: 'Terra Nova', initialGoods: [
|
||||||
y: 950,
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.2 },
|
||||||
texture: 'terra-nova',
|
|
||||||
config: {
|
|
||||||
name: 'Terra Nova',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.18 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.3 },
|
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 4000,
|
|
||||||
y: 1500,
|
|
||||||
texture: 'mechanica-prime',
|
|
||||||
config: {
|
|
||||||
name: 'Mechanica Prime',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.07 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.05 },
|
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 1.5 },
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 1800,
|
|
||||||
y: 3800,
|
|
||||||
texture: 'aqualis',
|
|
||||||
config: {
|
|
||||||
name: 'Aqualis',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.5 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.06 },
|
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 0.2 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 4500,
|
|
||||||
y: 5500,
|
|
||||||
texture: 'planet',
|
|
||||||
config: {
|
|
||||||
name: 'Ferron',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.02 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.03 },
|
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 2.2 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
x: 7400,
|
|
||||||
y: 2400,
|
|
||||||
texture: 'novus-reach',
|
|
||||||
config: {
|
|
||||||
name: 'Novus Reach',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.6 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.07 },
|
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 0.1 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
,
|
|
||||||
{
|
|
||||||
x: 3700,
|
|
||||||
y: 7600,
|
|
||||||
texture: 'volaris',
|
|
||||||
config: {
|
|
||||||
name: 'Volaris',
|
|
||||||
initialGoods: [
|
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.25 },
|
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.2 },
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.2 },
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 0 }
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.1 },
|
||||||
]
|
]}},
|
||||||
}
|
{ x: 12500, y: 10200, texture: 'mechanica-prime', config: { name: 'Mechanica Prime', initialGoods: [
|
||||||
},
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.1 },
|
||||||
{
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.2 },
|
||||||
x: 8000,
|
{ type: GoodType.Erz, amount: 10, productionBonus: 1.7 },
|
||||||
y: 6600,
|
]}},
|
||||||
texture: 'ignis-prime',
|
{ x: 9700, y: 12500, texture: 'volaris', config: { name: 'Volaris', initialGoods: [
|
||||||
config: {
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.3 },
|
||||||
name: 'Ignis Prime',
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.0 },
|
||||||
initialGoods: [
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.3 },
|
]}},
|
||||||
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.06 },
|
{ x: 7500, y: 9700, texture: 'ferron', config: { name: 'Ferron', initialGoods: [
|
||||||
{ type: GoodType.Erz, amount: 10, productionBonus: 0.1 }
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.1 },
|
||||||
]
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.2 },
|
||||||
}
|
{ type: GoodType.Erz, amount: 10, productionBonus: 2.0 },
|
||||||
},
|
]}},
|
||||||
]
|
{ x: 12000, y: 7600, texture: 'solaris', config: { name: 'Solaris', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.4 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.4 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 8000, y: 12500, texture: 'arboris', config: { name: 'Arboris', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.6 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.2 },
|
||||||
|
]}},
|
||||||
|
|
||||||
|
// Mittelzone
|
||||||
|
{ x: 19000, y: 10000, texture: 'aqualis', config: { name: 'Aqualis', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.5 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 16500, y: 16000, texture: 'dryad', config: { name: 'Dryad', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.0 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.1 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 15000, y: 8500, texture: 'ignis-prime', config: { name: 'Ignis Prime', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.5 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.4 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.3 },
|
||||||
|
]}},
|
||||||
|
{ x: 11000, y: 19500, texture: 'novus-reach', config: { name: 'Novus Reach', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.8 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.3 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.5 },
|
||||||
|
]}},
|
||||||
|
{ x: 5000, y: 15000, texture: 'borealis', config: { name: 'Borealis', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 1.5 },
|
||||||
|
]}},
|
||||||
|
{ x: 3000, y: 10000, texture: 'flamara', config: { name: 'Flamara', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.5 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.2 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 14000, y: 4000, texture: 'celestia', config: { name: 'Celestia', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.0 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.2 },
|
||||||
|
]}},
|
||||||
|
{ x: 9000, y: 3000, texture: 'maridia', config: { name: 'Maridia', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.8 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.4 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
|
||||||
|
// Außenzone
|
||||||
|
{ x: 26000, y: 10000, texture: 'crystallia', config: { name: 'Crystallia', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.3 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.0 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 22000, y: 19000, texture: 'draco', config: { name: 'Draco', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.05 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 2.5 },
|
||||||
|
]}},
|
||||||
|
{ x: 18000, y: 26000, texture: 'titanus', config: { name: 'Titanus', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.1 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.3 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 2.5 },
|
||||||
|
]}},
|
||||||
|
{ x: 10000, y: 27000, texture: 'zephyra', config: { name: 'Zephyra', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.3 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 1000, y: 22000, texture: 'aurora', config: { name: 'Aurora', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.6 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.0 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.2 },
|
||||||
|
]}},
|
||||||
|
{ x: 500, y: 14000, texture: 'luminis', config: { name: 'Luminis', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.3 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.4 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 2000, y: 5000, texture: 'eclipse', config: { name: 'Eclipse', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.0 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 7000, y: 500, texture: 'umbra', config: { name: 'Umbra', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 2.2 },
|
||||||
|
]}},
|
||||||
|
{ x: 14000, y: 1000, texture: 'ignis-minor', config: { name: 'Ignis Minor', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 1.5 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.3 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0.3 },
|
||||||
|
]}},
|
||||||
|
{ x: 21000, y: 4000, texture: 'nautilus', config: { name: 'Nautilus', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 2.3 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 0.1 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
{ x: 25000, y: 7000, texture: 'vespera', config: { name: 'Vespera', initialGoods: [
|
||||||
|
{ type: GoodType.Wasser, amount: 10, productionBonus: 0.2 },
|
||||||
|
{ type: GoodType.Nahrung, amount: 10, productionBonus: 2.5 },
|
||||||
|
{ type: GoodType.Erz, amount: 10, productionBonus: 0 },
|
||||||
|
]}},
|
||||||
|
];
|
||||||
|
|||||||
54
src/app/model/factories/spaceship-launcher.model.ts
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
import { inject } from "@angular/core";
|
||||||
|
import { MapScene } from "../../scene/map.scene";
|
||||||
|
import { GameService } from "../../service/game.service";
|
||||||
|
import { Planet } from "../planet.model";
|
||||||
|
import { Ship } from "../ships/ship.model";
|
||||||
|
import { ShipUi } from "../ship";
|
||||||
|
|
||||||
|
export class SpaceshipLauncher {
|
||||||
|
durationInSeconds = 10;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
|
||||||
|
private planet: Planet;
|
||||||
|
private gameService: GameService;
|
||||||
|
|
||||||
|
public buildProcess: number = 0;
|
||||||
|
|
||||||
|
|
||||||
|
constructor(config: {planet: Planet, x: number, y: number, gameService: GameService}) {
|
||||||
|
this.planet = config.planet;
|
||||||
|
this.gameService = config.gameService;
|
||||||
|
this.x = config.x;
|
||||||
|
this.y = config.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async buildShip(scene: MapScene, ship: Ship) {
|
||||||
|
await this.waitForBuilding();
|
||||||
|
const ui = new ShipUi(scene, this.x, this.y, this.gameService, ship);
|
||||||
|
ui.activateRoute();
|
||||||
|
scene.physics.world.enable(ui);
|
||||||
|
scene.ships.push(ui);
|
||||||
|
this.buildProcess = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async waitForBuilding() {
|
||||||
|
this.buildProcess = 0;
|
||||||
|
return new Promise(async resolve=> {
|
||||||
|
for (let i = 0; i < this.durationInSeconds * 100; i++) {
|
||||||
|
this.buildProcess += 0.10;
|
||||||
|
await this.timeout(10);
|
||||||
|
}
|
||||||
|
resolve(null)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private async timeout(ms: number) {
|
||||||
|
return new Promise(resolve => {
|
||||||
|
setTimeout(() => {
|
||||||
|
resolve(null);
|
||||||
|
}, ms)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -9,11 +9,11 @@ export interface GoodConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const GOODS_DATA: Record<GoodType, GoodConfig> = {
|
export const GOODS_DATA: Record<GoodType, GoodConfig> = {
|
||||||
[GoodType.Wasser]: { baseProduction: 1, baseDemand: 0.0012, storageLimit: 500, isRawResource: true },
|
[GoodType.Wasser]: { baseProduction: 1, baseDemand: 0.0052, storageLimit: 500, isRawResource: true },
|
||||||
[GoodType.Nahrung]: { baseProduction: 1, baseDemand: 0.001, storageLimit: 300, isRawResource: true },
|
[GoodType.Nahrung]: { baseProduction: 1, baseDemand: 0.0041, storageLimit: 300, isRawResource: true },
|
||||||
[GoodType.Erz]: { baseProduction: 1.0, baseDemand: 0.0005, storageLimit: 200, isRawResource: true },
|
[GoodType.Erz]: { baseProduction: 1.0, baseDemand: 0.0015, storageLimit: 200, isRawResource: true },
|
||||||
[GoodType.Metall]: { baseProduction: 0.7, baseDemand: 0.003, storageLimit: 300, isRawResource: false, dependsOn: [GoodType.Erz, GoodType.Wasser] },
|
[GoodType.Metall]: { baseProduction: 0.7, baseDemand: 0.0003, storageLimit: 300, isRawResource: false, dependsOn: [GoodType.Erz, GoodType.Wasser] },
|
||||||
[GoodType.Treibstoff]: { baseProduction: 0.5, baseDemand: 0.002, storageLimit: 150, isRawResource: false, dependsOn: [GoodType.Wasser] },
|
[GoodType.Treibstoff]: { baseProduction: 0.5, baseDemand: 0.0002, storageLimit: 150, isRawResource: false, dependsOn: [GoodType.Wasser] },
|
||||||
[GoodType.Elektronik]: { baseProduction: 0.3, baseDemand: 0.001, storageLimit: 100, isRawResource: false, dependsOn: [GoodType.Bauteile, GoodType.Treibstoff] },
|
[GoodType.Elektronik]: { baseProduction: 0.3, baseDemand: 0.0001, storageLimit: 100, isRawResource: false, dependsOn: [GoodType.Bauteile, GoodType.Treibstoff] },
|
||||||
[GoodType.Bauteile]: { baseProduction: 0.5, baseDemand: 0.0015, storageLimit: 100, isRawResource: false, dependsOn: [GoodType.Metall] }
|
[GoodType.Bauteile]: { baseProduction: 0.5, baseDemand: 0.00015, storageLimit: 100, isRawResource: false, dependsOn: [GoodType.Metall] }
|
||||||
};
|
};
|
||||||
@ -5,6 +5,7 @@ import { Good } from "./goods/good.interface";
|
|||||||
import { Ship } from "./ships/ship.model";
|
import { Ship } from "./ships/ship.model";
|
||||||
import { GameService } from "../service/game.service";
|
import { GameService } from "../service/game.service";
|
||||||
import { Factory } from "./factories/factory.model";
|
import { Factory } from "./factories/factory.model";
|
||||||
|
import { SpaceshipLauncher } from "./factories/spaceship-launcher.model";
|
||||||
|
|
||||||
export class Planet {
|
export class Planet {
|
||||||
public population: number = 100;
|
public population: number = 100;
|
||||||
@ -30,12 +31,26 @@ export class Planet {
|
|||||||
private gameService: GameService;
|
private gameService: GameService;
|
||||||
|
|
||||||
hasHarbour = false;
|
hasHarbour = false;
|
||||||
|
spaceShipLauncher: SpaceshipLauncher | undefined;
|
||||||
|
|
||||||
|
private config: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
texture: string;
|
||||||
|
config: PlanetInit;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
constructor(config: PlanetInit, gameService: GameService) {
|
constructor(data: {
|
||||||
this.name = config.name;
|
x: number;
|
||||||
this.image = config.name.toLowerCase().split(' ').join('-')
|
y: number;
|
||||||
|
texture: string;
|
||||||
|
config: PlanetInit;
|
||||||
|
}, gameService: GameService) {
|
||||||
|
this.name = data.config.name;
|
||||||
|
this.image = data.config.name.toLowerCase().split(' ').join('-')
|
||||||
this.gameService = gameService;
|
this.gameService = gameService;
|
||||||
|
this.config = data;
|
||||||
/** set all empty */
|
/** set all empty */
|
||||||
Object.values(GoodType).forEach(c => {
|
Object.values(GoodType).forEach(c => {
|
||||||
this.goods.set(c, {
|
this.goods.set(c, {
|
||||||
@ -48,7 +63,7 @@ export class Planet {
|
|||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
config.initialGoods.forEach(good => {
|
data.config.initialGoods.forEach(good => {
|
||||||
const base = GOODS_DATA[good.type];
|
const base = GOODS_DATA[good.type];
|
||||||
this.goods.set(good.type, {
|
this.goods.set(good.type, {
|
||||||
type: good.type,
|
type: good.type,
|
||||||
@ -58,7 +73,6 @@ export class Planet {
|
|||||||
productionStorage: base.storageLimit
|
productionStorage: base.storageLimit
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
console.log(this.getAllGoods())
|
|
||||||
this.updatePopulation(0)
|
this.updatePopulation(0)
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -194,7 +208,7 @@ export class Planet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
result.push({
|
result.push({
|
||||||
amount: demand * 5 - good.amount - inTransit, // Request 3x buffer amount
|
amount: demand * 2 - good.amount - inTransit, // Request 3x buffer amount
|
||||||
type: good.type,
|
type: good.type,
|
||||||
target: this.name,
|
target: this.name,
|
||||||
})
|
})
|
||||||
@ -238,7 +252,8 @@ export class Planet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (allSupplied) {
|
if (allSupplied) {
|
||||||
this.population += this.population * this.populationGrowthRate * seconds;
|
const grow = Phaser.Math.Between(this.populationGrowthRate * 0.8 * 100000, this.populationGrowthRate * 1.2 * 100000) / 100000;
|
||||||
|
this.population += this.population * grow * seconds;
|
||||||
this.isGrowing = true;
|
this.isGrowing = true;
|
||||||
} else {
|
} else {
|
||||||
this.isGrowing = false;
|
this.isGrowing = false;
|
||||||
@ -351,6 +366,18 @@ export class Planet {
|
|||||||
buildHarbour() {
|
buildHarbour() {
|
||||||
this.hasHarbour = true;
|
this.hasHarbour = true;
|
||||||
this.gameService.money -= 30000;
|
this.gameService.money -= 30000;
|
||||||
|
if (!this.gameService.planets.some(p => p.spaceShipLauncher)) {
|
||||||
|
this.buildSpaceshipLauncher();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buildSpaceshipLauncher() {
|
||||||
|
this.spaceShipLauncher = new SpaceshipLauncher({
|
||||||
|
planet: this,
|
||||||
|
x: this.config.x,
|
||||||
|
y: this.config.y,
|
||||||
|
gameService: this.gameService
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
upgradeProduction() {
|
upgradeProduction() {
|
||||||
@ -392,6 +419,7 @@ export class Planet {
|
|||||||
|
|
||||||
|
|
||||||
public getStatus(): void {
|
public getStatus(): void {
|
||||||
|
return;
|
||||||
console.log(`[${this.name}]: ${this.isGrowing ? '🚀' : '⬇️'}`);
|
console.log(`[${this.name}]: ${this.isGrowing ? '🚀' : '⬇️'}`);
|
||||||
console.log('Population:', Math.round(this.population));
|
console.log('Population:', Math.round(this.population));
|
||||||
console.log('Goods:\n', Array.from(this.goods.entries()).map(([type, good]) =>
|
console.log('Goods:\n', Array.from(this.goods.entries()).map(([type, good]) =>
|
||||||
|
|||||||
@ -1,11 +1,17 @@
|
|||||||
import { Planet, TradeInstance } from "../planet.model"
|
import { Planet, TradeInstance } from "../planet.model"
|
||||||
|
import { Ship } from "../ships/ship.model";
|
||||||
|
|
||||||
export class TradeRoute {
|
export class TradeRoute {
|
||||||
private route: ITradePlanet[] = [];
|
private route: ITradePlanet[] = [];
|
||||||
|
private _ships: Ship[] = [];
|
||||||
|
|
||||||
private target!: ITradePlanet;
|
private target!: ITradePlanet;
|
||||||
|
|
||||||
constructor(route: Planet[]) {
|
constructor(route: Planet[]) {
|
||||||
|
this.setPlanets(route);
|
||||||
|
}
|
||||||
|
|
||||||
|
setPlanets(route: Planet[]) {
|
||||||
const r: any[] = route.map(r => { return {target: r, next: null }})
|
const r: any[] = route.map(r => { return {target: r, next: null }})
|
||||||
if (route.length < 2) { return;}
|
if (route.length < 2) { return;}
|
||||||
|
|
||||||
@ -17,6 +23,10 @@ export class TradeRoute {
|
|||||||
this.route = r;
|
this.route = r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPlanets() {
|
||||||
|
return this.route.map(r => r.target);
|
||||||
|
}
|
||||||
|
|
||||||
get nextPlanetName(): string {
|
get nextPlanetName(): string {
|
||||||
return this.target?.target.name ?? '';
|
return this.target?.target.name ?? '';
|
||||||
}
|
}
|
||||||
|
|||||||
@ -19,8 +19,8 @@ export interface ShipType {
|
|||||||
|
|
||||||
|
|
||||||
export const SHIP_DATA: Record<ShipClass, ShipType> = {
|
export const SHIP_DATA: Record<ShipClass, ShipType> = {
|
||||||
[ShipClass.light]: { name: 'Pioneer-01', cargoSize: 25, loadingSpeed: 15, maxSpeed: 350, acceleration: 300, class: ShipClass.light, buyCost: 3000, cost: 0.6, texture: 'swift-hauler', desciption: 'Ein kleines, schnelles Schiff. Es hat wenig Platz für Ladung, lädt aber schnell und ist sehr wendig.' },
|
[ShipClass.light]: { name: 'Pioneer-01', cargoSize: 25, loadingSpeed: 15, maxSpeed: 350, acceleration: 300, class: ShipClass.light, buyCost: 2000, cost: 0.6, texture: 'swift-hauler', desciption: 'Ein kleines, schnelles Schiff. Es hat wenig Platz für Ladung, lädt aber schnell und ist sehr wendig.' },
|
||||||
[ShipClass.medium]: { name: 'Colony Carrier', cargoSize: 80, loadingSpeed: 20, maxSpeed: 250, acceleration: 90, class: ShipClass.medium, buyCost: 8000, cost: 1.6, texture: 'colony-carrier', desciption: 'Eine größere Version von der Pioneer-01. Der größere Frachtraum geht zu Lasten der Beschleunigung und Maximalgeschwindigkeit.' },
|
[ShipClass.medium]: { name: 'Colony Carrier', cargoSize: 80, loadingSpeed: 20, maxSpeed: 250, acceleration: 90, class: ShipClass.medium, buyCost: 5000, cost: 1.6, texture: 'colony-carrier', desciption: 'Eine größere Version von der Pioneer-01. Der größere Frachtraum geht zu Lasten der Beschleunigung und Maximalgeschwindigkeit.' },
|
||||||
[ShipClass.heavy]: { name: 'Industrial Tanker', cargoSize: 400, loadingSpeed: 11, maxSpeed: 180, acceleration: 20, class: ShipClass.heavy, buyCost: 18000, cost: 3.8, texture: 'industrial-tanker', desciption: 'Ein großes behäbiges Schiff. Es wird durchaus schnell, beschleunigt aber sehr langsam und erreicht die Spitzengeschwindigkeit nur selten.' }
|
[ShipClass.heavy]: { name: 'Industrial Tanker', cargoSize: 400, loadingSpeed: 11, maxSpeed: 180, acceleration: 20, class: ShipClass.heavy, buyCost: 12000, cost: 3.8, texture: 'industrial-tanker', desciption: 'Ein großes behäbiges Schiff. Es wird durchaus schnell, beschleunigt aber sehr langsam und erreicht die Spitzengeschwindigkeit nur selten.' }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ export class MapScene extends Phaser.Scene {
|
|||||||
private isDragging = false;
|
private isDragging = false;
|
||||||
private dragStart = new Phaser.Math.Vector2();
|
private dragStart = new Phaser.Math.Vector2();
|
||||||
private ship!: ShipUi; // Das Raumschiff
|
private ship!: ShipUi; // Das Raumschiff
|
||||||
private ships: ShipUi[] = [];
|
public ships: ShipUi[] = [];
|
||||||
private planets: PlanetUi[] = [];
|
private planets: PlanetUi[] = [];
|
||||||
|
|
||||||
|
|
||||||
@ -24,15 +24,22 @@ export class MapScene extends Phaser.Scene {
|
|||||||
this.load.image('swift-hauler', 'sprites/ships/swift-hauler.png');
|
this.load.image('swift-hauler', 'sprites/ships/swift-hauler.png');
|
||||||
this.load.image('colony-carrier', 'sprites/ships/colony-carrier.png');
|
this.load.image('colony-carrier', 'sprites/ships/colony-carrier.png');
|
||||||
this.load.image('industrial-tanker', 'sprites/ships/industrial-tanker.png');
|
this.load.image('industrial-tanker', 'sprites/ships/industrial-tanker.png');
|
||||||
this.load.image('harbour', 'sprites/buildings/harbour.png');
|
|
||||||
this.load.image('planet', 'sprites/planets/planet-1.png');
|
this.load.image('planet', 'sprites/planets/planet-1.png');
|
||||||
this.load.image('terra-nova', 'sprites/planets/terra-nova.png');
|
// this.load.image('terra-nova', 'sprites/planets/terra-nova.png');
|
||||||
this.load.image('volaris', 'sprites/planets/volaris.png');
|
// this.load.image('volaris', 'sprites/planets/volaris.png');
|
||||||
this.load.image('ignis-prime', 'sprites/planets/ignis-prime.png');
|
// this.load.image('ignis-prime', 'sprites/planets/ignis-prime.png');
|
||||||
this.load.image('mechanica-prime', 'sprites/planets/mechanica-prime.png');
|
// this.load.image('mechanica-prime', 'sprites/planets/mechanica-prime.png');
|
||||||
this.load.image('novus-reach', 'sprites/planets/novus-reach.png');
|
// this.load.image('novus-reach', 'sprites/planets/novus-reach.png');
|
||||||
this.load.image('aqualis', 'sprites/planets/aqualis.png');
|
// this.load.image('aqualis', 'sprites/planets/aqualis.png');
|
||||||
this.load.image('ferron', 'sprites/planets/ferron.png');
|
// this.load.image('ferron', 'sprites/planets/ferron.png');
|
||||||
|
|
||||||
|
|
||||||
|
this.load.image('harbour', 'sprites/buildings/harbour.png');
|
||||||
|
this.load.image('spaceship-launch-place', 'sprites/buildings/spaceship-launch-place.png');
|
||||||
|
|
||||||
|
|
||||||
|
this.loadPlanetSprites()
|
||||||
}
|
}
|
||||||
|
|
||||||
create() {
|
create() {
|
||||||
@ -40,17 +47,17 @@ export class MapScene extends Phaser.Scene {
|
|||||||
|
|
||||||
this.createPlaceHolderGraphic();
|
this.createPlaceHolderGraphic();
|
||||||
// this.camera.setBackgroundColor('0x99ccff')
|
// this.camera.setBackgroundColor('0x99ccff')
|
||||||
|
const worldSize = 30000;
|
||||||
// Weltgröße groß setzen, z. B. 5000x5000 Pixel
|
// Weltgröße groß setzen, z. B. 5000x5000 Pixel
|
||||||
this.camera.setBounds(0, 0, 10000, 10000);
|
this.camera.setBounds(0, 0, worldSize, worldSize);
|
||||||
this.physics.world.setBounds(0, 0, 10000, 10000);
|
this.physics.world.setBounds(0, 0, worldSize, worldSize);
|
||||||
this.cameras.main.setBounds(0, 0, 10000, 10000);
|
this.cameras.main.setBounds(0, 0, worldSize, worldSize);
|
||||||
|
|
||||||
|
|
||||||
/* Sterne */
|
/* Sterne */
|
||||||
for (let i = 0; i< 1000; i++) {
|
for (let i = 0; i< 1000; i++) {
|
||||||
const x = Phaser.Math.Between(0, 10000);
|
const x = Phaser.Math.Between(0, worldSize);
|
||||||
const y = Phaser.Math.Between(0, 10000);
|
const y = Phaser.Math.Between(0, worldSize);
|
||||||
this.add.circle(x, y, Phaser.Math.Between(2, 10), 0x88ccff)
|
this.add.circle(x, y, Phaser.Math.Between(2, 10), 0x88ccff)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,20 +97,22 @@ export class MapScene extends Phaser.Scene {
|
|||||||
this.camera.setZoom(this.camera.zoom * factor);
|
this.camera.setZoom(this.camera.zoom * factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const minScale = Math.max(window.innerWidth / 10000, window.innerHeight / 10000)
|
const minScale = Math.max(window.innerWidth / worldSize, window.innerHeight / worldSize)
|
||||||
// Begrenze Zoom
|
// Begrenze Zoom
|
||||||
this.camera.setZoom(Phaser.Math.Clamp(this.camera.zoom, minScale, 1));
|
this.camera.setZoom(Phaser.Math.Clamp(this.camera.zoom, minScale, 1));
|
||||||
});
|
});
|
||||||
|
|
||||||
this.camera.setZoom(0.4)
|
this.camera.setZoom(0.4)
|
||||||
|
// this.camera.setPosition(1000, 1000)
|
||||||
|
this.camera.scrollX = 10000;
|
||||||
|
this.camera.scrollY = 10000;
|
||||||
|
|
||||||
|
|
||||||
this.gameService.onShipCreate.subscribe(ship => {
|
this.gameService.onShipCreate.subscribe(ship => {
|
||||||
const ui = new ShipUi(this, 100, 100, this.gameService, ship);
|
const factory = this.gameService.planets.find(p => p.spaceShipLauncher)?.spaceShipLauncher;
|
||||||
ui.activateRoute();
|
if (!factory) { return; }
|
||||||
this.physics.world.enable(ui);
|
factory.buildShip(this, ship)
|
||||||
this.ships.push(ui);
|
|
||||||
})
|
})
|
||||||
|
|
||||||
this.gameService.onShipDestroy.subscribe(ship => {
|
this.gameService.onShipDestroy.subscribe(ship => {
|
||||||
@ -130,7 +139,7 @@ export class MapScene extends Phaser.Scene {
|
|||||||
}
|
}
|
||||||
private buildPlanets() {
|
private buildPlanets() {
|
||||||
for (let config of PLANETCONFIGS) {
|
for (let config of PLANETCONFIGS) {
|
||||||
const planet = new PlanetUi(this, config.x, config.y, config.texture, config.config, this.gameService);
|
const planet = new PlanetUi(this, config.x, config.y, config.texture, config, this.gameService);
|
||||||
planet.rightClick.subscribe(planet => {
|
planet.rightClick.subscribe(planet => {
|
||||||
this.ship.moveTo(planet);
|
this.ship.moveTo(planet);
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
@ -171,4 +180,11 @@ export class MapScene extends Phaser.Scene {
|
|||||||
mouseText.setText(`X: ${pointer.worldX.toFixed(0)}\nY: ${pointer.worldY.toFixed(0)}`);
|
mouseText.setText(`X: ${pointer.worldX.toFixed(0)}\nY: ${pointer.worldY.toFixed(0)}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
loadPlanetSprites() {
|
||||||
|
const planets = PLANETCONFIGS;
|
||||||
|
for (let planet of planets) {
|
||||||
|
this.load.image(planet.texture, 'sprites/planets/' + planet.texture + '.png');
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { EventEmitter, Injectable } from "@angular/core";
|
import { EventEmitter, Injectable } from "@angular/core";
|
||||||
import { Planet } from "../model/planet.model";
|
import { Planet } from "../model/planet.model";
|
||||||
import { Ship, ShipConfig } from "../model/ships/ship.model";
|
import { Ship, ShipConfig } from "../model/ships/ship.model";
|
||||||
|
import { TradeRoute } from "../model/routes/trade-route.model";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@ -10,6 +11,7 @@ export class GameService {
|
|||||||
public showShipInfo: Ship | undefined;
|
public showShipInfo: Ship | undefined;
|
||||||
public showBuyShip = false;
|
public showBuyShip = false;
|
||||||
|
|
||||||
|
public tradeRoutes: TradeRoute[] = [];
|
||||||
public ships: Ship[] = [];
|
public ships: Ship[] = [];
|
||||||
public planets: Planet[] = [];
|
public planets: Planet[] = [];
|
||||||
|
|
||||||
@ -31,7 +33,7 @@ export class GameService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get canDrag(): boolean {
|
get canDrag(): boolean {
|
||||||
return this.showShipInfo == undefined && this.showPlanetInfo == undefined;
|
return this.showShipInfo == undefined && this.showPlanetInfo == undefined && !this.showBuyShip;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -3,6 +3,7 @@ import { interval } from "rxjs";
|
|||||||
import { Planet } from "../model/planet.model";
|
import { Planet } from "../model/planet.model";
|
||||||
import { PlanetStatus } from "./planet-status.ui";
|
import { PlanetStatus } from "./planet-status.ui";
|
||||||
import { GameService } from "../service/game.service";
|
import { GameService } from "../service/game.service";
|
||||||
|
import { MapScene } from "../scene/map.scene";
|
||||||
|
|
||||||
export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
||||||
|
|
||||||
@ -10,12 +11,16 @@ export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
|||||||
public rightClick: EventEmitter<PlanetUi> = new EventEmitter();
|
public rightClick: EventEmitter<PlanetUi> = new EventEmitter();
|
||||||
public model: Planet;
|
public model: Planet;
|
||||||
private status: PlanetStatus | undefined;
|
private status: PlanetStatus | undefined;
|
||||||
private harbourImage!: any;
|
private harbourImage!: Phaser.GameObjects.Image;
|
||||||
|
private spaceshipLauncherImage!: Phaser.GameObjects.Image;
|
||||||
|
|
||||||
|
private gameService: GameService;
|
||||||
|
|
||||||
private updateInterval = interval(1000)
|
private updateInterval = interval(1000)
|
||||||
|
|
||||||
constructor(scene: Phaser.Scene, x: number, y: number, texture: string, config: any, gameService: GameService) {
|
constructor(scene: Phaser.Scene, x: number, y: number, texture: string, config: any, gameService: GameService) {
|
||||||
super(scene, x, y, texture);
|
super(scene, x, y, texture);
|
||||||
|
this.gameService = gameService;
|
||||||
// this.setDisplaySize(200, 200);
|
// this.setDisplaySize(200, 200);
|
||||||
|
|
||||||
|
|
||||||
@ -43,10 +48,17 @@ export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
|||||||
|
|
||||||
|
|
||||||
this.harbourImage = this.scene.add.image(this.getWorldPoint().x, this.getWorldPoint().y, 'harbour')
|
this.harbourImage = this.scene.add.image(this.getWorldPoint().x, this.getWorldPoint().y, 'harbour')
|
||||||
this.harbourImage.setDisplaySize(164, 256);
|
this.harbourImage.setDisplaySize(256, 256);
|
||||||
this.harbourImage.setVisible(false);
|
this.harbourImage.setVisible(false);
|
||||||
|
|
||||||
console.log(this.height)
|
this.spaceshipLauncherImage = this.scene.add.image(this.getWorldPoint().x + 260, this.getWorldPoint().y, 'spaceship-launch-place')
|
||||||
|
this.spaceshipLauncherImage.setScale(0.1)
|
||||||
|
this.spaceshipLauncherImage.setVisible(false);
|
||||||
|
this.spaceshipLauncherImage.setInteractive({ useHandCursor: true });
|
||||||
|
this.spaceshipLauncherImage.on('pointerdown', (pointer: Phaser.Input.Pointer) => {
|
||||||
|
this.gameService.showBuyShip = true;
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
// this.setScale(0.5)
|
// this.setScale(0.5)
|
||||||
|
|
||||||
@ -71,7 +83,8 @@ export class PlanetUi extends Phaser.Physics.Arcade.Sprite {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.status?.update();
|
this.status?.update();
|
||||||
this.harbourImage.setVisible(this.model.hasHarbour)
|
this.harbourImage.setVisible(this.model.hasHarbour);
|
||||||
|
this.spaceshipLauncherImage.setVisible(this.model.spaceShipLauncher != undefined);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,10 @@ $font-size-base: 14px;
|
|||||||
@include button;
|
@include button;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.active-button {
|
||||||
|
background-color: $color-success;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
.ui-section {
|
.ui-section {
|
||||||
padding: 16px;
|
padding: 16px;
|
||||||
|
|||||||