[Juego] Pong

Ver el tema anterior Ver el tema siguiente Ir abajo

[Juego] Pong

Mensaje  HarZe el Jue Ago 12, 2010 12:31 am

El juego es el Pong clásico, un juego de uno contra uno, con dos barras y una bola:



Los controles son W y S para mover la barra izquierda, I y K para mover la barra derecha, Enter para sacar la bola.
La velocidad de la bola aumenta progresivamente si no se mete un gol, para forzar que esto suceda.
Golpear con la parte roja duplica la velocidad de la bola.

Aquí el código en C++:
Código:
#include <GL/glut.h>
#include <stdio.h>
#include <math.h>
#define PI 3.141592

bool teclas[5];

class Barra {
   public:
      float posicion;
      bool lado;
      
      void Iniciar(bool lado_barra) {
         posicion = 12;
         lado = lado_barra;
      }
      
      void Avanzar(bool arriba, bool abajo) {
         if (arriba) posicion += 0.5f;
         if (abajo) posicion -= 0.5f;
         if (posicion < 0) posicion = 0;
         if (posicion > 24) posicion = 24;
      }
      
      void Pintar(bool lado) {
         glPushMatrix();
         glTranslatef(5+(lado*30),posicion,0);
         glColor3f(1,0,0);
         glRectf(-0.25,0,0.25f,1);
         glColor3f(1,1,1);
         glRectf(-0.25f,1,0.25f,5);
         glColor3f(1,0,0);
         glRectf(-0.25,5,0.25f,6);
         glPopMatrix();
      }
};

class Bola {
   public:
      float posicion[2], velocidad, rapida, angulo;
      bool pausado;
      
      void Iniciar() {
         posicion[0] = 20;
         posicion[1] = 15;
         velocidad = 0.25f;
         rapida = 1;
         angulo = 1.3*PI;
         pausado = 1;
      }
      
      void desPausar(bool pausa) {
         if (pausa) pausado = 0;
      }
      
      void Acelerar() {
         velocidad += 0.0001f;
      }
      
      void Avanzar(int direccion) {
         posicion[0] += (!pausado)*direccion*rapida*velocidad*cosf(angulo);
         posicion[1] += (!pausado)*direccion*rapida*velocidad*sinf(angulo);
      }
      
      void Rebotar(Barra *bar) {
         if (posicion[1] > 30 || posicion[1] < 0) {
            Avanzar(-1);
            angulo = 2*PI - angulo;
            Avanzar(1);
         }
         if (posicion[0] < 5.5f && posicion[0] > 4.5f && posicion[1] > bar[0].posicion && posicion[1] < bar[0].posicion + 6) {
            Avanzar(-1);
            angulo = (-PI/2) + ((PI/8) + ((posicion[1] - bar[0].posicion)/6)*(PI - PI/4));
            if (posicion[1] - bar[0].posicion < 1 || posicion[1] - bar[0].posicion > 5) rapida = 2;
            else rapida = 1;
            Avanzar(1);
         }
         if (posicion[0] < 35.5f && posicion[0] > 34.5f && posicion[1] > bar[1].posicion && posicion[1] < bar[1].posicion + 6) {
            Avanzar(-1);
            angulo = (-PI/2) - ((PI/8) + ((posicion[1] - bar[1].posicion)/6)*(PI - PI/4));
            if (posicion[1] - bar[1].posicion < 1 || posicion[1] - bar[1].posicion > 5) rapida = 2;
            else rapida = 1;
            Avanzar(1);
         }
      }
      
      void Pintar() {
         glPushMatrix();
         glColor3f(1,1,1);
         glTranslatef(posicion[0],posicion[1],0);
         glBegin(GL_TRIANGLE_FAN);
            glVertex2f(0,0);
            for (float ang = 0; ang <= PI*2; ang += PI/8) glVertex2f(0.25*cosf(ang),0.25*sinf(ang));
         glEnd();
         glPopMatrix();
      }
};

class Marcador {
   public:
      int jugador[2];
      
      void Puntuar(Bola& bola) {
         if (bola.posicion[0] < 2) {
            jugador[0]++;
            bola.Iniciar();
         }
         if (bola.posicion[0] > 38) {
            jugador[1]++;
            bola.Iniciar();
         }
      }
      
      void Pintar() {
         char marcador[15];
         sprintf(marcador,"J1: %i | J2: %i",jugador[0],jugador[1]);
         glRasterPos3f(18,29,0);
         for (int i = 0; i < strlen(marcador); i++) glutBitmapCharacter(GLUT_BITMAP_HELVETICA_10, marcador[i]);
      }
};

Barra barras[2];
Bola bola;
Marcador puntos;

void PintarEscena() {
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho(0,40,0,30,-1,1);
   
   glMatrixMode(GL_MODELVIEW);
   glClear(GL_COLOR_BUFFER_BIT);
   glLoadIdentity();
   
   for (int i = 0; i < 2; i++) barras[i].Pintar(i);
   bola.Pintar();
   puntos.Pintar();
   
     glutSwapBuffers();
}

void ReProyectar(int w, int h) {
   glutReshapeWindow(800,600);
   glViewport(0, 0, w, h);

     PintarEscena();
}

void Teclas(unsigned char key, int x, int y) {
   if (key == 13) teclas[0] = 1;
   if (key == 'w' || key == 'W') teclas[1] = 1;
   if (key == 's' || key == 'S') teclas[2] = 1;
   if (key == 'i' || key == 'I') teclas[3] = 1;
   if (key == 'k' || key == 'K') teclas[4] = 1;
}

void TeclasUp(unsigned char key, int x, int y) {
   if (key == 13) teclas[0] = 0;
   if (key == 'w' || key == 'W') teclas[1] = 0;
   if (key == 's' || key == 'S') teclas[2] = 0;
   if (key == 'i' || key == 'I') teclas[3] = 0;
   if (key == 'k' || key == 'K') teclas[4] = 0;
}

void Mover(int value) {
   glutTimerFunc(17,Mover,1);
   glutPostRedisplay();
   
   barras[0].Avanzar(teclas[1],teclas[2]);
   barras[1].Avanzar(teclas[3],teclas[4]);
   bola.Avanzar(1);
   bola.desPausar(teclas[0]);
   bola.Rebotar(barras);
   bola.Acelerar();
   puntos.Puntuar(bola);
}

int main(int argc, char **argv) {
     glutInit(&argc,argv);
   glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
     glutInitWindowSize(800,600);
     glutInitWindowPosition(40,40);
     glutCreateWindow("Pong por HarZe");
   
   for (int i = 0; i < 2; i++) barras[i].Iniciar(i);
   bola.Iniciar();
 
     glutReshapeFunc(ReProyectar);
   glutDisplayFunc(PintarEscena);
     glutKeyboardFunc(Teclas);
     glutKeyboardUpFunc(TeclasUp);
     glutTimerFunc(17,Mover,1);

     glutMainLoop();
   return 0;
}

Para compilar en Windows, crear Proyecto -> glut. Para compilar en Linux:
Código:
g++ pong.c -o pong -lglut

HarZe
WebMaster & Desarrollador

Cantidad de envíos : 58
Fecha de inscripción : 21/06/2009
Edad : 24

Ver perfil de usuario http://opengl-esp.superforo.net

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.