From 49f10ec09f56ba34282e336833036d2fce575075 Mon Sep 17 00:00:00 2001 From: Cyrus Mobini Date: Fri, 25 Aug 2023 00:34:32 -0400 Subject: [PATCH 1/4] Drone flight system --- src/experience/Experience.tsx | 2 + src/experience/character/Drone.tsx | 94 ++++++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/experience/character/Drone.tsx diff --git a/src/experience/Experience.tsx b/src/experience/Experience.tsx index 0fe4f37..64893f0 100644 --- a/src/experience/Experience.tsx +++ b/src/experience/Experience.tsx @@ -4,6 +4,7 @@ import Effects from "./effects/Effects"; import Character from "./character/Character"; import World from "./world/World"; import CanvasInterface from "./interface/CanvasInterface"; +import Drone from "./character/Drone"; function Experience() { return ( @@ -15,6 +16,7 @@ function Experience() { + diff --git a/src/experience/character/Drone.tsx b/src/experience/character/Drone.tsx new file mode 100644 index 0000000..dee60c8 --- /dev/null +++ b/src/experience/character/Drone.tsx @@ -0,0 +1,94 @@ +import { useFrame } from "@react-three/fiber"; +import { RapierRigidBody, RigidBody } from "@react-three/rapier"; +import { useRef } from "react"; + +let xCoord = 13.3; +let yCoord = 8; +let zCoord = 10; +let hDirection = true; +let prev = { x: 0, y: 0, z: 0 }; +const step = 0.002; + +const getCoordinates = () => { + const prevX = Math.floor(prev.x); + const prevZ = Math.floor(prev.z); + const prevY = Math.floor(prev.y); + + if (hDirection) { + if (prevX === 3 && prevZ === 9 && prevY > 3) { + // Come down by bridge + yCoord += step * 2; + } else if (prevX === 3 && prevZ === -12 && prevY < 10) { + // Go up by Tech Center roof + yCoord += step * 2; + } else if (prevZ > 7 && prevX > -17 && prevX < -13) { + // Slow down by post office roof + xCoord += step / 5; + } else { + xCoord += step; + } + if (prevX === -22 || prevX === 9) { + hDirection = false; + } + } else { + zCoord += step; + if (prevZ === -12 || prevZ === 9) { + hDirection = true; + } + } + + prev = { + x: Math.sin(xCoord) * 15.5 - 6, + y: Math.sin(yCoord) * 3.5 + 7, + z: Math.cos(zCoord) * 10.6 - 1.2, + }; + return prev; +}; + +function Drone() { + const bodyRef = useRef(); + + useFrame((state) => { + if (!bodyRef.current) return; + bodyRef.current.setTranslation(getCoordinates(), false); + }); + + return ( + <> + } + colliders={"hull"} + type="fixed" + position={[10, 100, 10]} + linearDamping={0} + angularDamping={0} + friction={1} + restitution={0} + mass={10} + > + + + + + + + + + + + + + + + + + + + + + + + ); +} + +export default Drone; From 5bc869f54f8db00291c55b6f91de8b1918ade5ae Mon Sep 17 00:00:00 2001 From: Cyrus Mobini Date: Sat, 26 Aug 2023 00:19:19 -0400 Subject: [PATCH 2/4] Added Drone Model + Drone Cabin resize --- public/blob/{ => model}/Fox/Fox.bin | 0 public/blob/{ => model}/Fox/Fox.gltf | 0 public/blob/{ => model}/Fox/Texture.png | 0 public/blob/model/drone.glb | 3 + public/blob/model/night-city.glb | 3 + public/blob/night-city.glb | 3 - src/experience/character/Drone.tsx | 111 +++++++++++++++++++----- src/experience/lights/Lights.tsx | 2 +- src/experience/utils/constants.ts | 6 +- src/pages/Credit.md | 3 + 10 files changed, 103 insertions(+), 28 deletions(-) rename public/blob/{ => model}/Fox/Fox.bin (100%) rename public/blob/{ => model}/Fox/Fox.gltf (100%) rename public/blob/{ => model}/Fox/Texture.png (100%) create mode 100644 public/blob/model/drone.glb create mode 100644 public/blob/model/night-city.glb delete mode 100644 public/blob/night-city.glb diff --git a/public/blob/Fox/Fox.bin b/public/blob/model/Fox/Fox.bin similarity index 100% rename from public/blob/Fox/Fox.bin rename to public/blob/model/Fox/Fox.bin diff --git a/public/blob/Fox/Fox.gltf b/public/blob/model/Fox/Fox.gltf similarity index 100% rename from public/blob/Fox/Fox.gltf rename to public/blob/model/Fox/Fox.gltf diff --git a/public/blob/Fox/Texture.png b/public/blob/model/Fox/Texture.png similarity index 100% rename from public/blob/Fox/Texture.png rename to public/blob/model/Fox/Texture.png diff --git a/public/blob/model/drone.glb b/public/blob/model/drone.glb new file mode 100644 index 0000000..1a91c9a --- /dev/null +++ b/public/blob/model/drone.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7de8285cd839ddb28475e4ceb4c0e58ad5ce82b5f08f5883a6e5484b23ed8567 +size 188576 diff --git a/public/blob/model/night-city.glb b/public/blob/model/night-city.glb new file mode 100644 index 0000000..a88b897 --- /dev/null +++ b/public/blob/model/night-city.glb @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d9f3a5c5de28c1e0a255c4979719165c6f6e98368233188fe0bbb4b26249489e +size 4796556 diff --git a/public/blob/night-city.glb b/public/blob/night-city.glb deleted file mode 100644 index 84a4b76..0000000 --- a/public/blob/night-city.glb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3a9b6dbc13959a8f439b6f2a655aca660bc95d7623b0e150c2aeda86de77ae45 -size 4793380 diff --git a/src/experience/character/Drone.tsx b/src/experience/character/Drone.tsx index dee60c8..a69ce0f 100644 --- a/src/experience/character/Drone.tsx +++ b/src/experience/character/Drone.tsx @@ -1,6 +1,8 @@ import { useFrame } from "@react-three/fiber"; import { RapierRigidBody, RigidBody } from "@react-three/rapier"; import { useRef } from "react"; +import { ASSETS } from "../utils/constants"; +import { useGLTF } from "@react-three/drei"; let xCoord = 13.3; let yCoord = 8; @@ -45,8 +47,20 @@ const getCoordinates = () => { return prev; }; +const cabin = { + opacity: 1, + thickness: 0.2, + height: 0.7, + length: 2.5, + width: 1.5, + depth: 0.5, + mass: 20, + color: "white", +}; + function Drone() { const bodyRef = useRef(); + const drone = useGLTF(ASSETS.MODELS.DRONE); useFrame((state) => { if (!bodyRef.current) return; @@ -62,33 +76,86 @@ function Drone() { position={[10, 100, 10]} linearDamping={0} angularDamping={0} - friction={1} + friction={0.5} restitution={0} - mass={10} + mass={cabin.mass} > - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + ); } +useGLTF.preload(ASSETS.MODELS.DRONE); + export default Drone; diff --git a/src/experience/lights/Lights.tsx b/src/experience/lights/Lights.tsx index f674d2b..48f5720 100644 --- a/src/experience/lights/Lights.tsx +++ b/src/experience/lights/Lights.tsx @@ -19,7 +19,7 @@ function Lights() { return ( <> - + ); } diff --git a/src/experience/utils/constants.ts b/src/experience/utils/constants.ts index 65baf09..eebbe60 100644 --- a/src/experience/utils/constants.ts +++ b/src/experience/utils/constants.ts @@ -1,6 +1,7 @@ import { Vector3 } from "three"; // export const CHARACTER_INITIAL_POSITION = new Vector3(-20, 0.01, 11); +// export const CHARACTER_INITIAL_POSITION = new Vector3(5.5, 9, 12); export const CHARACTER_INITIAL_POSITION = new Vector3(21, 0.01, 7); export const isTouchDevice = "ontouchstart" in window || navigator.maxTouchPoints > 0; @@ -21,8 +22,9 @@ export const WORLD_THRESHOLD = { export const ASSETS = { MODELS: { - FOX: "/blob/Fox/Fox.gltf", - CITY: "/blob/night-city.glb", + FOX: "/blob/model/Fox/Fox.gltf", + CITY: "/blob/model/night-city.glb", + DRONE: "/blob/model/drone.glb", }, ENV_MAP: "/blob/envMap/night_city.jpg", BACKGROUND_MUSIC: { diff --git a/src/pages/Credit.md b/src/pages/Credit.md index ef7780d..fc96531 100644 --- a/src/pages/Credit.md +++ b/src/pages/Credit.md @@ -43,6 +43,9 @@ Content: - Models by [Cordula Hansen](https://poly.pizza/u/Cordula%20Hansen) from [Poly Pizza](https://poly.pizza/) under [CC-BY](https://creativecommons.org/licenses/by/3.0/) - [Space Bar](https://poly.pizza/m/4vlKrz5wDOF) +- Models by [Nick Olson](https://poly.pizza/u/Nick%20Olson) from [Poly Pizza](https://poly.pizza/) under [CC-BY](https://creativecommons.org/licenses/by/3.0/) + - [Little Drone](https://poly.pizza/m/dJ9mjQQqDQJ) + --- ### Textures From 5dacc07d24971687bcd56d34e619e26a1de1b0a3 Mon Sep 17 00:00:00 2001 From: Cyrus Mobini Date: Sun, 27 Aug 2023 11:37:17 -0400 Subject: [PATCH 3/4] Drone Audio + Non-primary territory system --- public/blob/audio/guy/bridge.wav | 3 ++ .../interface/TerritoryInterface.tsx | 4 +- src/experience/interface/ui/StatsView.tsx | 8 ++-- src/experience/stores/useLocation.ts | 8 ++-- src/experience/utils/enums.ts | 8 +++- src/experience/utils/guyAudios.ts | 30 +++++++----- src/experience/utils/territories.ts | 48 ++++++++++++------- 7 files changed, 69 insertions(+), 40 deletions(-) create mode 100644 public/blob/audio/guy/bridge.wav diff --git a/public/blob/audio/guy/bridge.wav b/public/blob/audio/guy/bridge.wav new file mode 100644 index 0000000..f1b2a49 --- /dev/null +++ b/public/blob/audio/guy/bridge.wav @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:df7b3492104101b93fc5b3006081a78f3ae31e2228abb09e67fbef4d311d62c2 +size 182830 diff --git a/src/experience/interface/TerritoryInterface.tsx b/src/experience/interface/TerritoryInterface.tsx index 7e8770b..43b2a00 100644 --- a/src/experience/interface/TerritoryInterface.tsx +++ b/src/experience/interface/TerritoryInterface.tsx @@ -3,7 +3,7 @@ import useLocation from "../stores/useLocation"; import { useEffect, useState } from "react"; import useGlobal from "../stores/useGlobal"; import { Vector3 } from "three"; -import { TERRITORIES_NAMES } from "../utils/enums"; +import { MAIN_TERRITORIES_NAMES } from "../utils/enums"; import { TERRITORY_AUDIOS } from "../utils/guyAudios"; import useSound from "../stores/useSound"; @@ -80,7 +80,7 @@ function TerritoryInterfaceDebug({ } type VisitedTerritoriesInterface = { - [key in TERRITORIES_NAMES]?: { + [key in MAIN_TERRITORIES_NAMES]?: { lastVisited: number; }; }; diff --git a/src/experience/interface/ui/StatsView.tsx b/src/experience/interface/ui/StatsView.tsx index cd5748a..7f82206 100644 --- a/src/experience/interface/ui/StatsView.tsx +++ b/src/experience/interface/ui/StatsView.tsx @@ -1,13 +1,13 @@ import { useEffect, useState } from "react"; import useLocation from "../../stores/useLocation"; import "./StatsView.scss"; -import { TERRITORIES_NAMES } from "../../utils/enums"; +import { MAIN_TERRITORIES_NAMES } from "../../utils/enums"; import { ASSETS, LOCAL_STORAGE_KEYS } from "../../utils/constants"; import useSound from "../../stores/useSound"; import { GUY_AUDIOS, TERRITORY_AUDIOS } from "../../utils/guyAudios"; import useGlobal from "../../stores/useGlobal"; -const totalTerritories = Object.values(TERRITORIES_NAMES); +const totalTerritories = Object.values(MAIN_TERRITORIES_NAMES); const totalAudios = Object.values(TERRITORY_AUDIOS).map((audio) => audio.path.replace(ASSETS.GUY_AUDIO, "") ); @@ -26,7 +26,7 @@ function StatsView() { // Update places count const visitedPlaces = JSON.parse( localStorage.getItem(LOCAL_STORAGE_KEYS.VISITED_PLACES) || "[]" - ).filter((place: TERRITORIES_NAMES) => totalTerritories.includes(place)); + ).filter((place: MAIN_TERRITORIES_NAMES) => totalTerritories.includes(place)); visitedPlaces.push(...territoriesName); const uniquePlaces = [...new Set(visitedPlaces)]; setPlaces(uniquePlaces.length); @@ -40,7 +40,7 @@ function StatsView() { // Update audios count const discoveredAudios = JSON.parse( localStorage.getItem(LOCAL_STORAGE_KEYS.DISCOVERED_AUDIOS) || "[]" - ).filter((audio: TERRITORIES_NAMES) => totalAudios.includes(audio)); + ).filter((audio: MAIN_TERRITORIES_NAMES) => totalAudios.includes(audio)); discoveredAudios.push( ...activeSounds .filter((audio) => diff --git a/src/experience/stores/useLocation.ts b/src/experience/stores/useLocation.ts index 627591b..00be0c8 100644 --- a/src/experience/stores/useLocation.ts +++ b/src/experience/stores/useLocation.ts @@ -7,14 +7,14 @@ import { subscribeWithSelector } from "zustand/middleware"; import { Vector3 } from "three"; import { checkTerritories } from "../utils/utils"; import TERRITORIES from "../utils/territories"; -import { TERRITORIES_NAMES } from "../utils/enums"; +import { MAIN_TERRITORIES_NAMES } from "../utils/enums"; interface LocationState { location: Vector3; setLocation: (location: Vector3) => void; - territoriesName: TERRITORIES_NAMES[]; - setTerritoriesName: (territoriesName: TERRITORIES_NAMES[]) => void; + territoriesName: MAIN_TERRITORIES_NAMES[]; + setTerritoriesName: (territoriesName: MAIN_TERRITORIES_NAMES[]) => void; } export default create( @@ -51,7 +51,7 @@ export default create( }), territoriesName: [], - setTerritoriesName: (territoriesName: TERRITORIES_NAMES[]) => + setTerritoriesName: (territoriesName: MAIN_TERRITORIES_NAMES[]) => set({ territoriesName }), }; }) diff --git a/src/experience/utils/enums.ts b/src/experience/utils/enums.ts index 3237c50..f14886d 100644 --- a/src/experience/utils/enums.ts +++ b/src/experience/utils/enums.ts @@ -5,7 +5,7 @@ export enum TerritoryType { RECTANGULAR_ALTITUDE = "rectangular-altitude", } -export enum TERRITORIES_NAMES { +export enum MAIN_TERRITORIES_NAMES { BAR = "Space Bar", PARK = "Park", PARK_FOUNTAIN = "Park Fountain", @@ -17,6 +17,12 @@ export enum TERRITORIES_NAMES { POST_OFFICE = "Post Office", } +export enum OTHER_TERRITORIES_NAMES { + PIPES = "Duct Pipes", +} + +export type TERRITORIES_NAMES = MAIN_TERRITORIES_NAMES | OTHER_TERRITORIES_NAMES; + export enum MODEL_ANIMATIONS { IDLE = "Survey", WALK = "Walk", diff --git a/src/experience/utils/guyAudios.ts b/src/experience/utils/guyAudios.ts index af215e7..c352990 100644 --- a/src/experience/utils/guyAudios.ts +++ b/src/experience/utils/guyAudios.ts @@ -1,5 +1,5 @@ import { ASSETS } from "./constants"; -import { TERRITORIES_NAMES } from "./enums"; +import { MAIN_TERRITORIES_NAMES, OTHER_TERRITORIES_NAMES, TERRITORIES_NAMES } from "./enums"; import { AudioConfig } from "./interfaces"; interface TerritoryInstanceAudio extends AudioConfig { @@ -15,56 +15,62 @@ const FIVE_MIN_MS = 5 * 60 * 1000; const TEN_MIN_MS = 10 * 60 * 1000; export const TERRITORY_AUDIOS: TerritoryAudio = { - [TERRITORIES_NAMES.BAR]: { + [MAIN_TERRITORIES_NAMES.BAR]: { path: ASSETS.GUY_AUDIO + "space-bar.wav", playInterval: FIVE_MIN_MS, duration: 4000, subtitle: "Look! Space Bar! They have coffee too. Click on the coffee.", }, - [TERRITORIES_NAMES.TV_BRIDGE]: { - path: ASSETS.GUY_AUDIO + "death-by-fall.wav", - playInterval: FIVE_MIN_MS, + [MAIN_TERRITORIES_NAMES.TV_BRIDGE]: { + path: ASSETS.GUY_AUDIO + "bridge.wav", + playInterval: THREE_MIN_MS, duration: 2000, - subtitle: "We probably die if we fall from here!", + subtitle: "Maybe we can jump on the drone that passes by here.", }, - [TERRITORIES_NAMES.DEAD_END_ALLEY]: { + [MAIN_TERRITORIES_NAMES.DEAD_END_ALLEY]: { path: ASSETS.GUY_AUDIO + "duct-pipes.wav", playInterval: FIVE_MIN_MS, duration: 4000, subtitle: "The duct pipes are suspiciously connected to those escape stairs, but it's probably just a coincidence.", }, - [TERRITORIES_NAMES.STORE]: { + [MAIN_TERRITORIES_NAMES.STORE]: { path: ASSETS.GUY_AUDIO + "building-with-interior.wav", playInterval: TEN_MIN_MS, duration: 2000, subtitle: "Woa! We can actually go inside this building!", }, - [TERRITORIES_NAMES.TECH_CENTER]: { + [MAIN_TERRITORIES_NAMES.TECH_CENTER]: { path: ASSETS.GUY_AUDIO + "sci-fi-stuff.wav", playInterval: TEN_MIN_MS, duration: 2000, subtitle: "Woohoo! There is so many sci-fi stuff here!", }, - [TERRITORIES_NAMES.POST_OFFICE]: { + [MAIN_TERRITORIES_NAMES.POST_OFFICE]: { path: ASSETS.GUY_AUDIO + "dev-contact.wav", playInterval: TEN_MIN_MS, duration: 3000, subtitle: "Those seems like the developers contact information! Let's click them!", }, - [TERRITORIES_NAMES.BLOCKED_ROAD]: { + [MAIN_TERRITORIES_NAMES.BLOCKED_ROAD]: { path: ASSETS.GUY_AUDIO + "block-way.wav", playInterval: THREE_MIN_MS, duration: 2000, subtitle: "We probably can't go this way. It's blocked!", }, - [TERRITORIES_NAMES.PARK_FOUNTAIN]: { + [MAIN_TERRITORIES_NAMES.PARK_FOUNTAIN]: { path: ASSETS.GUY_AUDIO + "empty-city.wav", playInterval: THREE_MIN_MS, duration: 1000, subtitle: "Why there's no one else in this city?", }, + [OTHER_TERRITORIES_NAMES.PIPES]: { + path: ASSETS.GUY_AUDIO + "death-by-fall.wav", + playInterval: FIVE_MIN_MS, + duration: 2000, + subtitle: "We probably die if we fall from here!", + }, }; export const GUY_AUDIOS: { [key: string]: AudioConfig } = { diff --git a/src/experience/utils/territories.ts b/src/experience/utils/territories.ts index 71b4985..72ce14e 100644 --- a/src/experience/utils/territories.ts +++ b/src/experience/utils/territories.ts @@ -1,16 +1,21 @@ -import { TERRITORIES_NAMES, TerritoryType } from "./enums"; +import { + MAIN_TERRITORIES_NAMES, + OTHER_TERRITORIES_NAMES, + TerritoryType, +} from "./enums"; import { Territory } from "./interfaces"; const TERRITORIES: Territory[] = [ { - name: TERRITORIES_NAMES.BAR, - center: { x: -4.5, y: 2.5 }, - type: TerritoryType.RECTANGULAR, - width: 10, - height: 16, + name: MAIN_TERRITORIES_NAMES.BAR, + center: { x: -4, y: 2.5 }, + type: TerritoryType.RECTANGULAR_ALTITUDE, + altitude: 0, + width: 7.5, + height: 11, }, { - name: TERRITORIES_NAMES.PARK, + name: MAIN_TERRITORIES_NAMES.PARK, center: { x: -12.5, y: 19.5 }, type: TerritoryType.RECTANGULAR, width: 19, @@ -18,16 +23,23 @@ const TERRITORIES: Territory[] = [ mustInclude: true, children: [ { - name: TERRITORIES_NAMES.PARK_FOUNTAIN, + name: MAIN_TERRITORIES_NAMES.PARK_FOUNTAIN, center: { x: -8, y: 21 }, type: TerritoryType.CIRCULAR, - altitude: 8.5, radius: 3, }, ], }, { - name: TERRITORIES_NAMES.TV_BRIDGE, + name: OTHER_TERRITORIES_NAMES.PIPES, + center: { x: 11, y: 14 }, + type: TerritoryType.RECTANGULAR_ALTITUDE, + altitude: 10.5, + width: 6, + height: 1, + }, + { + name: MAIN_TERRITORIES_NAMES.TV_BRIDGE, center: { x: 5.5, y: 10.5 }, type: TerritoryType.RECTANGULAR_ALTITUDE, altitude: 8.5, @@ -35,37 +47,39 @@ const TERRITORIES: Territory[] = [ height: 6, }, { - name: TERRITORIES_NAMES.DEAD_END_ALLEY, + name: MAIN_TERRITORIES_NAMES.DEAD_END_ALLEY, center: { x: 13.5, y: 16 }, type: TerritoryType.RECTANGULAR, width: 4.5, height: 9, }, { - name: TERRITORIES_NAMES.BLOCKED_ROAD, + name: MAIN_TERRITORIES_NAMES.BLOCKED_ROAD, center: { x: 10, y: -23 }, type: TerritoryType.RECTANGULAR, width: 5.5, height: 3, }, { - name: TERRITORIES_NAMES.STORE, + name: MAIN_TERRITORIES_NAMES.STORE, center: { x: -1.5, y: -18.5 }, type: TerritoryType.RECTANGULAR, width: 8, height: 6, }, { - name: TERRITORIES_NAMES.POST_OFFICE, + name: MAIN_TERRITORIES_NAMES.POST_OFFICE, center: { x: -15, y: -2 }, - type: TerritoryType.RECTANGULAR, + type: TerritoryType.RECTANGULAR_ALTITUDE, + altitude: 0, width: 6, height: 13, }, { - name: TERRITORIES_NAMES.TECH_CENTER, + name: MAIN_TERRITORIES_NAMES.TECH_CENTER, center: { x: 4, y: -1 }, - type: TerritoryType.RECTANGULAR, + type: TerritoryType.RECTANGULAR_ALTITUDE, + altitude: 0, width: 6, height: 12.5, }, From c9585eb8894c9cb3c91453f3fb63c54bec3bf617 Mon Sep 17 00:00:00 2001 From: Cyrus Mobini Date: Sun, 27 Aug 2023 13:09:02 -0400 Subject: [PATCH 4/4] Fixed varies bugs with Drone movement and location system --- src/experience/character/Drone.tsx | 42 +++++++++++++++++------- src/experience/interface/ui/TitleBar.tsx | 8 ++++- src/experience/stores/useLocation.ts | 8 ++--- 3 files changed, 42 insertions(+), 16 deletions(-) diff --git a/src/experience/character/Drone.tsx b/src/experience/character/Drone.tsx index a69ce0f..17ed774 100644 --- a/src/experience/character/Drone.tsx +++ b/src/experience/character/Drone.tsx @@ -4,23 +4,32 @@ import { useRef } from "react"; import { ASSETS } from "../utils/constants"; import { useGLTF } from "@react-three/drei"; -let xCoord = 13.3; -let yCoord = 8; -let zCoord = 10; -let hDirection = true; -let prev = { x: 0, y: 0, z: 0 }; +const minmax = { + x: { min: -22, max: 9, middle: -6 }, + y: { min: 3, max: 10 }, + z: { min: -12, max: 9, middle: -1 }, +}; const step = 0.002; +let prev = { x: minmax.x.min, y: minmax.y.max, z: minmax.z.min }; + +let xCoord = 4.8; +let yCoord = 2; +let zCoord = 3; + +let hDirection = false; +let passedMiddle = true; + const getCoordinates = () => { const prevX = Math.floor(prev.x); const prevZ = Math.floor(prev.z); const prevY = Math.floor(prev.y); if (hDirection) { - if (prevX === 3 && prevZ === 9 && prevY > 3) { + if (prevX === 3 && prevZ === minmax.z.max && prevY > minmax.y.min) { // Come down by bridge yCoord += step * 2; - } else if (prevX === 3 && prevZ === -12 && prevY < 10) { + } else if (prevX === 3 && prevZ === minmax.z.min && prevY < minmax.y.max) { // Go up by Tech Center roof yCoord += step * 2; } else if (prevZ > 7 && prevX > -17 && prevX < -13) { @@ -29,15 +38,26 @@ const getCoordinates = () => { } else { xCoord += step; } - if (prevX === -22 || prevX === 9) { - hDirection = false; + // Passed the middle point (good to turn) + if (prevX === minmax.x.middle && !passedMiddle) { + passedMiddle = true; } } else { zCoord += step; - if (prevZ === -12 || prevZ === 9) { - hDirection = true; + // Passed the middle point (good to turn) + if (prevZ === minmax.z.middle && !passedMiddle) { + passedMiddle = true; } } + // Change direction (turn) + if ( + ((hDirection && (prevX === minmax.x.min || prevX === minmax.x.max)) || + (!hDirection && (prevZ === minmax.z.max || prevZ === minmax.z.min))) && + passedMiddle + ) { + hDirection = !hDirection; + passedMiddle = false; + } prev = { x: Math.sin(xCoord) * 15.5 - 6, diff --git a/src/experience/interface/ui/TitleBar.tsx b/src/experience/interface/ui/TitleBar.tsx index 63dbbf9..0982dc8 100644 --- a/src/experience/interface/ui/TitleBar.tsx +++ b/src/experience/interface/ui/TitleBar.tsx @@ -1,6 +1,9 @@ import { useEffect, useState } from "react"; import "./TitleBar.scss"; import useLocation from "../../stores/useLocation"; +import { MAIN_TERRITORIES_NAMES } from "../../utils/enums"; + +const mainTerritories = Object.values(MAIN_TERRITORIES_NAMES); function TitleBar() { const territoriesName = useLocation((state) => state.territoriesName); @@ -8,7 +11,10 @@ function TitleBar() { const [isHidden, setIsHidden] = useState(true); useEffect(() => { - if (territoriesName.length) { + if ( + territoriesName.length && + mainTerritories.includes(territoriesName.at(-1) as MAIN_TERRITORIES_NAMES) + ) { setText(territoriesName.at(-1) as string); } }, [territoriesName]); diff --git a/src/experience/stores/useLocation.ts b/src/experience/stores/useLocation.ts index 00be0c8..627591b 100644 --- a/src/experience/stores/useLocation.ts +++ b/src/experience/stores/useLocation.ts @@ -7,14 +7,14 @@ import { subscribeWithSelector } from "zustand/middleware"; import { Vector3 } from "three"; import { checkTerritories } from "../utils/utils"; import TERRITORIES from "../utils/territories"; -import { MAIN_TERRITORIES_NAMES } from "../utils/enums"; +import { TERRITORIES_NAMES } from "../utils/enums"; interface LocationState { location: Vector3; setLocation: (location: Vector3) => void; - territoriesName: MAIN_TERRITORIES_NAMES[]; - setTerritoriesName: (territoriesName: MAIN_TERRITORIES_NAMES[]) => void; + territoriesName: TERRITORIES_NAMES[]; + setTerritoriesName: (territoriesName: TERRITORIES_NAMES[]) => void; } export default create( @@ -51,7 +51,7 @@ export default create( }), territoriesName: [], - setTerritoriesName: (territoriesName: MAIN_TERRITORIES_NAMES[]) => + setTerritoriesName: (territoriesName: TERRITORIES_NAMES[]) => set({ territoriesName }), }; })