feat:(game) added interraction and particles for items/coins
This commit is contained in:
1 parent
cff143c925
commit
db52f49e09
33 files changed
+516
-44
No files matched your search
+4
-2
@@ -30,24 +30,26 @@ function App() {
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Loader />
|
||||
<Canvas
|
||||
shadows
|
||||
dpr={1}
|
||||
gl={{ antialias: false, stencil: false, powerPreference: 'high-performance' }}
|
||||
>
|
||||
<Suspense fallback={null}>
|
||||
<Preload all />
|
||||
<Physics
|
||||
gravity={[0, -90, 0]}
|
||||
timeStep={'vary'}
|
||||
// debug
|
||||
>
|
||||
<KeyboardControls map={map}>
|
||||
<Experience />
|
||||
</KeyboardControls>
|
||||
<Stats />
|
||||
</Physics>
|
||||
</Suspense>
|
||||
</Canvas>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ export const HUD = () => {
|
||||
</div>
|
||||
<div className="wheel">
|
||||
<img
|
||||
ref={wheel}
|
||||
ref={wheel}
|
||||
src="./steering_wheel.png"
|
||||
alt="steering wheel"
|
||||
className="steering-wheel"
|
||||
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
Vignette,
|
||||
} from "@react-three/postprocessing";
|
||||
import { Banana } from "./models/items/Banana_peel_mario_kart";
|
||||
import { ItemBox } from "./models/misc/Mario_kart_item_box";
|
||||
import { ItemBox } from "./models/misc/Gift";
|
||||
import { useStore } from "./store";
|
||||
import { Shell } from "./models/items/Mario_shell_red";
|
||||
import { Coin } from "./models/misc/Super_mario_bros_coin";
|
||||
@@ -36,7 +36,7 @@ export const Experience = () => {
|
||||
<Paris position={[0, 0, 0]} />
|
||||
<Banana onCollide={onCollide} position={[-10, 1.8, -119]} />
|
||||
{/* <Shell position={[-20, 2, -119]} /> */}
|
||||
<ItemBox position={[-20, 2, -119]} />
|
||||
<ItemBox position={[-20, 2.5, -119]} />
|
||||
<Coin position={[-30, 2, -119]} />
|
||||
|
||||
<Ground position={[0, 0, 0]} />
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
import React, { useEffect,useRef, useState } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
export const CircleCoinParticle = ({ position, coins }) => {
|
||||
const texture = useLoader(THREE.TextureLoader, "./particles/circle_coin.png");
|
||||
const pointsRef = useRef();
|
||||
const materialRef = useRef();
|
||||
const [size, setSize] = useState(1);
|
||||
const [opacity, setOpacity] = useState(1);
|
||||
|
||||
const points = React.useMemo(() => {
|
||||
const geom = new THREE.BufferGeometry();
|
||||
geom.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(position, 3)
|
||||
);
|
||||
return geom;
|
||||
}, [position]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.color.multiplyScalar(4);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
setSize(0);
|
||||
setOpacity(1);
|
||||
}, [coins]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (size < 5) {
|
||||
setSize((size) => Math.min(size + 0.2 * delta * 144, 5));
|
||||
} else if (opacity > 0) {
|
||||
setOpacity((opacity) => Math.max(opacity - 0.1 * delta * 144, 0));
|
||||
setSize((size) => Math.max(size - 0.1 * delta * 144, 0));
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef} geometry={points}>
|
||||
<pointsMaterial
|
||||
ref={materialRef}
|
||||
size={size}
|
||||
alphaMap={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
opacity={opacity}
|
||||
toneMapped={false}
|
||||
color={0xbf8717}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { CircleCoinParticle } from "./CircleCoinParticle"
|
||||
import { StarCoinParticle } from "./StarCoinParticle"
|
||||
|
||||
export const CoinParticles = ({ coins }) => {
|
||||
return (
|
||||
<>
|
||||
<CircleCoinParticle position={[0,0.8, 0.2]} coins={coins}/>
|
||||
<StarCoinParticle position={[0,0.8, 0.2]} coins={coins} timeModifier={50}/>
|
||||
<StarCoinParticle position={[0,0.8, 0.2]} coins={coins} timeModifier={60}/>
|
||||
<StarCoinParticle position={[0,0.8, 0.2]} coins={coins} timeModifier={40}/>
|
||||
<StarCoinParticle position={[0,0.8, 0.2]} coins={coins} timeModifier={90}/>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
export const StarCoinParticle = ({ position, coins, timeModifier }) => {
|
||||
const texture = useLoader(THREE.TextureLoader, "./particles/star_coin.png");
|
||||
const pointsRef = useRef();
|
||||
const materialRef = useRef();
|
||||
const sizeRef = useRef(1);
|
||||
const opacityRef = useRef(1);
|
||||
const originalYpos = useRef(0);
|
||||
|
||||
const points = React.useMemo(() => {
|
||||
const geom = new THREE.BufferGeometry();
|
||||
geom.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(position, 3)
|
||||
);
|
||||
return geom;
|
||||
}, [position]);
|
||||
|
||||
useEffect(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.color.multiplyScalar(6);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
sizeRef.current = 0;
|
||||
opacityRef.current = 1;
|
||||
pointsRef.current.position.x = Math.random() * 1 - 0.5;
|
||||
pointsRef.current.position.y = Math.random() * 0.5 - 0.25;
|
||||
originalYpos.current = pointsRef.current.position.y;
|
||||
}, [coins]);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
const time = state.clock.getElapsedTime();
|
||||
pointsRef.current.position.y += 0.008 * delta * 144;
|
||||
if (sizeRef.current < 1) {
|
||||
sizeRef.current = Math.min(sizeRef.current + 0.01 * delta * 144, 1);
|
||||
}
|
||||
|
||||
if (pointsRef.current.position.y > originalYpos.current + 0.01) {
|
||||
opacityRef.current = Math.max(opacityRef.current - 0.01 * delta * 144, 0);
|
||||
} else {
|
||||
opacityRef.current = Math.abs(Math.sin(time * timeModifier * 1500));
|
||||
}
|
||||
|
||||
// Update material properties directly
|
||||
if (materialRef.current) {
|
||||
materialRef.current.size = sizeRef.current;
|
||||
materialRef.current.opacity = opacityRef.current;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef} geometry={points}>
|
||||
<pointsMaterial
|
||||
ref={materialRef}
|
||||
alphaMap={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
toneMapped={false}
|
||||
color={0xbf8717}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -0,0 +1,61 @@
|
||||
import React, { useEffect,useRef, useState } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
export const CircleItemParticle = ({ position, item, color }) => {
|
||||
const texture = useLoader(THREE.TextureLoader, "./particles/circle_coin.png");
|
||||
const pointsRef = useRef();
|
||||
const materialRef = useRef();
|
||||
const [size, setSize] = useState(1);
|
||||
const [opacity, setOpacity] = useState(1);
|
||||
|
||||
const [currentColor, setCurrentColor] = useState(color);
|
||||
|
||||
const points = React.useMemo(() => {
|
||||
const geom = new THREE.BufferGeometry();
|
||||
geom.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(position, 3)
|
||||
);
|
||||
return geom;
|
||||
}, [position]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.color.multiplyScalar(4);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if(item){
|
||||
setSize(0);
|
||||
setOpacity(1);
|
||||
}
|
||||
}, [item]);
|
||||
|
||||
useFrame((_, delta) => {
|
||||
if (size < 5) {
|
||||
setSize((size) => Math.min(size + 0.2 * delta * 144, 5));
|
||||
} else if (opacity > 0) {
|
||||
setOpacity((opacity) => Math.max(opacity - 0.1 * delta * 144, 0));
|
||||
setSize((size) => Math.max(size - 0.1 * delta * 144, 0));
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef} geometry={points}>
|
||||
<pointsMaterial
|
||||
ref={materialRef}
|
||||
size={size}
|
||||
alphaMap={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
opacity={opacity}
|
||||
toneMapped={false}
|
||||
color={currentColor}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,20 @@
|
||||
import { CircleItemParticle } from "./CircleItemParticle"
|
||||
import { StarItemParticle } from "./StarItemParticle"
|
||||
import { SmallCircleParticle } from "./SmallCircleParticle"
|
||||
|
||||
export const ItemParticles = ({item}) => {
|
||||
return (
|
||||
<>
|
||||
<CircleItemParticle position={[0,0.8, 0.2]} item={item} color={0x75ff9a}/>
|
||||
<StarItemParticle position={[0,0.8, 0.2]} item={item} timeModifier={50} color={0x75ff9a}/>
|
||||
<StarItemParticle position={[0,0.8, 0.2]} item={item} timeModifier={60} color={0xe872fc}/>
|
||||
<StarItemParticle position={[0,0.8, 0.2]} item={item} timeModifier={40} color={0x72e5fc}/>
|
||||
<StarItemParticle position={[0,0.8, 0.2]} item={item} timeModifier={90} color={0xf0db7f}/>
|
||||
<SmallCircleParticle position={[0,0.8, 0.2]} item={item} timeModifier={50} color={0x75ff9a}/>
|
||||
<SmallCircleParticle position={[0,0.8, 0.2]} item={item} timeModifier={60} color={0xe872fc}/>
|
||||
<SmallCircleParticle position={[0,0.8, 0.2]} item={item} timeModifier={40} color={0x72e5fc}/>
|
||||
<SmallCircleParticle position={[0,0.8, 0.2]} item={item} timeModifier={90} color={0xf0db7f}/>
|
||||
|
||||
</>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
export const SmallCircleParticle = ({ position, item, timeModifier, color }) => {
|
||||
const texture = useLoader(THREE.TextureLoader, "./particles/circle_01.png");
|
||||
const pointsRef = useRef();
|
||||
const materialRef = useRef();
|
||||
const sizeRef = useRef(1);
|
||||
const opacityRef = useRef(1);
|
||||
const originalYpos = useRef(0);
|
||||
|
||||
const points = React.useMemo(() => {
|
||||
const geom = new THREE.BufferGeometry();
|
||||
geom.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(position, 3)
|
||||
);
|
||||
return geom;
|
||||
}, [position]);
|
||||
|
||||
useEffect(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.color.multiplyScalar(6);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if(item){
|
||||
sizeRef.current = 0;
|
||||
opacityRef.current = 1;
|
||||
pointsRef.current.position.x = Math.random() * 1 - 0.5;
|
||||
pointsRef.current.position.y = Math.random() * 0.5 - 0.25;
|
||||
originalYpos.current = pointsRef.current.position.y;
|
||||
}
|
||||
}, [item]);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
const time = state.clock.getElapsedTime();
|
||||
pointsRef.current.position.y += 0.008 * delta * 144;
|
||||
if (sizeRef.current < 1) {
|
||||
sizeRef.current = Math.min(sizeRef.current + 0.01 * delta * 144, 1);
|
||||
}
|
||||
|
||||
if (pointsRef.current.position.y > originalYpos.current + 0.01) {
|
||||
opacityRef.current = Math.max(opacityRef.current - 0.01 * delta * 144, 0);
|
||||
} else {
|
||||
opacityRef.current = Math.abs(Math.sin(time * timeModifier * 1500));
|
||||
}
|
||||
|
||||
// Update material properties directly
|
||||
if (materialRef.current) {
|
||||
materialRef.current.size = sizeRef.current;
|
||||
materialRef.current.opacity = opacityRef.current;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef} geometry={points}>
|
||||
<pointsMaterial
|
||||
ref={materialRef}
|
||||
alphaMap={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
toneMapped={false}
|
||||
color={color}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useLoader, useFrame } from "@react-three/fiber";
|
||||
import * as THREE from "three";
|
||||
|
||||
export const StarItemParticle = ({ position, item, timeModifier, color }) => {
|
||||
const texture = useLoader(THREE.TextureLoader, "./particles/star_coin.png");
|
||||
const pointsRef = useRef();
|
||||
const materialRef = useRef();
|
||||
const sizeRef = useRef(1);
|
||||
const opacityRef = useRef(1);
|
||||
const originalYpos = useRef(0);
|
||||
|
||||
const points = React.useMemo(() => {
|
||||
const geom = new THREE.BufferGeometry();
|
||||
geom.setAttribute(
|
||||
"position",
|
||||
new THREE.Float32BufferAttribute(position, 3)
|
||||
);
|
||||
return geom;
|
||||
}, [position]);
|
||||
|
||||
useEffect(() => {
|
||||
if (materialRef.current) {
|
||||
materialRef.current.color.multiplyScalar(6);
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
if(item){
|
||||
sizeRef.current = 0;
|
||||
opacityRef.current = 1;
|
||||
pointsRef.current.position.x = Math.random() * 1 - 0.5;
|
||||
pointsRef.current.position.y = Math.random() * 0.5 - 0.25;
|
||||
originalYpos.current = pointsRef.current.position.y;
|
||||
}
|
||||
}, [item]);
|
||||
|
||||
useFrame((state, delta) => {
|
||||
const time = state.clock.getElapsedTime();
|
||||
pointsRef.current.position.y += 0.008 * delta * 144;
|
||||
if (sizeRef.current < 1) {
|
||||
sizeRef.current = Math.min(sizeRef.current + 0.01 * delta * 144, 1);
|
||||
}
|
||||
|
||||
if (pointsRef.current.position.y > originalYpos.current + 0.01) {
|
||||
opacityRef.current = Math.max(opacityRef.current - 0.01 * delta * 144, 0);
|
||||
} else {
|
||||
opacityRef.current = Math.abs(Math.sin(time * timeModifier * 1500));
|
||||
}
|
||||
|
||||
// Update material properties directly
|
||||
if (materialRef.current) {
|
||||
materialRef.current.size = sizeRef.current;
|
||||
materialRef.current.opacity = opacityRef.current;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<points ref={pointsRef} geometry={points}>
|
||||
<pointsMaterial
|
||||
ref={materialRef}
|
||||
alphaMap={texture}
|
||||
transparent={true}
|
||||
depthWrite={false}
|
||||
toneMapped={false}
|
||||
color={color}
|
||||
/>
|
||||
</points>
|
||||
);
|
||||
};
|
||||
@@ -14,16 +14,18 @@ import { useRef, useState, useEffect, useCallback } from "react";
|
||||
import * as THREE from "three";
|
||||
|
||||
import { Mario } from "./models/characters/Mario_kart";
|
||||
import { DriftParticlesLeft } from "./Particles/DriftParticlesLeft";
|
||||
import { DriftParticlesRight } from "./Particles/DriftParticlesRight";
|
||||
import { DriftParticlesLeft } from "./Particles/drifts/DriftParticlesLeft";
|
||||
import { DriftParticlesRight } from "./Particles/drifts/DriftParticlesRight";
|
||||
|
||||
import { PointParticle } from "./Particles/PointParticle";
|
||||
import { PointParticle } from "./Particles/drifts/PointParticle";
|
||||
|
||||
import { FlameParticles } from "./Particles/FlameParticles";
|
||||
import { FlameParticles } from "./Particles/flames/FlameParticles";
|
||||
import { useStore } from "./store";
|
||||
import { Cylinder } from "@react-three/drei";
|
||||
import FakeGlowMaterial from "./ShaderMaterials/FakeGlow/FakeGlowMaterial";
|
||||
import { HitParticles } from "./Particles/HitParticles";
|
||||
import { HitParticles } from "./Particles/hits/HitParticles";
|
||||
import { CoinParticles } from "./Particles/coins/CoinParticles";
|
||||
import { ItemParticles } from "./Particles/items/ItemParticles";
|
||||
|
||||
export const PlayerController = () => {
|
||||
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||
@@ -83,7 +85,7 @@ export const PlayerController = () => {
|
||||
const effectiveBoost = useRef(0);
|
||||
|
||||
|
||||
const { actions, shouldSlowDown, item, bananas} = useStore();
|
||||
const { actions, shouldSlowDown, item, bananas, coins} = useStore();
|
||||
const slowDownDuration = useRef(1500);
|
||||
|
||||
|
||||
@@ -461,7 +463,7 @@ export const PlayerController = () => {
|
||||
actions.useItem();
|
||||
}
|
||||
|
||||
|
||||
console.log("coins", coins);
|
||||
});
|
||||
|
||||
return (
|
||||
@@ -497,12 +499,8 @@ export const PlayerController = () => {
|
||||
steeringAngleWheels={steeringAngleWheels}
|
||||
isBoosting={isBoosting}
|
||||
/>
|
||||
<pointLight
|
||||
position={[0.6, 0.05, 0.5]}
|
||||
intensity={scale}
|
||||
color={turboColor}
|
||||
/>
|
||||
|
||||
<CoinParticles coins={coins}/>
|
||||
<ItemParticles item={item}/>
|
||||
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
||||
<sphereGeometry args={[0.05, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
@@ -522,11 +520,6 @@ export const PlayerController = () => {
|
||||
glowSharpness={1}
|
||||
/>
|
||||
</mesh>
|
||||
<pointLight
|
||||
position={[-0.6, 0.05, 0.5]}
|
||||
intensity={scale}
|
||||
color={turboColor}
|
||||
/>
|
||||
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
||||
<sphereGeometry args={[0.05, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
Auto-generated by: https://github.com/pmndrs/gltfjsx
|
||||
Command: npx gltfjsx@6.2.16 .\gift.glb --shadows --transform
|
||||
Files: .\gift.glb [694.14KB] > C:\Users\mouli\dev\r3f-vite-starter\public\models\misc\gift-transformed.glb [86.34KB] (88%)
|
||||
Author: gorzi (https://sketchfab.com/gorzi90)
|
||||
License: CC-BY-4.0 (http://creativecommons.org/licenses/by/4.0/)
|
||||
Source: https://sketchfab.com/3d-models/gift-f3d8abcd3b9442f39a9a2017d59b56a1
|
||||
Title: Gift
|
||||
*/
|
||||
|
||||
import React, { useRef } from 'react'
|
||||
import { useGLTF, Float } from '@react-three/drei'
|
||||
import { CuboidCollider, RigidBody } from "@react-three/rapier";
|
||||
import { useStore } from "../../store";
|
||||
import { useFrame } from '@react-three/fiber';
|
||||
|
||||
export function ItemBox(props) {
|
||||
const { nodes, materials } = useGLTF('./models/misc/gift-transformed.glb');
|
||||
const { actions } = useStore();
|
||||
const ref = useRef();
|
||||
const [scale, setScale] = React.useState(0.6);
|
||||
const frames = useRef(0);
|
||||
const body = useRef();
|
||||
useFrame((state, delta) => {
|
||||
const time = state.clock.getElapsedTime();
|
||||
ref.current.position.y = Math.sin(time) * 0.1 + 2.5;
|
||||
ref.current.rotation.x = Math.sin(time) * 0.1;
|
||||
ref.current.rotation.y += delta;
|
||||
ref.current.rotation.z = Math.sin(time) * 0.5;
|
||||
if(scale < 0.6 && frames.current > 0){
|
||||
frames.current -= 1 * delta * 144;
|
||||
|
||||
}
|
||||
if(frames.current <= 0){
|
||||
setScale(Math.min(scale + 0.5 * delta, 0.6));
|
||||
if(body.current){
|
||||
body.current.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<RigidBody type="fixed" name="itemBox"
|
||||
sensor
|
||||
ref={body}
|
||||
onIntersectionEnter={({other}) => {
|
||||
if(other.rigidBodyObject.name === "player"){
|
||||
|
||||
console.log("item box hit");
|
||||
actions.setItem();
|
||||
setScale(0);
|
||||
frames.current = 400;
|
||||
body.current.setEnabled(false);
|
||||
}
|
||||
}}
|
||||
position={props.position}
|
||||
colliders={false}
|
||||
>
|
||||
<CuboidCollider args={[1.5, 1.5, 1.5]} />
|
||||
</RigidBody>
|
||||
<group ref={ref} position={props.position} scale={scale} dispose={null}>
|
||||
<mesh castShadow receiveShadow geometry={nodes.Cube000.geometry} material={materials.Material} position={[0.077, 0.5, -0.019]} rotation={[-Math.PI / 2, 0, 0]} />
|
||||
<mesh castShadow receiveShadow geometry={nodes.Cube000_1.geometry} material={materials['Material.001']} position={[0.077, 0.5, -0.019]} rotation={[-Math.PI / 2, 0, 0]} />
|
||||
</group>
|
||||
</>
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
useGLTF.preload('./models/misc/gift-transformed.glb')
|
||||
@@ -8,30 +8,64 @@ Source: https://sketchfab.com/3d-models/super-mario-bros-coin-aa97e093847a439f9f
|
||||
Title: Super Mario Bros Coin
|
||||
*/
|
||||
|
||||
import React, { useEffect, useRef } from 'react'
|
||||
import { useGLTF, useAnimations } from '@react-three/drei'
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import React, { useEffect, useRef } from "react";
|
||||
import { useGLTF, useAnimations } from "@react-three/drei";
|
||||
import { useFrame } from "@react-three/fiber";
|
||||
import { RigidBody } from "@react-three/rapier";
|
||||
import { useStore } from "../../store";
|
||||
|
||||
export function Coin(props) {
|
||||
const group = useRef()
|
||||
const { nodes, materials, animations } = useGLTF('./models/misc/super_mario_bros_coin-transformed.glb')
|
||||
const { actions } = useAnimations(animations, group)
|
||||
|
||||
const group = useRef();
|
||||
const { nodes, materials } = useGLTF(
|
||||
"./models/misc/super_mario_bros_coin-transformed.glb"
|
||||
);
|
||||
const { actions } = useStore();
|
||||
const [scale, setScale] = React.useState(0.424);
|
||||
const frames = useRef(0);
|
||||
useFrame((state, delta) => {
|
||||
group.current.rotation.y += 4 * delta
|
||||
})
|
||||
|
||||
group.current.rotation.y += 4 * delta;
|
||||
if(scale < 0.424 && frames.current > 0){
|
||||
frames.current -= 1 * delta * 144;
|
||||
|
||||
}
|
||||
if(frames.current <= 0){
|
||||
setScale(Math.min(scale + 0.5 * delta, 0.424));
|
||||
if(body.current){
|
||||
body.current.setEnable(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const body = useRef();
|
||||
|
||||
return (
|
||||
<group ref={group} {...props} dispose={null}>
|
||||
<group name="Sketchfab_Scene">
|
||||
<group name="RootNode" scale={0.588}>
|
||||
<group name="Coin" scale={0.424}>
|
||||
<mesh name="Coin_CoinBlinn_0" castShadow receiveShadow geometry={nodes.Coin_CoinBlinn_0.geometry} material={materials.CoinBlinn} />
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
</group>
|
||||
)
|
||||
<>
|
||||
<RigidBody
|
||||
type="fixed"
|
||||
name="coin"
|
||||
sensor
|
||||
onIntersectionEnter={({ manifold, target, other}) => {
|
||||
if(other.rigidBodyObject.name === "player"){
|
||||
actions.addCoins();
|
||||
setScale(0);
|
||||
frames.current = 600;
|
||||
body.current.setEnable(false);
|
||||
}
|
||||
}}
|
||||
position={props.position}
|
||||
>
|
||||
<mesh
|
||||
ref={group}
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.Coin_CoinBlinn_0.geometry}
|
||||
material={materials.CoinBlinn}
|
||||
scale={scale}
|
||||
/>
|
||||
</RigidBody>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
useGLTF.preload('./models/misc/super_mario_bros_coin-transformed.glb')
|
||||
useGLTF.preload("./models/misc/super_mario_bros_coin-transformed.glb");
|
||||
@@ -24,6 +24,7 @@ export const useStore = create((set, get) => ({
|
||||
item: "",
|
||||
shells: [],
|
||||
skids: [],
|
||||
coins : 0,
|
||||
addPastPosition: (position) => {
|
||||
set((state) => ({
|
||||
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
||||
@@ -111,6 +112,16 @@ export const useStore = create((set, get) => ({
|
||||
skids: [...state.skids, skid],
|
||||
}));
|
||||
},
|
||||
addCoins : () => {
|
||||
set((state) => ({
|
||||
coins: state.coins + 1,
|
||||
}));
|
||||
},
|
||||
looseCoins : () => {
|
||||
set((state) => ({
|
||||
coins: state.coins - 1,
|
||||
}));
|
||||
},
|
||||
},
|
||||
|
||||
}));
|
||||
@@ -39,6 +39,7 @@ pointer-events: none;
|
||||
}
|
||||
|
||||
.logo{
|
||||
display: none;
|
||||
position:absolute;
|
||||
top:150px;
|
||||
left:500px;
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@ import { HUD } from './HUD'
|
||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||
<React.StrictMode>
|
||||
<App />
|
||||
{/* <HUD /> */}
|
||||
<HUD />
|
||||
</React.StrictMode>,
|
||||
)
|
||||
Reference in new issue
Block a user