1º Reto de Retrodev

Iniciado por kaltorak, 18 Junio 2013, 14:53 PM

0 Miembros y 3 Visitantes están viendo este tema.

SrCooper

#20
Ya está lista la ALPHA de mi juego. Aquí el código:

Código (cpp) [Seleccionar]
#include <allegro.h>
#include <list>
#include <cstdlib>
#include <time.h>
#include <string>
using namespace std;

const int XTAM = 60, YTAM = 40;
const int SZ = 12;

int vx = 1, vy = 0;
int al, score = 0;

BITMAP *cuadrado1;
BITMAP *cuadradobmp;
BITMAP *buffer;
BITMAP *fruta;
BITMAP *manzanabmp;
BITMAP *fresabmp;
BITMAP *bombabmp;

void draw_score()
{
   rectfill(screen, 0,0,200,14,0);
   textprintf(screen, font, 0, 0, -1, "SCORE:  %d", score);
}

void pantalla(){
   blit(buffer, screen, 0,0,0,0, XTAM*SZ, YTAM*SZ);
}
struct Punto{
   int x,y;
};

void cuadrado(const Punto& p){
   blit(cuadradobmp, cuadrado1, 0, 0, 0, 0, 12, 12);
   draw_sprite(buffer, cuadrado1, p.x*SZ, p.y*SZ);
}

void pinta_comida(const Punto& p){
   srand(time(0));
   if (al==0) blit(manzanabmp, fruta, 0, 0, 0, 0, 12, 12);
   if (al==1) blit(fresabmp, fruta, 0, 0, 0, 0, 12, 12);
   draw_sprite(buffer, fruta, p.x*SZ, p.y*SZ);
}

Punto al_azar(){
   srand(time(0));
   Punto p = {rand() % XTAM, rand() % YTAM};
   al = rand() % 2;
   return p;
}

void teclas(){
       if (key[KEY_UP] && vy != 1){
           vx = 0, vy = -1;
      }else if (key[KEY_DOWN] && vy != -1){
           vx = 0; vy = 1;
      }else if (key[KEY_LEFT] && vx != 1){
           vx = -1, vy = 0;
      }else if (key[KEY_RIGHT] && vx != -1){
           vx = 1, vy = 0;
      }
}

bool hay_choque(const Punto& cabeza, const list<Punto>& cola){
   if (cabeza.x >= XTAM  || cabeza.x < 0) return true;
   if (cabeza.y >= YTAM  || cabeza.y < 0) return true;
   list <Punto>::const_iterator it = cola.begin();
   for (; it != cola.end(); it++){
       if (cabeza.x == it->x && cabeza.y == it->y){
           return true;
       }
   }
   return false;
}

int main(){
   allegro_init();
   install_keyboard();

   set_color_depth(32);
   set_gfx_mode(GFX_AUTODETECT_WINDOWED, XTAM * SZ, YTAM * SZ, 0, 0);

   buffer = create_bitmap(XTAM * SZ, YTAM * SZ);
   cuadrado1 = create_bitmap(12,12);
   cuadradobmp = load_bitmap("imagenes/cabeza.bmp", NULL);
   fruta = create_bitmap(12,12);
   fresabmp = load_bitmap("imagenes/fresa.bmp", NULL);
   manzanabmp = load_bitmap("imagenes/manzana.bmp", NULL);
   bombabmp = load_bitmap("imagenes/bomba.bmp", NULL); //Ya desvelo lo que incluire proximamente ;D

   list<Punto> cola;
   int engorda = 0;
   int retraso = 0;

   bool choque = false;
   Punto cara = {30, 30};
   Punto comida = al_azar();

   while(!key[KEY_ESC] && !choque ){
       pantalla();
       retraso++;
       teclas();
       draw_score();

        if (retraso==8){
           cola.push_front(cara);
           if (engorda > 0){
               engorda--;
           }else {
               cola.pop_back();
           }
           cara.x += vx;
           cara.y += vy;
           if (hay_choque(cara, cola)){
               choque = true;

           } else if (cara.x == comida.x && cara.y == comida.y){
               engorda = 5;
               if (al==0) score += 5;
               else if (al==1) score +=10;
               comida = al_azar();
               while (hay_choque(comida, cola) ||
                   comida.x == cara.x && comida.y == cara.y ||
                   comida.y < 5){
                       comida = al_azar();
                   }
           }

           retraso = 0;
       }
   if (!choque){
           clear(buffer);
           list<Punto>::const_iterator it;
           for (it = cola.begin(); it != cola.end(); it++){
               cuadrado(*it);
           }
           cuadrado(cara);
           pinta_comida(comida);

       }
       rest(10);
   }

   rectfill(screen, 0,0,200,14,0);
   textprintf(screen, font, 200, 200, -1, "Tu puntuacion ha sido de:  %d", score);
   rest(2000);
   return 0;
}
END_OF_MAIN();


He usado Allegro, una lista para crear a mi serpiente y estructuras en lugar de clases. El juego de momento solo tiene una fruta cada vez, aunque hay varios tipos de fruta (cada una da diferentes puntos).
El juego funciona perfectamente, aunque aún me queda incluirle un menú, más frutas y algún tipo de jefe o algo así  >:D

PD: Cuando pueda subiré los archivos compilados en linux y windows :D

amchacon

¡Allegro! Por fin alguien lo usa ^^

Aunque no acabo de entender bien tú código, no sé, es un poco extraño (¿Que es retraso?)
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

SrCooper

Cita de: amchacon en  7 Julio 2013, 00:18 AM
¡Allegro! Por fin alguien lo usa ^^

Aunque no acabo de entender bien tú código, no sé, es un poco extraño (¿Que es retraso?)

Ahora que lo veo, en realidad es un poco retorcido pero es útil. Retraso es una variable que aumenta cada vez que se realiza un ciclo. Y solo cuando esta variable es igual a 10 (se han completado 10 ciclos) se realizan las acciones de mover a la serpiente y se resetea el valor. Si te fijas las acciones que no son de movimiento están fuera de este if.

La función de este valor es bajar un poco la velocidad del juego. También podría haberse hecho aumentando el valor del rest del final, pero con esta variable se concreta que solo queremos bajarle el "ritmo" al movimiento de la serpiente. Prueba a quitarla y se hace injugable, te lo aseguro  :xD
Un saludo

amchacon

Cita de: SrCooper en  7 Julio 2013, 00:41 AM
Ahora que lo veo, en realidad es un poco retorcido pero es útil. Retraso es una variable que aumenta cada vez que se realiza un ciclo. Y solo cuando esta variable es igual a 10 (se han completado 10 ciclos) se realizan las acciones de mover a la serpiente y se resetea el valor. Si te fijas las acciones que no son de movimiento están fuera de este if.
Entiendo... Bueno es factible ^^

Aunque lo ideal (tanto en rendimiento como en claridad) sería hacer una tarea en segundo plano (hilo). Además es mucho más flexible (puedes ponerle el tiempo que quieras).
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

SrCooper

#24
Ya está listo el archivo compilado de mi juego, la verdad,  había olvidado completamente que tenía que subirlo  :silbar:

En el archivo están el código fuente y el ejecutable, que por alguna razón que desconozco, no funciona. Sin embargo desde el CodeBlocks si que corre, supongo que faltará algo, pero no consigo averiguar que es, agradecería que alguien lo dijese.

Esta era solo una versión ALPHA, para probar la dinámica del juego y todo eso. Ahora mismo estoy realizando una versión definitiva en SDL y OpenGL, que espero poder terminar y que sea mucho mejor  :xD

Un saludo

Descarga: http://www.mediafire.com/?fb8qoly710qnkzk

PD: Una captura, un poco cutre la verdad, pero estoy mejorandolo  :D



amchacon

#25
No te funciona directamente porque no encuentra la carpeta "Imagenes" (cuando lo ejecutas desde el Codeblocks, te pilla la carpeta del proyecto como raiz y no la del ejecutable). Por otro lado es posible compilar las Allegro estáticamente (es decir, incrustar la librería dentro del ejecutable, de esa forma no necesitas la DLL).

Esta es la configuración que tienes que poner:
http://imageshack.us/a/img546/3949/nst6.png
http://imageshack.us/a/img812/1416/qr2o.png

El código me da muchos warnings:
Código (cpp) [Seleccionar]
textprintf(screen, font, 0, 0, -1, "SCORE:  %d", score);

Esta función está anticuada, en su lugar puedes usar textprintf_ex:
https://www.allegro.cc/manual/4/api/text-output/textprintf_ex

Y me da problemas cada vez que se come una fruta (sufre un retraso apreciable).
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

SrCooper

#26
Cita de: amchacon en 10 Julio 2013, 00:42 AM
Y me da problemas cada vez que se come una fruta (sufre un retraso apreciable).

Te diré a qué creo que se debe: cada vez que la serpiente se come una fruta se selecciona una nueva posición para esta. Si esta posición coincide con cualquiera de las posiciones de la serpiente entonces se vuelve a llamar a la función random(). Sé que no es la manera más eficiente pero no se me ocurría otra.

Gracias por todo lo demás, ya está añadido todo lo nuevo.

PD: ¿Cómo se compila estáticamente en SDL/OpenGL?

amchacon

Cita de: SrCooper en 10 Julio 2013, 00:50 AM
Te diré a qué creo que se debe: cada vez que la serpiente se come una fruta se selecciona una nueva posición para esta. Si esta posición coincide con cualquiera de las posiciones de la serpiente entonces se vuelve a llamar a la función random(). Sé que no es la manera más eficiente pero no se me ocurría otra.
Yo también hago ese algoritmo, pero no es normal que pase eso (por probabilidad, eso pasará en el 1% de los casos).

Mirando tú código:

Código (cpp) [Seleccionar]
while (hay_choque(comida, cola) ||
                    comida.x == cara.x && comida.y == cara.y ||
                    comida.y < 5)


Este while es muy confuso (hasta el mismo compilador me lo ha dicho). Pon paréntesis para separar los && de los ||
Cita de: SrCooper en 10 Julio 2013, 00:50 AM
PD: ¿Cómo se compila estáticamente en SDL/OpenGL?
Para compilar estaticamente (static link) los creadores deben hacer hecho una versión estática de la librería.

Dado que SDL no tiene licencia libre, es poco probable que tenga una versión estática. OpenGL no lo he llegado a usar nunca, asi que no puedo decirte.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

SrCooper

Cita de: amchacon en 10 Julio 2013, 01:20 AM
Este while es muy confuso (hasta el mismo compilador me lo ha dicho).

A mí también me advertía de algo pero no suelo hacerle caso xD. Aunque ahora que lo dices debería...
Ya he escrito los paréntesis y he probado un poco el programa, y por lo que parece sigue parándose a veces aunque menos a menudo.

Quizás debería hacer una función para estabilizar los FPS a 60. En fin, ya lo probaré en la siguiente versión. Por ahora estoy contento con esta  :laugh:

Un saludo

amchacon

Pues es extraño, lo normal esque ni se note.

Mirando un poco, he visto esto:
Código (cpp) [Seleccionar]
void alzar()
{
srand(time(0));


La semilla hay que inicializarla una vez (al principio del juego por ejemplo), no se debe iniciar cada vez o obtendrás el mismo número una y otra vez.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar