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);