Unidad 22. Ejercicio: Colisión y Movimiento



Colisión y Movimiento

Reproduciremos la película que vimos en la teoría:

Ejercicio paso a paso.

  1. Abre el archivo colision.fla que encontrarás en la carpeta ejercicios/colision del curso.
    En él encontrarás dos elementos: miClip que será el cuadradito que se desplazará, y fondo, que delimita el área por el que se puede desplazar.
  2. Selecciona el primer fotograma y abre el Panel Acciones, escribe en él lo siguiente:
    //definimos las variables que vamos a utilizar
    //Variables que indican la dirección del movimiento
    var izquierda:Boolean=false;
    var derecha:Boolean=false;
    var subir:Boolean=false;
    var bajar:Boolean=false;
    var velocidad:Number=1;//Espacio que se desplazará
    
    //Al pulsar una tecla...
    stage.addEventListener(KeyboardEvent.KEY_DOWN, capturarTeclado);
    //Averiguamos la tecla pulsada para decidir la dirección
    function capturarTeclado(tecla:KeyboardEvent):void {
    	switch (tecla.keyCode) {
    		case Keyboard.RIGHT :
    			derecha=true;
    			break;
    		case Keyboard.LEFT :
    			izquierda=true;
    			break;
    		case Keyboard.UP :
    			subir=true;
    			break;
    		case Keyboard.DOWN :
    			bajar=true;
    			break;
    	}
    }
    
    //Al soltar una tecla
    stage.addEventListener(KeyboardEvent.KEY_UP, parar);
    //Anulamso el movimiento en dirección de la tecla
    function parar(tecla:KeyboardEvent):void {
    	switch (tecla.keyCode) {
    		case Keyboard.RIGHT :
    			derecha=false;
    			break;
    		case Keyboard.LEFT :
    			izquierda=false;
    			break;
    		case Keyboard.UP :
    			subir=false;
    			break;
    		case Keyboard.DOWN :
    			bajar=false;
    			break;
    	}
    }
    Este código se parece mucho al que vimos en la teoría. Lo único que hacemos es obtener qué tecla se ha pulsado y en función de la dirección, activamos una variable booleana que indica que se ha de mover el objeto en esa dirección. Cuando se suelte la tecla, hacemos lo mismo para desactivar la variable.
  3. Vamos ahora con el movimiento. Lo haremos en el evento "enterFrame" del objeto que se mueve. Añade el siguiente código:
    //En el enterFrame del clip, comprobamos la posición futura, y si no hay impacto, movemos
    miClip.addEventListener(Event.ENTER_FRAME, mover);
    function mover(event):void {
    	//Utilizamos un objeto rectángulo para que nos sea más cómodo acceder a las propiedades
    	var rect:Rectangle= miClip.getBounds(stage);
    	if (bajar) { //Comprobamos la colisión abajo - izquierda y abajo - derecha, aumentando abajo
    		if (!(fondo.hitTestPoint(rect.left, rect.bottom+velocidad, true) || fondo.hitTestPoint(rect.right, rect.bottom+velocidad, true))) {	
    			miClip.y+=velocidad; //Si no hay colisión, cambiamos la posición del objeto.
    		}
    	}
    	if (subir) { //Comprobamos la colisión izquierda - arriba y derecha - arriba, aumentando arriba
    		if (!(fondo.hitTestPoint(rect.left, rect.top-velocidad, true) || fondo.hitTestPoint(rect.right, rect.top-velocidad, true))) {
    			miClip.y-=velocidad; 
    		}
    	}
    	if (izquierda) { //Comprobamos la colisión izquierda - arriba e izquierda - abajo, aumentando izquierda
    		if (!(fondo.hitTestPoint(rect.left-velocidad, rect.top, true) || fondo.hitTestPoint(rect.left-velocidad, rect.bottom, true))) {
    			miClip.x-=velocidad;
    		}
    	}
    	if (derecha) {//Comprobamos la colisión derecha - arriba y derecha - abajo, aumentando derecha
    		if (!(fondo.hitTestPoint(rect.right+velocidad, rect.top, true) || fondo.hitTestPoint(rect.right+velocidad, rect.bottom, true))) {
    			miClip.x+=velocidad;
    		}
    	}
    }

Parece un poco complicado pero en esencia es más largo, pero sencillo. Para cada uno de los movimiento (arriba, abajo, izquierda y derecha) tendremos que evaluar si se produce colisión con el objeto miClip y el clip fondo.
Pero no bastará con hacerlo sólo de una esquina, veamos un ejemplo para verlos con más claridad:

¿Se producirá colisión?

Como ves en la imagen, deberemos ver si se producen dos colisiones. En el movimiento hacia abajo una será la de la esquina inferior izquierda y la otra de la esquina inferior derecha. Si por ejemplo, no evaluásemos el choque con la esquina inferior izquierda e intentásemos realizar un movimiento hacia abajo, ¡éste se realizaría! Y en definitiva es lo que queremos evitar.

Hemos empleado un objeto Rectángulo al que le hemos dados las medidas del objeto para que nos sea más cómodo trabajar. Por ejemplo, para acceder a la parte superior, tendríamos que escribir miClip.getBounds(fondo).top cada vez, mientras que así solo ponemos rect.top.

Observa también que para realizar el hitTestPoint hemos tenido en cuenta la posición que adoptará el objeto después del movimiento (sumándole la velocidad, o lo que es lo mismo, el número de píxeles que se desplaza el objeto a cada pulsación). Además, le hemos enviado un tercer parámetro true para que tenga en cuenta la forma del objeto (del fondo).



   Inicio    




.