¿Cómo crear un videojuego en C?

Iniciado por DickGumshoe, 29 Abril 2012, 14:01 PM

0 Miembros y 1 Visitante están viendo este tema.

david_BS

también podías dar más detalles de que tipo de juego deseás hacer...
por ejemplo un juego 2D , un ajedréz, truco, damas chinas, sudoku, etc

en otro caso puede ser un juego 3D, como el quake 1, etc

son diferentes conceptos, porque en juegos 3D hay algo que se denomina "world", osea mundo, y se refiere a que estás en un espacio de 3 dimensiones como en la realidad y necesitás de alguna forma programar que el juego tenga las mismas leyes que en el mundo real, osea la gravedad y la velocidad, entre otras cosas; todo eso lleva una cantidad de matemática tremenda por eso muchos reutilizan los proyectos que ya fueron publicados, así no reprograman todo lo que ya fue hecho.

DickGumshoe

Bueno, como querer, querría terminar haciendo todo tipo de juegos. Pero para empezar, mejor sería un juego 2D, que es más fácil.

Saludos.

STANHMAL

Cita de: DickGumshoe en 29 Abril 2012, 17:34 PM
....

Por nada   ;)

Olvide pasarte esta pagina :

http://www.nachocabanes.com/videojuegos/ipj/index.php

allí hay muchos ejemplos de programación de vídeo-juegos en C con Allegro, comenzando desde lo más básico.

$4!U2
Power Metal vs Reggaeton



Que es mi ordenador mi tesoro que todo el mundo ha de temer. Mi ley, el ratón y el módem. Mi única patria, la red

DickGumshoe

¡Muchísimas gracias! Esa página la estuve mirando esta mañana, y me pareció muy buena.

Creo que entre el PDF que me pasaste y esa página será de donde aprenda ^^

Saludos.

david_BS


y generalmente esos juegos de tablero, inclusive los de laberinto como ser el pacman, se plantean como que el tablero es una matriz de tipo 'struct posicion', donde dentro de esa struct tenés algo como..

struct posicion {

     int id_pos; // identificador de celda
     float pos[2]; //guarda coordenadas x;y
     bool bloqueado; //para saber si es una pos libre o bloqueada
};


entonces vos ya tenés que saber cuanto va a ser la dimensión de tu tablero y crear la matríz.

después tenés que dibujar las paredes del laberinto como si fueran líneas, eso lo hacés con alguna librería gráfica... que si lo hicieras en modo consola directamente podés usar funciones de consola para dibujar líneas..

y te faltaría el tema de las colisiones , que es el caso de que quieras crear alguna 'entidad' como puede ser el pacman en sí, y esta entidad tiene que poder detectar si puede desplazarse hacia una posición que no esté bloqueada (ver struct).

en cuanto a la 'entidad' , obviamente te convendría dedicarle una clase o struct para manejarla, es decir los movimientos por ejemplo, en donde tendrías que usar algo que detecte las teclas asignadas al desplazamiento y en base a eso redibujar el pacman en la posición actualizada.

Algunos consejos solamente, yo estuve en una curso en donde hacían juegos 2D pero realmente no me interesaba mucho :p





DickGumshoe

Muchas gracias, david_BS. Tomaré en cuenta tus consejos.

Saludos.

linkingcrk

yo te recomendaria SDL  ;)

es la que yo uso y ps en internet hay mas documentacion que Allegro a ver aqui te dejo una pagina(para mi es la mejor) donde encontraras incluso tutoriales para programar videojuegos en general...
http://www.loosersjuegos.com.ar/referencia

ahora veras para desarrollar video juegos se suele usar + C++ por que es un C pero + objetos y ps así es super ya que te permite tener un perfecto control de tu juego + que puedes usar Herencia que es propia de la POO (programacion orientada a objetos).

en la programacion de video juegos se suele reutilizar codigo usando esa tecnica magica de la herencia ya que puedes tener una clase base llamada personaje y usarla para casí cualquier juego futuro ;)... es solo un ejemplo pero se puede reutilizar mucho mas codigo.

con C te digo que no es jugar perinola esto de hacer juegos ... te recomiendo que primero te aprendas el lenguaje completo mas las funciones estandar que te ofrece para que no te estanques a cada rato con tu juego...  ;D

Saludos y suerte!!!  la programacion de videojuegos es un camino largo y oscuro xD

DickGumshoe

Muchas gracias, linkingcrk

Durante el día de hoy pensaré si usar finalmente Allegro o SDL.

Saludos.

pajaras

#18
Aqui te dejo un videojuego que hice en la universidad, adaptado y modificado. Espero que te sirva. :)


/*
* correForest.c
*/

#include "correForest.h"

//Variables del personatge (jugador)

int x,   // posicio actual del jugador
   x_ant, // posicio anterior del jugador
   veloc, // velocitat jugador
   vides, // vides que te el jugador
   metres; // metres recorreguts

//Variables escena

int c[LLARGADA]; // c[i] defineix el centre de la carretera a la
                // fila (i+2)-essima a la pantalla amb l'index
                // "i" prenent valors en [0..LLARGADA-1]

// Variables de control

int fi_partida, // fi de partida
   fi_joc;     // fi del joc


//---------------- MAIN --------------------

int main(){

       fi_joc = 0;
       while (! fi_joc){
   Inicialitzacio();
 Bucle();
 Finalitzacio();
       }
return 0;
}

// Inicialitza recursos, variables del jugador y
// estructura de dades de l'escena (carretera)

void Inicialitzacio(){

int i;

// Inicialitzem el generador de nombres aleatoris
       // srand(13);
srand(GetTickCount() % 1000);

// Pantalla en mode text 80x50
textmode(PANTALLA_80x50);

// Cursor no invisible
_setcursortype(_NOCURSOR);

       // Status inicial del joc
metres = 0;           // espai recorregut
veloc  = 0;           // velocitat del jugador
vides  = VIDES_MAX;   // vides restants

// Posicio inicial pantalla = (80/2=40,42)
//
// - 1
// o 2 -> c[0]
// o
// ...
// o 42 -> c[40]
// ...
// o 49
// - 50 -> c[48]

       // Centres de la carretera inicial
c[0] = CENTRE_INI;
for(i=1; i<LLARGADA; i++){
c[i] = c[i-1] + Aleatori();
if(c[i] < CENTRE_MIN)   c[i] = CENTRE_MIN;
else if(c[i] > CENTRE_MAX) c[i] = CENTRE_MAX;
}

       // Dibuix de la carretera inicial
clrscr();
for(i=0; i<LLARGADA; i++){   //LLARGADA-1 ????
         gotoxy(1, i+2);
 PintaLiniaCarretera(i);
}

       // Posicio inicial del jugador. No col.lisiona
x     = c[INDEX_FIX];
x_ant = x;
textcolor(BLUE);
textbackground(LIGHTGRAY);
gotoxy(x, FILA_FIXA);
cprintf("%c", CARA);
textbackground(BLACK);

       // Inici del joc
       MostraVelocitat();
       MostraMetres();
       MostraVides();

BaixadaDeBandera();
}

// Baixada de bandera inicial

void BaixadaDeBandera(){

       fi_partida = 0;
veloc      = VELO_MIN;    // velocitat del jugador

       MostraMissatge(0);
textcolor(LIGHTRED);
       MostraMissatge(1);
       while(! kbhit()){}        // espera
       MostraMissatge(0);
       MostraMissatge(2);
}



// Bucle de vida del joc amb sincronitzacio per framerate
// GetTickCount() retorna temps transcorregut en milisegons
// des del boot del sistema

void Bucle(){

long t1, t2;
       tEvent event;

while(!fi_partida){
  t1 = GetTickCount();
Entrada(&event);
Proces(event);
Sortida();

do {
t2 = GetTickCount();
} while((t2-t1) < (DELAY_SINC/veloc));
}
}

// Tasques finals i alliberament de recursos

void Finalitzacio(){

      char fi;

       // No resten vides
       MostraVides();

       // Neteja missatges
       MostraMissatge(0);

       // Fi de partida
textcolor(YELLOW);
gotoxy(31,20); cprintf("------------------");
gotoxy(31,21); cprintf(" FI DE LA PARTIDA ");
gotoxy(31,22); cprintf("------------------");

       // Fi de joc o partida nova

gotoxy(22,32); cprintf("---------------------------------");
gotoxy(22,33); cprintf(" F: Fi del joc  N : Nova partida ");
gotoxy(22,34); cprintf("---------------------------------");

       fi = getch();
       while (!(fi == 'F' || fi == 'f' || fi == 'N' || fi == 'n')){
           fi = getch();
}
       if(fi == 'F' || fi == 'f') fi_joc = 1;


//        fi_joc = fi == 'F' || fi == 'f') fi_joc;

//Pantalla en mode text inicial
textmode(LASTMODE);
}

// Captura de les ordres que l'usuari entra pel teclat

void Entrada(tEvent *event){

 char c;

 *event = EVENT_BUIT;
 if(kbhit()){
   switch(getch()) {
     case TECLA_ESC:   *event = FI_PARTIDA;
               break;
     case TECLA_ESQ:   *event = MOU_ESQUERRA;
       break;
     case TECLA_DRE:   *event = MOU_DRETA;
       break;
     case TECLA_AMUNT: *event = MES_VELOCITAT;
                       break;
     case TECLA_AVALL: *event = MENYS_VELOCITAT;
                       break;
   }
 }
}

// Logica del programa
// Deteccio de col.lisions i avançar per la carretera
// Generacio nova escena

void Proces(tEvent event)
{
int i;

       switch(event) {
 case FI_PARTIDA:      fi_partida = 1;
       break;
   case MOU_ESQUERRA:    x--;
       break;
         case MOU_DRETA:       x++;
       break;
 case MES_VELOCITAT:   if(veloc < VELO_MAX) veloc++;
                       break;
 case MENYS_VELOCITAT: if(veloc > VELO_MIN) veloc--;
                               break;
       }

       // Esborrar jugador de la posicio anterior
textcolor(LIGHTGRAY);
gotoxy(x_ant, FILA_FIXA);
cprintf("%c", QSOLID);

// Avançar un pas
metres++;

// memcpy(&c[1],&c[0],(LLARGADA-1)*sizeof(int));
memmove(&c[1],&c[0],(LLARGADA-1)*sizeof(int));

  // Linia nova de carretera

c[0] = c[0] + Aleatori();
if(c[0] < CENTRE_MIN)      c[0] = CENTRE_MIN;
else if(c[0] > CENTRE_MAX) c[0] = CENTRE_MAX;

// Deteccio de col.lisions amb els vorals

if( (x < (c[INDEX_FIX] - MEITAT_AMP)) ||
   (x > (c[INDEX_FIX] + MEITAT_AMP)) )  {

         // Donem temps pel missatge
           textcolor(LIGHTRED);
       MostraMissatge(0);
               MostraMissatge(3);
i = GetTickCount();
while((GetTickCount() - i) < DELAY_COL) {}
       MostraMissatge(0);
       MostraMissatge(2);

         // Actualitzacio de l'estatus del joc
vides--;
if(vides == 0){
fi_partida = 1;
}else{
veloc = VELO_MIN;
x     = c[INDEX_FIX];
               x_ant = x;
}
       }else{  // No hi ha col.lisio
       x_ant = x;
}
}


// Pintat de l'escenari (carretera),
// Actualitzacio de l'estatus (vides, metres, velocidad)
// i personatges (jugador)

void Sortida()
{
//gotoxy(x,y) => x=1..80,y=1..50

       MostraVelocitat();
       MostraMetres();
       MostraVides();

//Scroll carretera
movetext(1,2,FINESTRA_W,LLARGADA,1,3);

//Nou troç de carretera
gotoxy(1, 2);
PintaLiniaCarretera(0);

//Situar jugador en nova posicio
textcolor(BLUE);
textbackground(LIGHTGRAY);
gotoxy(x, FILA_FIXA);
cprintf("%c", CARA);
textbackground(BLACK);
}

// Retorna un valor aleatori en {-1,0,1}

int Aleatori(){

return (rand() % 3) - 1;
}

// Actualitzacio del retol de velocitat

void MostraVelocitat(){

      int i;

       // Retol
       gotoxy(5, 1);
textcolor(LIGHTCYAN);
cprintf("Velocitat: ");
       //Velolcitat actual
textcolor(LIGHTCYAN);
for(i=1; i<=veloc; i++)
cprintf("%c", DIAMANT);
       //Velocitats superiors possibles
textcolor(CYAN);
for(i=1; i<=(VELO_MAX-veloc); i++)
cprintf("%c", DIAMANT);
}

// Actualitzacio del retol dels metres recorreguts

void MostraMetres(){

gotoxy(40, 1);
textcolor(YELLOW);
cprintf("Metres: %d", metres);
}


// Actualitzacio del retol de les vides

void MostraVides(){

       int i;

// Retol
gotoxy(65, 1);
textcolor(LIGHTRED);
cprintf("Vides: ");
       //Vides restants
textcolor(LIGHTRED);
for(i=1; i<=vides; i++)
cprintf("%c", COR);
       //Vides perdudes
textcolor(RED);
for(i=1; i<=(VIDES_MAX - vides); i++)
cprintf("%c", COR);
}

// Pinta la linia horitzontal corresponent a c[i] amb
// i en [0..LLARGADA - 1] al lloc (x, y) on estigui
// posicionat el cursor de la pantalla

void PintaLiniaCarretera(int i)
{
// -------123........c........321-----
int j;
int nesq, ndre;

nesq = c[i] - (MEITAT_I_VORAL + 1); // sense () no calcula be !!
ndre = c[i] + MEITAT_I_VORAL + 1;

//Gespa de l'esquerra
textcolor(GREEN);
for(j=1; j<=nesq; j++)
cprintf("%c", QSOLID);

//Voral de l'esquerra
textcolor(RED);
cprintf("%c", QRATLLAT);
textcolor(WHITE);
cprintf("%c", QRATLLAT);
textcolor(RED);
cprintf("%c", QRATLLAT);

//Carretera
textcolor(LIGHTGRAY);
for(j=1; j<=AMPLADA; j++)
cprintf("%c", QSOLID);

//Voral de la dreta
textcolor(RED);
cprintf("%c", QRATLLAT);
textcolor(WHITE);
cprintf("%c", QRATLLAT);
textcolor(RED);
cprintf("%c", QRATLLAT);

//Gespa de la dreta
textcolor(GREEN);
for(j=ndre; j<=FINESTRA_W; j++)
cprintf("%c", QSOLID);
}

// Mostra un missatge a l'area de missatges

void MostraMissatge(int missatge){

gotoxy(2, FINESTRA_H);
       cprintf("%s", missatges[missatge]);
}





/*
* correForest.h
*
*/

#include <stdio.h>
#include <conio.h>
// #include <time.h>
#include <stdlib.h>
//#include <mem.h>
#include <Windows.h>

#pragma hdrstop
#pragma argused

/* #include <random.h> */


//Codis ASCII tecles del joc

#define TECLA_ESC    27
#define TECLA_ESQ    75
#define TECLA_DRE    77
#define TECLA_AMUNT       72
#define TECLA_AVALL    80

// Codis dels grafismes

#define DIAMANT          0x04
#define COR              0x03
#define CARA             0x02
#define QSOLID           0xDB
#define QRATLLAT         0xB1

// Tipus pantalla

#define PANTALLA_80x50  C4350


//Posicions minima i maxima del centre
//de la carretera en pantalla
//MIN = -123........o =  1+3+8+1 = 13
//MAX = o........321- = 80-3-8-1 = 68

#define FINESTRA_W      80            // Amplada finestra del joc
#define FINESTRA_H 50            // Alçaria finestra del joc
#define LLARGADA        48            // FINESTRA_H-2 
                                      // Llargada de la carretera
#define AMPLADA         17            // Amplada de la carretera
#define MEITAT_AMP       8            // AMPLADA/2
#define VORAL            3            // Voral de la carretera
#define MEITAT_I_VORAL  11            // MEITAT_AMP + VORAL
#define CENTRE_MIN    13            // Posicio minima pel centre
#define CENTRE_MAX      68            // Posicio maxima pel centre
#define CENTRE_INI      FINESTRA_W/2  // Centre inicial de la carretera
#define INDEX_FIX       40            // Index de referencia fixa pel jugador
#define FILA_FIXA       INDEX_FIX+2   // Fila de referencia fixa pel jugador
#define VIDES_MAX        5
#define VIDES_MIN        1
#define VELO_MAX        10
#define VELO_MIN         1
#define DELAY_SINC     100            // Temporitzacio per sincronisme
#define DELAY_COL      500            // Temporitzacio per col.lisio

// Taula de missatges

char *missatges[] =
{
  "                                   ",
  "QUAN ESTIGUIS LLEST, PREM UNA TECLA",
  "EN MARXA!",
  "CATACROOOOOOOOOOC!!!"
};

// Definicio d'events

typedef enum{
  EVENT_BUIT,
  FI_PARTIDA,
  MOU_ESQUERRA,
  MOU_DRETA,
  MES_VELOCITAT,
  MENYS_VELOCITAT
} tEvent;

//Funcions de l'estructura basica del joc

void Inicialitzacio(void);
void Bucle(void);
void Finalitzacio(void);

void Entrada(tEvent *event);
void Proces(tEvent event);
void Sortida(void);

//Funcions auxiliars

int  Aleatori(void);
void PintaLiniaCarretera(int i);
void BaixadaDeBandera(void);
void MostraVelocitat(void);
void MostraMetres(void);
void MostraVides(void);
void MostraMissatge(int missatge);