From 2e0622a0f87fa0dfa037c8e7285988d219926877 Mon Sep 17 00:00:00 2001 From: Steven Schwarz Date: Fri, 22 Dec 2023 20:10:47 +0100 Subject: [PATCH] Refactor position handling and teleport MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Zentralisiertes Positionstracking durch Einführung eines Enum und eines Records für verschiedene Positionstypen, was die Skalierbarkeit und Lesbarkeit des Spielermanagements verbessert. - Aktualisierte Berechnung der Zufallspositionen mit Math.floor zur Einbeziehung der unteren Grenze des Bereichs. - Teleportationslogik ist nun in der neuen Funktion teleportPlayerToArea gekapselt, getrennt von den Button-Callback-Funktionen, was die Wiederverwendbarkeit erhöht. - Diese Funktion merkt sich auch die letzte Position des Spielers vor der Teleportation, was ein reibungsloseres Hin- und Her-Teleportieren ermöglicht. - Einführung separater Funktionen zum Hinzufügen spezifischer Aktionsbuttons, was den UI-Code weiter verdeutlicht. --- map.tmj | 8 +- src/main.ts | 243 +++++++++++++++++++++++++++------------------------- 2 files changed, 129 insertions(+), 122 deletions(-) diff --git a/map.tmj b/map.tmj index 3eaf13d..f3fb467 100644 --- a/map.tmj +++ b/map.tmj @@ -3166,15 +3166,15 @@ "y":959.440052700922 }, { - "height":190, + "height":192, "id":59, "name":"pauseArea", "rotation":0, "type":"area", "visible":true, - "width":286, - "x":1185, - "y":705 + "width":288, + "x":1184, + "y":704 }, { "height":118, diff --git a/src/main.ts b/src/main.ts index df20ecd..c83f577 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,21 +1,29 @@ +import { Area } from '@workadventure/iframe-api-typings/front/Api/Iframe/Area/Area'; import { bootstrapExtra } from '@workadventure/scripting-api-extra'; (async () => { await WA.onInit(); })(); -let tileSize = 32; +const tileSize = 32; + +enum PositionType { + LastPositionBreak, + LastPositionCall, +} interface Position { x: number | undefined; y: number | undefined; } -let lastPositionBreak: Position = {x: undefined, y: undefined}; -let lastPositionCall: Position = {x: undefined, y: undefined}; +const positions: Record = { + [PositionType.LastPositionBreak]: { x: undefined, y: undefined }, + [PositionType.LastPositionCall]: { x: undefined, y: undefined }, +}; function getRandomInt(min: number, max: number): number { - return Math.ceil(Math.random() * (max - min + 1)) + min; + return Math.floor(Math.random() * (max - min + 1)) + min; } function getDistance(x1: number, y1: number, x2: number, y2: number) { @@ -35,124 +43,123 @@ function showOrHideLayer(layerName: string, startDate: Date, endDate: Date) { } function clearLastPositions() { - lastPositionBreak.x = undefined; - lastPositionBreak.y = undefined; - lastPositionCall.x = undefined; - lastPositionCall.y = undefined; + for (let position of Object.values(positions)) { + position.x = undefined; + position.y = undefined; + } } function showOrHideChristmasLayer() { - let today = new Date(); + const today = new Date(); // December 1st (current year) to January 6th (next year) - let startDate = new Date(today.getFullYear(), 11, 1); - let endDate = new Date(today.getFullYear() + 1, 0, 6); + const startDate = new Date(today.getFullYear(), 11, 1); + const endDate = new Date(today.getFullYear() + 1, 0, 6); showOrHideLayer('Christmas', startDate, endDate); } -function addActionButtons() { - WA.ui.actionBar.addButton({ - id: 'pause-btn', - // @ts-ignore - type: 'action', - imageSrc: - 'https://github.com/othaldo/workadventure-ds/blob/master/src/assets/ds/pause.png?raw=true', - toolTip: 'Zum Pausenbereich teleportieren und zurück', - callback: async () => { - let x; - let y; - if (lastPositionBreak.x === undefined || lastPositionBreak.y === undefined) { - const area = await WA.room.area.get("pauseArea"); - let xStart = area.x; - let xEnd = area.x + area.width - (tileSize / 2); - - let yStart = area.y; - let yEnd = area.y + area.height - (tileSize / 2); - - x = getRandomInt(xStart , xEnd); - y = getRandomInt(yStart , yEnd); - lastPositionBreak.x = (await WA.player.getPosition()).x; - lastPositionBreak.y = (await WA.player.getPosition()).y; - } else { - x = lastPositionBreak.x; - y = lastPositionBreak.y; - lastPositionBreak.x = undefined; - lastPositionBreak.y = undefined; - } +async function teleportPlayerToArea(area: Area | undefined, positionType: PositionType) { + let x = positions[positionType].x; + let y = positions[positionType].y; + + if (area !== undefined) { + const xStart = area.x; + const xEnd = area.x + area.width - (tileSize / 2); + + const yStart = area.y; + const yEnd = area.y + area.height - (tileSize / 2); + + x = getRandomInt(xStart, xEnd); + y = getRandomInt(yStart, yEnd); - WA.player.teleport(x, y); - removeButtons(); - addActionButtons(); + const position = await WA.player.getPosition(); + if (position) { + Object.assign(positions[positionType], position); } - }); + } else { + Object.assign(positions[positionType], { x: undefined, y: undefined }); + } + if (x !== undefined && y !== undefined) { + WA.player.teleport(x, y); + } + + removeButtons(); + addActionButtons(); +} + +function addTeleportButton(id: string, imageSrc: string, toolTip: string, positionType: PositionType, getArea: () => Promise) { WA.ui.actionBar.addButton({ - id: 'customer-call-btn', - // @ts-ignore + id, type: 'action', - imageSrc: - 'https://github.com/othaldo/workadventure-ds/blob/master/src/assets/ds/call.png?raw=true', - toolTip: 'Zum \'Im Gespräch\'-Bereich teleportieren und zurück', + imageSrc, + toolTip, callback: async () => { - let x; - let y; - if (lastPositionCall.x === undefined || lastPositionCall.y === undefined) { - const customerCallArea1 = await WA.room.area.get('ccArea1'); - const customerCallArea2 = await WA.room.area.get('ccArea2'); - const position = await WA.player.getPosition(); - - // Berechne die Mittelpunkte der Areas - const midPointArea1 = { - x: customerCallArea1.x + customerCallArea1.width / 2, - y: customerCallArea1.y + customerCallArea1.height / 2 - }; - const midPointArea2 = { - x: customerCallArea2.x + customerCallArea2.width / 2, - y: customerCallArea2.y + customerCallArea2.height / 2 - }; - - // Berechne die Distanzen zur aktuellen Position - const distanceToArea1 = - getDistance(position.x, position.y, midPointArea1.x, midPointArea1.y); - const distanceToArea2 = - getDistance(position.x, position.y, midPointArea2.x, midPointArea2.y); - - // Bestimme die nächstgelegene Area - const nearestArea = distanceToArea1 < distanceToArea2 ? - customerCallArea1 : - customerCallArea2; - - // Berechne zufällige Position innerhalb der nächstgelegenen Area - let xStart = nearestArea.x; - let xEnd = nearestArea.x + nearestArea.width - (tileSize / 2); - let yStart = nearestArea.y; - let yEnd = nearestArea.y + nearestArea.height - (tileSize / 2); - - x = getRandomInt(xStart , xEnd); - y = getRandomInt(yStart , yEnd); - lastPositionCall.x = (await WA.player.getPosition()).x; - lastPositionCall.y = (await WA.player.getPosition()).y; - } else { - x = lastPositionCall.x; - y = lastPositionCall.y; - lastPositionCall.x = undefined; - lastPositionCall.y = undefined; + const position = positions[positionType]; + let area; + + if (position.x === undefined || position.y === undefined) { + area = await getArea(); } - // Teleportiere den Spieler - WA.player.teleport(x, y); - removeButtons(); - addActionButtons(); + + teleportPlayerToArea(area, positionType); } }); } +function addPauseButton() { + addTeleportButton('pause-btn', + 'https://github.com/othaldo/workadventure-ds/blob/master/src/assets/ds/pause.png?raw=true', + 'Zum Pausenbereich teleportieren und zurück', + PositionType.LastPositionBreak, + async () => await WA.room.area.get("pauseArea")); +} + +function addCustomerCallButton() { + addTeleportButton('customer-call-btn', + 'https://github.com/othaldo/workadventure-ds/blob/master/src/assets/ds/call.png?raw=true', + 'Zum \'Im Gespräch\'-Bereich teleportieren und zurück', + PositionType.LastPositionCall, + async () => { + const customerCallArea1 = await WA.room.area.get('ccArea1'); + const customerCallArea2 = await WA.room.area.get('ccArea2'); + const position = await WA.player.getPosition(); + + // Berechne die Mittelpunkte der Areas + const midPointArea1 = { + x: customerCallArea1.x + customerCallArea1.width / 2, + y: customerCallArea1.y + customerCallArea1.height / 2 + }; + const midPointArea2 = { + x: customerCallArea2.x + customerCallArea2.width / 2, + y: customerCallArea2.y + customerCallArea2.height / 2 + }; + + // Berechne die Distanzen zur aktuellen Position + const distanceToArea1 = + getDistance(position.x, position.y, midPointArea1.x, midPointArea1.y); + const distanceToArea2 = + getDistance(position.x, position.y, midPointArea2.x, midPointArea2.y); + + // Bestimme die nächstgelegene Area + return distanceToArea1 < distanceToArea2 ? + customerCallArea1 : + customerCallArea2; + }); +} + +function addActionButtons() { + addPauseButton(); + addCustomerCallButton(); +} + function removeButtons() { WA.ui.actionBar.removeButton('pause-btn'); WA.ui.actionBar.removeButton('customer-call-btn'); } -function registerAreaOnLeaveHandler(){ +function registerAreaOnLeaveHandler() { WA.room.area.onLeave('pauseArea').subscribe(() => { clearLastPositions(); }); @@ -166,26 +173,26 @@ function registerAreaOnLeaveHandler(){ // Waiting for the API to be ready WA.onInit() - .then(() => { - const userTag = WA.player.tags; + .then(() => { + const userTag = WA.player.tags; - // If user is admin, name it with a dark blue border - if (userTag.includes('admin')) { - WA.player.setOutlineColor(27, 42, 65); - } + // If user is admin, name it with a dark blue border + if (userTag.includes('admin')) { + WA.player.setOutlineColor(27, 42, 65); + } - addActionButtons(); - showOrHideChristmasLayer(); - registerAreaOnLeaveHandler(); - - // The line below bootstraps the Scripting API Extra library that adds a - // number of advanced properties/features to WorkAdventure - bootstrapExtra() - .then(() => { - console.log('Scripting API Extra ready'); - }) - .catch(e => console.error(e)); - }) - .catch(e => console.error(e)); - -export {}; + addActionButtons(); + showOrHideChristmasLayer(); + registerAreaOnLeaveHandler(); + + // The line below bootstraps the Scripting API Extra library that adds a + // number of advanced properties/features to WorkAdventure + bootstrapExtra() + .then(() => { + console.log('Scripting API Extra ready'); + }) + .catch(e => console.error(e)); + }) + .catch(e => console.error(e)); + +export { };