diff --git a/public/models/misc/gift-transformed.glb b/public/models/misc/gift-transformed.glb
new file mode 100644
index 0000000..237aa4c
Binary files /dev/null and b/public/models/misc/gift-transformed.glb differ
diff --git a/public/models/misc/gift.glb b/public/models/misc/gift.glb
new file mode 100644
index 0000000..11456f0
Binary files /dev/null and b/public/models/misc/gift.glb differ
diff --git a/public/particles/circle_01.png b/public/particles/circle_01.png
new file mode 100644
index 0000000..adabdd9
Binary files /dev/null and b/public/particles/circle_01.png differ
diff --git a/public/particles/circle_coin.png b/public/particles/circle_coin.png
new file mode 100644
index 0000000..adabdd9
Binary files /dev/null and b/public/particles/circle_coin.png differ
diff --git a/public/particles/star_coin.png b/public/particles/star_coin.png
new file mode 100644
index 0000000..5836541
Binary files /dev/null and b/public/particles/star_coin.png differ
diff --git a/src/App.jsx b/src/App.jsx
index 6dab505..5906eb4 100644
--- a/src/App.jsx
+++ b/src/App.jsx
@@ -30,24 +30,26 @@ function App() {
)
return (
+ <>
+
+ >
)
}
diff --git a/src/HUD.jsx b/src/HUD.jsx
index 19bae30..bf4ca5d 100644
--- a/src/HUD.jsx
+++ b/src/HUD.jsx
@@ -30,7 +30,7 @@ export const HUD = () => {
{
{/*
*/}
-
+
diff --git a/src/components/Particles/coins/CircleCoinParticle.jsx b/src/components/Particles/coins/CircleCoinParticle.jsx
new file mode 100644
index 0000000..a036261
--- /dev/null
+++ b/src/components/Particles/coins/CircleCoinParticle.jsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/src/components/Particles/coins/CoinParticles.jsx b/src/components/Particles/coins/CoinParticles.jsx
new file mode 100644
index 0000000..c4ba52d
--- /dev/null
+++ b/src/components/Particles/coins/CoinParticles.jsx
@@ -0,0 +1,15 @@
+import { CircleCoinParticle } from "./CircleCoinParticle"
+import { StarCoinParticle } from "./StarCoinParticle"
+
+export const CoinParticles = ({ coins }) => {
+ return (
+ <>
+
+
+
+
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/components/Particles/coins/StarCoinParticle.jsx b/src/components/Particles/coins/StarCoinParticle.jsx
new file mode 100644
index 0000000..9333d10
--- /dev/null
+++ b/src/components/Particles/coins/StarCoinParticle.jsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/src/components/Particles/DriftParticlesLeft.jsx b/src/components/Particles/drifts/DriftParticlesLeft.jsx
similarity index 100%
rename from src/components/Particles/DriftParticlesLeft.jsx
rename to src/components/Particles/drifts/DriftParticlesLeft.jsx
diff --git a/src/components/Particles/DriftParticlesRight.jsx b/src/components/Particles/drifts/DriftParticlesRight.jsx
similarity index 100%
rename from src/components/Particles/DriftParticlesRight.jsx
rename to src/components/Particles/drifts/DriftParticlesRight.jsx
diff --git a/src/components/Particles/Particles1.jsx b/src/components/Particles/drifts/Particles1.jsx
similarity index 100%
rename from src/components/Particles/Particles1.jsx
rename to src/components/Particles/drifts/Particles1.jsx
diff --git a/src/components/Particles/Particles2.jsx b/src/components/Particles/drifts/Particles2.jsx
similarity index 100%
rename from src/components/Particles/Particles2.jsx
rename to src/components/Particles/drifts/Particles2.jsx
diff --git a/src/components/Particles/Particles3.jsx b/src/components/Particles/drifts/Particles3.jsx
similarity index 100%
rename from src/components/Particles/Particles3.jsx
rename to src/components/Particles/drifts/Particles3.jsx
diff --git a/src/components/Particles/Particles4.jsx b/src/components/Particles/drifts/Particles4.jsx
similarity index 100%
rename from src/components/Particles/Particles4.jsx
rename to src/components/Particles/drifts/Particles4.jsx
diff --git a/src/components/Particles/PointParticle.jsx b/src/components/Particles/drifts/PointParticle.jsx
similarity index 100%
rename from src/components/Particles/PointParticle.jsx
rename to src/components/Particles/drifts/PointParticle.jsx
diff --git a/src/components/Particles/FlameParticle.jsx b/src/components/Particles/flames/FlameParticle.jsx
similarity index 100%
rename from src/components/Particles/FlameParticle.jsx
rename to src/components/Particles/flames/FlameParticle.jsx
diff --git a/src/components/Particles/FlameParticles.jsx b/src/components/Particles/flames/FlameParticles.jsx
similarity index 100%
rename from src/components/Particles/FlameParticles.jsx
rename to src/components/Particles/flames/FlameParticles.jsx
diff --git a/src/components/Particles/HitParticle.jsx b/src/components/Particles/hits/HitParticle.jsx
similarity index 100%
rename from src/components/Particles/HitParticle.jsx
rename to src/components/Particles/hits/HitParticle.jsx
diff --git a/src/components/Particles/HitParticleTwo.jsx b/src/components/Particles/hits/HitParticleTwo.jsx
similarity index 100%
rename from src/components/Particles/HitParticleTwo.jsx
rename to src/components/Particles/hits/HitParticleTwo.jsx
diff --git a/src/components/Particles/HitParticles.jsx b/src/components/Particles/hits/HitParticles.jsx
similarity index 100%
rename from src/components/Particles/HitParticles.jsx
rename to src/components/Particles/hits/HitParticles.jsx
diff --git a/src/components/Particles/items/CircleItemParticle.jsx b/src/components/Particles/items/CircleItemParticle.jsx
new file mode 100644
index 0000000..eac1629
--- /dev/null
+++ b/src/components/Particles/items/CircleItemParticle.jsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/src/components/Particles/items/ItemParticles.jsx b/src/components/Particles/items/ItemParticles.jsx
new file mode 100644
index 0000000..2c4b866
--- /dev/null
+++ b/src/components/Particles/items/ItemParticles.jsx
@@ -0,0 +1,20 @@
+import { CircleItemParticle } from "./CircleItemParticle"
+import { StarItemParticle } from "./StarItemParticle"
+import { SmallCircleParticle } from "./SmallCircleParticle"
+
+export const ItemParticles = ({item}) => {
+ return (
+ <>
+
+
+
+
+
+
+
+
+
+
+ >
+ )
+}
\ No newline at end of file
diff --git a/src/components/Particles/items/SmallCircleParticle.jsx b/src/components/Particles/items/SmallCircleParticle.jsx
new file mode 100644
index 0000000..f7cf737
--- /dev/null
+++ b/src/components/Particles/items/SmallCircleParticle.jsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/src/components/Particles/items/StarItemParticle.jsx b/src/components/Particles/items/StarItemParticle.jsx
new file mode 100644
index 0000000..554f317
--- /dev/null
+++ b/src/components/Particles/items/StarItemParticle.jsx
@@ -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 (
+
+
+
+ );
+};
diff --git a/src/components/PlayerController.jsx b/src/components/PlayerController.jsx
index 1ba0b0e..c34b567 100644
--- a/src/components/PlayerController.jsx
+++ b/src/components/PlayerController.jsx
@@ -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}
/>
-
-
+
+
{
glowSharpness={1}
/>
-
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 (
+ <>
+ {
+ 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}
+ >
+
+
+
+
+
+
+ >
+ )
+
+}
+
+useGLTF.preload('./models/misc/gift-transformed.glb')
diff --git a/src/components/models/misc/Super_mario_bros_coin.jsx b/src/components/models/misc/Super_mario_bros_coin.jsx
index 4153177..d71874b 100644
--- a/src/components/models/misc/Super_mario_bros_coin.jsx
+++ b/src/components/models/misc/Super_mario_bros_coin.jsx
@@ -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 (
-
-
-
-
-
-
-
-
-
- )
+ <>
+ {
+ if(other.rigidBodyObject.name === "player"){
+ actions.addCoins();
+ setScale(0);
+ frames.current = 600;
+ body.current.setEnable(false);
+ }
+ }}
+ position={props.position}
+ >
+
+
+ >
+ );
}
-useGLTF.preload('./models/misc/super_mario_bros_coin-transformed.glb')
+useGLTF.preload("./models/misc/super_mario_bros_coin-transformed.glb");
diff --git a/src/components/store.jsx b/src/components/store.jsx
index 5142044..a1e2bf1 100644
--- a/src/components/store.jsx
+++ b/src/components/store.jsx
@@ -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,
+ }));
+ },
},
}));
diff --git a/src/index.css b/src/index.css
index a397622..18e8d52 100644
--- a/src/index.css
+++ b/src/index.css
@@ -39,6 +39,7 @@ pointer-events: none;
}
.logo{
+ display: none;
position:absolute;
top:150px;
left:500px;
diff --git a/src/main.jsx b/src/main.jsx
index dc4b631..e35d3a2 100644
--- a/src/main.jsx
+++ b/src/main.jsx
@@ -7,6 +7,6 @@ import { HUD } from './HUD'
ReactDOM.createRoot(document.getElementById('root')).render(
- {/* */}
+
,
)