From fcc029fc563ca3505d34b7b079dd8320a427651b Mon Sep 17 00:00:00 2001 From: ad044 Date: Sun, 14 Feb 2021 00:03:39 +0400 Subject: [PATCH] end scene almost done --- src/App.tsx | 2 +- src/components/KeyPressHandler.tsx | 27 ++++-- src/components/MediaPlayer.tsx | 9 +- src/components/Preloader.tsx | 97 ++++++++++++++++------ src/core/setters/main/idleManager.ts | 4 - src/scenes/EndScene.tsx | 119 ++++++++++++++++++--------- src/scenes/IdleMediaScene.tsx | 9 +- src/scenes/MediaScene.tsx | 41 +++++---- src/scenes/TaKScene.tsx | 2 +- src/store.ts | 15 +--- 10 files changed, 215 insertions(+), 110 deletions(-) diff --git a/src/App.tsx b/src/App.tsx index 51501fd..e6c6f37 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -45,7 +45,7 @@ const App = () => { - + {/**/} {dispatchScene[currentScene as keyof typeof dispatchScene]} diff --git a/src/components/KeyPressHandler.tsx b/src/components/KeyPressHandler.tsx index e98568a..ff62293 100644 --- a/src/components/KeyPressHandler.tsx +++ b/src/components/KeyPressHandler.tsx @@ -4,6 +4,7 @@ import { getMainSceneContext, getMediaSceneContext, getSSknSceneContext, + playAudio, useStore, } from "../store"; import { getKeyCodeAssociation } from "../utils/keyPressUtils"; @@ -31,6 +32,7 @@ import soundManager from "../core/setters/soundManager"; import { useFrame } from "react-three-fiber"; import { getRandomIdleLainAnim, getRandomIdleMedia } from "../utils/idle-utils"; import idleManager from "../core/setters/main/idleManager"; +import * as audio from "../static/sfx"; const KeyPressHandler = () => { const mediaSceneSetters = useMemo( @@ -96,13 +98,14 @@ const KeyPressHandler = () => { mainSubscene !== "level_selection" && scene === "main" ) { - // if (now > lainIdleCounter.current + 10000) { - // lainManager({ event: getRandomIdleLainAnim() }); - // // after one idle animation plays, the second comes sooner than it would after a regular keypress - // lainIdleCounter.current = now - 2500; - // } + if (now > lainIdleCounter.current + 10000) { + lainManager({ event: getRandomIdleLainAnim() }); + // after one idle animation plays, the second comes sooner than it would after a regular keypress + lainIdleCounter.current = now - 2500; + } // if (now > idleSceneCounter.current + 5000) { // idleManager(getRandomIdleMedia()); + // playAudio(audio.sound32); // setTimeout(() => { // sceneManager({ event: "play_idle_media" }); // }, 1200); @@ -124,8 +127,10 @@ const KeyPressHandler = () => { const now = Date.now(); if (keyPress) { - lainIdleCounter.current = now; - idleSceneCounter.current = now; + if (scene === "main") { + lainIdleCounter.current = now; + idleSceneCounter.current = now; + } const sceneFns = (() => { switch (scene) { case "main": @@ -157,6 +162,14 @@ const KeyPressHandler = () => { return { action: () => useStore.setState({ currentScene: "main" }), }; + case "idle_media": + return { + action: () => + useStore.setState({ + currentScene: "main", + idleStarting: false, + }), + }; } })(); diff --git a/src/components/MediaPlayer.tsx b/src/components/MediaPlayer.tsx index 3e4e790..e060a5d 100644 --- a/src/components/MediaPlayer.tsx +++ b/src/components/MediaPlayer.tsx @@ -4,6 +4,9 @@ import { useStore } from "../store"; const MediaPlayer = () => { const setPercentageElapsed = useStore((state) => state.setPercentageElapsed); + // use it as a guard to avoid multiple set states inside updateTime + const lastSetPercentageRef = useRef(undefined); + const requestRef = useRef(); const videoRef = createRef(); const trackRef = createRef(); @@ -35,8 +38,12 @@ const MediaPlayer = () => { const duration = videoRef.current.duration; const percentageElapsed = Math.floor((timeElapsed / duration) * 100); - if (percentageElapsed % 5 === 0 && percentageElapsed !== 0) { + if ( + percentageElapsed % 5 === 0 && + lastSetPercentageRef.current !== percentageElapsed + ) { setPercentageElapsed(percentageElapsed); + lastSetPercentageRef.current = percentageElapsed; } } }, [setPercentageElapsed, videoRef]); diff --git a/src/components/Preloader.tsx b/src/components/Preloader.tsx index 0f79409..8f2de65 100644 --- a/src/components/Preloader.tsx +++ b/src/components/Preloader.tsx @@ -5,11 +5,8 @@ import standingSpriteSheet from "../static/sprite/standing.png"; import moveLeftSpriteSheet from "../static/sprite/move_left.png"; import moveRightSpriteSheet from "../static/sprite/move_right.png"; import bigHudSpriteSheet from "../static/sprite/big_hud.png"; -import bigHudMirroredSpriteSheet from "../static/sprite/big_hud_mirrored.png"; import longHudSpriteSheet from "../static/sprite/long_hud.png"; -import longHudMirroredSpriteSheet from "../static/sprite/long_hud_mirrored.png"; import boringHudSpriteSheet from "../static/sprite/long_hud_boring.png"; -import boringHudMirroredSpriteSheet from "../static/sprite/long_hud_boring_mirrored.png"; import throwNodeSpriteSheet from "../static/sprite/throw_node.png"; import ripMiddleRingSpriteSheet from "../static/sprite/rip_middle_ring.png"; import ripNodeSpriteSheet from "../static/sprite/rip_node.png"; @@ -17,14 +14,30 @@ import prayerSpriteSheet from "../static/sprite/prayer.png"; import knockSpriteSheet from "../static/sprite/knock.png"; import knockAndFallSpriteSheet from "../static/sprite/knock_and_fall.png"; import touchAndScareSpriteSheet from "../static/sprite/touch_and_scare.png"; +import touchSleeveSpriteSheet from "../static/sprite/touch_sleeve.png"; +import thinkingSpriteSheet from "../static/sprite/thinking.png"; +import stretchSpriteSheet from "../static/sprite/stretch.png"; +import stretch2SpriteSheet from "../static/sprite/stretch_2.png"; +import spinSpriteSheet from "../static/sprite/spin.png"; +import scratchHeadSpriteSheet from "../static/sprite/scratch_head.png"; +import blushSpriteSheet from "../static/sprite/blush.png"; +import handsBehindHeadSpriteSheet from "../static/sprite/hands_behind_head.png"; +import handsOnHipsSpriteSheet from "../static/sprite/hands_on_hips.png"; +import handsOnHips2SpriteSheet from "../static/sprite/hands_on_hips_2.png"; +import handsTogetherSpriteSheet from "../static/sprite/hands_together.png"; +import leanForwardSpriteSheet from "../static/sprite/lean_forward.png"; +import leanLeftSpriteSheet from "../static/sprite/lean_left.png"; +import leanRightSpriteSheet from "../static/sprite/lean_right.png"; +import lookAroundSpriteSheet from "../static/sprite/look_around.png"; +import playWithHairSpriteSheet from "../static/sprite/play_with_hair.png"; import * as THREE from "three"; import { useLoader, useThree } from "react-three-fiber"; -import { useLayoutEffect } from "react"; +import { memo, useLayoutEffect } from "react"; // this function just preloads lain's spritesheets and other assets cuz they're big and lazy loading them // used to make the suspense run for a couple milliseconds, resulting in flickering -const Preloader = () => { +const Preloader = memo(() => { const intro = useLoader(THREE.TextureLoader, introSpriteSheet); const moveDown = useLoader(THREE.TextureLoader, moveDownSpriteSheet); const moveUp = useLoader(THREE.TextureLoader, moveUpSpriteSheet); @@ -33,20 +46,8 @@ const Preloader = () => { const stand = useLoader(THREE.TextureLoader, standingSpriteSheet); const throwNode = useLoader(THREE.TextureLoader, throwNodeSpriteSheet); const bigHud = useLoader(THREE.TextureLoader, bigHudSpriteSheet); - const bigHudMirrored = useLoader( - THREE.TextureLoader, - bigHudMirroredSpriteSheet - ); const longHud = useLoader(THREE.TextureLoader, longHudSpriteSheet); - const longHudMirrored = useLoader( - THREE.TextureLoader, - longHudMirroredSpriteSheet - ); const boringHud = useLoader(THREE.TextureLoader, boringHudSpriteSheet); - const boringHudMirrored = useLoader( - THREE.TextureLoader, - boringHudMirroredSpriteSheet - ); const ripMiddleRing = useLoader( THREE.TextureLoader, ripMiddleRingSpriteSheet @@ -59,6 +60,28 @@ const Preloader = () => { THREE.TextureLoader, touchAndScareSpriteSheet ); + const touchSleeve = useLoader(THREE.TextureLoader, touchSleeveSpriteSheet); + const thinking = useLoader(THREE.TextureLoader, thinkingSpriteSheet); + const stretch = useLoader(THREE.TextureLoader, stretchSpriteSheet); + const stretch2 = useLoader(THREE.TextureLoader, stretch2SpriteSheet); + const spinSprite = useLoader(THREE.TextureLoader, spinSpriteSheet); + const scratchHead = useLoader(THREE.TextureLoader, scratchHeadSpriteSheet); + const blush = useLoader(THREE.TextureLoader, blushSpriteSheet); + const handsBehindHead = useLoader( + THREE.TextureLoader, + handsBehindHeadSpriteSheet + ); + const handsOnHips = useLoader(THREE.TextureLoader, handsOnHipsSpriteSheet); + const handsOnHips2 = useLoader(THREE.TextureLoader, handsOnHips2SpriteSheet); + const handsTogether = useLoader( + THREE.TextureLoader, + handsTogetherSpriteSheet + ); + const leanForward = useLoader(THREE.TextureLoader, leanForwardSpriteSheet); + const leanLeft = useLoader(THREE.TextureLoader, leanLeftSpriteSheet); + const leanRight = useLoader(THREE.TextureLoader, leanRightSpriteSheet); + const lookAround = useLoader(THREE.TextureLoader, lookAroundSpriteSheet); + const playWithHair = useLoader(THREE.TextureLoader, playWithHairSpriteSheet); const { gl } = useThree(); useLayoutEffect(() => { @@ -70,10 +93,7 @@ const Preloader = () => { gl.initTexture(stand); gl.initTexture(longHud); gl.initTexture(bigHud); - gl.initTexture(bigHudMirrored); - gl.initTexture(longHudMirrored); gl.initTexture(boringHud); - gl.initTexture(boringHudMirrored); gl.initTexture(throwNode); gl.initTexture(ripMiddleRing); gl.initTexture(ripNode); @@ -81,6 +101,22 @@ const Preloader = () => { gl.initTexture(touchAndScare); gl.initTexture(knock); gl.initTexture(knockAndFall); + gl.initTexture(touchSleeve); + gl.initTexture(thinking); + gl.initTexture(stretch); + gl.initTexture(stretch2); + gl.initTexture(spinSprite); + gl.initTexture(scratchHead); + gl.initTexture(blush); + gl.initTexture(handsBehindHead); + gl.initTexture(leanForward); + gl.initTexture(leanLeft); + gl.initTexture(leanRight); + gl.initTexture(lookAround); + gl.initTexture(playWithHair); + gl.initTexture(handsOnHips); + gl.initTexture(handsOnHips2); + gl.initTexture(handsTogether); }, [ moveDown, moveUp, @@ -89,11 +125,8 @@ const Preloader = () => { stand, gl, bigHud, - bigHudMirrored, boringHud, - boringHudMirrored, longHud, - longHudMirrored, intro, throwNode, ripMiddleRing, @@ -102,8 +135,24 @@ const Preloader = () => { touchAndScare, knock, knockAndFall, + touchSleeve, + thinking, + stretch, + stretch2, + spinSprite, + scratchHead, + blush, + handsBehindHead, + leanForward, + leanLeft, + leanRight, + lookAround, + playWithHair, + handsOnHips, + handsOnHips2, + handsTogether, ]); return null; -}; +}); export default Preloader; diff --git a/src/core/setters/main/idleManager.ts b/src/core/setters/main/idleManager.ts index ec1bb5b..f9ccbba 100644 --- a/src/core/setters/main/idleManager.ts +++ b/src/core/setters/main/idleManager.ts @@ -12,10 +12,6 @@ const idleManager = (eventState: any) => { action: () => { setIdleStarting(true); setIdleScene(eventState); - - setTimeout(() => { - setIdleStarting(false); - }, 6000); }, }); diff --git a/src/scenes/EndScene.tsx b/src/scenes/EndScene.tsx index 8062aed..48f0094 100644 --- a/src/scenes/EndScene.tsx +++ b/src/scenes/EndScene.tsx @@ -1,14 +1,21 @@ -import React, { useEffect, useRef, useState } from "react"; +import React, { useEffect, useMemo, useRef, useState } from "react"; import * as THREE from "three"; import { useFrame } from "react-three-fiber"; -import { useStore } from "../store"; +import { createAudioAnalyser, useStore } from "../store"; import EndSelectionScreen from "../components/EndScene/EndSelectionScreen"; +import endroll from "../static/movie/ENDROLL1.STR[0].webm"; +import endrollVtt from "../static/webvtt/Endroll.vtt"; +import Xa0001 from "../static/audio/Xa0001.mp4"; +import Xa0006 from "../static/audio/Xa0006.mp4"; +import LainSpeak from "../components/LainSpeak"; +import EndSphere from "../components/EndScene/EndSphere"; +import EndCylinder from "../components/EndScene/EndCylinder"; const EndScene = () => { - const mediaPlayedCount = useStore((state) => state.endMediaPlayedCount); - const mainCylinderRef = useRef(); + const setAudioAnalyser = useStore((state) => state.setAudioAnalyser); + useFrame(() => { if (mainCylinderRef.current) { mainCylinderRef.current.rotation.y -= 0.01; @@ -22,49 +29,81 @@ const EndScene = () => { } }); - const [isIntro, setIsIntro] = useState(true); + const [objectsVisible, setObjectsVisible] = useState(false); + const [isIntro, setIsIntro] = useState(false); const [isOutro, setIsOutro] = useState(false); const [sceneOutro, setSceneOutro] = useState(false); - useEffect(() => { - if (mediaPlayedCount === 1) { - setTimeout(() => { - const mediaElement = document.getElementById( - "media" - ) as HTMLMediaElement; + const playedMediaCountRef = useRef(0); - if (mediaElement) { + const mediaList = useMemo(() => [Xa0001, Xa0006], []); + + useEffect(() => { + const mediaElement = document.getElementById("media") as HTMLMediaElement; + + const playNextMedia = () => { + playedMediaCountRef.current++; + mediaElement.currentTime = 0; + if (playedMediaCountRef.current === 1) { + setObjectsVisible(true); + setIsIntro(true); + + setTimeout(() => { + mediaElement.src = Xa0001; + + mediaElement.load(); mediaElement.play(); setIsIntro(false); - } - }, 3800); - } else if (mediaPlayedCount > 1) { - setIsOutro(true); - setTimeout(() => { - setSceneOutro(true); - }, 4000); - } - }, [mediaPlayedCount]); + }, 3800); + } - // return mediaPlayedCount > 0 ? ( - // <> - // - // - // - // - // - // - // - // - // - // - // - // - // - // ) : ( - // <> - // ); - return ; + if (playedMediaCountRef.current === mediaList.length) { + mediaElement.src = Xa0006; + + mediaElement.load(); + mediaElement.play(); + setIsOutro(true); + setTimeout(() => { + setSceneOutro(true); + }, 4000); + } + }; + + mediaElement.addEventListener("ended", playNextMedia); + }, [mediaList]); + + useEffect(() => { + const mediaElement = document.getElementById("media") as HTMLMediaElement; + const trackElement = document.getElementById("track") as HTMLTrackElement; + + if (mediaElement) { + setAudioAnalyser(createAudioAnalyser()); + mediaElement.currentTime = 0; + + trackElement.src = endrollVtt; + mediaElement.src = endroll; + + mediaElement.load(); + mediaElement.play(); + } + }, [setAudioAnalyser]); + + return ( + + + + + + + + + + + + + + + ); }; export default EndScene; diff --git a/src/scenes/IdleMediaScene.tsx b/src/scenes/IdleMediaScene.tsx index d31deff..cba3c11 100644 --- a/src/scenes/IdleMediaScene.tsx +++ b/src/scenes/IdleMediaScene.tsx @@ -6,14 +6,17 @@ const IdleMediaScene = () => { const mediaPercentageElapsed = useStore( (state) => state.mediaPercentageElapsed ); - const setScene = useStore((state) => state.setScene); const idleMedia = useStore((state) => state.idleMedia); const idleNodeName = useStore((state) => state.idleNodeName); useEffect(() => { - if (mediaPercentageElapsed === 100) setScene("main"); - }, [mediaPercentageElapsed, setScene]); + if (mediaPercentageElapsed === 100) + useStore.setState({ + currentScene: "main", + idleStarting: false, + }); + }, [mediaPercentageElapsed]); useEffect(() => { const mediaElement = document.getElementById("media") as HTMLMediaElement; diff --git a/src/scenes/MediaScene.tsx b/src/scenes/MediaScene.tsx index abae436..662cb28 100644 --- a/src/scenes/MediaScene.tsx +++ b/src/scenes/MediaScene.tsx @@ -10,9 +10,13 @@ import GreenTextRenderer from "../components/TextRenderer/GreenTextRenderer"; import MediaYellowTextAnimator from "../components/TextRenderer/MediaYellowTextAnimator"; const MediaScene = () => { + const percentageElapsed = useStore((state) => state.mediaPercentageElapsed); + const setAudioAnalyser = useStore((state) => state.setAudioAnalyser); - const activeNodeMedia = useStore((state) => state.activeNode.media_file); + const activeNode = useStore((state) => state.activeNode); + + const setScene = useStore((state) => state.setScene); useEffect(() => { document.getElementsByTagName("canvas")[0].className = @@ -23,8 +27,11 @@ const MediaScene = () => { }; }, []); - const nodeMedia = useStore((state) => state.activeNode.media_file); - const nodeName = useStore((state) => state.activeNode.node_name); + useEffect(() => { + if (percentageElapsed === 100) { + setScene("end"); + } + }, [percentageElapsed, setScene]); useEffect(() => { const mediaElement = document.getElementById("media") as HTMLMediaElement; @@ -34,26 +41,30 @@ const MediaScene = () => { setAudioAnalyser(createAudioAnalyser()); mediaElement.currentTime = 0; - import("../static/webvtt/" + nodeName + ".vtt") + import("../static/webvtt/" + activeNode.node_name + ".vtt") .then((vtt) => { if (vtt) trackElement.src = vtt.default; }) // some entries have no spoken words, so the file doesnt exist. we catch that here. .catch((e) => console.log(e)); - if (nodeMedia.includes("XA")) { - import("../static/audio/" + nodeMedia + ".ogg").then((media) => { - mediaElement.src = media.default; - mediaElement.load(); - }); + if (activeNode.media_file.includes("XA")) { + import("../static/audio/" + activeNode.media_file + ".ogg").then( + (media) => { + mediaElement.src = media.default; + mediaElement.load(); + } + ); } else { - import("../static/movie/" + nodeMedia + "[0].webm").then((media) => { - mediaElement.src = media.default; - mediaElement.load(); - }); + import("../static/movie/" + activeNode.media_file + "[0].webm").then( + (media) => { + mediaElement.src = media.default; + mediaElement.load(); + } + ); } } - }, [nodeMedia, nodeName, setAudioAnalyser]); + }, [activeNode.media_file, activeNode.node_name, setAudioAnalyser]); return ( @@ -69,7 +80,7 @@ const MediaScene = () => { - + diff --git a/src/scenes/TaKScene.tsx b/src/scenes/TaKScene.tsx index 471cdee..f991e0b 100644 --- a/src/scenes/TaKScene.tsx +++ b/src/scenes/TaKScene.tsx @@ -54,7 +54,7 @@ const TaKScene = () => { setIsIntro(false); } }, 3800); - }, [nodeMedia, nodeName]); + }, [nodeMedia, nodeName, setAudioAnalyser]); return ; }; diff --git a/src/store.ts b/src/store.ts index 2899ab2..54546e5 100644 --- a/src/store.ts +++ b/src/store.ts @@ -93,9 +93,6 @@ type State = { authorizeUserLetterIdx: number; bootSubscene: "main_menu" | "load_data" | "authorize_user"; - // end scene - endMediaPlayedCount: number; - // prompt promptVisible: boolean; promptComponentMatrix: ["yes", "no"]; @@ -124,7 +121,7 @@ export const useStore = create( combine( { // scene data - currentScene: "main", + currentScene: "media", // game progress gameProgress: game_progress, @@ -226,9 +223,6 @@ export const useStore = create( authorizeUserLetterIdx: 0, bootSubscene: "main_menu", - // end scene - endMediaPlayedCount: 0, - // prompt promptVisible: false, promptComponentMatrix: ["yes", "no"], @@ -395,13 +389,6 @@ export const useStore = create( setAuthorizeUserLetterIdx: (to: number) => set(() => ({ authorizeUserLetterIdx: to })), - // end scene setters - incrementEndMediaPlayedCount: () => - set((state) => ({ - endMediaPlayedCount: state.endMediaPlayedCount + 1, - })), - resetEndMediaPlayedCount: () => set(() => ({ endMediaPlayedCount: 0 })), - // prompt setters setPromptVisible: (to: boolean) => set(() => ({ promptVisible: to })), setPromptComponentMatrixIdx: (to: 1 | 0) =>