December 29, 2007

My first game in C

So I had to do a project in C using graphics. What's better than creating a game? So I got started right off with it. Starting off with the simplest one I made that game where in you have all those cars goin straight on the road and you need to go through without hitting them. It was a simple approach and Here's how I did it:





class UCAR
{
int col;
public:
UCAR ()
{
x=getmaxx()/2;
y=getmaxy()/2;
}
void drawcar ();
void movecar (char key);
void selcol ();
};
UCAR car;

void UCAR :: drawcar ()
{
setcolor (col);
line (x-10,y-20,x-10,y+20);
line (x+10,y-20,x+10,y+20);
ellipse (x,y+20,180,0,10,3);
ellipse (x,y-20,0,180,10,5);
setfillstyle (SOLID_FILL,col);
floodfill (x-8,y-18,col);
line (x-8,y-6,x-8,y+15);

setcolor (col+8);
setfillstyle (SOLID_FILL,col+8);
rectangle (x-10,y-20,x-8,y+15);
rectangle (x-10,y+16,x-9,y+20);
line (x-10,y-21,x+10,y-21);
line (x-9,y-22,x+9,y-22);
line (x-9,y-19,x-9,y+16);
rectangle (x-8,y-4,x+8,y+15);
line (x-9,y+21,x-8,y+21);
line (x-8,y+22,x-8,y+22);
line (x-8,y+16,x-7,y+16);
line (x-8,y+17,x-8,y+18);

line (x,y-3,x,y+3);
line (x-3,y-3,x-3,y+3);
line (x+3,y-3,x+3,y+3);

line (x-5,y+23,x-5,y+19);
line (x-4,y+18,x+4,y+18);

setcolor (7);
line (x-11,y-12,x-11,y-9);
line (x+11,y-12,x+11,y-9);
line (x-11,y+11,x-11,y+14);
line (x+11,y+11,x+11,y+14);

setfillstyle (SOLID_FILL,7);
line (x-3,y-9,x+3,y-9);
line (x-2,y-10,x+2,y-10);

setcolor (8);
rectangle (x-4,y-24,x+4,y-23);
rectangle (x-3,y-7,x+3,y-8);

line (x-11,y-15,x-11,y-6);
line (x+11,y-15,x+11,y-6);
line (x-11,y+8,x-11,y+17);
line (x+11,y+8,x+11,y+17);

setcolor (15);
line (x-5,y-23,x-7,y-23);
line (x+5,y-23,x+7,y-23);

line (x-8,y-3,x+8,y-3);
line (x-9,y-4,x+9,y-4);
line (x-8,y+15,x+8,y+15);
}

void UCAR :: movecar (char key)
{
if (!flag)
{
if ((key==72 || key=='w') && y>30)
y-=10;
if ((key==75 || key=='a') && x>200)
x-=10;
if ((key==80 || key=='s') && y<440)
y+=10;
if ((key==77 || key=='d') && x<430)
x+=10;
}
}

void UCAR :: selcol ()
{
int menu=1;
char key;
settextjustify (0,0);
settextstyle (DEFAULT_FONT, HORIZ_DIR, 1);

while (1)
{
if (menu==1)
setcolor (9);
else
setcolor (1);
outtextxy (100,420,"[color]");

if (menu==2)
setcolor (10);
else
setcolor (2);
outtextxy (200,420,"[color]");

if (menu==3)
setcolor (11);
else
setcolor (3);
outtextxy (300,420,"[color]");

if (menu==4)
setcolor (12);
else
setcolor (4);
outtextxy (400,420,"[color]");

if (menu==5)
setcolor (13);
else
setcolor (5);
outtextxy (500,420,"[color]");

key=0;
if (kbhit ())
key=getch ();

if (key=='a' || key==75)
{
menu--;
if (menu<1)
menu=5;
}
if (key=='d' || key==77)
{
menu++;
if (menu>5)
menu=1;
}

if (key==' ' || key==13)
break;
}
col=menu;
}

// Other cars

class OCAR
{
int cx,cy,ccol;
public:
OCAR ()
{
cx=200+random(240);
cy=-20;
ccol=1+random(5);
}
void drawocar ();
void moveocar ();
int checkohit ();
};

void OCAR :: drawocar ()
{
setcolor (ccol);
line (cx-10,cy-16,cx-10,cy+20);
line (cx+10,cy-16,cx+10,cy+20);
ellipse (cx,cy+20,180,0,10,3);
ellipse (cx,cy-16,0,180,10,5);
setfillstyle (SOLID_FILL,ccol);
floodfill (cx-8,cy-15,ccol);

setcolor (ccol+8);
rectangle (cx-8,cy-2,cx+8,cy+13);
rectangle (cx-10,cy-16,cx-9,cy+20);
line (cx-10,cy-17,cx+10,cy-17);
line (cx-9,cy-18,cx+9,cy-18);

setcolor (15);
line (cx-5,cy-19,cx-7,cy-19);
line (cx+5,cy-19,cx+7,cy-19);

setcolor (7);
line (cx-8,cy-2,cx+8,cy-2);
line (cx-9,cy-3,cx+9,cy-3);
}

void OCAR :: moveocar ()
{
cy+=8;
}

int OCAR :: checkohit ()
{
int tcx,tcy;
tcx=abs(x-cx);
tcy=abs(y-cy);
if (tcx<=20 && tcy<=40 && cy<=440)
return 1;
else
return 0;
}

// Taxi (that moves even along X axis)

class TAXI
{
int tx,ty,lr;
public:
TAXI ()
{
ty=-20;
tx=200+random(240);
lr=1;
}
void drawtaxi ();
void movetaxi ();
int checkthit ();
};

void TAXI :: drawtaxi ()
{
setcolor (14);
line (tx-10,ty-16,tx-10,ty+20);
line (tx+10,ty-16,tx+10,ty+20);
ellipse (tx,ty+20,180,0,10,3);
ellipse (tx,ty-16,0,180,10,5);
setfillstyle (SOLID_FILL,14);
floodfill (tx-8,ty-15,14);

setcolor (15);
rectangle (tx-8,ty-2,tx+8,ty+13);
rectangle (tx-10,ty-16,tx-9,ty+20);
line (tx-10,ty-17,tx+10,ty-17);
line (tx-9,ty-18,tx+9,ty-18);

setcolor (15);
line (tx-5,ty-19,tx-7,ty-19);
line (tx+5,ty-19,tx+7,ty-19);

setcolor (7);
line (tx-8,ty-2,tx+8,ty-2);
line (tx-9,ty-3,tx+9,ty-3);
}

void TAXI :: movetaxi ()
{
ty+=8;
if (tx<220)
lr=1;
if (tx>440)
lr=0;
if (lr==0)
tx-=5;
if (lr==1)
tx+=5;
}

int TAXI :: checkthit ()
{
int tcx,tcy;
tcx=abs(x-tx);
tcy=abs(y-ty);
if (tcx<=20 && tcy<=40 && ty<=440)
return 1;
else
return 0;
}

// Lorrys

class LORRY
{
int lx,ly,lcol;
public:
LORRY ()
{
lx=200+random(240);
ly=-30;
lcol=1+random (5);
}
void drawlor ();
void movelor ();
int checklhit ();
};

void LORRY :: drawlor ()
{
setcolor (lcol);
rectangle (lx-13,ly-27,lx+13,ly-5);
setfillstyle (SOLID_FILL,lcol);
floodfill (lx-12,ly-26,lcol);
line (lx-13,ly-25,lx+13,ly-25);

setcolor (lcol+8);
rectangle (lx-12,ly-24,lx-11,ly-6);
rectangle (lx-10,ly-24,lx+12,ly-23);

setcolor (7);
rectangle (lx-15,ly-3,lx+15,ly+80);
setfillstyle (SOLID_FILL,7);
floodfill (lx-14,ly,7);

setcolor (8);
rectangle (lx+14,ly-1,lx+15,ly+80);
rectangle (lx-13,ly+79,lx+13,ly+80);

setcolor (15);
rectangle (lx-15,ly-3,lx-14,ly+80);
rectangle (lx-13,ly-3,lx+15,ly-2);
line (lx-8,ly-27,lx-6,ly-27);
line (lx+8,ly-27,lx+6,ly-27);
}

void LORRY :: movelor ()
{
ly+=10;
}

int LORRY :: checklhit ()
{
int tcx,tcy;
tcx=abs(x-lx);
tcy=abs(y-ly);
if (tcx<=20 && tcy<=40 && ly<=440)
return 1;
else
return 0;
}

// Function when the car bangs into something

void carcrash ()
{
int i,j;
for (i=0;i<10;i++)
for (j=1;j<15;j++)
{
setcolor (j);
ellipse (x,y,0,360,20,40);
}
}

// Main function ------------------------------------------------------------

void highway_car ()
{
int count=0,score=0,fuellev;
int tf=0,i;
int cc=-1,ll=-1;
char key,buf[10];

OCAR ocar[500];
TAXI taxi[300];
LORRY lor[300];

x=getmaxx ()/2;
y=getmaxy ()/2;

while (1)
{
cleardevice ();

if (tf>=950)
tf=0;
if (flag==0)
tf+=15;

setcolor (8);
rectangle (30,tf-140,160,tf-120);
rectangle (490,tf-340,600,tf-320);
rectangle (30,tf-20,160,tf);
rectangle (490,tf-80,600,tf-60);
rectangle (30,tf-500,160,tf-480);

rectangle (180,-1,460,480);
rectangle (175,-1,465,480);
setcolor (15);

key='1';
if (kbhit())
{
key=getch ();
if (flag==0)
car.movecar (key);
}
if (key=='o' || key=='O' || key==27)
break;

car.drawcar ();

if (count%20==0 && !flag)
cc++;
for (i=0;i< cc;i++)
{
if (i%7==0)
{
taxi[i].drawtaxi ();
if (!flag)
taxi[i].movetaxi ();
if (taxi[i].checkthit ())
flag=1;
}
else
{
ocar[i].drawocar ();
if (!flag)
ocar[i].moveocar ();
if (ocar[i].checkohit ())
flag=1;
}
}

if (count%55==0 && !flag)
ll++;
for (i=0;i {
lor[i].drawlor ();
if (!flag)
lor[i].movelor ();
if (lor[i].checklhit ())
flag=1;
}

if (flag==1)
carcrash ();

if (!flag)
score=count-50;

setcolor (15);
settextjustify (0,0);
sprintf (buf,"Score : %d",score);
outtextxy (10,8,buf);

count ++;

delay (50);
}

FILE *fp;
char name[10];

fp=fopen ("hcscores.txt","r");
getscores (fp);
fclose (fp);
if (score>fscore)
{
fopen ("hcscores.txt","w");
clrscr ();
cleardevice ();
cout << "\n\n\n\tYou nave the highest score!";
cout << "\n\n\n\tEnter name : ";
cin >> name;
fprintf (fp,"%d %s\n",score,name);
fclose (fp);
}
}



Ok... That was the code part. I haven't written any comments because I wrote it many years ago when I still hadn't realized the value of comments. If you're trying to understand it then you should start commenting your programs. Its pretty important.


Time for a quick explanation - There are four classes.


UCAR is the user's car which is controlled by the input. The movement is controlled by the keyboard keys WASD or the ARROW KEYS. It also has a select color function which I created mainly because of the 16 colors that I can use. If you've used TurboC, you might try changing the background color and all in the options menu. You'll see that there are eight basic (they're not basic actually) colors and the same are in lighter shades also. The colors are numbered from 0 being black till 15 being white. Now if you select the 'basic' color and add 8 you'll get the lighter shade of the same. I just wanted to use it in this program. Im drawing the car using lots of lines and curves because I was using clearscreen in the while loop and I wanted to reduce the flickering effect.


OCAR is the other car which keeps moving. Its pretty much the same as the previous one but im checking for crash with the user's car. The position of the user's car (int x,y) is global. The OCARs just keep moving down and there are some rectangles outside the road like thing which moves down faster than the OCARs which gives the impression of the UCAR moving up.


LORRYs are just OCARs with a differevt shape and size


TAXIs not only move along the Y axis but also along the X axis. Rest of it is just an OCAR.



Well, that's about it. My actual program has three games and I just wanted to put this code here. So just figure out the missing parts the headers and the main program which is not much actually.

December 27, 2007

Intro

I've been studying Computer Science for the past few years and I've learnt quite a few things. Enough to write a blog about. Someone may someday find this useful.

So... Cheers to my new blog!