在VC6.0平台下运用一个EasyX的图形库,用C语言编写了一个坦克大战的小游戏,代码和算法都是我自己源生的。文章的两幅配图,分别展示了游戏的开始选择界面和正在游戏界面。这个小游戏,具有游戏背景音乐,音乐是我在网上搜索到的坦克大战的音乐文件,然后将音乐的播放加入到代码的编写当中。另外游戏中坦克可以接道具,接道具后,会有相应的状态效应。由于利用的是EasyX的简单画图函数,因此整个界面的图形不是很友好,另外有的地方图片是读取的磁盘图片文件到内存中,然后显示在游戏界面中的。整个代码有1900多行,由于只是业余写来娱乐的,因此代码里面应该有不少位子存在冗余。欢迎有兴趣的朋友,对相关代码进行提出修改意见。
源代码:
#include<stdio.h>
#include<easyx.h>
#include<time.h>
#include<conio.h>
#include<graphics.h>
#define ok 0
#define eror 1
#define NUME 15
#pragma comment ( lib, "Winmm.lib" )
/*mciSendString( "open ./source/skycity.mp3 alias skycity", 0, 0, 0 );
mciSendString( "play skycity repeat ", 0, 0, 0 );*/
enum direction
{
left,up,right,down
};
enum condition
{
normal,addSpeed,addAggressivity,invincible,addOneLife,killAll
};
struct property
{
condition con;
int x;
int y;
int clock;
int flag;
};
struct ENEMY
{
int x;
int y;
int life; //有25 50 75三种生命值坦克
int aggressivity; //默认为20
direction dir;
};
struct USER //速度为3
{
int x;
int y;
int life; //默认为50
int aggressivity; //默认为25
direction dir;
condition speed; //加子弹速度状态
condition atack; //加攻击力状态
condition defence; //无敌状态
int clocks;
int clocka;
int clockd;
};
struct BOMB // r=4,circle
{
int x;
int y;
int aggressivity;
int speed; //速度默认为5
direction dir;
};
ENEMY enm[ NUME ];
USER use1,use2;
int MODEL=0; //为0表示单玩家,为1表示双玩家
int enemyNum=0, use1BNum=0,use2BNum=0;
BOMB enemyBomb[NUME],use1Bomb,use2Bomb;
bool FLAGBOMB1=false,FLAGBOMB2=false,flagB[NUME],flagLife[NUME];
int moveLength=5,BombNormalSpeed=5,BombAddSpeed=5,endOfGame=1;
int wall[10][3],use1life=3,use2life=3,use1Score=0,use2Score=0,highmark=0;
property pro[5];
int controlEnemy();
int controlUser();
int drawtank(int i,int j,int life,direction dir);
int drawBomb();
int controlBomb();
int tankMove();
int initGame();
int drawHome();
int is_collision(int x1,int y1,int x2,int y2,direction dir);
bool isTarget(USER tar,BOMB bomb);
bool isTarget2(ENEMY tar,BOMB bomb);
bool is_warded(int x,int y,direction dir,int tank);
int start_interface();
int control_property();
int control_userInfo(int count);
int init_userinfo();
void main()
{
int i=0,flag=0,temp1,count=0;
for(i=0;i<NUME;i++)
{
flagLife[i]=false;
flagB[i]=false;
}
for(i=0;i<4;i++)
{
wall[i][0]=430,wall[i][1]=630-i*20,wall[i][2]=1;
wall[i+5][0]=520,wall[i+5][1]=630-i*20,wall[i+5][2]=1;
pro[i].flag=0;
}
pro[4].flag=0;
wall[4][0]=480,wall[4][1]=590,wall[4][2]=1;
wall[9][0]=480,wall[9][1]=570,wall[9][2]=1;
for(i=0;i<3;i++)
{
temp1=wall[4][i];
wall[4][i]=wall[8][i];
wall[8][i]=temp1;
}
use1life=3,use2life=3;
use1.life=0,use2.life=0;
use1Score=0,use2Score=0,highmark=0;
moveLength=5,BombNormalSpeed=5,BombAddSpeed=5,endOfGame=1;
FLAGBOMB1=false,FLAGBOMB2=false;
enemyNum=0, use1BNum=0,use2BNum=0;
srand((unsigned)time(0));
initgraph(1200,650);
start_interface();
mciSendString( "open ./source/intimateLover.mp3 alias Lover", 0, 0, 0 );
mciSendString( "open ./source/begin.mp3 alias begin", 0, 0, 0 );
mciSendString( "open ./source/bombing.mp3 alias bombing", 0, 0, 0 );
mciSendString( "open ./source/eatting.mp3 alias eatting", 0, 0, 0 );
mciSendString( "open ./source/getLife.mp3 alias getLife", 0, 0, 0 );
mciSendString( "open ./source/launchBomb.mp3 alias launchBomb", 0, 0, 0 );
mciSendString( "open ./source/lose.mp3 alias lose", 0, 0, 0 );
mciSendString( "open ./source/moveSelf.mp3 alias moveSelf", 0, 0, 0 );
mciSendString( "open ./source/background.mp3 alias background", 0, 0, 0 );
mciSendString( "open ./source/shoot.mp3 alias shoot", 0, 0, 0 );
mciSendString( "open ./source/bomb.wav alias bomb", 0, 0, 0 );
mciSendString( "play moveSelf repeat", 0, 0, 0 );
mciSendString( "pause moveSelf", 0, 0, 0 );
mciSendString( "play Lover", 0, 0, 0 );
init_userinfo();
mciSendString( "play begin ", 0, 0, 0 );
initGame();
}
int initGame()
{
IMAGE p;
int i=0,k=0,m,count=0,countBeginMusic=0;
loadimage(&p,"./source/home.jpg", 40, 40);
BeginBatchDraw();
setfont( 30, 0,"楷体");
drawtank(use1.x,use1.y,use1.life,use1.dir);
drawtank(use2.x,use2.y,use2.life,use2.dir);
while(endOfGame)
{
controlEnemy();
controlUser();
controlBomb();
control_property();
for(i=0;i<NUME;i++) //判断敌军子弹是否出界
{
if(flagB[i]==true)
if(enemyBomb[i].x<0||enemyBomb[i].y<0||enemyBomb[i].x>1000||enemyBomb[i].y>650)
{
flagB[i]=false;
}
}
tankMove();
drawBomb();
for(i=0;i<NUME;i++)
{
if(flagLife[i]==true)
{
drawtank(enm[i].x,enm[i].y,enm[i].life,enm[i].dir);
}
}
if(use1.defence==invincible)
{
for(m=use1.x+5;m<=use1.x+45;m+=5)
{
circle(m,use1.y,5);
circle(m,use1.y+50,5);
}
for(m=use1.y+5;m<=use1.y+45;m+=5)
{
circle(use1.x,m,5);
circle(use1.x+50,m,5);
}
clearrectangle(use1.x,use1.y,use1.x+50,use1.y+50);
}
drawtank(use1.x,use1.y,use1.life,use1.dir);
if(MODEL)
{
if(use2.defence==invincible)
{
for(m=use2.x+5;m<=use2.x+45;m+=5)
{
circle(m,use2.y,5);
circle(m,use2.y+50,5);
}
for(m=use2.y+5;m<=use2.y+45;m+=5)
{
circle(use2.x,m,5);
circle(use2.x+50,m,5);
}
clearrectangle(use2.x,use2.y,use2.x+50,use2.y+50);
}
drawtank(use2.x,use2.y,use2.life,use2.dir);
}
drawHome();
setfillcolor(GREEN);
solidrectangle(1000,0,1010,650);
control_userInfo(count);
putimage(480, 610, &p, SRCINVERT);
FlushBatchDraw();
count++;
countBeginMusic++;
if(count==301)
count=0;
if(countBeginMusic==200)
{
mciSendString( "close begin", 0, 0, 0 );
mciSendString( "play background repeat", 0, 0, 0 );
}
if(countBeginMusic==600)
countBeginMusic=230;
Sleep(20);
mciSendString( "pause moveSelf", 0, 0, 0 );
clearrectangle(0,0,1000,650);
}
Sleep(50000);
return ok;
}
int init_userinfo()
{
FILE * fp;
int score=0;
if(use1life>0&&use1.life<=0)
{
use1.x=380;
use1.y=600;
use1.life=50;
use1.aggressivity=25;
use1.dir=up;
use1.speed=normal;
use1.atack=normal;
use1.defence=normal;
}
else
{
if(MODEL==1)
{
if(use2life<=0&&use2.life<=0)
{
setfont( 30, 0,"楷体");
outtextxy(350,300,"Game End!!");
if(use1Score>use2Score)
{
score=use1Score;
}
else
{
score=use2Score;
}
if(score>highmark)
{
if((fp=fopen("gameMark.txt","w"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fprintf(fp,"%d",score);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
}
}
}
else if(use1life<=0&&use1.life<=0)
{
setfont( 30, 0,"楷体");
outtextxy(350,300,"Game End!!");
if(use1Score>highmark)
{
if((fp=fopen("gameMark.txt","w"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fprintf(fp,"%d",use1Score);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
}
}
}
if(MODEL==1)
{
if(use2life>0&&use2.life<=0)
{
use2.x=570;
use2.y=600;
use2.life=50;
use2.aggressivity=25;
use2.dir=up;
use2.speed=normal;
use2.atack=normal;
use2.defence=normal;
}
}
return ok;
}
int control_userInfo(int count)
{
char num[10];
FILE * fp;
int k;
if(count==0) //读出历史最高分
{
if((fp=fopen("gameMark.txt","r"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fscanf(fp,"%d",&highmark);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
}
setfont( 20, 0,"楷体");
outtextxy(1020,50,"Score:");
sprintf(num, "%d", use1Score);
outtextxy(1080,50,num);
outtextxy(1020,90,"HP:");
setcolor(WHITE);
rectangle(1059,89,1161,111);
k=use1.life*2;
if(k<0)
k=0;
setfillcolor(RED);
solidrectangle(1060,90,1060+k,110);
setfillcolor(BLUE);
solidrectangle(1060+k,90,1160,110);
outtextxy(1020,120,"life:");
sprintf(num, "%d", use1life);
outtextxy(1080,120,num);
outtextxy(1070,200,"Player1");
outtextxy(1020,320,"Highrest:");
sprintf(num, "%d", highmark);
outtextxy(1110,320,num);
if(MODEL==1)
{
outtextxy(1020,350,"Score:");
sprintf(num, "%d", use2Score);
outtextxy(1080,350,num);
outtextxy(1020,90,"HP:");
k=use1.life*2;
if(k<0)
k=0;
setfillcolor(RED);
solidrectangle(1060,390,1060+k,410);
setfillcolor(BLUE);
solidrectangle(1060+k,390,1160,410);
outtextxy(1020,420,"life:");
sprintf(num, "%d", use2life);
outtextxy(1080,420,num);
outtextxy(1070,500,"Player2");
}
if(count==300) //存入历史记录最高分
{
if((MODEL==0&&use1Score>highmark)||(MODEL==1&&use1Score>highmark&&use1Score>use2Score))
{
if((fp=fopen("gameMark.txt","w"))==NULL)
{
printf("File open eror!\n");
exit(eror);
}
else
{
fprintf(fp,"%d",use1Score);
if(fclose(fp))
{
printf("file close eror\n");
exit(eror);
}
}
}
else if(MODEL==1&&use2Score>highmark&&use2Score>use1Score)
{
if((fp=fopen("gameMark.txt","w"))==NULL)

本文分享了使用C语言和EasyX图形库实现的坦克大战小游戏的代码与算法,包括游戏界面、背景音乐、道具系统及游戏逻辑。通过简单的代码展示了一个经典游戏的现代实现。
最低0.47元/天 解锁文章
563

被折叠的 条评论
为什么被折叠?



