第一句子网 - 唯美句子、句子迷、好句子大全
第一句子网 > 智能营销总部:编程教学 C语言开发打气球小游戏

智能营销总部:编程教学 C语言开发打气球小游戏

时间:2022-04-26 20:37:40

相关推荐

智能营销总部:编程教学 C语言开发打气球小游戏

首先我们写一下项目所需要的头文件

#include<stdio.h>//标准输入输出头文件#include<math.h>//数学库头文件#include<graphics.h>//EasyX图形库头文件#include<mmsystem.h>//多媒体音乐库头文件#pragmacomment(lib,"winmm.lib")//导入winmm库#pragmawarning(disable:4996)//4996警告杂注12345

接下来在涵盖几个宏定义进来

#defineWIDTH600//窗口宽度#defineWEIGHT400//窗口高度#defineNUM10//屏幕上所产生气球,子弹的最大数量12

然后我们开始打造一个漂亮的欢迎界面,这里需要二张图片,我把它贴出来。

1.jpg:

2.jpg:

图片有了,上代码,首先先在全局部分定义图片属性

IMAGEimg[2];

voidWelcome()//实现欢迎界面的函数{

loadimage(&img[0],"1.jpg",150,400);//加载图片

loadimage(&img[1],"2.jpg",450,400);//参数含义(图片地址,图片路径,图片宽,图片高)

putimage(0,0,&img[0]);//显示图片

putimage(150,0,&img[1]);//参数含义(显示坐标x,y+图片属性)

while(1)

{

if(MouseHit())//判断是否有鼠标消息

{

MOUSEMSGmsg=GetMouseMsg();//获取当前鼠标消息

if(msg.uMsg==WM_LBUTTONDOWN)//如果鼠标左键按下

{

return;//返回主函数

}

}

}}1234567891011121314151617

接下来我们开始准备音乐部分(音乐不方便贴出来,可以自己去网上找合适的)

我们为了不影响程序运行效率,决定使用多线程的方式实现音乐播放

背景音乐:

DWORDWINAPIMusic(LPVOIDlpParamter){

mciSendString("openmusic.mp3aliasBGM",0,0,0);//加载音乐

mciSendString("playBGMrepeat",0,0,0);//播放音乐

//repeat代表无限循环播放

while(1);}123456

气球爆炸音效:

DWORDWINAPIMCC(LPVOIDlpParamter){

mciSendString("openfill.mp3aliasBCC",0,0,0);

mciSendString("playBCC",0,0,0);

return0;}12345

做游戏之前,我们先把游戏中的炮台,气球,子弹这3个元素用结构体抽象出来

structBattery//炮台{//炮管二点的横纵坐标

intx;

inty;

intendx;

intendy;

intlen;

//炮管发射出来的子弹的速度

intspeed;

//炮管倾斜的弧度

doubleradian;

//玩家的游戏得分

intscore;}bat;structbullet{//子弹的横纵坐标

intx;

inty;

//子弹的半径

intr;

//子弹向炮管方向的位移量

intvx;

intvy;

//子弹是否存在的标志

boolfalg;

//炮管倾斜的弧度

doubleradian;

//子弹的颜色

DWORDcolor;}ball[NUM];structBalloon{//气球的横纵坐标

intx;

inty;

//气球的颜色

DWORDcolor;

//气球是否存在的标志

boolfalg;}boon[NUM];123456789101112131415161718192223242526272829303132333435363738394041

下面我们来初始化数据

voidGameInit(){

srand(GetTickCount());

bat.x=WIDTH/2;

bat.y=WEIGHT-10;

bat.len=50;

bat.endx=bat.x;

bat.endy=bat.y-bat.len;

bat.speed=7;

bat.score=0;

for(inti=0;i<NUM;i++)

{

ball[i].falg=false;

}//因为一开始子弹不存在,子弹需要鼠标点击才生成一个,所以我们先初始化为不存在(false代表不存在)

for(inti=0;i<NUM;i++)

{

//随机坐标

boon[i].x=rand()%(WIDTH-30);

boon[i].y=rand()%(WEIGHT-60);

//随机颜色

boon[i].color=RGB(rand()%256,rand()%256,rand()%256);

boon[i].falg=true;

}//因为气球是游戏一开始就要有的,所以我们把它全部初始化为true(存在),并且初始化坐标,颜色}123456789101112131415161718192223

接下来我们来把数据变得“看的见”

voidGameDraw(){

BeginBatchDraw();//开始双缓冲

setbkcolor(RGB(114,191,207));//设置窗口背景颜色

cleardevice();//清屏

for(inti=0;i<NUM;i++)//遍历所有气球(所有包括存在和不存在)

{

if(boon[i].falg==true)//如果气球存在

{

//画气球

setlinestyle(PS_SOLID,0.1);//设置线条风格PS_SOLID表示实线,0.1表示线条粗细程度

setlinecolor(WHITE);//设置线条颜色

setfillcolor(boon[i].color);//设置填充颜色

fillellipse(boon[i].x,boon[i].y,boon[i].x+40,boon[i].y+50);//画填充椭圆

//画气泡

arc(boon[i].x+5,boon[i].y+5,boon[i].x+35,boon[i].y+45,0,1.4);//画弧

//画绳子

arc(boon[i].x+15,boon[i].y+50,boon[i].x+25,boon[i].y+75,5.2,1.5);

}

}

//画炮台

setlinestyle(PS_SOLID,2);

circle(bat.x,bat.y,40);//画圆

setfillcolor(BLACK);

solidcircle(bat.x,bat.y,5);//画实心圆

//画炮管

setlinecolor(BLACK);

setlinestyle(PS_SOLID,5);

line(bat.x,bat.y,bat.endx,bat.endy);

//绘制子弹

for(inti=0;i<NUM;i++)//遍历所有子弹(所有包括存在和不存在)

{

if(ball[i].falg==true)//如果子弹存在

{

setfillcolor(ball[i].color);

solidcircle(ball[i].x,ball[i].y,ball[i].r);

}

}

charbar[80];//初始化字符串

sprintf(bar,"分数:%d",bat.score);//往这个字符串里写东西

setbkmode(0);//去掉文字背景

settextcolor(YELLOW);//设置文字颜色

settextstyle(40,0,"楷体");//设置文字字体大小和字体样式(注:0表示编译器自适应)

outtextxy(0,0,bar);//设置文字显示位置,以及所需要显示的字符串

EndBatchDraw();//结束双缓冲}12345678910111213141516171819222324252627282930313233343536373839404142434445

我们的炮管现在还是固定的,我们需要让它跟着鼠标动起来,走,现在我们去实现鼠标操作

voidMouseEvent(){

if(MouseHit())//如果有鼠标消息

{

MOUSEMSGmsg=GetMouseMsg();//获取当前鼠标消息

bat.radian=atan2((double)bat.y-msg.y,(double)msg.x-bat.x);//使用数学的正切求出炮台的炮管的倾斜弧度

//同样使用数学知识求出二条直角边的长度

bat.endx=bat.x+cos(bat.radian)*bat.len;//正弦

bat.endy=bat.y-sin(bat.radian)*bat.len;//余弦

if(msg.uMsg==WM_LBUTTONDOWN)//如果鼠标左键按下

{

CreatBullet();//产生子弹

}

}}1234567891011121314

那么鼠标操作这一步又涉及到子弹的产生,所以我们一起去看看子弹是如何产生的

//生成子弹voidCreatBullet(){

for(inti=0;i<NUM;i++)//遍历所有子弹(所有包括存在和不存在)

{

if(ball[i].falg==false)//如果子弹不存在才生成

{

ball[i].color=RGB(rand()%256,rand()%256,rand()%256);//颜色

//设置子弹坐标,让子弹从炮管出来

ball[i].x=bat.endx;

ball[i].y=bat.endy;

ball[i].radian=bat.radian;//让子弹运动方向的水平弧度等于当前炮管的水平弧度

//利用数学的正弦,余弦知识求出子弹的位移量,bat.speed是子弹的速度,一开始已经在炮台的结构体里面定义好了

ball[i].vx=cos(ball[i].radian)*bat.speed;

ball[i].vy=sin(ball[i].radian)*bat.speed;

//设置子弹的大小(圆的半径)

ball[i].r=5;

//最后一定要把子弹改为存在,好让GameDraw函数绘制出来

ball[i].falg=true;

//生成完一个子弹一定要break跳出for循环,否则程序会把所有子弹全部生成完,但我只要一个

break;

}

}}123456789101112131415161718192223

子弹生成完了我们也不能让它摆在那里不动,我们得让它飞,所以我们去实现一个函数让子弹移动

voidBulletMove(){

for(inti=0;i<NUM;i++)

//遍历所有子弹(所有包括存在和不存在)

{

if(ball[i].falg==true)//子弹存在才移动

{

//ball[i].vx,ball[i].vy我们在生成子弹里面就求出来了,这里我们就直接用

ball[i].x+=ball[i].vx;

ball[i].y-=ball[i].vy;

}

}}123456789101112

这时你会发现你打掉(宏定义)NUM个子弹后就没有了,这是什么原因呢?走,我们一起去升级一下这个函数

voidBulletMove(){

for(inti=0;i<NUM;i++)

//遍历所有子弹(所有包括存在和不存在)

{

if(ball[i].falg==true)//子弹存在才移动

{

//ball[i].vx,ball[i].vy我们在生成子弹里面就求出来了,这里我们就直接用

ball[i].x+=ball[i].vx;

ball[i].y-=ball[i].vy;

if(ball[i].x<0||ball[i].x>WIDTH||ball[i].y<0||ball[i].y>WEIGHT)

{

ball[i].falg=false;

}//如果子弹打出窗口了,就把该子弹设置为不存在,这样鼠标点击就可以继续生成子弹了(保证窗口一直可以容纳(宏定义)NUM个子弹)

}

}}12345678910111213141516

子弹移动了该气球了

//气球移动voidBalloonMove(intspeed){

for(inti=0;i<NUM;i++)//遍历所有气球(所有涵盖存在和不存在)

{

if(boon[i].falg==true)//如果气球存在

{

//%50的概率,让气球随风摇摆

if(rand()%2==1)

{

boon[i].x++;

}

else

{

boon[i].x--;

}

//气球上升

boon[i].y-=speed;

}}12345678910111213141516171819

然后我们会发现会产生与子弹移动同样的问题,气球一去不复返,所以我们升级一下这个函数

//气球移动voidBalloonMove(intspeed){

for(inti=0;i<NUM;i++)//遍历所有气球(所有涵盖存在和不存在)

{

if(boon[i].falg==true)//如果气球存在

{

//%50的概率,让气球随风摇摆

if(rand()%2==1)

{

boon[i].x++;

}

else

{

boon[i].x--;

}

//气球上升

boon[i].y-=speed;

if(boon[i].x-40<0||boon[i].x>WIDTH+40||boon[i].y+50<0||boon[i].y>WEIGHT)//如果气球升到了窗口之外

{

boon[i].falg=false;//把气球设置为不存在

CreatBall();//调用产生气球的函数(气球飞离窗口)

}

}}12345678910111213141516171819222324

好,接下来我们来实现一下产生气球的函数

//产生气球voidCreatBall(){

for(inti=0;i<NUM;i++)//遍历所有气球(所有涵盖存在与不存在)

{

if(boon[i].falg==false)//如果气球不存在

{

//随机气球坐标

boon[i].x=rand()%(WIDTH-30);

boon[i].y=(rand()%100)+WEIGHT;

//随机气球颜色

boon[i].color=RGB(rand()%256,rand()%256,rand()%256);

//生成完成把气球设置为存在

boon[i].falg=true;

break;//同理,只需要一个,break

}

}}1234567891011121314151617

现在一切准备就绪,开始打气球

//开始游戏voidPlayGame(){

for(inti=0;i<NUM;i++)//遍历所有气球(所有涵盖存在和不存在)

{

if(boon[i].falg==false)//如果气球不存在

continue;//跳过此次循环剩余部分,执行下一次循环判定

for(intj=0;j<NUM;j++)

//遍历所有子弹(所有涵盖存在和不存在)

{

if(ball[j].falg==false)//如果子弹不存在

continue;//跳过此次循环剩余部分,执行下一次循环判定

if(ball[j].x>boon[i].x&&ball[j].x<boon[i].x+40&&

ball[j].y>boon[i].y&&ball[j].y<boon[i].y+50)

//如果子弹与气球重叠(打到了气球)

{

CreateThread(NULL,0,MCC,NULL,0,NULL);//执行多线程,播放气球爆炸音效

ball[j].falg=false;//子弹设置为不存在

boon[i].falg=false;//气球设置为不存在

bat.score++;//玩家分数加1

CreatBall();//生成气球(气球被打)

}

}

}}12345678910111213141516171819222324

下面我们把主函数(程序的入口,程序的主干)写出来

intmain(){

initgraph(WIDTH,WEIGHT);//创建窗口

CreateThread(NULL,0,Music,NULL,0,NULL);//调用多线程,循环播放背景音乐

Welcome();//欢迎界面

GameInit();//数据初始化

while(1)//死循环

{

MouseEvent();//鼠标操作

GameDraw();//绘制(让游戏可视化)

BulletMove();//子弹移动

BalloonMove(1);//气球移动

Sleep(1);//适当延时

PlayGame();//开始打气球

}

getchar();//防止闪屏}12345678910111213141516

最后,博主送你源代码,感谢你认真的观看(因为我自己写代码很少注释,所以源代码注释少)但上面的详解可是注释慢慢,为了方便大家理解。

#include<stdio.h>#include<math.h>#include<graphics.h>#include<mmsystem.h>#pragmacomment(lib,"winmm.lib")#pragmawarning(disable:4996)#defineWIDTH600#defineWEIGHT400#defineNUM10structBattery{

intx;

inty;

intendx;

intendy;

intlen;

intspeed;

doubleradian;

intscore;}bat;structbullet{

intx;

inty;

intr;

intvx;

intvy;

boolfalg;

doubleradian;

DWORDcolor;}ball[NUM];structBalloon{

intx;

inty;

DWORDcolor;

boolfalg;}boon[NUM];IMAGEimg[2];DWORDWINAPIMCC(LPVOIDlpParamter){

mciSendString("openfill.mp3aliasBCC",0,0,0);

mciSendString("playBCC",0,0,0);

return0;}DWORDWINAPIMusic(LPVOIDlpParamter){

mciSendString("openmusic.mp3aliasBGM",0,0,0);

mciSendString("playBGMrepeat",0,0,0);

while(1);}voidWelcome(){

loadimage(&img[0],"1.jpg",150,400);

loadimage(&img[1],"2.jpg",450,400);

putimage(0,0,&img[0]);

putimage(150,0,&img[1]);

while(1)

{

if(MouseHit())

{

MOUSEMSGmsg=GetMouseMsg();

if(msg.uMsg==WM_LBUTTONDOWN)

{

return;

}

}

}}voidGameInit(){

srand(GetTickCount());

bat.x=WIDTH/2;

bat.y=WEIGHT-10;

bat.len=50;

bat.endx=bat.x;

bat.endy=bat.y-bat.len;

bat.speed=7;

bat.score=0;

for(inti=0;i<NUM;i++)

{

ball[i].falg=false;

}

for(inti=0;i<NUM;i++)

{

boon[i].x=rand()%(WIDTH-30);

boon[i].y=rand()%(WEIGHT-60);

boon[i].color=RGB(rand()%256,rand()%256,rand()%256);

boon[i].falg=true;

}}voidGameDraw(){

BeginBatchDraw();

setbkcolor(RGB(114,191,207));

cleardevice();

for(inti=0;i<NUM;i++)

{

if(boon[i].falg==true)

{

//画气球

setlinestyle(PS_SOLID,0.1);

setlinecolor(WHITE);

setfillcolor(boon[i].color);

fillellipse(boon[i].x,boon[i].y,boon[i].x+40,boon[i].y+50);

//画气泡

arc(boon[i].x+5,boon[i].y+5,boon[i].x+35,boon[i].y+45,0,1.4);

//画绳子

arc(boon[i].x+15,boon[i].y+50,boon[i].x+25,boon[i].y+75,5.2,1.5);

}

}

//画炮台

setlinestyle(PS_SOLID,2);

circle(bat.x,bat.y,40);

setfillcolor(BLACK);

solidcircle(bat.x,bat.y,5);

//画炮管

setlinecolor(BLACK);

setlinestyle(PS_SOLID,5);

line(bat.x,bat.y,bat.endx,bat.endy);

//绘制子弹

for(inti=0;i<NUM;i++)

{

if(ball[i].falg==true)

{

setfillcolor(ball[i].color);

solidcircle(ball[i].x,ball[i].y,ball[i].r);

}

}

charbar[80];

sprintf(bar,"分数:%d",bat.score);

setbkmode(0);

settextcolor(YELLOW);

settextstyle(40,0,"楷体");

outtextxy(0,0,bar);

EndBatchDraw();}//产生气球voidCreatBall(){

for(inti=0;i<NUM;i++)

{

if(boon[i].falg==false)

{

boon[i].x=rand()%(WIDTH-30);

boon[i].y=(rand()%100)+WEIGHT;

boon[i].color=RGB(rand()%256,rand()%256,rand()%256);

boon[i].falg=true;

break;

}

}}//开始游戏voidPlayGame(){

for(inti=0;i<NUM;i++)

{

if(boon[i].falg==false)

continue;

for(intj=0;j<NUM;j++)

{

if(ball[j].falg==false)

continue;

if(ball[j].x>boon[i].x&&ball[j].x<boon[i].x+40&&

ball[j].y>boon[i].y&&ball[j].y<boon[i].y+50)

{

CreateThread(NULL,0,MCC,NULL,0,NULL);

ball[j].falg=false;

boon[i].falg=false;

bat.score++;

CreatBall();

}

}

}}//气球移动voidBalloonMove(intspeed){

for(inti=0;i<NUM;i++)

{

if(boon[i].falg==true)

{

if(rand()%2==1)

{

boon[i].x++;

}

else

{

boon[i].x--;

}

boon[i].y-=speed;

if(boon[i].x-40<0||boon[i].x>WIDTH+40||boon[i].y+50<0||boon[i].y>WEIGHT)

{

boon[i].falg=false;

CreatBall();

}

}

}}//生成子弹voidCreatBullet(){

for(inti=0;i<NUM;i++)

{

if(ball[i].falg==false)

{

ball[i].color=RGB(rand()%256,rand()%256,rand()%256);

ball[i].x=bat.endx;

ball[i].y=bat.endy;

ball[i].radian=bat.radian;

ball[i].vx=cos(ball[i].radian)*bat.speed;

ball[i].vy=sin(ball[i].radian)*bat.speed;

ball[i].r=5;

ball[i].falg=true;

break;

}

}}//移动子弹voidBulletMove(){

for(inti=0;i<NUM;i++)

{

if(ball[i].falg==true)

{

ball[i].x+=ball[i].vx;

ball[i].y-=ball[i].vy;

if(ball[i].x<0||ball[i].x>WIDTH||ball[i].y<0||ball[i].y>WEIGHT)

{

ball[i].falg=false;

}

}

}}//鼠标操作voidMouseEvent(){

if(MouseHit())

{

MOUSEMSGmsg=GetMouseMsg();

bat.radian=atan2((double)bat.y-msg.y,(double)msg.x-bat.x);

bat.endx=bat.x+cos(bat.radian)*bat.len;

bat.endy=bat.y-sin(bat.radian)*bat.len;

if(msg.uMsg==WM_LBUTTONDOWN)

{

CreatBullet();

}

}}intmain(){

initgraph(WIDTH,WEIGHT);

CreateThread(NULL,0,Music,NULL,0,NULL);

Welcome();

GameInit();

while(1)

{

MouseEvent();

GameDraw();

BulletMove();

BalloonMove(1);

Sleep(1);

PlayGame();

}

getchar();}12345678910111213141516171819222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119111221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992000220320420520620720820921021121221321421521621721821921222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。