Page 1 of 1

A tortas con las colisiones

Posted: Fri Mar 11, 2022 7:26 am
by droman
Acabo de hacerme un ejemplito para colisionar con un mapa que tiene unas plataformas. En principio, he creado los Colliders de esta manera:

Code: Select all

	// Fondo es un sprite que contiene el mapa de plataformas. Un png simple con transparencia.
	
	fondo.setCollsision(true);			// Activamos las colisiones
	fondo.SetCollisionRect(0,368,640,272);		// Creamos el collider principal que no tiene el tamaño completo del sprite, es solo el suelo.
	fondo.AddColliderRect(80,320,47,15);		// Creamos el collider para la plataforma 1 que está por encima del suelo.
	fondo.AddColliderRect(160,320,144,15);		// Creamos el collider para la plataforma 2 que está por encima del suelo.

Se supone, según entiendo, que con SETCOLLISIONRECT estoy haciendo un bloque sobre la parte del suelo y efectivamente, al tener el DEBUG activado, se ve el recuadro amarillo, las otras ordenes son para generar las colisiones con las dos plataformas y también tienen su recuadro amarillo correspondiente... pero no colisionan. Cuando testeo la colisión, sólo me devuelve TRUE al colisionar con el recuadro correspondiente al SETCOLLISIONRECT, los demás los ignora.

Al principio pensé que podía ser por activar las colisiones antes de crear los colliders, pero he comprobado que pasa lo mismo si activo al final.

¿Que se me escapa?

Gracias :)

Re: A tortas con las colisiones

Posted: Fri Mar 11, 2022 10:22 pm
by droman
Bueno... voy controlando un poco más... explico como lo he realizado, por si a alguien más le sirve (no sé si es la forma correcta, pero funciona)

Dentro del fichero STAGE.PI tengo declarado un Sprite que actúa de plataformas y los colliders declarados así:

Code: Select all


		// Cargamos las plataformas.
		bg_level = app.NewSprite("plataformas");
		bg_level.AddFrame(GRAPHICS + "platforms.png");
		bg_level.setPriority(1);

		// Activamos las colisiones
		bg_level.SetCollision(true);
		bg_level.SetCollisionRect(0,368,640,272);
		bg_level.AddColliderRect(40,40,200,150);
		bg_level.AddColliderRect(80,320,47,15);
		bg_level.AddColliderRect(160,320,144,15);

Luego, en el PLAYER.PI tengo el personaje declarado y preparado para detectar colisiones:

Code: Select all


		player.setCollision(true);
		player.setColliderMode(true);
		player.setUserSpriteCollision(this,"OnSpriteCollision");

		...
		
						
		function OnSpriteCollision(_spr1, _spr2)
		{
			if(_spr1.GetColliderTouched())      // Ha colisionado con un collider adicional (AddColliderRect)
			{
				_spr1.SetColor(RGB(255,0,0));
				app.Collision.setText("Colision con Collider Adicional");
			}
			else		// Ha colisionado con el collider principal (SetColliderRect)
			{
				_spr1.SetColor(RGB(255,0,0));
				app.Collision.setText("Colision con Collider Principal");
			}
		}
		
		function OnMovePlayer(_controller)
		{
			if(!player.isColliding())
			{
				player.setColor(RGB(255,255,255));  //No está colisionando con nada.
				app.Collision.setText("No hay colisiones");
			}
			...	
		}
		


Esto funciona perfectamente :)

Ahora me surge una duda... Yo en el OnMovePlayer que es el callback del controller, compruebo que el player no está fuera de los límites de la pantalla para dejarle en el tope. Pero si choca con un collider... ¿donde evito que se mueva en la dirección del choque?

¿Debería mover el Player en el evento Move? ¿Cual sería la manera correcta de controlar el movimiento del personaje, en el OnPlayerMove del controlador o en el OnMove del player?


Gracias @msxvr por la manita.

Re: A tortas con las colisiones

Posted: Sat Mar 12, 2022 7:38 am
by msxvr
Si al player lo mueves con un controller .. para limitar desplazamiento tienes:

Code: Select all

function GL_Controller::EnableLimits (x, y, w, h)
Establece los límites de movimiento. Esto obligará a que nunca se pueda salir del rectángulo creado con posición (x, y) y tamaño (w, h).
function GL_Controller::DisableLimits ()
Desactiva el área de limitación de movimiento.
Y si quieres controlarlo tu .. lo suyo sería hacerlo en el "OnMove" del controller.