Moviendo Objetos

 


Vamos a ver la clase Objetos, que se necesita para realizar lo que deseamos. En nuestro caso poner un objeto en el escenario, que pueda actuar de obstáculo, y que se pueda mover por el escenario.

Para entender bien todo lo que se va a realizar a continuación tenemos un video que muestra todo ello. 


En el video los objetos añadidos al escenario son 4: dos calabazas, un arbusto y unas flores.

En ejemplo tenemos dos objetos que no podemos mover, que son el arbusto y las flores. Y otros dos que si se pueden mover. Pero además el arbusto actúa como un obstáculo.

Código de la Clase Objeto

class Objetos

{
    int x, y;
    ALLEGRO_BITMAP* img;
    bool colisiona;
    int ancho, alto;
public:
    int getAncho() { return ancho; }
    int getAlto() { return alto; }
    int getX() { return x; }
    int getY() { return y; }
    void crea(ALLEGRO_BITMAP* i, int _x, int _y, bool c = false)
    {
        img = i;
        x = _x;
        y = _y;
        colisiona = c;
        ancho = al_get_bitmap_width(img);
        alto = al_get_bitmap_height(img);
    }
    void pinta()
    {
        al_draw_bitmap(img, x + globalx, y + globaly, 0);
    }
    bool comprueba()
    {
        if (colisiona)
        {
            int jx = jugador.getX();
            int jy = jugador.getY();
         
            if (jx + jugador.getTam() > x && jx < x + ancho && jy + jugador.getTam() > y  && jy < y + alto/2 )
            {
                return true;
            }
        }
        return false;
    }
    void posiciona(int _x, int _y)
    {
        x = _x;
        y = _y;
    }
    bool cerca(int _x, int _y)
    {
        return abs(x - _x) + abs(y - _y) < jugador.getTam() + 2 ;
    }
    void cambiaImagen(ALLEGRO_BITMAP* i)
    {
        img = i;
    }
};


La clase objetos podría ser una clase independiente, salvo que en este ejemplo concretamente no lo es debido a que se utilizan algunas variables externas a la clase. Concretamente tenemos las variables globalx y globaly que contiene la posición para el scroll de la pantalla. Además se utilizan llamadas a la clase player. Aunque todo esto se podría arreglar, pasando esos datos que se utilizan como parámetros.

La clase objeto cuenta con una imagen, la posición x,y, el ancho y alto de la imagen, y una variable de control llamada colisiona.

Tiene varios métodos para obtener los datos, que son: getX(), getY(), getAlto(), getAncho().

El método principal para inicializar la clase se llama crea, y necesita varios parámetros para crear el objeto, el primero es la imagen del objeto, lo siguiente la posición donde quieres que aparezca x,y. Y por ultimo un valor booleano que nos indica si el objeto colisiona o no. 

El método pinta muestra por pantalla la imagen en la posición indicada por x,y.

La función comprueba, se encarga de comprobar si colisiona el objeto con el jugador.

El método posiciona, le indica una nueva posición al objeto mediante los parámetros x,y.

La función cerca, devuelve true si la posición dada por los parámetros x,y esta cerca del objeto.

La función cambiaImagen, sirve para cambiar la imagen una vez creado el objeto.

Para tener una clase mas independiente al jugador de la clase player, la función de colisión se puede hacer de la siguiente forma:

    // requiere posicion del jugador y el tamaño de la imagen del jugador
    bool comprueba(int jx, int jy, int tam)
    {
        if (colisiona)
        {            
            if (jx + tam > x && jx < x + ancho && jy + tam > y  && jy < y + alto/2 )
            {
                return true;
            }
        }
        return false;
    }


De este modo los datos necesarios del jugador se pasan por parámetro, que son la posición y el tamaño. En este caso la posición del jugador indica la esquina superior izquierda de la imagen.
De igual modo se puede cambiar el pinta, para recibir los datos del scroll por parámetro, quedando de la siguiente forma:

    void pinta(int globalx, int globaly)
    {
        al_draw_bitmap(img, x + globalx, y + globaly, 0);
    }


Aunque al_draw_bitmap sigue utilizando las mismas variables, ahora globalx y globaly no son variables globales sino locales, ya que ahora son parámetros del método. 

La función cerca cambia a:

    bool cerca(int _x, int _y, int tam)
    {
        return abs(x - _x) + abs(y - _y) < tam + 2;
    }


Añadiendo un nuevo parámetro del tamaño, el correcto funcionamiento de esta función recae en que se da por hecho que tanto el objeto como el personaje tienen el mismo tamaño, y son imágenes cuadradas por tanto ese tamaño es igual el alto que el ancho, es por ello que se podría sustituir tam por ancho o alto del objeto y así no necesitar el parámetro tam. Pudiendo quedar de la siguiente forma si se tiene en cuenta todo lo anterior.

    bool cerca(int _x, int _y)
    {
        return abs(x - _x) + abs(y - _y) < alto + 2;
    }



Y así ya tenemos una clase totalmente independiente que se podrá reutilizar en cualquier otro código.

SHARE
    Blogger Comment

2 comentarios:

  1. Una duda, como tienes el main? O desde donde instancias las clases, y otra duda; de donde implementas ALLEGRO_BITMAP* img

    ResponderEliminar
    Respuestas
    1. Puedes verlo descargando el código de ejemplo, el enlace esta en la última frase del post. O haz click aqui!! para descargar.

      Este ejemplo contiene lo mostrado en el video "Happy Halloween", en este caso el fichero principal se llama halloween.cpp y en el se encuentra todo el código, aunque se podría haber separado en archivos las distintas clases utilizadas.

      Eliminar