[LibGdx] Gravedad y salto

codek0rZ

Buenas, he tenido algo de tiempo estos días y he empezado a desarrollar un videojuego. Como soy novato en esto me he estoy basando en este proyecto https://github.com/libgdx/libgdx-demo-superjumper para mi propio Jumper.

El problema que tengo actualmente es que no consigo que me vaya igual de fluido que el ejemplo el tema de la gravedad y el salto. Aprecio como que cae muy despacio... no se si es paranoya mía...

Aquí os dejo el .jar del juego para que probeis (se salta con el espacio).
https://www.dropbox.com/s/isxpbb7tl5cr71s/LameJumper.jar?dl=0
La música puede resultar un poco molesta xd, podeis pausarla en el menu principal todo esto son pruebas que estoy haciendo jeje.

El código que utilizo para mi muñeco salte es el siguiente:

	public void update(float delta){
		velocity.add(World.gravity.x * delta, World.gravity.y * delta);
		position.add(velocity.x * delta, velocity.y * delta);
		bounds.x = position.x - bounds.width/2;	
		bounds.y = position.y - bounds.height/2;

	float accel = 0;
	if(Gdx.input.isKeyPressed(Keys.DPAD_RIGHT)) accel = WIDTH+(WIDTH/2);
	if(Gdx.input.isKeyPressed(Keys.DPAD_LEFT)) accel = -(WIDTH+(WIDTH/2));
	velocity.x = accel;
	
	
	if(Gdx.input.isKeyPressed(Keys.SPACE) && state != STATE_JUMP){
		jump();
	}

	if(position.y < 0){
		position.y = 0f;
		if(state == STATE_JUMP){
			state = STATE_STANDBY;
		}
	}
	if(position.x+WIDTH < 0) position.x = WorldRender.WIDTH;
	if(position.x > WorldRender.WIDTH) position.x = 0-WIDTH;
	
	stateTime += delta;
}
public void jump(){
	velocity.y = JUMP_VELOCITY;
	state = STATE_JUMP;
	stateTime = 0;
}
JUMP_VELOCITY = 120f;
public static final Vector2 gravity = new Vector2(0, -30f);

Creo que no me dejo nada referente al salto. Si de paso alguien puede explicarme para que es el "delta" o "deltaTime" lo agradezco. Me voy a sobar que ya esta bien por hoy jeje.

Saludos y gracias

YaW

#1 A mi me va todo lentisimo, tanto el salto como la caida.

Si lo que quieres hacer es que caiga con más velocidad (pero el salto no se vea afectado). La mejor solución es comprobar cuando el personaje ha empezado a caer (if velocity.x < 0) y aplicarle un multiplicador. Ej

public void update(float delta){

if(velocity.x < 0){
	//Aplicamos una caida más fuerte que la gravedad
	velocity.add(World.gravity.x * delta, World.gravity.y * delta * 2);
}else{
	//Aplicamos la gravedad normal para afectar en el salto
	velocity.add(World.gravity.x * delta, World.gravity.y * delta);
}

Sobre el deltaTime. El deltaTime te indica el tiempo que ha tardado en ejecutarse el último frame (si tu juego va a 60fps pues el valor del deltaTime será 1/60). Normalmente este valor se aplica a los modificadores de posición y demás para que la modificación sea estable sea como sean los fps del terminal donde estés jugando. Es decir que el personaje siempre salte la misma cantidad por ejemplo independiemente de si juegas en un terminal moderno donde va a 60fps o si juegas en uno viejuno donde va a 20.

1 respuesta
codek0rZ

#2 Gracias por responder. Bien ahora si conseguí que me baje algo más fluido, pero al saltar parece que este en el espacio hasta que llega al límite de salto y empieza a bajar xd.

No entiendo muy bien porque, si en el ejemplo que seguí usa valores más bajos tanto para la gravedad como para el salto y le va super fluido. ¿Las porporciones de las imágenes afectan a este tipo de cosas? Supongo que sí ¿no? cuánto más grande sea el cuerpo más gravedad tendré que aplicar ¿o como va exactamente?

edit: y otra pregunta, el ejemplo que seguí que puse arriba, cuando asigna valores para el alto y ancho del personaje principal en la clase de esta (Bob.java https://github.com/libgdx/libgdx-demo-superjumper/blob/master/core/src/com/badlogicgames/superjumper/Bob.java ) pone 0.8f a ambos.

¿Por qué este tamaño si la imagen que usa no mide eso? ¿Hago bien usando los valores reales (en px) de mis imágenes?

1 respuesta
YaW

#3 hay dos cosas a tener en cuenta, por un lado tienes el tamaño de la representación del personaje (el sprite vamos) y por otro lado tienes el tamaño del personaje en el mundo de las físicas. Normalmente los dos valores están correlacionados pero no son lo mismo.

No se si el ejemplo que has cogido de base usa Box2d o no, pero si lo usa es normal que el valor que ves de 0.8f no sea los pixeles de la imagen si no lo que mide el cubo que representa el personaje. Has probado a usar esos valores a ver como te reacciona?

1 respuesta
codek0rZ

Hmm gracias por responder de nuevo #4 . He estado buscando sobre como establecer estos valores y no encuentro ningún tutorial para saber como se correlacionan, aunque me sigue pareciendo poco 0.8 el muñeco ¿que pasa que simplemente hace el mundo "imaginariamente" a escala más pequeña para las físicas?
si puedes pasarme algun enlace sobre esto... porque no encuentro nada para orientarme sobre los tamaños y eso.

Gracias y saludos

1 respuesta
YaW

#5 http://www.emanueleferonato.com/2008/11/17/understanding-pixels-and-meters-with-box2d-and-how-to-select-an-object-with-mouse-part-2/

http://box2d.org/2011/12/pixels/

http://www.box2d.org/manual.html (1.7 Units)

codek0rZ

Vale, he estado leyendo sobre ello, también sobre Box2D que no conocía jeje. Pero aún tengo la duda de... la constante a utilizar (es decir, por lo que dividire cada medida en pixeles) he visto que en cada sitio utilizan una diferente, en el ejemplo que estaba fijandome divide todo entre 32 para obtener las medidas del mundo de las físicas. ¿Puedo utilizar cualquiera? ¿Según uno de los post que me pasastes en primer lugar recomiendan 30. Utilizaré esta supongo ¿o hay que basarse en alguna medida en pixel, como parece que hace el ejemplo que puse?

Porque su tamaño es 320x480 y dive todo entre 32.

1 respuesta
cabron

#7

Si te decides a usar box2d no uses jamás el deltatime, los motores de física usan un integrador que se vuelve loco si le pasas cada vez un tiempo distinto para la simulación.

Y sobre el tema de la relación en píxeles y el mundo físico, no está mal entender como funciona para saber que leches estás haciendo, pero con libgdx es tan sencillo como crear un viewport así:

private final float WORLD_WIDTH = 20;
private final float WORLD_HEIGHT = 10f;

OrthographicCamera camera = new OrthographicCamera();
ScalingViewport viewport = new ScalingViewport(Scaling.stretch, WORLD_WIDTH, WORLD_HEIGHT, camera);
viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);

Donde height y width es la parte de tu mundo en METROS que quieres que sea visible. Una vez hagas eso le das a tus sprites el tamaño en metros que quieres que tengan, y aparecerán siempre con el tamaño correcto sin importar la resolución.

La única desventaja de esto es que en pantallas con diferente aspect ratio puede que se te aplasten un poco los sprites, pero las proporciones serán siempre las mismas. Las alternativas son usar un aspect ratio fijo y mostrar barras negras en lo que sobre de pantalla o mostrar más o menos partes del mundo en diferentes pantallas con diferente aspect ratio, lo tienes documentado aquí:

https://github.com/libgdx/libgdx/wiki/Viewports

1 respuesta
sasher

#8 "Si te decides a usar box2d no uses jamás el deltatime, los motores de física usan un integrador que se vuelve loco si le pasas cada vez un tiempo distinto para la simulación."
Esa afirmación es únicamente válida para box2d no? porque con Bullet por ejemplo yo he usado delta time en un juego serio con Ogre3D y no he tenido ningún problema.

1 respuesta
cabron

#9

Es para todos, ya que tiene que ver con las matemáticas que se usan en el integrador, puedes ver más detalles aquí:

http://gafferongames.com/game-physics/fix-your-timestep/

No conozco bullet, pero mirando un poco como funciona aquí: http://www.bulletphysics.org/mediawiki-1.5.8/index.php/Stepping_The_World

No usa el deltatime realmente, si no que hace lo mismo que explican en el enlace que te he puesto,
basándose en el deltatime hace más o menos incrementos en la simulación en cada frame.

1 respuesta
sasher

#10 Vale ahora te sigo; no recordaba lo del stepSimulation, tienes razón.

Usuarios habituales

  • sasher
  • cabron
  • codek0rZ
  • YaW

Tags