diff --git a/back/src/Services/VariablesManager.ts b/back/src/Services/VariablesManager.ts index 00aac3dc..6ec1cc3a 100644 --- a/back/src/Services/VariablesManager.ts +++ b/back/src/Services/VariablesManager.ts @@ -1,12 +1,7 @@ /** * Handles variables shared between the scripting API and the server. */ -import { - ITiledMap, - ITiledMapLayer, - ITiledMapObject, - ITiledMapObjectLayer, -} from "@workadventure/tiled-map-type-guard/dist"; +import { ITiledMap, ITiledMapLayer, ITiledMapObject } from "@workadventure/tiled-map-type-guard/dist"; import { User } from "_Model/User"; import { variablesRepository } from "./Repository/VariablesRepository"; import { redisClient } from "./RedisClient"; diff --git a/docs/maps/camera.md b/docs/maps/camera.md new file mode 100644 index 00000000..ac25c843 --- /dev/null +++ b/docs/maps/camera.md @@ -0,0 +1,86 @@ +{.section-title.accent.text-primary} +# Working with camera + +## Focusable Zones + +It is possible to define special regions on the map that can make the camera zoom and center on themselves. We call them "Focusable Zones". When player gets inside, his camera view will be altered - focused, zoomed and locked on defined zone, like this: + +
+ +
+ +### Adding new **Focusable Zone**: + +1. Make sure you are editing an **Object Layer** + +
+ +
+ +2. Select **Insert Rectangle** tool + +
+ +
+ +3. Define new object wherever you want. For example, you can make your chilling room event cosier! + +
+ +
+ +4. Edit this new object and click on **Add Property**, like this: + +
+ +
+ +5. Add a **bool** property of name *focusable*: + +
+ +
+ +6. Make sure it's checked! :) + +
+ +
+ +All should be set up now and your new **Focusable Zone** should be working fine! + +### Defining custom zoom margin: + +If you want, you can add an additional property to control how much should the camera zoom onto focusable zone. + +1. Like before, click on **Add Property** + +
+ +
+ +2. Add a **float** property of name *zoom_margin*: + +
+ +
+ +2. Define how much (in percentage value) should the zoom be decreased: + +
+ +
+ + For example, if you define your zone as a 300x200 rectangle, setting this property to 0.5 *(50%)* means the camera will try to fit within the viewport the entire zone + margin of 50% of its dimensions, so 450x300. + + - No margin defined + +
+ +
+ + - Margin set to **0.35** + +
+ +
\ No newline at end of file diff --git a/docs/maps/images/camera/0_focusable_zone.png b/docs/maps/images/camera/0_focusable_zone.png new file mode 100644 index 00000000..8b54f11f Binary files /dev/null and b/docs/maps/images/camera/0_focusable_zone.png differ diff --git a/docs/maps/images/camera/1_object_layer.png b/docs/maps/images/camera/1_object_layer.png new file mode 100644 index 00000000..6f57d0ae Binary files /dev/null and b/docs/maps/images/camera/1_object_layer.png differ diff --git a/docs/maps/images/camera/2_rectangle_zone.png b/docs/maps/images/camera/2_rectangle_zone.png new file mode 100644 index 00000000..9b0b9cda Binary files /dev/null and b/docs/maps/images/camera/2_rectangle_zone.png differ diff --git a/docs/maps/images/camera/3_define_new_zone.png b/docs/maps/images/camera/3_define_new_zone.png new file mode 100644 index 00000000..226028eb Binary files /dev/null and b/docs/maps/images/camera/3_define_new_zone.png differ diff --git a/docs/maps/images/camera/4_click_add_property.png b/docs/maps/images/camera/4_click_add_property.png new file mode 100644 index 00000000..9aa96a2f Binary files /dev/null and b/docs/maps/images/camera/4_click_add_property.png differ diff --git a/docs/maps/images/camera/5_add_focusable_prop.png b/docs/maps/images/camera/5_add_focusable_prop.png new file mode 100644 index 00000000..3ba1b955 Binary files /dev/null and b/docs/maps/images/camera/5_add_focusable_prop.png differ diff --git a/docs/maps/images/camera/6_make_sure_checked.png b/docs/maps/images/camera/6_make_sure_checked.png new file mode 100644 index 00000000..7fbcdb89 Binary files /dev/null and b/docs/maps/images/camera/6_make_sure_checked.png differ diff --git a/docs/maps/images/camera/7_add_zoom_margin.png b/docs/maps/images/camera/7_add_zoom_margin.png new file mode 100644 index 00000000..8e3f5256 Binary files /dev/null and b/docs/maps/images/camera/7_add_zoom_margin.png differ diff --git a/docs/maps/images/camera/8_optional_zoom_margin_defined.png b/docs/maps/images/camera/8_optional_zoom_margin_defined.png new file mode 100644 index 00000000..8b41d7d0 Binary files /dev/null and b/docs/maps/images/camera/8_optional_zoom_margin_defined.png differ diff --git a/docs/maps/images/camera/no_margin.png b/docs/maps/images/camera/no_margin.png new file mode 100644 index 00000000..b8c9dd18 Binary files /dev/null and b/docs/maps/images/camera/no_margin.png differ diff --git a/docs/maps/images/camera/with_margin.png b/docs/maps/images/camera/with_margin.png new file mode 100644 index 00000000..ffd057ea Binary files /dev/null and b/docs/maps/images/camera/with_margin.png differ diff --git a/docs/maps/menu.php b/docs/maps/menu.php index 0bf0a7f9..10a2f4c5 100644 --- a/docs/maps/menu.php +++ b/docs/maps/menu.php @@ -51,6 +51,12 @@ return [ 'markdown' => 'maps.website-in-map', 'editUrl' => 'https://github.com/thecodingmachine/workadventure/edit/develop/docs/maps/website-in-map.md', ], + [ + 'title' => 'Camera', + 'url' => '/map-building/camera.md', + 'markdown' => 'maps.camera', + 'editUrl' => 'https://github.com/thecodingmachine/workadventure/edit/develop/docs/maps/camera.md', + ], [ 'title' => 'Variables', 'url' => '/map-building/variables.md', diff --git a/front/src/Api/Events/ChangeZoneEvent.ts b/front/src/Api/Events/ChangeZoneEvent.ts new file mode 100644 index 00000000..e7ca3668 --- /dev/null +++ b/front/src/Api/Events/ChangeZoneEvent.ts @@ -0,0 +1,11 @@ +import * as tg from "generic-type-guard"; + +export const isChangeZoneEvent = new tg.IsInterface() + .withProperties({ + name: tg.isString, + }) + .get(); +/** + * A message sent from the game to the iFrame when a user enters or leaves a zone. + */ +export type ChangeZoneEvent = tg.GuardedType; diff --git a/front/src/Api/Events/IframeEvent.ts b/front/src/Api/Events/IframeEvent.ts index 89230302..894e0c58 100644 --- a/front/src/Api/Events/IframeEvent.ts +++ b/front/src/Api/Events/IframeEvent.ts @@ -28,6 +28,7 @@ import type { MessageReferenceEvent } from "./ui/TriggerActionMessageEvent"; import { isMessageReferenceEvent, isTriggerActionMessageEvent } from "./ui/TriggerActionMessageEvent"; import type { MenuRegisterEvent, UnregisterMenuEvent } from "./ui/MenuRegisterEvent"; import type { ChangeLayerEvent } from "./ChangeLayerEvent"; +import type { ChangeZoneEvent } from "./ChangeZoneEvent"; import { isGetPropertyEvent } from "./GetPropertyEvent"; export interface TypedMessageEvent extends MessageEvent { @@ -77,6 +78,8 @@ export interface IframeResponseEventMap { leaveEvent: EnterLeaveEvent; enterLayerEvent: ChangeLayerEvent; leaveLayerEvent: ChangeLayerEvent; + enterZoneEvent: ChangeZoneEvent; + leaveZoneEvent: ChangeZoneEvent; buttonClickedEvent: ButtonClickedEvent; hasPlayerMoved: HasPlayerMovedEvent; menuItemClicked: MenuItemClickedEvent; diff --git a/front/src/Api/IframeListener.ts b/front/src/Api/IframeListener.ts index 3c6e8a07..16b6138c 100644 --- a/front/src/Api/IframeListener.ts +++ b/front/src/Api/IframeListener.ts @@ -31,6 +31,7 @@ import type { SetVariableEvent } from "./Events/SetVariableEvent"; import { ModifyEmbeddedWebsiteEvent, isEmbeddedWebsiteEvent } from "./Events/EmbeddedWebsiteEvent"; import { handleMenuRegistrationEvent, handleMenuUnregisterEvent } from "../Stores/MenuStore"; import type { ChangeLayerEvent } from "./Events/ChangeLayerEvent"; +import type { ChangeZoneEvent } from "./Events/ChangeZoneEvent"; type AnswererCallback = ( query: IframeQueryMap[T]["query"], @@ -420,6 +421,24 @@ class IframeListener { }); } + sendEnterZoneEvent(zoneName: string) { + this.postMessage({ + type: "enterZoneEvent", + data: { + name: zoneName, + } as ChangeZoneEvent, + }); + } + + sendLeaveZoneEvent(zoneName: string) { + this.postMessage({ + type: "leaveZoneEvent", + data: { + name: zoneName, + } as ChangeZoneEvent, + }); + } + hasPlayerMoved(event: HasPlayerMovedEvent) { if (this.sendPlayerMove) { this.postMessage({ diff --git a/front/src/Components/Companion/Companion.svelte b/front/src/Components/Companion/Companion.svelte new file mode 100644 index 00000000..54ee31ac --- /dev/null +++ b/front/src/Components/Companion/Companion.svelte @@ -0,0 +1,50 @@ + + + + + diff --git a/front/src/Components/Menu/ProfileSubMenu.svelte b/front/src/Components/Menu/ProfileSubMenu.svelte index 711981d0..e178d32f 100644 --- a/front/src/Components/Menu/ProfileSubMenu.svelte +++ b/front/src/Components/Menu/ProfileSubMenu.svelte @@ -15,7 +15,8 @@ import btnProfileSubMenuCamera from "../images/btn-menu-profile-camera.svg"; import btnProfileSubMenuIdentity from "../images/btn-menu-profile-identity.svg"; import btnProfileSubMenuCompanion from "../images/btn-menu-profile-companion.svg"; - import btnProfileSubMenuWoka from "../images/btn-menu-profile-woka.svg"; + import Woka from "../Woka/Woka.svelte"; + import Companion from "../Companion/Companion.svelte"; function disableMenuStores() { menuVisiblilityStore.set(false); @@ -67,12 +68,12 @@ -->