feat: it speaks
This commit is contained in:
Binary file not shown.
Binary file not shown.
+32
-6
@@ -2,7 +2,7 @@
|
||||
|
||||
import './page.css';
|
||||
|
||||
import { Canvas } from "@react-three/fiber";
|
||||
import { Canvas, useThree } from "@react-three/fiber";
|
||||
import { BrightnessContrast, EffectComposer, HueSaturation, Noise, Pixelation, Vignette } from "@react-three/postprocessing";
|
||||
import { Suspense, useEffect, useState } from "react";
|
||||
|
||||
@@ -14,34 +14,53 @@ import TheCreature from './scene-components/creature';
|
||||
import Player from './scene-components/player';
|
||||
import Hallway from './scene-components/hallway';
|
||||
|
||||
import { AudioListener } from 'three';
|
||||
|
||||
function PostProcessing() {
|
||||
const [getCaught, setCaught] = useState(fearState.wasCaught);
|
||||
const [wasCaught, setWasCaught] = useState(fearState.wasCaught);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = fearState.subscribe(() => {
|
||||
setCaught(fearState.wasCaught);
|
||||
setWasCaught(fearState.wasCaught);
|
||||
});
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
return (<EffectComposer>
|
||||
<Pixelation granularity={getCaught ? 18 : 12} />
|
||||
<Pixelation granularity={wasCaught ? 18 : 12} />
|
||||
<Vignette />
|
||||
<Noise opacity={getCaught ? 0.01 : 0.005} />
|
||||
<Noise opacity={wasCaught ? 0.01 : 0.005} />
|
||||
<BrightnessContrast
|
||||
brightness={-0.01}
|
||||
contrast={0.05}
|
||||
/>
|
||||
<HueSaturation saturation={getCaught ? 1 : 0} />
|
||||
<HueSaturation saturation={wasCaught ? 1 : 0} />
|
||||
</EffectComposer>)
|
||||
}
|
||||
|
||||
function ListenerCreator() {
|
||||
const { camera } = useThree();
|
||||
|
||||
useEffect(() => {
|
||||
const listener = new AudioListener();
|
||||
camera.add(listener);
|
||||
|
||||
return () => {
|
||||
camera.remove(listener);
|
||||
};
|
||||
}, [camera]);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export default function Fear() {
|
||||
const [isRustActive, setIsRustActive] = useState(fearState.isRustActive);
|
||||
const [wasCaught, setWasCaught] = useState(fearState.isRustActive);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = fearState.subscribe(() => {
|
||||
setIsRustActive(fearState.isRustActive);
|
||||
setWasCaught(fearState.wasCaught)
|
||||
});
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
@@ -53,6 +72,8 @@ export default function Fear() {
|
||||
className='canvas'
|
||||
camera={{ position: [0, 3, -5], fov: 65, far: 100 }}
|
||||
>
|
||||
<ListenerCreator/>
|
||||
|
||||
<color attach="background" args={['#050505']} />
|
||||
|
||||
<fogExp2 attach='fog' args={[0x050505, 0.035]} />
|
||||
@@ -67,6 +88,11 @@ export default function Fear() {
|
||||
url='fear/snd/ambience.mp3'
|
||||
volume={isRustActive ? 0 : 1}
|
||||
/>
|
||||
|
||||
{wasCaught ? <AmbientSound
|
||||
url='fear/snd/glitch.mp3'
|
||||
volume={1}
|
||||
/> : null}
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
</>)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useTexture } from "@react-three/drei";
|
||||
import { useTexture, PositionalAudio } from "@react-three/drei";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
@@ -8,6 +8,7 @@ import { fearState } from "../state";
|
||||
export default function TheCreature() {
|
||||
const texture = useTexture('fear/img/creature.png');
|
||||
const meshRef = useRef<THREE.Mesh>(null);
|
||||
const audioRef = useRef<THREE.PositionalAudio>(null);
|
||||
const { camera } = useThree();
|
||||
|
||||
const [hasTriggered, setHasTriggered] = useState(false);
|
||||
@@ -17,6 +18,8 @@ export default function TheCreature() {
|
||||
const globalDistance = useRef<number>(32);
|
||||
const [currentLoop, setCurrentLoop] = useState(fearState.loopCount);
|
||||
|
||||
const audioPlaying = useRef<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = fearState.subscribe(() => {
|
||||
setCurrentLoop(fearState.loopCount);
|
||||
@@ -25,6 +28,11 @@ export default function TheCreature() {
|
||||
setIsSpawned(false);
|
||||
setHasTriggered(false);
|
||||
globalDistance.current = 32;
|
||||
audioPlaying.current = false;
|
||||
|
||||
if (audioRef.current && audioRef.current.isPlaying) {
|
||||
audioRef.current.stop();
|
||||
}
|
||||
}
|
||||
});
|
||||
return () => unsubscribe();
|
||||
@@ -41,12 +49,22 @@ export default function TheCreature() {
|
||||
globalDistance.current = 32;
|
||||
}
|
||||
|
||||
if (!hasTriggered)
|
||||
if (globalDistance.current < 40) setHasTriggered(true);
|
||||
if (!hasTriggered) {
|
||||
if (globalDistance.current < 40) {
|
||||
setHasTriggered(true);
|
||||
}
|
||||
}
|
||||
|
||||
if (hasTriggered) {
|
||||
globalDistance.current -= speed * delta;
|
||||
|
||||
if (audioRef.current && !audioPlaying.current) {
|
||||
audioPlaying.current = true;
|
||||
if (audioRef.current.context.state === 'suspended')
|
||||
audioRef.current.context.resume();
|
||||
audioRef.current.play();
|
||||
}
|
||||
|
||||
const shakeIntensity = Math.max(0, 1 - (globalDistance.current / 32)) * 0.22;
|
||||
camera.position.x += (Math.random() - 0.5) * shakeIntensity;
|
||||
camera.position.y += (Math.random() - 0.5) * shakeIntensity;
|
||||
@@ -80,6 +98,16 @@ export default function TheCreature() {
|
||||
depthWrite={false}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
|
||||
{currentLoop >= 4 && (
|
||||
<PositionalAudio
|
||||
url="fear/snd/riser.mp3"
|
||||
ref={audioRef}
|
||||
distance={25}
|
||||
loop={false}
|
||||
autoplay={false}
|
||||
/>
|
||||
)}
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useEffect, useRef } from "react";
|
||||
import * as THREE from "three";
|
||||
import { FEAR_SETTINGS, fearState } from "../state";
|
||||
import { PointerLockControls } from "@react-three/drei";
|
||||
|
||||
import * as THREE from "three";
|
||||
|
||||
const forward = new THREE.Vector3();
|
||||
const side = new THREE.Vector3();
|
||||
const direction = new THREE.Vector3();
|
||||
|
||||
@@ -5,7 +5,7 @@ export const FEAR_SETTINGS = {
|
||||
HALLWAY_WIDTH: 6,
|
||||
HALLWAY_HEIGHT: 5,
|
||||
PLAYER_HEIGHT: 3,
|
||||
PLAYER_SPEED: 6,
|
||||
PLAYER_SPEED: 4,
|
||||
WALL_BUFFER: 0.6,
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user