Serpiente en modo 13h

El mítico juego de la serpiente programado en C++ en modo 13h a 256 colores. Utiliza la librería dide.h creada por mi para el trabajo con el modo 13h empleando objetos.
				/////// SE.CPP ///////

/*
Este ejercicio ha sido programado por Enrique Espejo Cabrera, Tarragona, 2003.
Por el simple hecho de disfrutar programando.
Es de 1 solo jugador, los parametros son modificables desde código dentro de unos términos lógicos mediante los defines.
Ojo con la libreria dide.h no tiene desperdicio
Espero difruten y saquen probecho del ejemplo.
El código de este documento y el código de la libreria dide.h es de libre distribución SIEMPRE QUE SEA CON FINES EDUCATIVOS, EN CASO CONTRARIO SE DEBE PEDIR COMFIRMACIÓN AL AUTOR
DEL DOCUMENTO, EN ESTE CASO YO, :) [email protected]
Un saludo a todos los Ceceadores de este pequeño planeta.


*/
#include <DidE.h>

#define X 30 // cantidad de cuadros en X
#define Y 30 // cantidadd de cuadros en Y
#define MX 6 // medida en pixeles de cada cuadro en X
#define MY 5 // medida en pixeles de cada cuadro en Y
#define S1 15 // color de snake 1
#define S2 14 // color de snake 2
#define S3 13 // color de snake 3
#define c1 149 // color del cuadro 1
#define c2 150 // color del cuadro 2
#define c3 148 // color del cuadro 3
#define inicioX 50 // distancia de cero con el cuadro en X
#define inicioY 10 // distancia de cero con el cuadro en Y
#define velini 100 // velocidad inicial de la serpiente
#define genesi 7 // numero de cuadros que tiene la snake cuando nace
#define incremento 1 // incremento de velocidad por cada bola de comida
#define crecimiento 3 // numero de partes de serpiente que salen al comer
#define bola 140 // color de la comida de la serpiente
#define MALOS 3 // cantidad de veneno


class snake
{ private:
int x[X*Y]; // pocicion en la cuadricula X
int y[X*Y]; // posicion en la cuadricula Y
int genes; // cantidad de cuadro de la serpiente
int direccion; // 1 arriba 2 derecha 3 abajo 4 izquierda
int estado; // 1 viva 2 muerta
int velocidad; // velocidad de la sepriente
public:
snake();
void dibuja();
int direactual();
void nuevadire(int direc);
void mueve();
void descansa();
void nuevoestado(int est);
int estadoactual();
int dameX();
int dameY();
void masvida();
void muere();
int tamanio();
void masvel();
void renace();
int estan(int xx,int yy);
}


snake::snake()
{ int i=0;
genes=genesi;
direccion = 2;
estado = 1;
velocidad = velini;
for(i=0;i<genesi;i++)
{
x[i]=(X/2)-i;
y[i]=(Y/2);
} }
int snake::estan(int xx, int yy)
{
int i;
int sale=0;
for(i=0;i<genes;i++)
{
if((x[i]==xx)&&(y[i]==yy))
{ sale=1;
}
}
return(sale);
}
void snake::renace()
{
int i=0;
genes=genesi;
direccion = 2;
estado = 1;
velocidad = velini;
for(i=0;i<genesi;i++)
{
x[i]=(X/2)-i;
y[i]=(Y/2);
} }

void snake::dibuja()
{ int i,posx,posy;


for(i=0;i<genes;i++)
{ posx = (x[i] * MX) + inicioX;
posy = (y[i] * MY) + inicioY;
cuadro13(posx,posy,posx+MX,posy+MY,220-i);
if(i==0)
{
recta(posx,posy,posx+MX,posy+MY,220-i);

}

if(i==0)
{
switch(direccion)
{

case 1:
case 3:
pon_punto(posx+(MX/3),posy+(MY/2),15);
pon_punto(posx+(2*(MX/3)),posy+(MY/2),15);
break;
case 2:
case 4:
pon_punto(posx+(MX/2),posy+(MY/3),15);
pon_punto(posx+(MX/2),posy+((MY/3)*2),15);
lineaH(posx+1,posx+MX-1,posy+MX-2,170);
}
}
} }
int snake::direactual()
{ return(direccion);
}
void snake::nuevadire(int direc)
{ direccion=direc;
}
void snake::mueve()
{ int i;
cuadro13(inicioX+(MX*x[genes]),inicioY+(MY*y[genes]),MX+inicioX+(MX*x[genes]),MY+inicioY+(MY*y[genes]),c3);
recta(inicioX+(MX*x[genes]),inicioY+(MY*y[genes]),MX+inicioX+(MX*x[genes]),MY+inicioY+(MY*y[genes]),c1);

for(i=genes;i>0;i--)
{ x[i]=x[i-1];
y[i]=y[i-1];
}
switch(direccion)
{ case 1: y[0]--; break;
case 2: x[0]++; break;
case 3: y[0]++; break;
case 4: x[0]--; break;
}
if ((x[0]==X)||(x[0]==-1)||(y[0]==Y)||(y[0]==-1))
muere();
for(i=2;i<=genes;i++)
if((x[0]==x[i])&&(y[0]==y[i]))
{
muere();
} }
void snake::descansa()
{ delay(velocidad);}
void snake::nuevoestado(int est)
{ estado = est;}
int snake::estadoactual()
{ return(estado);}
int snake::dameX()
{ return(x[0]); }
int snake::dameY()
{ return(y[0]); }
void snake::masvida()
{ int i;
for(i=0;i<crecimiento;i++)
{ genes++;
x[genes]=x[genes-1];
y[genes]=y[genes-1];
}
if (velocidad>20)
velocidad=velocidad-incremento;
}
void snake::masvel()
{
if (velocidad>20 + (incremento*10))
velocidad=velocidad-incremento*10;
}
void snake::muere()
{ estado = 0;
}
int snake::tamanio()
{ return(genes); }
void cuadricula()
{ int i,a;
int distX = (MX * X + inicioX);
int distY = (MY * Y) + inicioY;
for(i=0;i<5;i++)
recta(inicioX-i,inicioY-i,distX+i,distY+i,c2);
cuadro13(inicioX,inicioY,distX,distY,c3);
for(i=inicioX;i<distX;i=i+MX)
lineaV(inicioY,distY,i,c1);
for(a=inicioY;a<distY;a=a+MY)
lineaH(inicioX,distX,a,c1);
lineaH(inicioX,distX,distY,c2);
lineaV(distX,inicioY,distY,c2);
}
void comida(int x, int y,int mx, int color);
void main()
{ snake s;
char tecla,tecla2;
int px,py,p2x[MALOS],p2y[MALOS],i,a,encontrado;
char *puntos;
randomize();
IniMode( 0x13 );
cuadricula();
s.dibuja();
getch();
px=rand()%X;
py=rand()%Y;
for(i=0;i<MALOS;i++)
{ p2x[i]=rand()%X;
p2y[i]=rand()%Y;
}
cuadricula();
while (tecla2!=27)
{ while((tecla!=27)&&(s.estadoactual()==1))
{ if (kbhit())
{ tecla = getch();
switch(tecla)
{ case 72:
if(s.direactual()!=3)
s.nuevadire(1);
break;
case 77:
if(s.direactual()!=4)
s.nuevadire(2);
break;
case 80:
if(s.direactual()!=1)
s.nuevadire(3);
break;
case 75:
if (s.direactual()!=2)
s.nuevadire(4);
} }
else
{ s.mueve();
if (s.estadoactual()==1)
{ s.dibuja();
s.descansa();
}
if ((s.dameX()==px)&&(s.dameY()==py))
{ s.masvida();
do
{ encontrado=0;
px = rand()%X;
py = rand()%Y;
} while(s.estan(px,py)==1);
for(i=0;i<MALOS;i++)
{ comida(p2x[i],p2y[i],MX-1,c3);
p2x[i] = rand()%X;
p2y[i] = rand()%Y;
} }
for(i=0;i<MALOS;i++)
{ if ((s.dameX()==p2x[i])&&(s.dameY()==p2y[i]))
{ s.masvel();
for(a=0;a<MALOS;a++)
{ comida(p2x[a],p2y[a],MX-1,c3);
do {
p2x[a] = rand()%X;
p2y[a] = rand()%Y;
} while(s.estan(p2x[a],p2y[a])==1);
}

}
comida(p2x[i],p2y[i],MX-1,LIGHTRED);
}
comida(px,py,MX-1,14);
gotoxy(10,23);
printf("Puntos: %d - %d",s.tamanio()-genesi,get_pixel(200,100));
} }
cuadro13(1,1,640,480,RED);
gotoxy(5,5);
textcolor(BLUE);
printf("GAME OVER");
gotoxy(5,6);
printf("PUNTUACION: %dnPulsa cualquier tecla para jugar.nEscape para salir.",s.tamanio()-genesi);
sleep(1);
fflush(stdin);
s.renace();
tecla2 = getch();
cuadro13(1,1,800,600,0);
cuadricula();
}
}

void comida(int x,int y, int mx,int color)
{ int i;
x = inicioX + ( MX * x);
y = inicioY + ( MY * y);
cuadro13(x+1,y+1,x+mx,y+mx,color);
}


/////// DIDE.H ///////

/*

Esta libreria ha sido creada por Enrique Espejo Cabrera, Tarragaona , 2003.
La finalidad de estas funciones es disminuir en cantidad y optimizar el código del programa final.
Espero sepan sacar probecho de las siquientes lineas.
El código que aqui se muestra es de libre distribución SIEMPRE QUE SEA CON FINES EDUCATIVOS,
EN CASO CONTRARIO SE DEBE SOLICITAR PERMISO PARA SU PUBLICACIÓN/DISTRIBUCIÓN/MODIFICACIÓN AL RESPECTIVO AUTOR
DEL DOCUMENTO, EN ESTE CASO YO MISMO, :) [email protected]
Reciban un saludo desde el otro lado del cable.
Enrique.





*/

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <dos.h>
#include <math.h>
#include <string.h>
#include <mouse.h>
#define VVID 0xA0000000L
#define CANT 500

char *fondo_mouse;
char *cursor_mouse;
int lx_mouse,ly_mouse;
int x_mouse,y_mouse;
int _mouse_cargado=0;
int _cursor_cargado=0;


typedef enum{F,V} boolea;

void modo_13h();
void modogra();
void cuadro(int x1,int y1,int x2, int y2, int color);
void boton(char *cadena,int x1,int y1, int x2, int y2, int color);
void IniMode (char Mode);//prototipo de la funcion

int get_pixel(int x, int y)
{
char color;
int offset=320*y+x;
color=peekb(0xA000,offset);
return color;
}


void IniMode(char Mode) //nueva funcion
{
asm xor ah, ah
asm mov al, Mode
asm int 10h
}




//Procedimiento que vuelve al modo texto 03h
void modo_texto()
{
asm mov ah,0x00 //Funci¢n que fija el modo de v¡deo
asm mov al,0x03 //Coloca el v¡deo en modo texto
asm int 0x10 //Llama a la interrupci¢n del v¡deo
}

//Procedimiento que visualiza un punto en pantalla
void pon_punto(int x,int y,unsigned char color)
{
asm{
mov ax,0xA000
mov es,ax // {; Point to segment of screen }
mov dx,[y]
mov bx, dx // {; bx = dx}
mov dh, dl // {; dx = dx * 256}
xor dl, dl
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1
shl bx, 1 // {; bx = bx * 64}
add dx, bx // {; dx = dx + bx (ie y*320)}
mov bx,[x] // {; get our x}
add bx, dx // {; finalise location}
mov di, bx // {; di = offset }
// {; es:di = where to go}
mov ah, [color]
mov es:[di],ah // {; move the value in ah to screen
// point es:[di] }
} //equivale a esto:
// pokeb(0xA000,y*320+x,Color); //Ponemos un byte en la memoria de v¡deo
}

void modo_13h()
{
asm mov ah,0x00 //Funci¢n que fija el modo de v¡deo
asm mov al,0x13 //Coloca el v¡deo en modo 13 (320x200x256)
asm int 0x10 //Llama a la interrupci¢n del v¡deo
}







// RECTANGLE CON LOS BORDER DE COLORES
void lineaH(int x1,int x2,int y,int color)
{
int i;
for(i=x1;i<=x2;i++)
{
pon_punto(i,y,color);
}
}
void lineaV(int y1,int y2,int x, int color)
{
int i;
for(i=y1;i<=y2;i++)
{
pon_punto(x,i,color);
}
}

void recta(int x1, int y1, int x2, int y2,int color)
{
lineaH(x1,x2,y1,color);
lineaH(x1,x2,y2,color);
lineaV(y1,y2,x1,color);
lineaV(y1,y2,x2,color);
}
void cuadro13(int x1,int y1, int x2, int y2, int color)
{
int i;
for(i=y1;i<y2;i++)
{
lineaH(x1,x2,i,color);
}
}


int activa_mouse()
{
union REGS r;


r.x.ax=SERV_ACTIVA_MOUSE;

int86(INT_MOUSE,&r,&r);
if (r.x.ax){
_mouse_cargado=1;
return 1;
}
return 0;
}

int get_x_mouse()
{
union REGS r;

r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.cx;
}
int get_y_mouse()
{
union REGS r;

r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.dx;
}

int pulsado_left()
{
union REGS r;

r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.bx&1;
}
int pulsado_right()
{
union REGS r;

r.x.ax=SERV_GET_MOUSE_STATUS;
int86(INT_MOUSE,&r,&r);
return r.x.bx&2;
}
/*
void carga_cursor (char *nombre_fichero)
{
int i,j;
FILE *fp;

if ((fp=fopen(nombre_fichero,"rb"))==NULL){
printf("Error al abrir el fichero %s",nombre_fichero);
exit (EXIT_FAILURE);
}



if (!_mouse_cargado) return;
if (_cursor_cargado) libera_cursor();

fread(&lx_mouse,sizeof (char),1,fp);
fread(&ly_mouse,sizeof (char),1,fp);
x_mouse=LX/2;
y_mouse=LY/2;

if ((fondo_mouse=malloc(sizeof (char)*lx_mouse*ly_mouse))==NULL){
printf("Error de memoria");
exit(EXIT_FAILURE);
}
if ((cursor_mouse=malloc(sizeof (char)*lx_mouse*ly_mouse))==NULL){
printf("Error de memoria");
exit(EXIT_FAILURE);
}

fread(cursor_mouse,sizeof (char)*lx_mouse*ly_mouse,1,fp);
fclose(fp);
lee_sprite(x_mouse,y_mouse,lx_mouse,ly_mouse,fondo_mouse);
_cursor_cargado=1;

}

void pinta_mouse()
{
if (!_cursor_cargado) return;
borra_mouse();
if ( (x_mouse=get_x_mouse())>LX-lx_mouse){
x_mouse=LX-lx_mouse;
set_xy_mouse(x_mouse,y_mouse);
}
if ( (y_mouse=get_y_mouse())>LY-ly_mouse){
y_mouse=LY-ly_mouse;
set_xy_mouse(x_mouse,y_mouse);
}
lee_sprite(x_mouse,y_mouse,lx_mouse,ly_mouse,fondo_mouse);
pon_sprite(x_mouse,y_mouse,lx_mouse,ly_mouse,cursor_mouse);

}

void set_xy_mouse(int x,int y)
{
union REGS r;

r.x.ax=SERV_SET_MOUSE_XY;
r.x.cx=x;
r.x.dx=y;
int86(INT_MOUSE,&r,&r);
}

void borra_mouse()
{
if (!_cursor_cargado) return;
pon_sprite(x_mouse,y_mouse,lx_mouse,ly_mouse,fondo_mouse);
}
*/
int mouse_movido()
{
if (!_cursor_cargado) return 0;
if (x_mouse!=get_x_mouse() || y_mouse!=get_y_mouse())
return 1;
return 0;
}

void libera_cursor()
{
free (cursor_mouse);
free (fondo_mouse);
_cursor_cargado=0;
}
Descargar adjuntos
COMPARTE ESTE TUTORIAL

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
TUTORIAL ANTERIOR

SIGUIENTE TUTORIAL