Estoy tratando de implementar un efecto de gravedad en las imágenes de cookies. La idea era que tuvieran una aceleración y una velocidad iniciales mientras eran atraídos por la fuerza gravitacional al mismo tiempo. Usé setInterval para actualizar las cookies cada 1/60 de segundo para lograr 60 FPS (¿Es este el enfoque común? Dado que en la mayoría de los juegos FPS fluctúa, asumo que debe hacerse de manera diferente, pero no sé cómo). Aquí está mi código:
import './App.css'; import cookie from '../src/images/cookie.png'; import { Vector } from './Physics'; import { useEffect, useState } from 'react'; const GRAVITY = 1; function App() { const initCookieProps = () => { let cookiesProps = []; for(let i = 0; i < 1; i++){ let cookieProps = {}; cookieProps['pos'] = new Vector(0,0); cookieProps['acceleration'] = new Vector(0, GRAVITY); cookieProps['velocity'] = new Vector(10, 0); cookiesProps.push(cookieProps); } return cookiesProps; } const [cookiesProps, setCookiesProps] = useState(() => { const initialState = initCookieProps(); return initialState; }) const updateCookies = (delta) => { setCookiesProps(cookiesProps.map(cookieProps => { cookieProps['velocity'] = cookieProps['velocity'].add(cookieProps['acceleration'].multiply(delta)); cookieProps['pos'] = cookieProps['pos'].add(cookieProps['velocity'].multiply(delta)); return cookieProps; })); } useEffect(() => { setInterval(() => { updateCookies(1/60); }, 1000/60); }, []) return ( <div className="content"> {cookiesProps.map( props => <img className="cookie" style={{left: props['pos'].x, top: props['pos'].y}} src={cookie} alt="cookie"/>)} </div> ); } export default App;Perdí muchas horas tratando de implementar la Física correcta. No estoy seguro de si es correcto la forma en que lo estoy haciendo en este momento. Con el código especificado logré aumentar la velocidad en la dirección y en 1, y la posición en la dirección x en 10 cada segundo. Entonces creo que es correcto? Agradecería cualquier ayuda. ¿Esto también funcionaría si las cookies no solo se aceleran horizontalmente?
Physics.js se ve así:
export function Vector(x,y){ this.x = x; this.y = y; } Vector.prototype.normalize = function() { const abs = Math.sqrt(this.x*this.x+this.y*this.y); return new Vector(this.x/abs, this.y/abs); } Vector.prototype.add = function(other) { return new Vector(this.x+other.x,this.y+other.y); } Vector.prototype.multiply = function(scalar){ return new Vector(this.x*scalar,this.y*scalar); } Vector.prototype.subtract = function (other){ return new Vector(this.x-other.x,this.y-other.y); }¡Espero que alguien pueda ayudarme, pueda aprobar que se hace bien, o tal vez darme consejos sobre cómo hacerlo mejor!
Como JavaScript es de subproceso único y utiliza un bucle de eventos, no se garantiza el retraso del temporizador. En su lugar, debe utilizar un enfoque de tiempo delta :
class DeltaTimer { constructor(func, delay) { this.func = func; this.delay = delay; } start() { this.lastTime = Date.now(); this.timeout = setTimeout(this.loop.bind(this), this.delay); } stop() { if (this.timeout) { clearTimeout(this.timeout); } } loop() { const now = Date.now(); const delta = now - lastTime; this.func(delta); this.lastTime = now; this.timeout = setTimeout(this.loop.bind(this), this.delay); } }