最近在學C++,本想用面向對象的思想做一個小遊戲熱熱手 ,但先後用了vc和dev c++,發現竟然沒有找到我在win-tc下熟悉的graphics.h頭文件,頓時不知所措,詢問高人,回答“爲什麼不用DX或OPENGL”,暈~~~~,我要會的話還用DOS圖形界面嗎!!心有不甘,於是又拿起win-tc,寫了這個想用C++寫的小遊戲——坦克打飛機!!呵呵,暈~~~~BUG多多啊,玩了會兒發現坦克不用移動照樣打,不好玩!!而且飛機好像離地面好遠好遠,最後玩了會兒想起不應該叫坦克打飛機,而應該叫坦克打蚊子,哈哈~~~~
#include "Conio.h"
#include "graphics.h"
#include "math.h"
#include "stdlib.h"
#define GAMESPEED 2000
#define closegr closegraph
#define LEFT 0x4b00
#define RIGHT 0x4d00
#define DOWN 0x5000
#define UP 0x4800
#define ESC 0x011b
static int x,y;
static int bullets=10,hitted=0,count=0; //對子彈數量,擊落敵機數量和飛過敵機數量初始化
struct TANK //坦克結構體
{
int x; //坦克橫座標
int y; //坦克縱座標
}tank;
struct PLANE //敵機結構體
{
int x; //敵機橫座標
int y; //敵機縱座標
int show; //敵機顯隱,0爲隱,1爲顯
int dirction; //敵機的飛行方向,0爲從左向右,1爲從右向左
}plane;
struct BULLET //子彈結構體
{
int x; //子彈橫座標
int y; //子彈縱座標
int show; //子彈的顯隱
}bullet;
int key; //KEY爲按鍵
drawfloor() //繪製外圍
{
setfillstyle(EMPTY_FILL,BLACK); //設置填充模式
setcolor(BLUE);
bar(0,0,x,y); //實際目的爲清屏
rectangle(0,y*0.1,x,y*0.9); //畫邊界
setcolor(BLUE);
settextstyle(TRIPLEX_FONT,HORIZ_DIR,3); //設置文字風格
outtextxy(0,y*0.07,"HITTED:"); //用於顯示擊落數和剩餘子彈數
outtextxy(x*0.15,y*0.07,"BULLETS:");
}
drawtank(struct TANK tank) //繪製坦克
{
rectangle(tank.x-3,tank.y,tank.x+3,tank.y+15);
arc(tank.x,tank.y+25,0,180,10);
rectangle(tank.x-20,tank.y+25,tank.x+20,tank.y+35);
circle(tank.x-15,tank.y+40,5);
circle(tank.x-5,tank.y+40,5);
circle(tank.x+5,tank.y+40,5);
circle(tank.x+15,tank.y+40,5);
}
drawplanel(int x,int y) //繪製敵機(從左向右飛)
{
line(x-10,y-4,x-8,y);
line(x-8,y,x+8,y);
line(x,y-5,x+5,y);
line(x,y+5,x+5,y);
}
drawplaner(int x,int y) //繪製敵機(從右向左飛)
{
line(x-8,y,x+8,y);
line(x+10,y-4,x+8,y);
line(x,y-5,x-5,y);
line(x,y+5,x-5,y);
}
showdetail() //在頂端顯示詳細數據(擊落敵機數和剩餘子彈數)
{
char str1[2],str2[2];
setfillstyle(EMPTY_FILL,BLACK);
setcolor(RED);
bar(x*0.1,y*0.07,x*0.15,y*0.09); //用於抹去舊的數據
sprintf(str1,"%d",hitted);
outtextxy(x*0.1,y*0.07,str1);
bar(x*0.25,y*0.07,x*0.3,y*0.09);
sprintf(str2,"%d",bullets);
outtextxy(x*0.25,y*0.07,str2);
}
playgame() /*遊戲過程*/
{
int quit=0; //控制是否退出
bullet.show=0; //子彈開始不顯示
plane.x=10; //敵機出現位置
plane.y=y*0.15;
plane.show=1; //敵機開始時就要顯示
plane.dirction=0; //第一個敵機的飛行方向爲從左向右飛
tank.x=x*0.5; //開始時坦克的出現位置
tank.y=y*0.9-47;
drawtank(tank); //開始就要畫出坦克
showdetail(); //顯示初始的詳細數據
while (1)
{
while(!kbhit()) //在沒有按鍵的時候執行如下命令
{
setcolor(BLACK);
circle(bullet.x,bullet.y+2,3); //用黑筆將子彈抹去
if(bullet.show) //如果子彈是顯示的,就讓它向上移動
{
setcolor(BLUE);
circle(bullet.x,bullet.y,3);
bullet.y-=2;
if(bullet.y<y*0.15) //判斷子彈是否已經到達最高處
{
if(abs(bullet.x-plane.x)<=20) //如果子彈到達最高處就還要判斷是否擊中敵機
{
plane.show=0; //如果擊中了就要讓敵機消失
hitted++; //並且還要讓擊落數加1
setcolor(BLACK);
circle(plane.x,plane.y,5); //要用黑筆將子彈抹去
showdetail(); //刷新詳細數據
}/*end of if(abs(bullet.x-plane.x)<=30)*/
bullet.show=0; //子彈也要消失
}/*end of if(bullet.y<y*0.15)*/
}/*end of if(bullet.show)*/
setcolor(BLACK);
if(plane.dirction)
drawplaner(plane.x,plane.y);
else
drawplanel(plane.x,plane.y); //判斷飛行方向並用黑筆將敵機抹去,?
if(plane.show) //如果敵機是顯示的,則要讓它在飛行方向上往前飛
{
if(plane.dirction) //根據飛行方向決定需要什麼樣的繪製方法
{
plane.x-=1;
if(plane.x<10) plane.show=0; //如果敵機機到達最左端,則讓它消失,否則向左移動
else
{
setcolor(BLUE);
drawplaner(plane.x,plane.y);
}/*end of else(plane.x>x-10)*/
}/*end of if(plane.dirction)*/
else
{
plane.x+=1;
if(plane.x>x-10) plane.show=0; //如果敵機機到達最右端,則讓它消失,否則向右移動
else
{
setcolor(BLUE);
drawplanel(plane.x,plane.y);
}/*end of else(plane.x<10)*/
}/*end of else(plane.dirction))*/
}/*end of if(plane.show)*/
else //如果敵機沒有顯示,則讓它隨機從最左端或是從最右端出現
{
int random=0;
randomize(); //配置隨機數發生器
random=rand()%2; //將隨機數除以2的餘數賦給random
switch(random)
{
case 0:plane.x=10;plane.show=1;plane.dirction=0;count++;break; //設置敵機的出生位置並讓飛過敵機數加1
case 1:plane.x=x-10;plane.show=1;plane.dirction=1;count++;break;
}/*end of switch(random)*/
}/*end of else*/
if(count==10) return 0; //如果飛過敵機數爲10則終止遊戲
delay(GAMESPEED); //暫停一段時間
}/*end of while(!kbhit())*/
key=bioskey(0); //如果按鍵了,則讓key來接收
switch(key) //判斷按了什麼鍵
{
case UP:if(bullet.show==0&&bullets!=0) {bullet.x=tank.x;bullet.y=tank.y-5;bullet.show=1;bullets--;showdetail();}break;
//如果按了up鍵,屏幕上還沒有子彈並且還有剩餘子彈數,則把子彈的位置設在坦克的炮口,並讓剩餘子彈數減1,還要刷新詳細數據
case LEFT:if(tank.x-20<5) break; else {setcolor(BLACK);drawtank(tank);tank.x-=8;break;}
//如果按了left鍵,並且坦克沒有到最左邊,則用黑筆抹去坦克,並讓坦克的橫座標減8,等待重繪
case RIGHT:if(tank.x+20>x-10)break; else {setcolor(BLACK);drawtank(tank);tank.x+=8;break;}
//如果按了right鍵,並且坦克沒有到最右邊,則用黑筆抹去坦克,並讓坦克的橫座標加8,等待重繪
case ESC:quit=1;break; //如果按了ese鍵,則讓退出控制變量quit爲1
}/*end of switch(key)*/
if(quit) break; //判斷quit的值,如爲1,則跳出循環
setcolor(BLUE);
drawtank(tank); //繪製坦克
}/*end of while(1)*/
}/*end of playgame()*/
showrecord() //顯示成績
{
char str[20],str1[20];
settextstyle(DEFAULT_FONT,HORIZ_DIR,3);
setfillstyle(EMPTY_FILL,BLACK);
setcolor(BLUE);
bar(0,0,x,y); //實際作用爲清屏
sprintf(str,"you shot down %d planes",hitted);
outtextxy(50,200,str);
if(0<=hitted<=5) //根據hitted數量作出評價,
{
sprintf(str1,"You Are Bad Soldier");
outtextxy(60,300,str1);
}
else if(6<=hitted<=9)
{
sprintf(str1,"You Are Good Soldier");
outtextxy(60,300,str1);
}
else if(hitted==10)
{
sprintf(str1,"You Are Hero");
outtextxy(80,300,str1);
}
}
showbegin() //顯示開始界面
{
char str[50];
settextstyle(DEFAULT_FONT,HORIZ_DIR,4);
setcolor(RED);
sprintf(str,"DANGEROUS!!!!!");
outtextxy(110,100,str);
settextstyle(DEFAULT_FONT,HORIZ_DIR,2);
sprintf(str,"The enemy plane is coming,Harry up!!");
outtextxy(30,180,str);
sprintf(str,"UP:fire LEFT AND RIGHT:move"); //控制說明
outtextxy(80,400,str);
}
void initgr(void) /* BGI初始化 */
{
int gd = DETECT, gm = 0; /* 和gd = VGA,gm = VGAHI是同樣效果 */
registerbgidriver(EGAVGA_driver);/* 註冊BGI驅動後可以不需要.BGI文件的支持運行 */
initgraph(&gd, &gm, "");
}
int main(void)
{
initgr(); /* BGI初始化 */
x=getmaxx();/*最大橫座標*/
y=getmaxy();/*最大縱座標*/
showbegin();
sleep(5);
drawfloor();/*繪製遊戲圍牆*/
playgame();
showrecord();
sleep(2);
closegr(); /* 恢復TEXT屏幕模式 */
return 0;
}