The game is well know game - Space Invader. We implemented during our second semester of Bachelor of Engineering (Computer Science). We used simple BGI graphics library.
#include <stdio.h>
#include <iostream.h>
#include <conio.h>
#include <graphics.h>
#include <dos.h> //for delay()
#include <stdlib.h> //for malloc()
#include <ctype.h> //for tolower()
#include <bios.h>
#include <string.h>
#include <iomanip.h>
#define SPACE 0x3920
#define ESC 0x11b
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DELAYSHOT 15
#define DELAYSHOTBYALIENS 10
//int gameLevel = 1;
int gameSpeed = 1;
int score;
class Alien;
class shot
{
private:
int centerX, centerY; //coordinate positions of shots
//for the capture of bulletImage
unsigned int shotSize;
void *shotBuffer;
int shotsLife; //to determine if bullet exists or not
public:
shot(){};
shot(int , int );
void drawAndCapture();
inline int deadAlive(); //returns 0 if bullet is destroyed else returns 1
void deleteShots();
void move();
void checkForHit(Alien &); //didn't work when passed by value
};
class ship
{
private:
int x;
void *shipBuff;
unsigned int shipSize;
int shipLife;
public:
int left, top, right, bottom,length;
public:
ship(){}
ship(int ,int ,int,int);
void draw();
void capture();
void deleteShip();
inline int getShipLife();
void checkForCollisionWithAliens(Alien &);
void move();
};
class shotByAliens
{
private:
int centerX, centerY; //position of the shotByAliens
int shotByAliensLife; //shot exists if its value is 1
//to capture image
void *shotByAliensBuffer;
unsigned int shotByAliensSize;
public:
shotByAliens();
shotByAliens(Alien);
void drawAndCapture();
void deleteShotByAliens();
inline int getShotByAliensLife();
void move();
void checkForHit(ship &);
};
class Alien
{
private:
int centerX,centerY; //center coordinates of each alien
//for capturing image
void *alienBuff;
unsigned int imgSize;
//for deleting aliens
void *alienBuff2;
unsigned int imgSize2;
int toDelete; //if its value is 1, allows to delete upward aliens
int n; //its value used to skip erasing of
//upward aliens in very first movement towards right
int count; //determines how much has the aliens have moved
int dir; //dtermines in which direction should the aliens move
int left,top;
int aliensLife; //determines whether the aliens are alive or killed
public:
Alien();
void friend shot::checkForHit(Alien &);
friend shotByAliens::shotByAliens(Alien);
void friend ship::checkForCollisionWithAliens(Alien &);
void assignCoordinate(int , int ); //assigns initial center coordinates to each aliens
void resetDatas();
void drawAlien(int , int , int );
void capture();//capture the image of aliens
void capture2(); //capture the blank space
void move(); //move the aliens left and right
void deleteAlien();
inline int getAliensLife();
inline int getCenterY(); //get xcoordinate of the alien
};
class checkForLevelClear
{
public:
int check(Alien aliens[4][4]);
};
class welcome
{
public:
void display();
};
class gameover
{
public:
void display();
};
class completionOfLevel
{
public:
void display();
};
class congratulations
{
public:
void display();
};
class drawGameField
{
public:
void draw();
};
///////////////////////////////////universal variables
shot *shots[10];
ship ship1(300,440,350,450);
shotByAliens *alienShot[40];
gameover gameOver;
//////////////////////////////FUNCTIONS DEFINITIONS FOR CLASS SHOT
shot::shot(int x, int y)
{
centerX = x;
centerY = y;
shotsLife = 1; //bullet comes to life
}
void shot::drawAndCapture()
{
setcolor(4);
setfillstyle(SOLID_FILL,6);
fillellipse(centerX,centerY,3,3);
//capture bullet image
shotSize = imagesize(centerX - 5,centerY - 5, centerX + 5, centerY + 5);
shotBuffer = malloc(shotSize);
getimage((centerX - 4), (centerY - 4), (centerX + 4), (centerY + 4), shotBuffer);
}
int shot::deadAlive() //returns 0 if bullet is destroyed else returns 1
{
return shotsLife;
}
void shot::deleteShots()
{
putimage(centerX-4, centerY-4, shotBuffer, XOR_PUT); //to erase residue drawing of the bullet
shotsLife = 0; //indicates bullet is destroyed
}
void shot::move()
{
if(shotsLife == 1)
{
if(centerY > 55)
{
putimage(centerX-4, centerY-4, shotBuffer, XOR_PUT);
centerY-=5;
putimage(centerX-4, centerY-4, shotBuffer, XOR_PUT);
}
if(centerY <= 55)
{
//putimage(centerX-4, centerY-4, shotBuffer, XOR_PUT);
deleteShots();
}
}
}
void shot::checkForHit(Alien &alien)
{
if(alien.aliensLife == 1) //to hit alien, alien itself should be alive
{
if(centerX > alien.centerX-15 && centerX < alien.centerX+15 && centerY < alien.centerY+15 && centerY > alien.centerY-15)
{
this->deleteShots();
alien.deleteAlien();
score += 10*gameSpeed;
}
}
}
/////////////////////////////FUNCTIONS DEFINITIONS FOR CLASS SHIP
ship::ship(int leftX, int topY, int rightX, int bottomY)
{
left = leftX;
top = topY;
right = rightX;
bottom = bottomY;
length = right - left;
shipLife = 1;
}
void ship::draw()
{
setcolor(14);
rectangle(left,top,right,bottom);
setfillstyle(SOLID_FILL,13);
bar(left, top, right, bottom);
}
void ship::capture()
{
shipSize = imagesize(left, top, right, bottom);
shipBuff = malloc(shipSize);
getimage(left, top, right, bottom, shipBuff);
}
void ship::deleteShip()
{
putimage(left,top,shipBuff,XOR_PUT);
shipLife = 0;
}
int ship::getShipLife()
{
return shipLife;
}
void ship::checkForCollisionWithAliens(Alien &alien)
{
if(shipLife == 1 && alien.aliensLife == 1)
{
if(alien.centerX+15 >= left && alien.centerX-15 <= right && alien.centerY +15 >= top)
{
ship1.deleteShip();
//gameOver.display();
//closegraph();
//exit(0);
}
}
}
void ship::move()
{
if(shipLife == 1)
{
static delayShot=DELAYSHOT; //this value will be used to
//delay the shot after a preceeding shot
if(kbhit())
{
x = _bios_keybrd(_KEYBRD_READ);
if(x == RIGHT && left < (610 - length))
{
putimage(left,top, shipBuff, XOR_PUT);
putimage(left+10, top, shipBuff, XOR_PUT);
left+=10;
right+=10;
}
else if(x == LEFT && left > 90)
{
putimage(left,top, shipBuff, XOR_PUT);
putimage(left-10,top, shipBuff, XOR_PUT);
left-=10;
right-=10;
}
else if(tolower((char)x) == 'z')
{
if(delayShot == DELAYSHOT) //shot only after delayShot
//has gained value 20 from 0
{
static int recycleShots=0; //
shots[recycleShots] = new shot((left+(right-left)/2) , top-20);
//cout<<"\a";
shots[recycleShots]->drawAndCapture();
recycleShots++;
if(recycleShots == 9) //recycleShots =9 means
//all available shots are used up
recycleShots=0; //recycle the shots form beginning
delayShot = 0; //it will stop the shot for a
//moment till it becomes 20
}
}
if(x == ESC)
{
closegraph();
exit (0);
}
} //end of if(kbhit())
if(delayShot <DELAYSHOT)
delayShot++;
} //end if(shipLife == 1)
}//end move()
//////////////////////////FUNCTIONS DEFINITIONS OF CLASS SHOTBYALIENS
shotByAliens::shotByAliens():centerX(getmaxx()),centerY(getmaxy()){}
shotByAliens::shotByAliens(Alien alien)
{
centerX = alien.centerX; //assigns x coordinate
//of alien to shot
centerY = alien.centerY+20; //assigns y coordinate
//of alien to shot
shotByAliensLife = 1; //bring the shot to life
}
void shotByAliens::drawAndCapture()
{
setcolor(4);
setfillstyle(SOLID_FILL,11);
fillellipse(centerX,centerY,3,3);
//capture bullet image
shotByAliensSize = imagesize(centerX - 5,centerY - 5, centerX + 5, centerY + 5);
shotByAliensBuffer = malloc(shotByAliensSize);
getimage((centerX - 4), (centerY - 4), (centerX + 4), (centerY + 4), shotByAliensBuffer);
}
void shotByAliens::deleteShotByAliens()
{
putimage(centerX-4, centerY-4, shotByAliensBuffer, XOR_PUT); //to erase residue drawing of the bullet
shotByAliensLife = 0; //indicates shot is destroyed
}
int shotByAliens::getShotByAliensLife()
{
return shotByAliensLife;
}
void shotByAliens::move()
{
if(shotByAliensLife == 1)
{
if(centerY < 445)
{
putimage(centerX-4, centerY-4, shotByAliensBuffer, XOR_PUT);
centerY += 5;
putimage(centerX-4, centerY-4, shotByAliensBuffer, XOR_PUT);
}
if(centerY >= 445)
{
//putimage(centerX-4, centerY-4, shotByAliensBuffer, XOR_PUT);
deleteShotByAliens();
}
}
}
void shotByAliens::checkForHit(ship &ship1)
{
if(centerX > ship1.left-3 && centerX < ship1.right+3 && centerY+3 >= ship1.top)
{
this->deleteShotByAliens();
ship1.deleteShip();
}
}
///////////////////////////////FUNCTIONS DEFINITIONS FOR CLASS ALIEN
Alien::Alien():toDelete(1),n(1),count(0),dir(1),aliensLife(1){}
void Alien::assignCoordinate(int x, int y) //assigns initial center coordinates to each aliens
{
centerX = x;
centerY = y;
left = centerX -16;
top = centerY -16;
}
void Alien::resetDatas()
{
toDelete = 1;
n = 1;
count = 0;
dir = 1;
aliensLife = 1;
}
void Alien::drawAlien(int x, int y, int r)
{
setcolor(14);
setfillstyle(SOLID_FILL , BLUE);
fillellipse(x, y, r, r);
setfillstyle(SOLID_FILL , BLACK);
fillellipse(x-5, y-5, 3, 2);
setfillstyle(SOLID_FILL , BLACK);
fillellipse(x+5, y-5, 3, 2);
setfillstyle(SOLID_FILL , BLACK);
fillellipse(x, y+5, 5, 2);
}
void Alien::capture()//capture the image of aliens
{
imgSize = imagesize(centerX-16, centerY-16, centerX+16, centerY+16);
alienBuff = malloc(imgSize);
getimage(centerX-16, centerY-16, centerX+16, centerY+16, alienBuff);
}
void Alien::capture2() //capture the blank space
{
imgSize2 = imagesize(centerX-16, centerY-16, centerX+16, centerY+16);
alienBuff2 = malloc(imgSize2);
getimage(centerX-16, centerY-16, centerX+16, centerY+16, alienBuff2);
}
void Alien::move() //move the aliens left and right
{
//if(aliensLife == 1)
//{
static int distance;
if(gameSpeed == 1)
distance=200;
else if(gameSpeed == 2)
distance = 100;
else
distance=66;
if(dir == 1) //move the aliens towards right
{
if(n > 1) //will not be executed at first time because n =1
{
if(toDelete == 1)
{
if(aliensLife == 1)
putimage(left, top-40, alienBuff, XOR_PUT); //deletes upward aliens
else
putimage(left, top-40, alienBuff2, XOR_PUT);
toDelete = 0;
centerY += 40; //try
} //end of if(toDelete ==1)
} //end of if(n>1)
left+= gameSpeed;
if(aliensLife == 1)
{
putimage(left, top, alienBuff, XOR_PUT); //creates new aliens (may change)
putimage(left-gameSpeed, top, alienBuff, XOR_PUT); //deletes (may change)
}
else
{
putimage(left, top, alienBuff2, XOR_PUT);
putimage(left-gameSpeed, top, alienBuff2, XOR_PUT);
}
centerX+= gameSpeed; //coordinate of each alien is changed
//every time they move
count++;
if(count == distance)
{
dir =0;
top+=40;
//centerY+=40; //change of coordinate of alien
count = 0;
toDelete = 1;
if(aliensLife == 1)
putimage(left, top, alienBuff, XOR_PUT); //creates new aliens at down position
//which will be erased by putimage() function
else
putimage(left, top, alienBuff2, XOR_PUT);
if(n == 1)
n++; //to denote that first right movement is escaped
} //end of if(count == 200)
} //end of if(dir ==1)
else //move the aliens towards left
{
if(toDelete == 1)
{
if(aliensLife == 1)
putimage(left, top-40, alienBuff, XOR_PUT);
else
putimage(left, top-40, alienBuff2, XOR_PUT);
toDelete = 0;
centerY+=40; //try
} //end of if(toDelete == 1)
left-= gameSpeed;
if(aliensLife == 1)
{
putimage(left , top , alienBuff, XOR_PUT);
putimage(left+gameSpeed, top, alienBuff, XOR_PUT);
}
else
{
putimage(left, top, alienBuff2, XOR_PUT);
putimage(left+gameSpeed, top, alienBuff2, XOR_PUT);
}
centerX-= gameSpeed;
count++;
if(count == distance)
{
dir =1;
top += 40;
//centerY += 40;
count = 0;
//n = 3;
toDelete = 1;
if(aliensLife == 1)
putimage(left , top , alienBuff, XOR_PUT); //creates new aliens at down position
//which will be erased by putimage() function
else
putimage(left, top, alienBuff2, XOR_PUT);
} //end of if(count ==distance)
} //end of else
//} //end of if(aliensLife == 1)
} // end of function move()
void Alien::deleteAlien()
{
putimage(left , top , alienBuff, XOR_PUT);
aliensLife = 0;
}
int Alien::getAliensLife()
{
return aliensLife;
}
int Alien::getCenterY()
{
return centerY;
}
/////////////////////FUNCTION DEFINITIONS FOR CLASS CHECKFORLEVELCLEAR
int checkForLevelClear::check(Alien aliens[4][4])
{
int clear = 1;
for(int j=0; j<4; j++)
{
for(int i=0; i<4; i++)
{
if(aliens[i][j].getAliensLife())
{
clear = 0;
break;
}
}
if(clear == 0)
break;
}
return clear;
}
////////////////////////////////FUCNTION DEFINITIONS FOR CLASS WELCOME
void welcome::display()
{
setcolor(11);
delay(1500);
settextstyle(0,0,2);outtextxy(40,60,"SABBIR KUMAR MANANDHAR");
setcolor(10);outtextxy(410,60,"[062-BCT-537]");
setcolor(11);
settextstyle(0,0,2);outtextxy(105,120,"SUVASH SEDHAIN");
setcolor(10);outtextxy(350,120,"[062-BCT-548]");
delay(250);
setcolor(12);
settextstyle(0,0,3);outtextxy(230,200,"Presents");
settextstyle(0,0,3);outtextxy(125,240,"A Project on C++");
delay(250);
while(!kbhit())
{
int i=rand();
setcolor(i);
settextstyle(0,0,8);outtextxy(160,300,"SPACE");
settextstyle(0,0,8);outtextxy(100,370,"INVADER");
}
cleardevice();
setcolor(13);
settextstyle(0,0,2);
int ch;
while(ch != SPACE)
{
outtextxy(100,300,"Press SPACEBAR to START...");
getch();
ch = _bios_keybrd(_KEYBRD_READ);
}
cleardevice();
}
///////////////////////////////FUNCTION DEFINITIONS OF CLASS GAMEOVER
void gameover::display()
{
cleardevice();
setcolor(11);
settextstyle(0,0,4);
outtextxy(50,150,"You Lost the game!");
char stringScore[5];
itoa(score,stringScore,10); //itoa() converts integer to string
setcolor(13);
settextstyle(0,0,2);
outtextxy(130,300,"Your Total Score is");
outtextxy(460,300,stringScore);
setcolor(10);
settextstyle(0,0,2);
//outtextxy(120,400,"Want to play again? (y/n)");
outtextxy(65,450,"press the ESC key to continue....");
int ch;
while(ch != ESC)
{
ch = _bios_keybrd(_KEYBRD_READ);
}
cleardevice();
}
/////////////////////FUNCTIONS DEFINITIONS FOR CLASS COMPLETIONOFLEVEL
void completionOfLevel::display()
{
char levelOne[] = "Level 1 completed!";
char levelTwo[] = "Level 2 completed!";
cleardevice();
setcolor(14);
settextstyle(0,0,4);
if(gameSpeed-1 == 1)
outtextxy(60,150,levelOne);
else
outtextxy(60,150,levelTwo);
char stringScore[5];
itoa(score,stringScore,10); //itoa() converts integer to string
setcolor(13);
settextstyle(0,0,2);
outtextxy(115,300,"Your Score till now is");
outtextxy(475,300,stringScore);
setcolor(10);
settextstyle(0,0,2);
int ch;
while(ch != SPACE)
{
outtextxy(20,450,"Press SPACEBAR to continue next level");
ch = _bios_keybrd(_KEYBRD_READ);
}
cleardevice();
}
///////////////////////////FUCNTIONS DEFINITIONS FOR CLASS CONGRATULATIONS
void congratulations::display()
{
cleardevice();
setcolor(14);
settextstyle(0,0,4);
outtextxy(80,110,"CONGRATULATIONS!");
setcolor(10);
settextstyle(0,0,2);
outtextxy(110,215,"You have completed the game!");
char stringScore[5];
itoa(score,stringScore,10); //itoa() converts integer to string
setcolor(13);
settextstyle(0,0,2);
outtextxy(130,300,"Your Total Score is");
outtextxy(460,300,stringScore);
setcolor(12);
settextstyle(0,0,2);
outtextxy(100,450,"press ESC to continue.......");
int ch;
while(ch != ESC)
{
ch = _bios_keybrd(_KEYBRD_READ);
}
cleardevice();
}
////////////////////////////FUNCTIONS DEFINITIONS FOR CLASS DRAWGAMEFIELD
void drawGameField::draw()
{
setfillstyle(SOLID_FILL,4);
bar(0, 0, getmaxx(), 50);
bar(0, 452, getmaxx(), getmaxy());
setfillstyle(SOLID_FILL,GREEN);
bar(0, 0, 80,getmaxy());
bar(620, 0, getmaxx(), getmaxy());
setcolor(YELLOW);
line_widths(3);
rectangle(80, 0, 620, getmaxy());
settextstyle(0,0,2);
setcolor(14);
outtextxy(200,20,"Press ESC to quit...");
char level[6];
settextstyle(0,1,3);
setcolor(14);
outtextxy(50,200,"LEVEL");
if(gameSpeed == 1)
strcpy(level,"ONE");
else if(gameSpeed == 2)
strcpy(level,"TWO");
else
strcpy(level,"THREE");
outtextxy(50,70,level);
}
////////////////////////////////////////////////////////////////////////
void reassignLifeToAliens(Alien aliens[4][4])
{
for(int j=0; j<4; j++)
{
for(int i=0; i<4; i++)
aliens[i][j].resetDatas();
}
}
void startGraph()
{
int driver = DETECT, mode;
initgraph( &driver , &mode , "c:\\tc\\bgi");
}
int main()
{
startGraph();
drawGameField gameField;
completionOfLevel levelClear;
congratulations congrats;
checkForLevelClear clearOrNot;
Alien aliens[4][4];
welcome welCome;
welCome.display();
do
{
gameField.draw();
ship1.draw();
if(gameSpeed == 1)
ship1.capture();
for(int j=0 ; j<4 ; j++)
{
for(int i=0 ; i<4 ; i++)
{
aliens[i][j].assignCoordinate(100+100*i , 70+40*j);
}
}
if(gameSpeed == 1)
{
for(j=0; j<4; j++)
{
for(int i=0; i<4; i++)
aliens[i][j].capture2();
}
}
for(j=0 ; j<4 ; j++)
{
for(int i=0 ; i<4 ; i++)
{
aliens[i][j].drawAlien(100+100*i , 70+40*j , 15);
}
}
if(gameSpeed == 1)
{
for(j=0; j<4; j++)
{
for(int i=0; i<4; i++)
aliens[i][j].capture();
}
}
while(1)
{
ship1.move(); //move ship
for(int j=0; j<4; j++) //move aliens
{
for(int i=0; i<4; i++)
aliens[i][j].move();
}
for(j =0; j<4; j++) //check collision of ship and aliens
{
for(int i=0; i<4; i++)
ship1.checkForCollisionWithAliens(aliens[i][j]);
}
for(int i=0; i<10 ; i++) //move bullets and check for hit with aliens
{
if(shots[i]->deadAlive())
{
shots[i]->move();
for(int j=0; j<4; j++)
{
for(int i2=0; i2<4; i2++)
shots[i] -> checkForHit(aliens[i2][j]);
}
}
}
static int x,y;
static int delayShotByAliens = DELAYSHOTBYALIENS;
x = random(4);
y = random(4);
static int recycleAlienShots=0;
if(recycleAlienShots == 39) //recycleShots =9 means
//all available shots are used up
recycleAlienShots=0; //recycle the shots form beginning
if(delayShotByAliens == DELAYSHOTBYALIENS)
{
if(aliens[x][y].getAliensLife() && aliens[x][y].getCenterY()<430) //aliens will shoot only
//if aliens are alive and
//aliens are above 330 vertically
{
alienShot[recycleAlienShots] = new shotByAliens(aliens[x][y]);
alienShot[recycleAlienShots]->drawAndCapture();
recycleAlienShots++;
}
}
for(i=0; i<40 ; i++) //move the shots by aliens
{
if(alienShot[i]->getShotByAliensLife())
alienShot[i]->move();
}
if(delayShotByAliens == DELAYSHOTBYALIENS)
delayShotByAliens = 0;
delayShotByAliens++;
for(i=0; i<40 ; i++) //check for hit with ship
{
if(alienShot[i]->getShotByAliensLife() && ship1.getShipLife())
alienShot[i]->checkForHit(ship1);
}
for(i=0;i<4; i++) //end the game if the alive aliens reach the bottom
{
for(int j=0; j<4; j++)
{
if(aliens[i][j].getAliensLife() && aliens[i][j].getCenterY()>430)
{
cout<<"\a";
gameOver.display();
exit(0);
}
}
}
if(!ship1.getShipLife()) //game is over when ship is destroyed by
//alienshot or alien itself
{
cout<<"\a";
gameOver.display();
closegraph();
exit(0);
}
if(clearOrNot.check(aliens)) //level clear or not
{
gameSpeed ++;
reassignLifeToAliens(aliens);
for(int i=0; i<40; i++)
alienShot[i]->deleteShotByAliens();
for(i=0; i<10; i++)
shots[i]->deleteShots();
if(gameSpeed-1 <= 2)
levelClear.display();
else
{
congrats.display();
closegraph();
exit(1);
}
clrscr();
cleardevice();
//closegraph();
//startGraph();
break; //breaks nested while loop
}
}//ends nested while loop
}while(gameSpeed<4);
return 0;
}
No comments:
Post a Comment