added basic interactive layer functionality

This commit is contained in:
Johannes Berthel 2021-04-05 20:47:46 +02:00 committed by Thomas Basler
parent 5946e75db0
commit 66c20687c3
4 changed files with 180 additions and 8 deletions

View File

@ -96,6 +96,7 @@ import {DEPTH_OVERLAY_INDEX} from "./DepthIndexes";
import {waScaleManager} from "../Services/WaScaleManager";
import {peerStore} from "../../Stores/PeerStore";
import {EmoteManager} from "./EmoteManager";
import { InteractiveLayer } from "../Map/InteractiveLayer";
export interface GameSceneInitInterface {
initPosition: PointInterface|null,
@ -418,15 +419,19 @@ export class GameScene extends DirtyScene implements CenterListener {
let depth = -2;
for (const layer of this.gameMap.layersIterator) {
if (layer.type === 'tilelayer') {
this.addLayer(this.Map.createLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
if (this.isLayerInteractive(layer) === false) {
this.addLayer(this.Map.createLayer(layer.name, this.Terrains, 0, 0).setDepth(depth));
const exitSceneUrl = this.getExitSceneUrl(layer);
if (exitSceneUrl !== undefined) {
this.loadNextGame(exitSceneUrl);
}
const exitUrl = this.getExitUrl(layer);
if (exitUrl !== undefined) {
this.loadNextGame(exitUrl);
const exitSceneUrl = this.getExitSceneUrl(layer);
if (exitSceneUrl !== undefined) {
this.loadNextGame(exitSceneUrl);
}
const exitUrl = this.getExitUrl(layer);
if (exitUrl !== undefined) {
this.loadNextGame(exitUrl);
}
} else {
this.addInteractiveLayer(layer);
}
}
if (layer.type === 'objectgroup' && layer.name === 'floorLayer') {
@ -1058,6 +1063,10 @@ ${escapedMessage}
return this.getProperty(layer, "exitUrl") as string|undefined;
}
private isLayerInteractive(layer: ITiledMapLayer): boolean {
return Boolean(this.getProperty(layer, "interactive"));
}
/**
* @deprecated the map property exitSceneUrl is deprecated
*/
@ -1138,6 +1147,10 @@ ${escapedMessage}
this.Layers.push(Layer);
}
addInteractiveLayer(layer: ITiledMapLayer): void {
new InteractiveLayer(this, layer);
}
createCollisionWithPlayer() {
//add collision layer
this.Layers.forEach((Layer: Phaser.Tilemaps.TilemapLayer) => {

View File

@ -0,0 +1,159 @@
import Sprite = Phaser.GameObjects.Sprite;
import Container = Phaser.GameObjects.Container;
import type { ITiledMapLayer } from "./ITiledMap";
import type { GameScene } from "../Game/GameScene";
export class InteractiveLayer extends Container {
private activeSprite: string|null;
private spritesCollection: Array<{
animation: string;
sprite: Sprite;
}>;
private updateListener: Function;
constructor(scene: GameScene, layer: ITiledMapLayer) {
const { x, y } = layer;
super(scene, x, y);
this.activeSprite = null;
this.spritesCollection = [];
this.addSprites(layer);
this.updateListener = this.update.bind(this);
scene.events.addListener('update', this.updateListener);
this.setDepth(-2);
this.scene.add.existing(this);
}
public update(): void {
const scene = this.getScene();
const x = scene.CurrentPlayer.x + scene.CurrentPlayer.width;
const y = scene.CurrentPlayer.y + scene.CurrentPlayer.height * 2;
let foundSprite = false;
for (const i in this.spritesCollection) {
const entity = this.spritesCollection[i];
const sprite = entity.sprite;
if (sprite.x < x && sprite.y < y && sprite.x + sprite.width > x && sprite.y + sprite.height > y) {
if (this.activeSprite !== i) {
sprite.play(entity.animation, true);
}
foundSprite = true;
this.activeSprite = i;
break;
}
}
if (foundSprite === false) {
this.activeSprite = null;
}
}
public destroy(): void {
const scene = this.getScene();
for (const entity of this.spritesCollection) {
if (scene) {
scene.sys.updateList.remove(entity.sprite);
}
}
if (scene) {
scene.events.removeListener('update', this.updateListener);
}
super.destroy();
}
private addSprites(layer: ITiledMapLayer): void {
if (typeof layer.data === "string") {
return;
}
const scene = this.getScene();
for (let i = 0; i < layer.data.length; i++) {
const index = layer.data[i];
if (index !== 0) {
const tileset = this.getTileset(index);
if (tileset !== null) {
const x = (i % layer.width) * tileset.tileWidth;
const y = (Math.floor(i / layer.width)) * tileset.tileHeight;
const animation = this.getAnimationFromTile(tileset, index);
const key = `interactive-layer-${tileset.name}-${index}`;
if (animation !== null) {
if (typeof scene.anims.get(key) === 'undefined') {
for (const j in animation) {
if (!tileset.image.has(String(animation[j].tileid))) {
const frameCoordinates = (tileset.getTileTextureCoordinates(animation[j].tileid + tileset.firstgid) as any);
tileset.image.add(animation[j].tileid, 0, frameCoordinates.x, frameCoordinates.y, tileset.tileWidth, tileset.tileHeight);
}
}
scene.anims.create({
key,
frames: animation.map(frame => ({
key: tileset.image.key,
frame: frame.tileid,
duration: frame.duration
})),
repeat: 0
});
}
}
const sprite = new Sprite(scene, x, y, tileset.image, 0);
scene.sys.updateList.add(sprite);
this.add(sprite);
this.spritesCollection.push({
animation: key,
sprite
});
}
}
}
}
private getTileset(index: number): Phaser.Tilemaps.Tileset|null {
const scene = this.getScene();
for (const i in scene.Map.tilesets) {
const tileset = scene.Map.tilesets[i];
if (tileset.getTileData(index) !== null) {
return tileset;
}
}
return null;
}
private getAnimationFromTile(tileset: Phaser.Tilemaps.Tileset, index: number) {
const data = tileset.getTileData(index);
if (typeof data === "object" && data !== null && Array.isArray((data as any).animation)) {
const animation: Array<{duration: number; tileid: number}> = (data as any).animation;
return animation;
}
return null
}
private getScene(): GameScene {
return (this.scene as GameScene);
}
}

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 263 B