feat: he is here.
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
import { useTexture } from "@react-three/drei";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
import * as THREE from "three";
|
||||
import { fearState } from "../state";
|
||||
|
||||
export default function TheCreature() {
|
||||
const texture = useTexture('fear/img/creature.png');
|
||||
const meshRef = useRef<THREE.Mesh>(null);
|
||||
const { camera } = useThree();
|
||||
|
||||
const [hasTriggered, setHasTriggered] = useState(false);
|
||||
const [isSpawned, setIsSpawned] = useState(false);
|
||||
|
||||
const speed = 15;
|
||||
const globalDistance = useRef<number>(32);
|
||||
const [currentLoop, setCurrentLoop] = useState(fearState.loopCount);
|
||||
|
||||
useEffect(() => {
|
||||
const unsubscribe = fearState.subscribe(() => {
|
||||
setCurrentLoop(fearState.loopCount);
|
||||
|
||||
if (fearState.loopCount < 4) {
|
||||
setIsSpawned(false);
|
||||
setHasTriggered(false);
|
||||
globalDistance.current = 32;
|
||||
}
|
||||
});
|
||||
return () => unsubscribe();
|
||||
}, []);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
if (fearState.loopCount < 4) return;
|
||||
|
||||
const creature = meshRef.current;
|
||||
if (!creature) return;
|
||||
|
||||
if (!isSpawned) {
|
||||
setIsSpawned(true);
|
||||
globalDistance.current = 32;
|
||||
}
|
||||
|
||||
if (!hasTriggered)
|
||||
if (globalDistance.current < 40) setHasTriggered(true);
|
||||
|
||||
if (hasTriggered) {
|
||||
globalDistance.current -= speed * delta;
|
||||
|
||||
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;
|
||||
|
||||
if (globalDistance.current <= 0.1) {
|
||||
window.location.href = '/';
|
||||
fearState.registerCaught();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const forwardVector = new THREE.Vector3();
|
||||
camera.getWorldDirection(forwardVector);
|
||||
const lookDirZ = forwardVector.z < 0 ? -1 : 1;
|
||||
|
||||
const calculatedZ = camera.position.z + (lookDirZ * globalDistance.current);
|
||||
|
||||
creature.position.set(0, 1.6, calculatedZ);
|
||||
creature.lookAt(camera.position.x, creature.position.y, camera.position.z);
|
||||
});
|
||||
|
||||
return (
|
||||
<mesh
|
||||
ref={meshRef}
|
||||
visible={currentLoop >= 4}
|
||||
>
|
||||
<planeGeometry args={[3.0, 4.8]} />
|
||||
<meshBasicMaterial
|
||||
map={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
side={THREE.DoubleSide}
|
||||
/>
|
||||
</mesh>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user