parent
2753ec7127
commit
6232bf9498
|
@ -0,0 +1,152 @@
|
|||
/**
|
||||
* FakeFlame material component by Anderson Mancini - Jan 2024.
|
||||
*/
|
||||
|
||||
import React, { useMemo, useRef } from 'react'
|
||||
import { shaderMaterial } from '@react-three/drei'
|
||||
import { extend, useFrame } from '@react-three/fiber'
|
||||
import { Color, DoubleSide, AdditiveBlending } from 'three'
|
||||
|
||||
export default function FakeFlame({ falloff = 3, glowInternalRadius = 1.0, glowColor = 'orange', glowSharpness = 1.0 }) {
|
||||
const FakeFlame = useMemo(() => {
|
||||
return shaderMaterial(
|
||||
{
|
||||
falloffAmount: falloff,
|
||||
glowInternalRadius: glowInternalRadius,
|
||||
glowColor: new Color(glowColor),
|
||||
glowSharpness: glowSharpness,
|
||||
time: 0
|
||||
},
|
||||
/*GLSL */
|
||||
`
|
||||
varying vec3 vNormal;
|
||||
varying vec2 vUv;
|
||||
uniform float time;
|
||||
|
||||
float random2D(vec2 value)
|
||||
{
|
||||
return fract(sin(dot(value.xy, vec2(12.9898,78.233))) * 43758.5453123);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Position
|
||||
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
|
||||
vec4 modelNormal = modelMatrix * vec4(normal, 0.0);
|
||||
|
||||
// Glitch
|
||||
float glitchTime = time + modelPosition.y;
|
||||
float glitchStrength = sin(glitchTime) + sin(glitchTime * .05) + sin(glitchTime * .36);
|
||||
glitchStrength /= 2.0;
|
||||
glitchStrength = smoothstep(0.2, 0.8, glitchStrength);
|
||||
glitchStrength *= 0.25;
|
||||
modelPosition.x += (random2D(modelNormal.xx + time) - 0.5) * glitchStrength;
|
||||
modelPosition.x += (random2D(modelNormal.xx - time) - 0.2) * glitchStrength;
|
||||
modelPosition.y += sin(smoothstep(0.3, vUv.y - 1.8, position.y) * 2.) * sin(time * 2.);
|
||||
modelPosition.z += sin(smoothstep(0., vUv.x - 0.8, position.z) * 2.) * sin(time * 2.) * .6;
|
||||
|
||||
gl_Position = projectionMatrix * viewMatrix * modelPosition;
|
||||
|
||||
vUv = uv;
|
||||
}`,
|
||||
/*GLSL */
|
||||
`
|
||||
uniform vec3 glowColor;
|
||||
uniform float falloffAmount;
|
||||
uniform float glowSharpness;
|
||||
uniform float glowInternalRadius;
|
||||
uniform float time;
|
||||
|
||||
varying vec2 vUv;
|
||||
|
||||
vec2 hash( vec2 p )
|
||||
{
|
||||
p = vec2( dot(p,vec2(127.1,311.7)),
|
||||
dot(p,vec2(269.5,183.3)) );
|
||||
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
|
||||
}
|
||||
|
||||
float noise( in vec2 p )
|
||||
{
|
||||
const float K1 = 0.366025404; // (sqrt(3)-1)/2;
|
||||
const float K2 = 0.211324865; // (3-sqrt(3))/6;
|
||||
|
||||
vec2 i = floor( p + (p.x+p.y)*K1 );
|
||||
|
||||
vec2 a = p - i + (i.x+i.y)*K2;
|
||||
vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0);
|
||||
vec2 b = a - o + K2;
|
||||
vec2 c = a - 1.0 + 2.0*K2;
|
||||
|
||||
vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
|
||||
|
||||
vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
|
||||
|
||||
return dot( n, vec3(70.0) );
|
||||
}
|
||||
|
||||
float fbm(vec2 uv)
|
||||
{
|
||||
float f;
|
||||
mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 );
|
||||
f = 0.5000*noise( uv ); uv = m*uv;
|
||||
f += 0.2500*noise( uv ); uv = m*uv;
|
||||
// f += 0.1250*noise( uv ); uv = m*uv;
|
||||
// f += 0.0625*noise( uv ); uv = m*uv;
|
||||
f = 0.5 + 0.5*f;
|
||||
return f;
|
||||
}
|
||||
|
||||
// #define BLUE_FLAME
|
||||
// #define GREEN_FLAME
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 q = vUv;
|
||||
q.x *= 2.;
|
||||
q.y *= 2.;
|
||||
float strength = floor(q.x+1.5);
|
||||
float T3 = max(2.,2.25*strength)*time;
|
||||
q.x = mod(q.x,1.)-0.5;
|
||||
q.y -= 0.05;
|
||||
float n = fbm(strength*q + vec2(0,T3));
|
||||
float c = 0.7 - 0.01 * pow( max( 0., length(q*vec2(1.8+q.y*1.5,.75) ) - n * max( 0., q.y+.25 ) ),.2 );
|
||||
// float c1 = n * c * fract((1.9-pow(0.15*vUv.y,2.))) * 2.;
|
||||
float c1 = n * c * (pow(1.90*vUv.y,2.));
|
||||
c1=clamp(c1,0.,1.);
|
||||
|
||||
vec3 col = smoothstep(0.1, 0.8, vec3(c1, c1*c1*c1, c1*c1*c1*c1*c1*c1));
|
||||
|
||||
#ifdef BLUE_FLAME
|
||||
col = col.zyx;
|
||||
#endif
|
||||
#ifdef GREEN_FLAME
|
||||
col = 0.85*col.yxz;
|
||||
#endif
|
||||
|
||||
gl_FragColor = vec4( col, 1.0);
|
||||
|
||||
#include <tonemapping_fragment>
|
||||
#include <colorspace_fragment>
|
||||
}`
|
||||
)
|
||||
}, [falloff, glowInternalRadius, glowColor, glowSharpness])
|
||||
|
||||
extend({ FakeFlame })
|
||||
|
||||
useFrame((state, delta) => {
|
||||
ref.current.time += delta
|
||||
})
|
||||
|
||||
const ref = useRef()
|
||||
|
||||
return (
|
||||
<fakeFlame
|
||||
key={FakeFlame.key}
|
||||
side={DoubleSide}
|
||||
transparent={true}
|
||||
blending={AdditiveBlending}
|
||||
depthTest={false}
|
||||
ref={ref}
|
||||
/>
|
||||
)
|
||||
}
|
|
@ -1,82 +1,73 @@
|
|||
/**
|
||||
* FakeGlow material component by Anderson Mancini - Dec 2024.
|
||||
* fakeGlow material component by Anderson Mancini - Dec 2023.
|
||||
*/
|
||||
|
||||
import React, { useRef, useMemo } from 'react'
|
||||
import React, { useMemo } from 'react'
|
||||
import { shaderMaterial } from '@react-three/drei'
|
||||
import { extend, useFrame } from '@react-three/fiber'
|
||||
import { Color, BackSide, AdditiveBlending } from 'three'
|
||||
import { extend } from '@react-three/fiber'
|
||||
import { Color, DoubleSide, AdditiveBlending } from 'three'
|
||||
|
||||
export default function FakeGlowMaterial({ glowCenter = 0.05, edgeIntensity = 6.0, glowColor = '#00ff00', glowOpacity = 1.0, fresnelOpacity = 0.5, fresnelAmount = 0.5, wireframe = false }) {
|
||||
export default function FakeGlowMaterial({ falloff = 3, glowInternalRadius = 1.0, glowColor = '#b97939', glowSharpness = 1.0 }) {
|
||||
const FakeGlowMaterial = useMemo(() => {
|
||||
return shaderMaterial(
|
||||
{
|
||||
time: 0,
|
||||
glowCenter: glowCenter,
|
||||
edgeIntensity: edgeIntensity,
|
||||
falloffAmount: falloff,
|
||||
glowInternalRadius: glowInternalRadius,
|
||||
glowColor: new Color(glowColor),
|
||||
glowOpacity: glowOpacity,
|
||||
fresnelOpacity: fresnelOpacity,
|
||||
fresnelAmount: fresnelAmount
|
||||
glowSharpness: glowSharpness
|
||||
},
|
||||
/*GLSL */
|
||||
`
|
||||
uniform float glowCenter;
|
||||
uniform float edgeIntensity;
|
||||
varying float intensity;
|
||||
varying vec3 vNormel;
|
||||
varying vec3 vPosition;
|
||||
varying vec3 vNormal;
|
||||
uniform float fresnelOpacity;
|
||||
uniform float fresnelAmount;
|
||||
|
||||
void main() {
|
||||
vec3 viewVector = normalize(vec3(cameraPosition-position));
|
||||
float fresnelEffect = dot(vNormel, vNormal) * ( fresnelOpacity);
|
||||
fresnelEffect = clamp(fresnelAmount - fresnelEffect, 0.5, fresnelOpacity);
|
||||
vec3 vNormal = normalize( normalMatrix * normal );
|
||||
vec3 vNormel = normalize( normalMatrix * viewVector );
|
||||
intensity = pow( glowCenter - dot(vNormal, vNormel), edgeIntensity / fresnelEffect );
|
||||
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
|
||||
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
|
||||
gl_Position = projectionMatrix * viewMatrix * modelPosition;
|
||||
vec4 modelNormal = modelMatrix * vec4(normal, 0.0);
|
||||
vPosition = modelPosition.xyz;
|
||||
vNormal = modelNormal.xyz;
|
||||
|
||||
}`,
|
||||
/*GLSL */
|
||||
`
|
||||
uniform vec3 glowColor;
|
||||
varying float intensity;
|
||||
uniform float glowOpacity;
|
||||
uniform float fresnelOpacity;
|
||||
uniform float fresnelAmount;
|
||||
varying vec3 vNormel;
|
||||
uniform float falloffAmount;
|
||||
uniform float glowSharpness;
|
||||
uniform float glowInternalRadius;
|
||||
|
||||
varying vec3 vPosition;
|
||||
varying vec3 vNormal;
|
||||
uniform float glowCenter;
|
||||
uniform float edgeIntensity;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 glow = glowColor * intensity;
|
||||
float fresnelEffect = - dot(vNormel, vNormal);
|
||||
fresnelEffect = clamp(fresnelEffect, 0.1, 1.0);
|
||||
gl_FragColor = vec4( clamp(glow, 0., 1.0), clamp(glowOpacity - intensity * fresnelEffect, 0., 1.0 ));
|
||||
// Normal
|
||||
vec3 normal = normalize(vNormal);
|
||||
if(!gl_FrontFacing){ normal *= - 1.0; }
|
||||
vec3 viewDirection = normalize(cameraPosition - vPosition);
|
||||
float fresnel = dot(viewDirection, normal);
|
||||
fresnel = pow(fresnel, glowInternalRadius);
|
||||
float falloff = smoothstep(0., falloffAmount, fresnel);
|
||||
float fakeGlow = fresnel;
|
||||
fakeGlow += fresnel * glowSharpness;
|
||||
fakeGlow *= falloff;
|
||||
gl_FragColor = vec4(clamp(glowColor * fresnel, 0., 1.0), clamp(fakeGlow, 0., 1.0));
|
||||
|
||||
#include <tonemapping_fragment>
|
||||
#include <colorspace_fragment>
|
||||
}`
|
||||
)
|
||||
}, [glowCenter, edgeIntensity, glowColor, glowOpacity, fresnelOpacity, fresnelAmount])
|
||||
}, [falloff, glowInternalRadius, glowColor, glowSharpness])
|
||||
|
||||
extend({ FakeGlowMaterial })
|
||||
|
||||
useFrame((state, delta) => {
|
||||
ref.current.time += delta
|
||||
})
|
||||
|
||||
const ref = useRef()
|
||||
|
||||
return (
|
||||
<fakeGlowMaterial
|
||||
wireframe={wireframe}
|
||||
key={FakeGlowMaterial.key}
|
||||
side={BackSide}
|
||||
side={DoubleSide}
|
||||
transparent={true}
|
||||
blending={AdditiveBlending}
|
||||
depthTest={false}
|
||||
ref={ref}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,310 +1,246 @@
|
|||
import { Controls } from "../App";
|
||||
import { BallCollider, RigidBody, useRapier } from "@react-three/rapier";
|
||||
import {
|
||||
useKeyboardControls,
|
||||
PerspectiveCamera,
|
||||
ContactShadows,
|
||||
Sphere,
|
||||
OrbitControls,
|
||||
Trail,
|
||||
PositionalAudio,
|
||||
} from "@react-three/drei";
|
||||
import { useFrame, useThree } from "@react-three/fiber";
|
||||
import { useRef, useState, useEffect, useCallback } from "react";
|
||||
import * as THREE from "three";
|
||||
import { Model } from "./models/Racing_kart";
|
||||
import { FrontRightWheel } from "./models/Front_Right_Wheel";
|
||||
import { FrontLeftWheel } from "./models/Front_Left_Wheel";
|
||||
import { RearWheels } from "./models/Rear_wheels";
|
||||
import gsap from "gsap";
|
||||
import { Mario } from "./models/Mario_kart";
|
||||
import { Particles1 } from "./Particles1";
|
||||
import { DriftParticlesLeft } from "./DriftParticlesLeft";
|
||||
import { DriftParticlesRight } from "./DriftParticlesRight";
|
||||
import FakeGlowMaterial from "./FakeGlow/FakeGlowMaterial";
|
||||
import { PointParticle } from "./PointParticle";
|
||||
import { FlameParticle } from "./FlameParticle";
|
||||
import { FlameParticles } from "./FlameParticles";
|
||||
import { Controls } from '../App'
|
||||
import { BallCollider, RigidBody, useRapier } from '@react-three/rapier'
|
||||
import { useKeyboardControls, PerspectiveCamera, ContactShadows, Sphere, OrbitControls, Trail, PositionalAudio } from '@react-three/drei'
|
||||
import { useFrame, useThree } from '@react-three/fiber'
|
||||
import { useRef, useState, useEffect, useCallback } from 'react'
|
||||
import * as THREE from 'three'
|
||||
import { Model } from './models/Racing_kart'
|
||||
import { FrontRightWheel } from './models/Front_Right_Wheel'
|
||||
import { FrontLeftWheel } from './models/Front_Left_Wheel'
|
||||
import { RearWheels } from './models/Rear_wheels'
|
||||
import gsap from 'gsap'
|
||||
import { Mario } from './models/Mario_kart'
|
||||
import { Particles1 } from './Particles1'
|
||||
import { DriftParticlesLeft } from './DriftParticlesLeft'
|
||||
import { DriftParticlesRight } from './DriftParticlesRight'
|
||||
import FakeGlowMaterial from './FakeGlow/FakeGlowMaterial'
|
||||
import { PointParticle } from './PointParticle'
|
||||
import { FlameParticle } from './FlameParticle'
|
||||
import { FlameParticles } from './FlameParticles'
|
||||
|
||||
export const PlayerController = () => {
|
||||
const upPressed = useKeyboardControls((state) => state[Controls.up]);
|
||||
const downPressed = useKeyboardControls((state) => state[Controls.down]);
|
||||
const leftPressed = useKeyboardControls((state) => state[Controls.left]);
|
||||
const rightPressed = useKeyboardControls((state) => state[Controls.right]);
|
||||
const jumpPressed = useKeyboardControls((state) => state[Controls.jump]);
|
||||
const [isOnGround, setIsOnGround] = useState(false);
|
||||
const body = useRef();
|
||||
const kart = useRef();
|
||||
const cam = useRef();
|
||||
const initialSpeed = 0;
|
||||
const maxSpeed = 30;
|
||||
const boostSpeed = 50;
|
||||
const acceleration = 0.1;
|
||||
const decceleration = 0.2;
|
||||
const damping = -0.1;
|
||||
const MaxSteeringSpeed = 0.01;
|
||||
const [currentSteeringSpeed, setCurrentSteeringSpeed] = useState(0);
|
||||
const [currentSpeed, setCurrentSpeed] = useState(initialSpeed);
|
||||
const camMaxOffset = 1;
|
||||
let steeringAngle = 0;
|
||||
const isOnFloor = useRef(false);
|
||||
const jumpForce = useRef(0);
|
||||
const jumpIsHeld = useRef(false);
|
||||
const driftDirection = useRef(0);
|
||||
const driftLeft = useRef(false);
|
||||
const driftRight = useRef(false);
|
||||
const driftForce = useRef(0);
|
||||
const mario = useRef();
|
||||
const accumulatedDriftPower = useRef(0);
|
||||
const blueTurboThreshold = 10;
|
||||
const orangeTurboThreshold = 30;
|
||||
const purpleTurboThreshold = 60;
|
||||
const [turboColor, setTurboColor] = useState(0xffffff);
|
||||
const boostDuration = useRef(0);
|
||||
const [isBoosting, setIsBoosting] = useState(false);
|
||||
let targetXPosition = 0;
|
||||
let targetZPosition = 8;
|
||||
const [steeringAngleWheels, setSteeringAngleWheels] = useState(0);
|
||||
const engineSound = useRef();
|
||||
const upPressed = useKeyboardControls((state) => state[Controls.up])
|
||||
const downPressed = useKeyboardControls((state) => state[Controls.down])
|
||||
const leftPressed = useKeyboardControls((state) => state[Controls.left])
|
||||
const rightPressed = useKeyboardControls((state) => state[Controls.right])
|
||||
const jumpPressed = useKeyboardControls((state) => state[Controls.jump])
|
||||
const [isOnGround, setIsOnGround] = useState(false)
|
||||
const body = useRef()
|
||||
const kart = useRef()
|
||||
const cam = useRef()
|
||||
const initialSpeed = 0
|
||||
const maxSpeed = 30
|
||||
const boostSpeed = 50
|
||||
const acceleration = 0.1
|
||||
const decceleration = 0.2
|
||||
const damping = -0.1
|
||||
const MaxSteeringSpeed = 0.01
|
||||
const [currentSteeringSpeed, setCurrentSteeringSpeed] = useState(0)
|
||||
const [currentSpeed, setCurrentSpeed] = useState(initialSpeed)
|
||||
const camMaxOffset = 1
|
||||
let steeringAngle = 0
|
||||
const isOnFloor = useRef(false)
|
||||
const jumpForce = useRef(0)
|
||||
const jumpIsHeld = useRef(false)
|
||||
const driftDirection = useRef(0)
|
||||
const driftLeft = useRef(false)
|
||||
const driftRight = useRef(false)
|
||||
const driftForce = useRef(0)
|
||||
const mario = useRef()
|
||||
const accumulatedDriftPower = useRef(0)
|
||||
const blueTurboThreshold = 10
|
||||
const orangeTurboThreshold = 30
|
||||
const purpleTurboThreshold = 60
|
||||
const [turboColor, setTurboColor] = useState(0xffffff)
|
||||
const boostDuration = useRef(0)
|
||||
const [isBoosting, setIsBoosting] = useState(false)
|
||||
let targetXPosition = 0
|
||||
let targetZPosition = 8
|
||||
const [steeringAngleWheels, setSteeringAngleWheels] = useState(0)
|
||||
const engineSound = useRef()
|
||||
|
||||
const [scale, setScale] = useState(0);
|
||||
const [scale, setScale] = useState(0)
|
||||
|
||||
useFrame(({ pointer, clock }, delta) => {
|
||||
const time = clock.getElapsedTime();
|
||||
if (!body.current && !mario.current) return;
|
||||
const time = clock.getElapsedTime()
|
||||
if (!body.current && !mario.current) return
|
||||
|
||||
// HANDLING AND STEERING
|
||||
const kartRotation =
|
||||
kart.current.rotation.y - driftDirection.current * driftForce.current;
|
||||
const forwardDirection = new THREE.Vector3(
|
||||
-Math.sin(kartRotation),
|
||||
0,
|
||||
-Math.cos(kartRotation)
|
||||
);
|
||||
const kartRotation = kart.current.rotation.y - driftDirection.current * driftForce.current
|
||||
const forwardDirection = new THREE.Vector3(-Math.sin(kartRotation), 0, -Math.cos(kartRotation))
|
||||
|
||||
if (leftPressed && currentSpeed > 0) {
|
||||
steeringAngle = currentSteeringSpeed;
|
||||
targetXPosition = -camMaxOffset;
|
||||
steeringAngle = currentSteeringSpeed
|
||||
targetXPosition = -camMaxOffset
|
||||
} else if (rightPressed && currentSpeed > 0) {
|
||||
steeringAngle = -currentSteeringSpeed;
|
||||
targetXPosition = camMaxOffset;
|
||||
steeringAngle = -currentSteeringSpeed
|
||||
targetXPosition = camMaxOffset
|
||||
} else {
|
||||
steeringAngle = 0;
|
||||
targetXPosition = 0;
|
||||
1;
|
||||
steeringAngle = 0
|
||||
targetXPosition = 0
|
||||
1
|
||||
}
|
||||
|
||||
// mouse steering
|
||||
|
||||
|
||||
if(!driftLeft.current && !driftRight.current){
|
||||
steeringAngle = currentSteeringSpeed * -pointer.x;
|
||||
targetXPosition = -camMaxOffset * -pointer.x;
|
||||
}
|
||||
|
||||
else if (driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(pointer.x - 0.5);
|
||||
targetXPosition = -camMaxOffset * -pointer.x;
|
||||
}
|
||||
else if (driftRight.current && !driftLeft.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(pointer.x + 0.5);
|
||||
targetXPosition = -camMaxOffset * -pointer.x;
|
||||
if (!driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -pointer.x
|
||||
targetXPosition = -camMaxOffset * -pointer.x
|
||||
} else if (driftLeft.current && !driftRight.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(pointer.x - 0.5)
|
||||
targetXPosition = -camMaxOffset * -pointer.x
|
||||
} else if (driftRight.current && !driftLeft.current) {
|
||||
steeringAngle = currentSteeringSpeed * -(pointer.x + 0.5)
|
||||
targetXPosition = -camMaxOffset * -pointer.x
|
||||
}
|
||||
// ACCELERATING
|
||||
|
||||
if (upPressed && currentSpeed < maxSpeed) {
|
||||
// Accelerate the kart within the maximum speed limit
|
||||
setCurrentSpeed(Math.min(currentSpeed + acceleration * delta * 144, maxSpeed));
|
||||
} else if (
|
||||
upPressed &&
|
||||
currentSpeed > maxSpeed &&
|
||||
boostDuration.current > 0
|
||||
) {
|
||||
setCurrentSpeed(Math.max(currentSpeed - decceleration * delta * 144, maxSpeed));
|
||||
setCurrentSpeed(Math.min(currentSpeed + acceleration * delta * 144, maxSpeed))
|
||||
} else if (upPressed && currentSpeed > maxSpeed && boostDuration.current > 0) {
|
||||
setCurrentSpeed(Math.max(currentSpeed - decceleration * delta * 144, maxSpeed))
|
||||
}
|
||||
|
||||
if (upPressed) {
|
||||
if (currentSteeringSpeed < MaxSteeringSpeed) {
|
||||
setCurrentSteeringSpeed(
|
||||
Math.min(currentSteeringSpeed + 0.0001 * delta * 144, MaxSteeringSpeed)
|
||||
);
|
||||
setCurrentSteeringSpeed(Math.min(currentSteeringSpeed + 0.0001 * delta * 144, MaxSteeringSpeed))
|
||||
}
|
||||
}
|
||||
// REVERSING
|
||||
if (downPressed && currentSpeed < -maxSpeed) {
|
||||
setCurrentSpeed(Math.max(currentSpeed - acceleration * delta * 144, -maxSpeed));
|
||||
setCurrentSpeed(Math.max(currentSpeed - acceleration * delta * 144, -maxSpeed))
|
||||
}
|
||||
// DECELERATING
|
||||
else if (!upPressed && !downPressed) {
|
||||
if (currentSteeringSpeed > 0) {
|
||||
setCurrentSteeringSpeed(Math.max(currentSteeringSpeed - 0.00005 * delta * 144, 0));
|
||||
setCurrentSteeringSpeed(Math.max(currentSteeringSpeed - 0.00005 * delta * 144, 0))
|
||||
} else if (currentSteeringSpeed < 0) {
|
||||
setCurrentSteeringSpeed(Math.min(currentSteeringSpeed + 0.00005 * delta * 144, 0));
|
||||
setCurrentSteeringSpeed(Math.min(currentSteeringSpeed + 0.00005 * delta * 144, 0))
|
||||
}
|
||||
setCurrentSpeed(Math.max(currentSpeed - decceleration * delta * 144, 0));
|
||||
setCurrentSpeed(Math.max(currentSpeed - decceleration * delta * 144, 0))
|
||||
}
|
||||
|
||||
// Update the kart's rotation based on the steering angle
|
||||
kart.current.rotation.y += steeringAngle * delta * 144;
|
||||
kart.current.rotation.y += steeringAngle * delta * 144
|
||||
|
||||
// Apply damping to simulate slowdown when no keys are pressed
|
||||
body.current.applyImpulse(
|
||||
{
|
||||
x: -body.current.linvel().x * (1 - damping) * delta * 144,
|
||||
y: 0,
|
||||
z: -body.current.linvel().z * (1 - damping) * delta * 144,
|
||||
z: -body.current.linvel().z * (1 - damping) * delta * 144
|
||||
},
|
||||
true
|
||||
);
|
||||
const bodyPosition = body.current.translation();
|
||||
kart.current.position.set(
|
||||
bodyPosition.x,
|
||||
bodyPosition.y - 0.5,
|
||||
bodyPosition.z
|
||||
);
|
||||
)
|
||||
const bodyPosition = body.current.translation()
|
||||
kart.current.position.set(bodyPosition.x, bodyPosition.y - 0.5, bodyPosition.z)
|
||||
|
||||
// JUMPING
|
||||
if (jumpPressed && isOnFloor.current && !jumpIsHeld.current) {
|
||||
jumpForce.current += 10 ;
|
||||
isOnFloor.current = false;
|
||||
jumpIsHeld.current = true;
|
||||
jumpForce.current += 10
|
||||
isOnFloor.current = false
|
||||
jumpIsHeld.current = true
|
||||
}
|
||||
|
||||
if (!isOnFloor.current && jumpForce.current > 0) {
|
||||
jumpForce.current -= 1 * delta * 144;
|
||||
jumpForce.current -= 1 * delta * 144
|
||||
}
|
||||
if (!jumpPressed) {
|
||||
jumpIsHeld.current = false;
|
||||
driftDirection.current = 0;
|
||||
driftForce.current = 0;
|
||||
driftLeft.current = false;
|
||||
driftRight.current = false;
|
||||
jumpIsHeld.current = false
|
||||
driftDirection.current = 0
|
||||
driftForce.current = 0
|
||||
driftLeft.current = false
|
||||
driftRight.current = false
|
||||
}
|
||||
// DRIFTING
|
||||
if (
|
||||
jumpIsHeld.current &&
|
||||
currentSteeringSpeed > 0 &&
|
||||
pointer.x < -0.1 &&
|
||||
!driftRight.current
|
||||
) {
|
||||
driftLeft.current = true;
|
||||
if (jumpIsHeld.current && currentSteeringSpeed > 0 && pointer.x < -0.1 && !driftRight.current) {
|
||||
driftLeft.current = true
|
||||
}
|
||||
if (
|
||||
jumpIsHeld.current &&
|
||||
currentSteeringSpeed > 0 &&
|
||||
pointer.x > 0.1 &&
|
||||
!driftLeft.current
|
||||
) {
|
||||
driftRight.current = true;
|
||||
if (jumpIsHeld.current && currentSteeringSpeed > 0 && pointer.x > 0.1 && !driftLeft.current) {
|
||||
driftRight.current = true
|
||||
}
|
||||
|
||||
if (!jumpIsHeld.current && !driftLeft.current && !driftRight.current) {
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(
|
||||
mario.current.rotation.y,
|
||||
0,
|
||||
0.0001 * delta * 144
|
||||
);
|
||||
setTurboColor(0xffffff);
|
||||
accumulatedDriftPower.current = 0;
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(mario.current.rotation.y, 0, 0.0001 * delta * 144)
|
||||
setTurboColor(0xffffff)
|
||||
accumulatedDriftPower.current = 0
|
||||
}
|
||||
|
||||
if (driftLeft.current) {
|
||||
driftDirection.current = 1;
|
||||
driftForce.current = 0.4;
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(
|
||||
mario.current.rotation.y,
|
||||
steeringAngle * 50 + 0.5,
|
||||
0.05 * delta * 144
|
||||
);
|
||||
accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144;
|
||||
driftDirection.current = 1
|
||||
driftForce.current = 0.4
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(mario.current.rotation.y, steeringAngle * 50 + 0.5, 0.05 * delta * 144)
|
||||
accumulatedDriftPower.current += 0.1 * (steeringAngle + 1) * delta * 144
|
||||
}
|
||||
if (driftRight.current) {
|
||||
driftDirection.current = -1;
|
||||
driftForce.current = 0.4;
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(
|
||||
mario.current.rotation.y,
|
||||
-(-steeringAngle * 50 + 0.5),
|
||||
0.05 * delta * 144
|
||||
);
|
||||
accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144 ;
|
||||
driftDirection.current = -1
|
||||
driftForce.current = 0.4
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(mario.current.rotation.y, -(-steeringAngle * 50 + 0.5), 0.05 * delta * 144)
|
||||
accumulatedDriftPower.current += 0.1 * (-steeringAngle + 1) * delta * 144
|
||||
}
|
||||
if (!driftLeft.current && !driftRight.current) {
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(
|
||||
mario.current.rotation.y,
|
||||
steeringAngle * 30,
|
||||
0.05 * delta * 144
|
||||
);
|
||||
setScale(0);
|
||||
mario.current.rotation.y = THREE.MathUtils.lerp(mario.current.rotation.y, steeringAngle * 30, 0.05 * delta * 144)
|
||||
setScale(0)
|
||||
}
|
||||
if (accumulatedDriftPower.current > blueTurboThreshold) {
|
||||
setTurboColor(0x00ffff);
|
||||
boostDuration.current = 50;
|
||||
setTurboColor(0x00ffff)
|
||||
boostDuration.current = 50
|
||||
}
|
||||
if (accumulatedDriftPower.current > orangeTurboThreshold) {
|
||||
setTurboColor(0xffcf00);
|
||||
boostDuration.current = 100;
|
||||
setTurboColor(0xffcf00)
|
||||
boostDuration.current = 100
|
||||
}
|
||||
if (accumulatedDriftPower.current > purpleTurboThreshold) {
|
||||
setTurboColor(0xff00ff);
|
||||
boostDuration.current = 250;
|
||||
setTurboColor(0xff00ff)
|
||||
boostDuration.current = 250
|
||||
}
|
||||
|
||||
if (driftLeft.current || driftRight.current) {
|
||||
const oscillation = Math.sin(time * 1000) * 0.1 ;
|
||||
|
||||
const vibration = oscillation + 0.9;
|
||||
const oscillation = Math.sin(time * 1000) * 0.1
|
||||
|
||||
if (turboColor === 0xffffff) {
|
||||
setScale(vibration * 0.8);
|
||||
setScale(vibration * 0.8)
|
||||
} else {
|
||||
setScale(vibration);
|
||||
setScale(vibration)
|
||||
}
|
||||
}
|
||||
// RELEASING DRIFT
|
||||
|
||||
if (boostDuration.current > 1 && !jumpIsHeld.current) {
|
||||
setCurrentSpeed(boostSpeed);
|
||||
boostDuration.current -= 1 * delta * 144;
|
||||
targetZPosition = 10;
|
||||
setIsBoosting(true);
|
||||
} else if (boostDuration.current <= 1 ) {
|
||||
targetZPosition = 8;
|
||||
setIsBoosting(false);
|
||||
setCurrentSpeed(boostSpeed)
|
||||
boostDuration.current -= 1 * delta * 144
|
||||
targetZPosition = 10
|
||||
setIsBoosting(true)
|
||||
} else if (boostDuration.current <= 1) {
|
||||
targetZPosition = 8
|
||||
setIsBoosting(false)
|
||||
}
|
||||
|
||||
// CAMERA WORK
|
||||
|
||||
cam.current.updateMatrixWorld();
|
||||
cam.current.updateMatrixWorld()
|
||||
|
||||
cam.current.position.x = THREE.MathUtils.lerp(
|
||||
cam.current.position.x,
|
||||
targetXPosition,
|
||||
0.01 * delta * 144
|
||||
);
|
||||
cam.current.position.x = THREE.MathUtils.lerp(cam.current.position.x, targetXPosition, 0.01 * delta * 144)
|
||||
|
||||
cam.current.position.z = THREE.MathUtils.lerp(
|
||||
cam.current.position.z,
|
||||
targetZPosition,
|
||||
0.01 * delta * 144
|
||||
);
|
||||
cam.current.position.z = THREE.MathUtils.lerp(cam.current.position.z, targetZPosition, 0.01 * delta * 144)
|
||||
|
||||
body.current.applyImpulse(
|
||||
{
|
||||
x: forwardDirection.x * currentSpeed * delta * 144,
|
||||
y: 0 + jumpForce.current * delta * 144,
|
||||
z: forwardDirection.z * currentSpeed * delta * 144,
|
||||
z: forwardDirection.z * currentSpeed * delta * 144
|
||||
},
|
||||
true
|
||||
);
|
||||
)
|
||||
|
||||
// Update the kart's rotation based on the steering angle
|
||||
setSteeringAngleWheels(steeringAngle * 25);
|
||||
setSteeringAngleWheels(steeringAngle * 25)
|
||||
|
||||
// SOUND WORK
|
||||
|
||||
|
||||
console.log(body.current.translation())
|
||||
});
|
||||
// console.log(body.current.translation())
|
||||
})
|
||||
|
||||
return (
|
||||
<group>
|
||||
|
@ -319,16 +255,19 @@ export const PlayerController = () => {
|
|||
args={[0.5]}
|
||||
mass={3}
|
||||
onCollisionEnter={(event) => {
|
||||
isOnFloor.current = true;
|
||||
isOnFloor.current = true
|
||||
}}
|
||||
/>
|
||||
onCollisionEnter=
|
||||
{(event) => {
|
||||
isOnFloor.current = false;
|
||||
isOnFloor.current = false
|
||||
}}
|
||||
</RigidBody>
|
||||
|
||||
<group ref={kart} rotation={[0, Math.PI / 2, 0]}>
|
||||
<group
|
||||
ref={kart}
|
||||
rotation={[0, Math.PI / 2, 0]}
|
||||
>
|
||||
<group ref={mario}>
|
||||
<Mario
|
||||
currentSpeed={currentSpeed}
|
||||
|
@ -341,7 +280,10 @@ export const PlayerController = () => {
|
|||
distance={1}
|
||||
/>
|
||||
|
||||
<mesh position={[0.6, 0.05, 0.5]} scale={scale}>
|
||||
<mesh
|
||||
position={[0.6, 0.05, 0.5]}
|
||||
scale={scale}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
emissive={turboColor}
|
||||
|
@ -357,7 +299,10 @@ export const PlayerController = () => {
|
|||
color={turboColor}
|
||||
distance={1}
|
||||
/>
|
||||
<mesh position={[-0.6, 0.05, 0.5]} scale={scale}>
|
||||
<mesh
|
||||
position={[-0.6, 0.05, 0.5]}
|
||||
scale={scale}
|
||||
>
|
||||
<sphereGeometry args={[0.1, 16, 16]} />
|
||||
<meshStandardMaterial
|
||||
emissive={turboColor}
|
||||
|
@ -368,13 +313,35 @@ export const PlayerController = () => {
|
|||
/>
|
||||
</mesh>
|
||||
{/* <Flame/> */}
|
||||
<FlameParticles isBoosting={isBoosting}/>
|
||||
<DriftParticlesLeft turboColor={turboColor} scale={scale} />
|
||||
<DriftParticlesRight turboColor={turboColor} scale={scale} />
|
||||
<PointParticle position={[-0.6, 0.05, 0.5]} png="./circle.png" turboColor={turboColor}/>
|
||||
<PointParticle position={[0.6, 0.05, 0.5]} png="./circle.png" turboColor={turboColor}/>
|
||||
<PointParticle position={[-0.6, 0.05, 0.5]} png="./star.png" turboColor={turboColor}/>
|
||||
<PointParticle position={[0.6, 0.05, 0.5]} png="./star.png" turboColor={turboColor}/>
|
||||
<FlameParticles isBoosting={isBoosting} />
|
||||
<DriftParticlesLeft
|
||||
turboColor={turboColor}
|
||||
scale={scale}
|
||||
/>
|
||||
<DriftParticlesRight
|
||||
turboColor={turboColor}
|
||||
scale={scale}
|
||||
/>
|
||||
<PointParticle
|
||||
position={[-0.6, 0.05, 0.5]}
|
||||
png='./circle.png'
|
||||
turboColor={turboColor}
|
||||
/>
|
||||
<PointParticle
|
||||
position={[0.6, 0.05, 0.5]}
|
||||
png='./circle.png'
|
||||
turboColor={turboColor}
|
||||
/>
|
||||
<PointParticle
|
||||
position={[-0.6, 0.05, 0.5]}
|
||||
png='./star.png'
|
||||
turboColor={turboColor}
|
||||
/>
|
||||
<PointParticle
|
||||
position={[0.6, 0.05, 0.5]}
|
||||
png='./star.png'
|
||||
turboColor={turboColor}
|
||||
/>
|
||||
</group>
|
||||
|
||||
{/* <ContactShadows frames={1} /> */}
|
||||
|
@ -385,8 +352,7 @@ export const PlayerController = () => {
|
|||
ref={cam}
|
||||
/>
|
||||
{/* <PositionalAudio ref={engineSound} url="./sounds/engine.wav" autoplay loop distance={10}/> */}
|
||||
|
||||
</group>
|
||||
</group>
|
||||
);
|
||||
};
|
||||
)
|
||||
}
|
||||
|
|
|
@ -4,10 +4,12 @@ Command: npx gltfjsx@6.2.16 .\mariokarttest.glb --shadows
|
|||
*/
|
||||
|
||||
import React, { useRef } from 'react'
|
||||
import { useGLTF } from '@react-three/drei'
|
||||
import { Cylinder, OrbitControls, Sphere, useGLTF } from '@react-three/drei'
|
||||
import { useFrame } from '@react-three/fiber'
|
||||
import FakeGlowMaterial from '../FakeGlow/FakeGlowMaterial'
|
||||
import FakeFlame from '../FakeFlame/FakeFlame'
|
||||
|
||||
export function Mario({currentSpeed, steeringAngleWheels, ...props}) {
|
||||
export function Mario({ currentSpeed, steeringAngleWheels, ...props }) {
|
||||
const { nodes, materials } = useGLTF('./models/mariokarttest.glb')
|
||||
|
||||
const frontLeftWheel = useRef()
|
||||
|
@ -21,17 +23,75 @@ export function Mario({currentSpeed, steeringAngleWheels, ...props}) {
|
|||
frontRightWheel.current.rotation.x += rotation
|
||||
rearWheels.current.rotation.x += rotation
|
||||
frontWheels.current.rotation.y = steeringAngleWheels
|
||||
|
||||
})
|
||||
return (
|
||||
<group {...props} rotation={[0, Math.PI, 0]} dispose={null}>
|
||||
<mesh castShadow receiveShadow geometry={nodes.mt_kart_Mario_S.geometry} material={materials.mt_kart_Mario_S} />
|
||||
<mesh ref={rearWheels} castShadow receiveShadow geometry={nodes.mt_Kart_Mario_Tire_S001.geometry} material={materials.mt_Kart_Mario_Tire_S} position={[0, 0.22, -0.347]} />
|
||||
<group ref={frontWheels} >
|
||||
<mesh ref={frontLeftWheel} castShadow receiveShadow geometry={nodes.mt_Kart_Mario_Tire_S002.geometry} material={materials.mt_Kart_Mario_Tire_S} position={[0.370, 0.193, 0.441]} />
|
||||
<mesh ref={frontRightWheel} castShadow receiveShadow geometry={nodes.mt_Kart_Mario_Tire_S003.geometry} material={materials.mt_Kart_Mario_Tire_S} position={[-0.370, 0.193, 0.441]} rotation={[-Math.PI, 0, 0]} scale={-1} />
|
||||
<group
|
||||
{...props}
|
||||
rotation={[0, Math.PI, 0]}
|
||||
dispose={null}
|
||||
>
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.mt_kart_Mario_S.geometry}
|
||||
material={materials.mt_kart_Mario_S}
|
||||
/>
|
||||
<mesh
|
||||
ref={rearWheels}
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.mt_Kart_Mario_Tire_S001.geometry}
|
||||
material={materials.mt_Kart_Mario_Tire_S}
|
||||
position={[0, 0.22, -0.347]}
|
||||
/>
|
||||
<group ref={frontWheels}>
|
||||
<mesh
|
||||
ref={frontLeftWheel}
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.mt_Kart_Mario_Tire_S002.geometry}
|
||||
material={materials.mt_Kart_Mario_Tire_S}
|
||||
position={[0.37, 0.193, 0.441]}
|
||||
/>
|
||||
<mesh
|
||||
ref={frontRightWheel}
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.mt_Kart_Mario_Tire_S003.geometry}
|
||||
material={materials.mt_Kart_Mario_Tire_S}
|
||||
position={[-0.37, 0.193, 0.441]}
|
||||
rotation={[-Math.PI, 0, 0]}
|
||||
scale={-1}
|
||||
/>
|
||||
</group>
|
||||
<mesh castShadow receiveShadow geometry={nodes.mt_mario.geometry} material={materials.mt_mario} />
|
||||
<mesh
|
||||
castShadow
|
||||
receiveShadow
|
||||
geometry={nodes.mt_mario.geometry}
|
||||
material={materials.mt_mario}
|
||||
/>
|
||||
<Sphere
|
||||
position={[0, 0.6, -1.2]}
|
||||
scale={1.2}
|
||||
>
|
||||
<FakeGlowMaterial />
|
||||
</Sphere>
|
||||
|
||||
<Cylinder
|
||||
args={[0.1, 0.5, 1, 128, 64, true]}
|
||||
position={[0.3, 0.6, -1.2]}
|
||||
rotation={[Math.PI / 1.5, 0, 0]}
|
||||
>
|
||||
<FakeFlame />
|
||||
</Cylinder>
|
||||
|
||||
<Cylinder
|
||||
args={[0.1, 0.5, 1, 128, 64, true]}
|
||||
position={[-0.3, 0.6, -1.2]}
|
||||
rotation={[Math.PI / 1.5, 0, 0]}
|
||||
>
|
||||
<FakeFlame />
|
||||
</Cylinder>
|
||||
</group>
|
||||
)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue