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
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
+4
-2
@@ -30,24 +30,26 @@ function App() {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<Loader />
|
||||||
<Canvas
|
<Canvas
|
||||||
shadows
|
shadows
|
||||||
dpr={1}
|
dpr={1}
|
||||||
gl={{ antialias: false, stencil: false, powerPreference: 'high-performance' }}
|
gl={{ antialias: false, stencil: false, powerPreference: 'high-performance' }}
|
||||||
>
|
>
|
||||||
<Suspense fallback={null}>
|
<Suspense fallback={null}>
|
||||||
|
<Preload all />
|
||||||
<Physics
|
<Physics
|
||||||
gravity={[0, -90, 0]}
|
gravity={[0, -90, 0]}
|
||||||
timeStep={'vary'}
|
timeStep={'vary'}
|
||||||
// debug
|
|
||||||
>
|
>
|
||||||
<KeyboardControls map={map}>
|
<KeyboardControls map={map}>
|
||||||
<Experience />
|
<Experience />
|
||||||
</KeyboardControls>
|
</KeyboardControls>
|
||||||
<Stats />
|
|
||||||
</Physics>
|
</Physics>
|
||||||
</Suspense>
|
</Suspense>
|
||||||
</Canvas>
|
</Canvas>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -30,7 +30,7 @@ export const HUD = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="wheel">
|
<div className="wheel">
|
||||||
<img
|
<img
|
||||||
ref={wheel}
|
ref={wheel}
|
||||||
src="./steering_wheel.png"
|
src="./steering_wheel.png"
|
||||||
alt="steering wheel"
|
alt="steering wheel"
|
||||||
className="steering-wheel"
|
className="steering-wheel"
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
Vignette,
|
Vignette,
|
||||||
} from "@react-three/postprocessing";
|
} from "@react-three/postprocessing";
|
||||||
import { Banana } from "./models/items/Banana_peel_mario_kart";
|
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 { useStore } from "./store";
|
||||||
import { Shell } from "./models/items/Mario_shell_red";
|
import { Shell } from "./models/items/Mario_shell_red";
|
||||||
import { Coin } from "./models/misc/Super_mario_bros_coin";
|
import { Coin } from "./models/misc/Super_mario_bros_coin";
|
||||||
@@ -36,7 +36,7 @@ export const Experience = () => {
|
|||||||
<Paris position={[0, 0, 0]} />
|
<Paris position={[0, 0, 0]} />
|
||||||
<Banana onCollide={onCollide} position={[-10, 1.8, -119]} />
|
<Banana onCollide={onCollide} position={[-10, 1.8, -119]} />
|
||||||
{/* <Shell position={[-20, 2, -119]} /> */}
|
{/* <Shell position={[-20, 2, -119]} /> */}
|
||||||
<ItemBox position={[-20, 2, -119]} />
|
<ItemBox position={[-20, 2.5, -119]} />
|
||||||
<Coin position={[-30, 2, -119]} />
|
<Coin position={[-30, 2, -119]} />
|
||||||
|
|
||||||
<Ground position={[0, 0, 0]} />
|
<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 * as THREE from "three";
|
||||||
|
|
||||||
import { Mario } from "./models/characters/Mario_kart";
|
import { Mario } from "./models/characters/Mario_kart";
|
||||||
import { DriftParticlesLeft } from "./Particles/DriftParticlesLeft";
|
import { DriftParticlesLeft } from "./Particles/drifts/DriftParticlesLeft";
|
||||||
import { DriftParticlesRight } from "./Particles/DriftParticlesRight";
|
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 { useStore } from "./store";
|
||||||
import { Cylinder } from "@react-three/drei";
|
import { Cylinder } from "@react-three/drei";
|
||||||
import FakeGlowMaterial from "./ShaderMaterials/FakeGlow/FakeGlowMaterial";
|
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 = () => {
|
export const PlayerController = () => {
|
||||||
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||||
@@ -83,7 +85,7 @@ export const PlayerController = () => {
|
|||||||
const effectiveBoost = useRef(0);
|
const effectiveBoost = useRef(0);
|
||||||
|
|
||||||
|
|
||||||
const { actions, shouldSlowDown, item, bananas} = useStore();
|
const { actions, shouldSlowDown, item, bananas, coins} = useStore();
|
||||||
const slowDownDuration = useRef(1500);
|
const slowDownDuration = useRef(1500);
|
||||||
|
|
||||||
|
|
||||||
@@ -461,7 +463,7 @@ export const PlayerController = () => {
|
|||||||
actions.useItem();
|
actions.useItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log("coins", coins);
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -497,12 +499,8 @@ export const PlayerController = () => {
|
|||||||
steeringAngleWheels={steeringAngleWheels}
|
steeringAngleWheels={steeringAngleWheels}
|
||||||
isBoosting={isBoosting}
|
isBoosting={isBoosting}
|
||||||
/>
|
/>
|
||||||
<pointLight
|
<CoinParticles coins={coins}/>
|
||||||
position={[0.6, 0.05, 0.5]}
|
<ItemParticles item={item}/>
|
||||||
intensity={scale}
|
|
||||||
color={turboColor}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
||||||
<sphereGeometry args={[0.05, 16, 16]} />
|
<sphereGeometry args={[0.05, 16, 16]} />
|
||||||
<meshStandardMaterial
|
<meshStandardMaterial
|
||||||
@@ -522,11 +520,6 @@ export const PlayerController = () => {
|
|||||||
glowSharpness={1}
|
glowSharpness={1}
|
||||||
/>
|
/>
|
||||||
</mesh>
|
</mesh>
|
||||||
<pointLight
|
|
||||||
position={[-0.6, 0.05, 0.5]}
|
|
||||||
intensity={scale}
|
|
||||||
color={turboColor}
|
|
||||||
/>
|
|
||||||
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
||||||
<sphereGeometry args={[0.05, 16, 16]} />
|
<sphereGeometry args={[0.05, 16, 16]} />
|
||||||
<meshStandardMaterial
|
<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
|
Title: Super Mario Bros Coin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useEffect, useRef } from 'react'
|
import React, { useEffect, useRef } from "react";
|
||||||
import { useGLTF, useAnimations } from '@react-three/drei'
|
import { useGLTF, useAnimations } from "@react-three/drei";
|
||||||
import { useFrame } from '@react-three/fiber'
|
import { useFrame } from "@react-three/fiber";
|
||||||
|
import { RigidBody } from "@react-three/rapier";
|
||||||
|
import { useStore } from "../../store";
|
||||||
|
|
||||||
export function Coin(props) {
|
export function Coin(props) {
|
||||||
const group = useRef()
|
const group = useRef();
|
||||||
const { nodes, materials, animations } = useGLTF('./models/misc/super_mario_bros_coin-transformed.glb')
|
const { nodes, materials } = useGLTF(
|
||||||
const { actions } = useAnimations(animations, group)
|
"./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) => {
|
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 (
|
return (
|
||||||
<group ref={group} {...props} dispose={null}>
|
<>
|
||||||
<group name="Sketchfab_Scene">
|
<RigidBody
|
||||||
<group name="RootNode" scale={0.588}>
|
type="fixed"
|
||||||
<group name="Coin" scale={0.424}>
|
name="coin"
|
||||||
<mesh name="Coin_CoinBlinn_0" castShadow receiveShadow geometry={nodes.Coin_CoinBlinn_0.geometry} material={materials.CoinBlinn} />
|
sensor
|
||||||
</group>
|
onIntersectionEnter={({ manifold, target, other}) => {
|
||||||
</group>
|
if(other.rigidBodyObject.name === "player"){
|
||||||
</group>
|
actions.addCoins();
|
||||||
</group>
|
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: "",
|
item: "",
|
||||||
shells: [],
|
shells: [],
|
||||||
skids: [],
|
skids: [],
|
||||||
|
coins : 0,
|
||||||
addPastPosition: (position) => {
|
addPastPosition: (position) => {
|
||||||
set((state) => ({
|
set((state) => ({
|
||||||
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
pastPositions: [position, ...state.pastPositions.slice(0, 499)],
|
||||||
@@ -111,6 +112,16 @@ export const useStore = create((set, get) => ({
|
|||||||
skids: [...state.skids, skid],
|
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{
|
.logo{
|
||||||
|
display: none;
|
||||||
position:absolute;
|
position:absolute;
|
||||||
top:150px;
|
top:150px;
|
||||||
left:500px;
|
left:500px;
|
||||||
|
|||||||
+1
-1
@@ -7,6 +7,6 @@ import { HUD } from './HUD'
|
|||||||
ReactDOM.createRoot(document.getElementById('root')).render(
|
ReactDOM.createRoot(document.getElementById('root')).render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<App />
|
<App />
|
||||||
{/* <HUD /> */}
|
<HUD />
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
)
|
)
|
||||||
Reference in new issue
Block a user