From 2abb5440a80cf96201a9228619a834a31c6ba09b Mon Sep 17 00:00:00 2001 From: cramerL Date: Sat, 5 Aug 2023 02:55:49 +0200 Subject: [PATCH 1/8] added parallax layer rendering and editing with different layer sizes, fixes #272 --- .../components/layers/layers.component.html | 54 ++++++++++- .../components/layers/layers.component.scss | 8 +- .../app/components/layers/layers.component.ts | 40 +++++--- .../components/sidenav/sidenav.component.ts | 7 -- .../3d/layer-generation/texture-generator.ts | 2 - .../src/app/services/phaser/layer-parallax.ts | 77 +++++++++++++++ webapp/src/app/services/phaser/main-scene.ts | 27 +----- webapp/src/app/services/phaser/map-pan.ts | 1 - .../services/phaser/phaser-events.service.ts | 2 - .../services/phaser/tilemap/cc-map-layer.ts | 89 +++++++++++++++--- .../src/app/services/phaser/tilemap/cc-map.ts | 8 +- .../services/phaser/tilemap/tile-drawer.ts | 14 +-- webapp/src/assets/ingame.png | Bin 0 -> 9352 bytes 13 files changed, 254 insertions(+), 75 deletions(-) create mode 100644 webapp/src/app/services/phaser/layer-parallax.ts create mode 100644 webapp/src/assets/ingame.png diff --git a/webapp/src/app/components/layers/layers.component.html b/webapp/src/app/components/layers/layers.component.html index df6f8573..c6fdd037 100644 --- a/webapp/src/app/components/layers/layers.component.html +++ b/webapp/src/app/components/layers/layers.component.html @@ -34,6 +34,41 @@
+
+
+ Size: + +
+ +
+ + X: + + + + + Y: + + +
+
+
Type: @@ -59,7 +94,8 @@ Level: + [ngModel]="selectedLayer?.details?.level" + (selectionChange)="updateLevel($event.value)"> {{i}} @@ -68,16 +104,24 @@
Distance: - +
Tileset: - - {{getTilesetName(tileset)}} + + {{getTilesetName(tileset)}}
diff --git a/webapp/src/app/components/layers/layers.component.scss b/webapp/src/app/components/layers/layers.component.scss index be07dd60..365c7248 100644 --- a/webapp/src/app/components/layers/layers.component.scss +++ b/webapp/src/app/components/layers/layers.component.scss @@ -67,12 +67,13 @@ mat-nav-list { .small-list { min-height: 80px !important; + & mat-list-item, .mat-list-item-content { height: 36px !important; } } -.layers-tab-container{ +.layers-tab-container { height: 100%; } @@ -86,6 +87,7 @@ mat-nav-list { .label { flex: 0 0 80px; + @include mat.icon-button-density(-3); } .list-item { @@ -93,6 +95,10 @@ mat-nav-list { width: 100%; } +.size-prefix { + margin-left: 6px; +} + .simple-input { padding-bottom: 5px !important; box-shadow: inset 0px -1px 0px 0px rgb(255, 255, 255); diff --git a/webapp/src/app/components/layers/layers.component.ts b/webapp/src/app/components/layers/layers.component.ts index a326ec06..a5d8aa5c 100644 --- a/webapp/src/app/components/layers/layers.component.ts +++ b/webapp/src/app/components/layers/layers.component.ts @@ -25,9 +25,9 @@ export class LayersComponent implements OnInit { tilesets: string[] = []; //Angular view data constructor(private mapLoader: MapLoaderService, - private stateHistory: StateHistoryService, - private http: HttpClientService, - events: GlobalEventsService) { + private stateHistory: StateHistoryService, + private http: HttpClientService, + events: GlobalEventsService) { events.toggleVisibility.subscribe(() => { if (this.selectedLayer) { this.toggleVisibility({ @@ -36,12 +36,18 @@ export class LayersComponent implements OnInit { } as Event, this.selectedLayer); } }); - + this.loadTilesets(); } ngOnInit() { - this.mapLoader.selectedLayer.subscribe(layer => this.selectedLayer = layer); + this.mapLoader.selectedLayer.subscribe(layer => { + this.selectedLayer = layer; + for (const layer of (this.map?.layers ?? [])) { + layer.select(false); + } + layer?.select(true); + }); this.mapLoader.tileMap.subscribe(tilemap => this.map = tilemap); } @@ -117,9 +123,6 @@ export class LayersComponent implements OnInit { } selectLayer(layer?: CCMapLayer) { - if (layer) { - layer.visible = true; - } this.mapLoader.selectedLayer.next(layer); } @@ -130,17 +133,17 @@ export class LayersComponent implements OnInit { this.selectedLayer.updateTileset(name); this.mapLoader.selectedLayer.next(this.selectedLayer); } - + getTilesetName(path: string): string { return path.substring('media/map/'.length, path.length - '.png'.length); } - + private async loadTilesets() { if (LayersComponent.tilesets.length > 0) { this.tilesets = LayersComponent.tilesets; return; } - + LayersComponent.tilesets = await firstValueFrom(this.http.getAllTilesets()); this.tilesets = LayersComponent.tilesets; } @@ -152,6 +155,21 @@ export class LayersComponent implements OnInit { this.selectedLayer.updateLevel(level); } + updateSize() { + this.selectedLayer?.resize(this.selectedLayer?.details.width, this.selectedLayer?.details.height); + this.stateHistory.saveState({ + name: 'Layer resized', + icon: 'resize' + }); + } + + updateDistance() { + this.stateHistory.saveState({ + name: 'Distance changed', + icon: 'fit_screen' + }); + } + drop(event: CdkDragDrop) { if (event.previousIndex === event.currentIndex) { return; diff --git a/webapp/src/app/components/sidenav/sidenav.component.ts b/webapp/src/app/components/sidenav/sidenav.component.ts index 31421e3b..eb010d72 100644 --- a/webapp/src/app/components/sidenav/sidenav.component.ts +++ b/webapp/src/app/components/sidenav/sidenav.component.ts @@ -15,9 +15,7 @@ import { CCMapLayer } from '../../services/phaser/tilemap/cc-map-layer'; export class SidenavComponent implements OnInit { activeTab = EditorView.Layers; - selectedLayer?: CCMapLayer; tilemap?: CCMap; - editorViewEnum = EditorView; disableLayersTab = false; constructor( @@ -27,11 +25,6 @@ export class SidenavComponent implements OnInit { } ngOnInit() { - this.mapLoader.selectedLayer.subscribe(layer => { - if (layer) { - this.selectedLayer = layer; - } - }); this.mapLoader.tileMap.subscribe(tilemap => { this.tilemap = tilemap; const currentView = this.globalEvents.currentView; diff --git a/webapp/src/app/services/3d/layer-generation/texture-generator.ts b/webapp/src/app/services/3d/layer-generation/texture-generator.ts index a0221969..97bbf411 100644 --- a/webapp/src/app/services/3d/layer-generation/texture-generator.ts +++ b/webapp/src/app/services/3d/layer-generation/texture-generator.ts @@ -26,11 +26,9 @@ export class TextureGenerator { .filter(l => l.details.type.toLowerCase() === 'background') .sort((a, b) => a.details.level - b.details.level); - Globals.phaserEventsService.showMapBorder.next(false); } destroy() { - Globals.phaserEventsService.showMapBorder.next(true); } /** diff --git a/webapp/src/app/services/phaser/layer-parallax.ts b/webapp/src/app/services/phaser/layer-parallax.ts new file mode 100644 index 00000000..7345b671 --- /dev/null +++ b/webapp/src/app/services/phaser/layer-parallax.ts @@ -0,0 +1,77 @@ +import { BaseObject } from './base-object'; +import { Globals } from '../globals'; +import { CCMap } from './tilemap/cc-map'; + +export class LayerParallax extends BaseObject { + + private map?: CCMap; + private centerObject?: Phaser.GameObjects.Image; + + constructor(scene: Phaser.Scene) { + super(scene, LayerParallax.name, true); + } + + protected activate(): void { + this.addSubscription(Globals.mapLoaderService.tileMap.subscribe(map => this.map = map)); + + // TODO: move image into new class, maybe toggleable with a secret hotkey? + this.centerObject = this.scene.add.image(0, 0, 'ingame'); + this.centerObject.depth = 99999999; + this.centerObject.visible = false; + } + + protected deactivate(): void { + if (!this.map) { + return; + } + for (const layer of this.map.layers) { + layer.setOffset(0, 0); + } + this.centerObject?.destroy(true); + } + + protected init(): void { + } + + override preUpdate(time: number, delta: number) { + if (!this.map) { + return; + } + const layers = this.map.layers; + const cam = this.scene.cameras.main; + + const midX = cam.scrollX + cam.width * 0.5; + const midY = cam.scrollY + cam.height * 0.5; + + const displayWidth = cam.width / cam.zoomX; + const displayHeight = cam.height / cam.zoomY; + + const centerX = midX - displayWidth * 0.15; + const centerY = midY - displayHeight * 0.05; + + if (this.centerObject?.visible) { + this.centerObject.x = centerX; + this.centerObject.y = centerY; + } + + // half of game resolution + const offX = centerX - 284; + const offY = centerY - 160; + + for (const layer of layers) { + if (!layer.visible) { + continue; + } + let x = offX / (layer.details?.distance ?? 1); + let y = offY / (layer.details?.distance ?? 1); + + if (layer.details.distance < 1) { + x += 16; + y += 16; + } + + layer.setOffset(offX - x, offY - y); + } + } + +} diff --git a/webapp/src/app/services/phaser/main-scene.ts b/webapp/src/app/services/phaser/main-scene.ts index 9b39bb4a..2ca6e97c 100644 --- a/webapp/src/app/services/phaser/main-scene.ts +++ b/webapp/src/app/services/phaser/main-scene.ts @@ -7,14 +7,13 @@ import { EntityManager } from './entities/entity-manager'; import { MapPan } from './map-pan'; import { CCMap } from './tilemap/cc-map'; import { TileDrawer } from './tilemap/tile-drawer'; +import { LayerParallax } from './layer-parallax'; export class MainScene extends Phaser.Scene { private readonly borderSize = 1; - private border?: Phaser.GameObjects.Rectangle; private sub?: Subscription; - private borderVisible = true; constructor() { super({key: 'main'}); @@ -23,6 +22,7 @@ export class MainScene extends Phaser.Scene { preload() { this.load.image('pixel', 'assets/pixel.png'); + this.load.image('ingame', 'assets/ingame.png'); this.load.json('destructibles.json', 'assets/destructibles.json'); this.load.json('destructible-types.json', 'assets/destructible-types.json'); @@ -52,7 +52,6 @@ export class MainScene extends Phaser.Scene { this.sub = Globals.mapLoaderService.map.subscribe((map) => { if (map) { tileMap.loadMap(map); - this.rescaleBorder(); // reset camera position on map load const cam = this.cameras.main; @@ -64,13 +63,6 @@ export class MainScene extends Phaser.Scene { cam.centerOn(map.mapWidth * s / 2 + offset, map.mapHeight * s / 2); } }); - Globals.phaserEventsService.updateMapBorder.subscribe(() => this.rescaleBorder()); - Globals.phaserEventsService.showMapBorder.subscribe(visible => { - if (this.border) { - this.border.visible = visible; - } - this.borderVisible = visible; - }); const pan = new MapPan(this, 'mapPan'); this.add.existing(pan); @@ -79,6 +71,7 @@ export class MainScene extends Phaser.Scene { this.add.existing(tileDrawer); this.add.existing(entityManager); + this.add.existing(new LayerParallax(this)); const coordsReporter = new CoordsReporter(this); this.add.existing(coordsReporter); @@ -105,18 +98,4 @@ export class MainScene extends Phaser.Scene { this.sub.unsubscribe(); } } - - private rescaleBorder() { - const s = Globals.TILE_SIZE; - - if (this.border) { - this.border.destroy(); - } - const map = Globals.map; - - this.border = this.add.rectangle(-this.borderSize, -this.borderSize, map.mapWidth * s + this.borderSize * 2, map.mapHeight * s + this.borderSize * 2); - this.border.setStrokeStyle(this.borderSize * 2, 0xfc4445, 1); - this.border.setOrigin(0, 0); - this.border.visible = this.borderVisible; - } } diff --git a/webapp/src/app/services/phaser/map-pan.ts b/webapp/src/app/services/phaser/map-pan.ts index 17f60ba3..11c7b70b 100644 --- a/webapp/src/app/services/phaser/map-pan.ts +++ b/webapp/src/app/services/phaser/map-pan.ts @@ -77,7 +77,6 @@ export class MapPan extends Phaser.GameObjects.GameObject { cam.scrollX += oldX - mouse.x; cam.scrollY += oldY - mouse.y; } - Globals.phaserEventsService.updateMapBorder.next(true); } preUpdate() { diff --git a/webapp/src/app/services/phaser/phaser-events.service.ts b/webapp/src/app/services/phaser/phaser-events.service.ts index 5be64f3a..991249c4 100644 --- a/webapp/src/app/services/phaser/phaser-events.service.ts +++ b/webapp/src/app/services/phaser/phaser-events.service.ts @@ -8,6 +8,4 @@ import { SelectedTile } from '../../models/tile-selector'; export class PhaserEventsService { changeSelectedTiles = new Subject(); - updateMapBorder = new Subject(); - showMapBorder = new Subject(); } diff --git a/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts b/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts index acf4f936..0de7f246 100644 --- a/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts +++ b/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts @@ -3,6 +3,7 @@ import { BlendModes } from 'phaser'; import { MapLayer, Point } from '../../../models/cross-code-map'; import { Helper } from '../helper'; import { customPutTilesAt } from './layer-helper'; +import { Globals } from '../../globals'; import Tile = Phaser.Tilemaps.Tile; export class CCMapLayer { @@ -10,8 +11,12 @@ export class CCMapLayer { public details!: MapLayer; private layer!: Phaser.Tilemaps.TilemapLayer; + private border!: Phaser.GameObjects.Rectangle; + private container!: Phaser.GameObjects.Container; - constructor(private tilemap: Phaser.Tilemaps.Tilemap) { + constructor( + private tilemap: Phaser.Tilemaps.Tilemap + ) { } public async init(details: MapLayer) { @@ -41,7 +46,12 @@ export class CCMapLayer { details.distance = parseFloat(details.distance); } this.details = details; - this.layer = this.tilemap.createBlankLayer(details.name + Math.random(), 'stub')!; + this.border = this.tilemap.scene.add.rectangle(); + this.border.visible = false; + this.container = this.tilemap.scene.add.container(0, 0, this.border); + this.container.depth = 999; + this.makeLayer('stub'); + this.updateBorder(); if (details.data) { customPutTilesAt(details.data, this.layer); } @@ -61,6 +71,8 @@ export class CCMapLayer { } set visible(val: boolean) { + this.container.visible = val; + this.container.active = val; this.layer.visible = val; this.layer.active = val; } @@ -73,8 +85,24 @@ export class CCMapLayer { this.layer.alpha = val; } + get x(): number { + return this.container.x; + } + + get y(): number { + return this.container.y; + } + destroy() { - this.layer.destroy(); + this.container.destroy(true); + this.layer?.destroy(true); + } + + select(val: boolean) { + if (val) { + this.visible = true; + } + this.border.visible = val; } offsetLayer(offset: Point, borderTiles = false) { @@ -114,12 +142,9 @@ export class CCMapLayer { newData[y][x] = old[x]?.index ?? 0; } } - const tilesetName = this.layer.tileset[0].name; const visible = this.layer.visible; - this.layer.destroy(); - - this.layer = this.tilemap.createBlankLayer(this.details.name + Math.random(), tilesetName, 0, 0, width, height)!; - customPutTilesAt(newData, this.layer); + this.makeLayer(undefined, newData); + this.updateBorder(); this.visible = visible; } @@ -128,14 +153,10 @@ export class CCMapLayer { const details = this.details; details.tilesetName = tilesetname; - const oldLayer = this.layer; await Helper.loadTexture(tilesetname, this.tilemap.scene); const newTileset = this.tilemap.addTilesetImage(tilesetname, undefined, undefined, undefined, undefined, undefined, 1); - this.layer = this.tilemap.createBlankLayer(details.name + Math.random(), newTileset ?? [], 0, 0, details.width, details.height)!; - customPutTilesAt(oldLayer.layer.data, this.layer); - - oldLayer.destroy(); + this.makeLayer(newTileset ?? []); this.updateLevel(this.details.level); this.updateLighter(!!this.details.lighter); @@ -150,6 +171,13 @@ export class CCMapLayer { this.layer.depth = this.details.level * 10; } + setOffset(x: number, y: number) { + this.container.x = x; + this.container.y = y; + this.layer.x = x; + this.layer.y = y; + } + updateLighter(lighter: boolean) { this.details.lighter = lighter; const blendMode = lighter ? BlendModes.ADD : BlendModes.NORMAL; @@ -160,6 +188,41 @@ export class CCMapLayer { return this.layer; } + private makeLayer(tileset?: string | string[] | Phaser.Tilemaps.Tileset, tiles?: Tile[][] | number[][]) { + const oldLayer = this.layer as typeof this.layer | undefined; + + if (!tileset) { + tileset = oldLayer?.tileset[0].name ?? []; + } + if (!tiles) { + tiles = oldLayer?.layer?.data; + } + this.layer = this.tilemap.createBlankLayer(this.details.name + Math.random(), tileset, 0, 0, this.details.width, this.details.height)!; + if (tiles) { + customPutTilesAt(tiles, this.layer); + } + this.layer.alpha = oldLayer?.alpha ?? 1; + this.setOffset(this.container.x, this.container.y); + this.updateLevel(this.details.level); + if (oldLayer) { + oldLayer.destroy(true); + } + } + + private updateBorder() { + const s = Globals.TILE_SIZE; + + const borderSize = 2; + + this.border.setPosition(-borderSize * 0.5, -borderSize * 0.5); + this.border.setSize( + this.details.width * s + borderSize, + this.details.height * s + borderSize, + ); + this.border.setStrokeStyle(borderSize, 0xfc4445, 1); + this.border.setOrigin(0, 0); + } + exportLayer(): MapLayer { const out: MapLayer = Object.assign({}, this.details); if (out.levelName) { diff --git a/webapp/src/app/services/phaser/tilemap/cc-map.ts b/webapp/src/app/services/phaser/tilemap/cc-map.ts index 8bc1a4d5..eab44d47 100644 --- a/webapp/src/app/services/phaser/tilemap/cc-map.ts +++ b/webapp/src/app/services/phaser/tilemap/cc-map.ts @@ -135,8 +135,12 @@ export class CCMap { this.mapWidth = width; this.mapHeight = height; - this.layers.forEach(layer => layer.resize(width, height)); - Globals.phaserEventsService.updateMapBorder.next(true); + this.layers.forEach(layer => { + // only update layers with distance: 1, parallax should not be touched + if (layer.details.distance === 1) { + layer.resize(width, height); + } + }); } offsetMap(offset: Point, borderTiles = false) { diff --git a/webapp/src/app/services/phaser/tilemap/tile-drawer.ts b/webapp/src/app/services/phaser/tilemap/tile-drawer.ts index 75a6f65d..b1cb04db 100644 --- a/webapp/src/app/services/phaser/tilemap/tile-drawer.ts +++ b/webapp/src/app/services/phaser/tilemap/tile-drawer.ts @@ -99,7 +99,7 @@ export class TileDrawer extends BaseObject { return; } const pointer = this.scene.input.activePointer; - const p = Helper.worldToTile(pointer.worldX, pointer.worldY); + const p = Helper.worldToTile(pointer.worldX - this.layer.x, pointer.worldY - this.layer.y); // render selection border if (this.rightClickStart) { @@ -135,15 +135,15 @@ export class TileDrawer extends BaseObject { container.x = pointer.worldX; container.y = pointer.worldY; - if (container.x < 0) { + if (container.x < this.layer.x) { container.x -= Globals.TILE_SIZE; } - if (container.y < 0) { + if (container.y < this.layer.y) { container.y -= Globals.TILE_SIZE; } - container.x -= container.x % Globals.TILE_SIZE; - container.y -= container.y % Globals.TILE_SIZE; + container.x -= (container.x - this.layer.x) % Globals.TILE_SIZE; + container.y -= (container.y - this.layer.y) % Globals.TILE_SIZE; if (this.previewLayer) { Vec2.assign(this.previewLayer, container); @@ -151,7 +151,7 @@ export class TileDrawer extends BaseObject { // draw tiles // trigger only when mouse is over canvas element (the renderer), avoids triggering when interacting with ui - if (pointer.leftButtonDown() && pointer.downElement.nodeName === 'CANVAS' && this.layer) { + if (pointer.leftButtonDown() && pointer.downElement?.nodeName === 'CANVAS' && this.layer) { const finalPos = {x: 0, y: 0}; const startPos = {x: 0, y: 0}; @@ -297,7 +297,7 @@ export class TileDrawer extends BaseObject { // only start tile copy when cursor in bounds const pointer = this.scene.input.activePointer; - const p = Helper.worldToTile(pointer.worldX, pointer.worldY); + const p = Helper.worldToTile(pointer.worldX - this.layer.x, pointer.worldY - this.layer.y); if (!Helper.isInBounds(this.layer, p)) { return; } diff --git a/webapp/src/assets/ingame.png b/webapp/src/assets/ingame.png new file mode 100644 index 0000000000000000000000000000000000000000..c208eb534bf26f7af8af7f22c7916194635426a3 GIT binary patch literal 9352 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 literal 0 HcmV?d00001 From d8c97a068d124e86605ad173e29b6b74672a2a42 Mon Sep 17 00:00:00 2001 From: cramerL Date: Sat, 5 Aug 2023 16:00:07 +0200 Subject: [PATCH 2/8] fixed issue with fill on parallax layers --- webapp/src/app/services/phaser/tilemap/tile-drawer.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/webapp/src/app/services/phaser/tilemap/tile-drawer.ts b/webapp/src/app/services/phaser/tilemap/tile-drawer.ts index b1cb04db..47ccd924 100644 --- a/webapp/src/app/services/phaser/tilemap/tile-drawer.ts +++ b/webapp/src/app/services/phaser/tilemap/tile-drawer.ts @@ -398,10 +398,14 @@ export class TileDrawer extends BaseObject { } const pointer = this.scene.input.activePointer; - const p = Helper.worldToTile(pointer.worldX, pointer.worldY); + const p = Helper.worldToTile(pointer.worldX - this.layer.x, pointer.worldY - this.layer.y); if (this.selectedTiles.length > 0) { Filler.fill(this.layer, this.selectedTiles[0].id, p); + Globals.stateHistoryService.saveState({ + name: 'fill', + icon: 'format_color_fill' + }); } } From 0f8e8740ee4cb61f61cf6624e222062ca3024a73 Mon Sep 17 00:00:00 2001 From: cramerL Date: Sat, 5 Aug 2023 18:14:51 +0200 Subject: [PATCH 3/8] added ingame preview --- CHANGELOG.md | 8 +++++ .../app/components/phaser/phaser.component.ts | 10 +++--- .../components/toolbar/toolbar.component.html | 25 +++++++++++-- .../components/toolbar/toolbar.component.scss | 4 --- .../components/toolbar/toolbar.component.ts | 12 ++++--- .../src/app/services/global-events.service.ts | 1 + webapp/src/app/services/phaser/base-object.ts | 3 +- .../src/app/services/phaser/ingame-preview.ts | 36 +++++++++++++++++++ .../src/app/services/phaser/layer-parallax.ts | 32 +++++------------ webapp/src/app/services/phaser/main-scene.ts | 8 +++-- webapp/src/app/services/phaser/map-pan.ts | 3 +- webapp/src/app/services/phaser/pre-update.ts | 3 ++ .../services/phaser/tilemap/cc-map-layer.ts | 2 +- 13 files changed, 102 insertions(+), 45 deletions(-) create mode 100644 webapp/src/app/services/phaser/ingame-preview.ts create mode 100644 webapp/src/app/services/phaser/pre-update.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 147d9c54..e923ce21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ## [Unreleased] + +### Added +- Added support for parallax layers (`distance != 1`) +- The size of every individual layer can now be changed instead of using the map size + +### Fixed +- Layers with different sizes are now saved properly [#272](https://github.com/CCDirectLink/crosscode-map-editor/issues/272) + ## [1.0.0] 2023-08-04 ### Added diff --git a/webapp/src/app/components/phaser/phaser.component.ts b/webapp/src/app/components/phaser/phaser.component.ts index bc14fd53..2043365e 100644 --- a/webapp/src/app/components/phaser/phaser.component.ts +++ b/webapp/src/app/components/phaser/phaser.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, HostListener, OnInit, ViewChild } from '@angular/core'; +import { AfterViewInit, Component, ElementRef, HostListener, ViewChild } from '@angular/core'; import * as Phaser from 'phaser'; import { AutotileService } from '../../services/autotile/autotile.service'; @@ -18,7 +18,7 @@ import { MatSnackBar } from '@angular/material/snack-bar'; templateUrl: './phaser.component.html', styleUrls: ['./phaser.component.scss'] }) -export class PhaserComponent implements OnInit { +export class PhaserComponent implements AfterViewInit { @ViewChild('content', {static: true}) content!: ElementRef; @@ -45,7 +45,7 @@ export class PhaserComponent implements OnInit { } - ngOnInit() { + ngAfterViewInit() { this.heightMap.init(); const scene = new MainScene(); const scale = this.getScale(); @@ -83,8 +83,8 @@ export class PhaserComponent implements OnInit { private getScale() { const rect = this.content.nativeElement.getBoundingClientRect(); return { - width: (rect.width + 5) * window.devicePixelRatio, - height: (rect.height + 5) * window.devicePixelRatio + width: rect.width * window.devicePixelRatio, + height: rect.height * window.devicePixelRatio }; } } diff --git a/webapp/src/app/components/toolbar/toolbar.component.html b/webapp/src/app/components/toolbar/toolbar.component.html index 1cb7cbbd..7f792157 100644 --- a/webapp/src/app/components/toolbar/toolbar.component.html +++ b/webapp/src/app/components/toolbar/toolbar.component.html @@ -29,9 +29,28 @@ -
- 3D! - +
+
+ + 3D! + +
+ +
+ + ingame preview + +
diff --git a/webapp/src/app/components/toolbar/toolbar.component.scss b/webapp/src/app/components/toolbar/toolbar.component.scss index 63c1100b..ef38b909 100644 --- a/webapp/src/app/components/toolbar/toolbar.component.scss +++ b/webapp/src/app/components/toolbar/toolbar.component.scss @@ -5,10 +5,6 @@ z-index: 2; } -.toggle-3d { - margin-left: 16px; -} - mat-spinner { height: 40px; } diff --git a/webapp/src/app/components/toolbar/toolbar.component.ts b/webapp/src/app/components/toolbar/toolbar.component.ts index b112d3f9..c9011b7f 100644 --- a/webapp/src/app/components/toolbar/toolbar.component.ts +++ b/webapp/src/app/components/toolbar/toolbar.component.ts @@ -32,7 +32,7 @@ export class ToolbarComponent implements OnInit { public loadMapClicked = new EventEmitter(false); constructor(private mapLoader: MapLoaderService, - private events: GlobalEventsService, + public events: GlobalEventsService, private dialog: MatDialog, private overlayService: OverlayService, private overlay: Overlay, @@ -123,8 +123,12 @@ export class ToolbarComponent implements OnInit { }); } - changeTo3d(event: MatSlideToggleChange) { - this.is3d = event.checked; - this.router.navigate([event.checked ? '3d' : '']); + changeTo3d(checked: boolean) { + this.is3d = checked; + this.router.navigate([checked ? '3d' : '']); + } + + toggleIngamePreview(checked: boolean) { + this.events.showIngamePreview.next(checked); } } diff --git a/webapp/src/app/services/global-events.service.ts b/webapp/src/app/services/global-events.service.ts index 1adc93f9..fe140de8 100644 --- a/webapp/src/app/services/global-events.service.ts +++ b/webapp/src/app/services/global-events.service.ts @@ -20,6 +20,7 @@ export class GlobalEventsService { showAddEntityMenu = new Subject(); updateCoords = new Subject(); + showIngamePreview = new BehaviorSubject(false); babylonLoading = new BehaviorSubject(false); is3D = new BehaviorSubject(false); diff --git a/webapp/src/app/services/phaser/base-object.ts b/webapp/src/app/services/phaser/base-object.ts index a0ed77ac..991f88f7 100644 --- a/webapp/src/app/services/phaser/base-object.ts +++ b/webapp/src/app/services/phaser/base-object.ts @@ -1,5 +1,6 @@ import * as Phaser from 'phaser'; import { Subscription } from 'rxjs'; +import { PreUpdate } from './pre-update'; export interface KeyBinding { event: string; @@ -7,7 +8,7 @@ export interface KeyBinding { emitter: Phaser.Events.EventEmitter; } -export abstract class BaseObject extends Phaser.GameObjects.GameObject { +export abstract class BaseObject extends Phaser.GameObjects.GameObject implements PreUpdate { private subs: Subscription[] = []; private keyBindings: KeyBinding[] = []; diff --git a/webapp/src/app/services/phaser/ingame-preview.ts b/webapp/src/app/services/phaser/ingame-preview.ts new file mode 100644 index 00000000..77ecbcf1 --- /dev/null +++ b/webapp/src/app/services/phaser/ingame-preview.ts @@ -0,0 +1,36 @@ +import { PreUpdate } from './pre-update'; +import { Globals } from '../globals'; +import { Subscription } from 'rxjs'; + +export class IngamePreview extends Phaser.GameObjects.Image implements PreUpdate { + + private sub: Subscription; + + constructor(scene: Phaser.Scene) { + super(scene, 0, 0, 'ingame'); + this.depth = 99999; + this.sub = Globals.globalEventsService.showIngamePreview.subscribe(v => this.visible = v); + } + + override destroy(fromScene?: boolean) { + super.destroy(fromScene); + this.sub.unsubscribe(); + } + + preUpdate(time: number, delta: number): void { + const cam = this.scene.cameras.main; + + const midX = cam.scrollX + cam.width * 0.5; + const midY = cam.scrollY + cam.height * 0.5; + + const displayWidth = cam.width / cam.zoomX; + const displayHeight = cam.height / cam.zoomY; + + const centerX = midX - displayWidth * 0.1; + const centerY = midY - displayHeight * 0.06; + + this.x = centerX; + this.y = centerY; + } + +} diff --git a/webapp/src/app/services/phaser/layer-parallax.ts b/webapp/src/app/services/phaser/layer-parallax.ts index 7345b671..1d432a2d 100644 --- a/webapp/src/app/services/phaser/layer-parallax.ts +++ b/webapp/src/app/services/phaser/layer-parallax.ts @@ -1,23 +1,21 @@ import { BaseObject } from './base-object'; import { Globals } from '../globals'; import { CCMap } from './tilemap/cc-map'; +import { IngamePreview } from './ingame-preview'; export class LayerParallax extends BaseObject { private map?: CCMap; - private centerObject?: Phaser.GameObjects.Image; - constructor(scene: Phaser.Scene) { + constructor( + scene: Phaser.Scene, + private preview: IngamePreview + ) { super(scene, LayerParallax.name, true); } protected activate(): void { this.addSubscription(Globals.mapLoaderService.tileMap.subscribe(map => this.map = map)); - - // TODO: move image into new class, maybe toggleable with a secret hotkey? - this.centerObject = this.scene.add.image(0, 0, 'ingame'); - this.centerObject.depth = 99999999; - this.centerObject.visible = false; } protected deactivate(): void { @@ -27,32 +25,20 @@ export class LayerParallax extends BaseObject { for (const layer of this.map.layers) { layer.setOffset(0, 0); } - this.centerObject?.destroy(true); } protected init(): void { } - override preUpdate(time: number, delta: number) { + preUpdate(time: number, delta: number) { if (!this.map) { return; } - const layers = this.map.layers; - const cam = this.scene.cameras.main; - - const midX = cam.scrollX + cam.width * 0.5; - const midY = cam.scrollY + cam.height * 0.5; - const displayWidth = cam.width / cam.zoomX; - const displayHeight = cam.height / cam.zoomY; - - const centerX = midX - displayWidth * 0.15; - const centerY = midY - displayHeight * 0.05; + const layers = this.map.layers; - if (this.centerObject?.visible) { - this.centerObject.x = centerX; - this.centerObject.y = centerY; - } + const centerX = this.preview.x; + const centerY = this.preview.y; // half of game resolution const offX = centerX - 284; diff --git a/webapp/src/app/services/phaser/main-scene.ts b/webapp/src/app/services/phaser/main-scene.ts index 2ca6e97c..b853df94 100644 --- a/webapp/src/app/services/phaser/main-scene.ts +++ b/webapp/src/app/services/phaser/main-scene.ts @@ -8,11 +8,10 @@ import { MapPan } from './map-pan'; import { CCMap } from './tilemap/cc-map'; import { TileDrawer } from './tilemap/tile-drawer'; import { LayerParallax } from './layer-parallax'; +import { IngamePreview } from './ingame-preview'; export class MainScene extends Phaser.Scene { - private readonly borderSize = 1; - private sub?: Subscription; constructor() { @@ -71,7 +70,10 @@ export class MainScene extends Phaser.Scene { this.add.existing(tileDrawer); this.add.existing(entityManager); - this.add.existing(new LayerParallax(this)); + + const preview = new IngamePreview(this); + this.add.existing(preview); + this.add.existing(new LayerParallax(this, preview)); const coordsReporter = new CoordsReporter(this); this.add.existing(coordsReporter); diff --git a/webapp/src/app/services/phaser/map-pan.ts b/webapp/src/app/services/phaser/map-pan.ts index 11c7b70b..f7f3c909 100644 --- a/webapp/src/app/services/phaser/map-pan.ts +++ b/webapp/src/app/services/phaser/map-pan.ts @@ -1,8 +1,9 @@ import { Point } from '../../models/cross-code-map'; import { Globals } from '../globals'; import { Vec2 } from './vec2'; +import { PreUpdate } from './pre-update'; -export class MapPan extends Phaser.GameObjects.GameObject { +export class MapPan extends Phaser.GameObjects.GameObject implements PreUpdate{ private isScrolling = false; private startMouse: Point = {x: 0, y: 0}; private startCam: Point = {x: 0, y: 0}; diff --git a/webapp/src/app/services/phaser/pre-update.ts b/webapp/src/app/services/phaser/pre-update.ts new file mode 100644 index 00000000..290f8a7a --- /dev/null +++ b/webapp/src/app/services/phaser/pre-update.ts @@ -0,0 +1,3 @@ +export interface PreUpdate { + preUpdate(time: number, delta: number): void; +} diff --git a/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts b/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts index 0de7f246..6d9195f5 100644 --- a/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts +++ b/webapp/src/app/services/phaser/tilemap/cc-map-layer.ts @@ -192,7 +192,7 @@ export class CCMapLayer { const oldLayer = this.layer as typeof this.layer | undefined; if (!tileset) { - tileset = oldLayer?.tileset[0].name ?? []; + tileset = oldLayer?.tileset[0]?.name ?? []; } if (!tiles) { tiles = oldLayer?.layer?.data; From 86ed507455b06a0e91cea6a7c392e6af9290a9b7 Mon Sep 17 00:00:00 2001 From: cramerL Date: Sat, 5 Aug 2023 18:25:54 +0200 Subject: [PATCH 4/8] updated changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e923ce21..50f11df0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). ### Added - Added support for parallax layers (`distance != 1`) - The size of every individual layer can now be changed instead of using the map size +- Added preview to see how the parallax effect would look ingame ### Fixed - Layers with different sizes are now saved properly [#272](https://github.com/CCDirectLink/crosscode-map-editor/issues/272) From 44ae67aa9ad8737f92271017af8407c88375b914 Mon Sep 17 00:00:00 2001 From: Jan Date: Sun, 20 Aug 2023 17:09:07 +0200 Subject: [PATCH 5/8] Update webapp/src/app/components/toolbar/toolbar.component.html Co-authored-by: 2767mr <2767mr@users.noreply.github.com> --- webapp/src/app/components/toolbar/toolbar.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/app/components/toolbar/toolbar.component.html b/webapp/src/app/components/toolbar/toolbar.component.html index 7f792157..9baa59cf 100644 --- a/webapp/src/app/components/toolbar/toolbar.component.html +++ b/webapp/src/app/components/toolbar/toolbar.component.html @@ -48,7 +48,7 @@ color="primary" (change)="toggleIngamePreview($event.checked)" > - ingame preview + Ingame Preview
From b699f37dc74f07a95c2ca8df8f98b3d1ea3988fa Mon Sep 17 00:00:00 2001 From: cramerL Date: Sun, 20 Aug 2023 17:14:10 +0200 Subject: [PATCH 6/8] added comment why parallax layers shouldn't be resized --- webapp/src/app/services/phaser/tilemap/cc-map.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/webapp/src/app/services/phaser/tilemap/cc-map.ts b/webapp/src/app/services/phaser/tilemap/cc-map.ts index eab44d47..118c6b1f 100644 --- a/webapp/src/app/services/phaser/tilemap/cc-map.ts +++ b/webapp/src/app/services/phaser/tilemap/cc-map.ts @@ -136,7 +136,8 @@ export class CCMap { this.mapHeight = height; this.layers.forEach(layer => { - // only update layers with distance: 1, parallax should not be touched + // only update layers with distance: 1 + // Parallax Layers shouldn't be updated because they usually have different dimensions than the map if (layer.details.distance === 1) { layer.resize(width, height); } From 3c01ce8fb4e413ebe0aa0041a06096802dc46036 Mon Sep 17 00:00:00 2001 From: cramerL Date: Sun, 20 Aug 2023 17:26:10 +0200 Subject: [PATCH 7/8] resize layer only when clicking on button --- .../src/app/components/layers/layers.component.html | 4 ++-- webapp/src/app/components/layers/layers.component.ts | 12 +++++++++--- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/webapp/src/app/components/layers/layers.component.html b/webapp/src/app/components/layers/layers.component.html index c6fdd037..62b86ed0 100644 --- a/webapp/src/app/components/layers/layers.component.html +++ b/webapp/src/app/components/layers/layers.component.html @@ -52,7 +52,7 @@ @@ -62,7 +62,7 @@ diff --git a/webapp/src/app/components/layers/layers.component.ts b/webapp/src/app/components/layers/layers.component.ts index a5d8aa5c..f1323ba7 100644 --- a/webapp/src/app/components/layers/layers.component.ts +++ b/webapp/src/app/components/layers/layers.component.ts @@ -24,6 +24,9 @@ export class LayersComponent implements OnInit { newLayerName = ''; tilesets: string[] = []; //Angular view data + width = 0; + height = 0; + constructor(private mapLoader: MapLoaderService, private stateHistory: StateHistoryService, private http: HttpClientService, @@ -46,7 +49,11 @@ export class LayersComponent implements OnInit { for (const layer of (this.map?.layers ?? [])) { layer.select(false); } - layer?.select(true); + if (layer){ + layer.select(true); + this.width = layer.details.width; + this.height = layer.details.height; + } }); this.mapLoader.tileMap.subscribe(tilemap => this.map = tilemap); } @@ -156,7 +163,7 @@ export class LayersComponent implements OnInit { } updateSize() { - this.selectedLayer?.resize(this.selectedLayer?.details.width, this.selectedLayer?.details.height); + this.selectedLayer?.resize(this.width, this.height); this.stateHistory.saveState({ name: 'Layer resized', icon: 'resize' @@ -183,5 +190,4 @@ export class LayersComponent implements OnInit { icon: 'open_with', }, true); } - } From 937aef4febe40dbc253bb8f3c34c18298a11846b Mon Sep 17 00:00:00 2001 From: cramerL Date: Sun, 20 Aug 2023 17:30:15 +0200 Subject: [PATCH 8/8] add history entry for distance only on blur, not on every change --- webapp/src/app/components/layers/layers.component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webapp/src/app/components/layers/layers.component.html b/webapp/src/app/components/layers/layers.component.html index 62b86ed0..ed1a4080 100644 --- a/webapp/src/app/components/layers/layers.component.html +++ b/webapp/src/app/components/layers/layers.component.html @@ -110,7 +110,7 @@ matInput [disabled]="!selectedLayer" [(ngModel)]="selectedLayer?.details!.distance" - (ngModelChange)="updateDistance()" + (blur)="updateDistance()" >