飞翔的小鸟C语言课设
- 一、课设思路
- 二、准备素材
- (一)背景图片
- (二)小鸟、柱子创建
- (三)背景音乐
- 三、代码
- (一)引用头文件
- (二)定义各种变量
- (三)创建菜单
- (四)加载各种资源
- (五)创建小鸟及其各种情况
- (六)创建柱子
- (七)结束背景图片创建
- (八)背景音乐创建
- (九)主函数调用
- 四、游戏进行流程图
一、课设思路
思维导图:
二、准备素材
首先安装easyx插件
(一)背景图片
(二)小鸟、柱子创建
(三)背景音乐
三、代码
(一)引用头文件
#include "stdafx.h"
#include <graphics.h> //图形库头文件
#include <stdlib.h> //Sleep
#include <conio.h> //_getch()按键盘
#include <stdio.h> //C语言头文件
#include <time.h> //随机函数使用
#include <mmsystem.h> //音乐播放的多媒体库
#pragma comment(lib,"winmm.lib") //链接winmm.lib这个库
(二)定义各种变量
//定义画布大小
#define WIGHT 288
#define HIGHT 608
//起名字
IMAGE background;
IMAGE mybird[2]; //鸟有两张:mybird[0]、mybird[1]
IMAGE overImg[2]; //游戏结束动画两张
IMAGE downPillar[2]; //朝下的柱子两张
IMAGE upPillar[2]; //朝上的柱子两张
//菜单图片
IMAGE image;
//定义结构体
struct Bird //鸟的属性
{
int x; //初始坐标
int y;
int speed; //上升速度
};
struct Pillar
{
int x; //上面柱子起始坐标
int y;
int height; //上面柱子显示高度
};
struct Bird flyBird={124,304,50}; //初始化。在窗口正中间
(三)创建菜单
void StartMenu()
{
loadimage(&image,L"ks.png");
putimage(0,0,&image);
//菜单界面捕获鼠标操作
while(1)
{
MOUSEMSG m=GetMouseMsg();
if(m.x>=39&&m.x<=114&&m.y>=270&&m.y<=342)
{
setlinecolor(YELLOW);
roundrect(39-5,270-5,114+5,342+5,10,20);
if(m.uMsg==WM_LBUTTONDOWN)
{
exit(0); //退出游戏
}
}
else if(m.x>=157&&m.x<=231&&m.y>=270&&m.y<=342)
{
setlinecolor(YELLOW);
roundrect(157-5,270-5,231+5,342+5,10,20);
if(m.uMsg==WM_LBUTTONDOWN)
{
break; //进入游戏
}
}
else//当鼠标不在框内使外框为浅蓝色
{
setlinecolor(LIGHTBLUE);
roundrect(39-5,270-5,114+5,342+5,10,20);
roundrect(157-5,270-5,231+5,342+5,10,20);
}
}
}
(四)加载各种资源
//加载资源。相同的操作归类处理
void loadResource()
{
loadimage(&background,L"background.bmp"); //背景
loadimage(&mybird[0],L"birdy.bmp",48,48); //先是掩码图y
loadimage(&mybird[1],L"bird.bmp",48,48); //鸟
loadimage(&overImg[0],L"endy.bmp");
loadimage(&overImg[1],L"end.bmp"); //结束动画
loadimage(&downPillar[0],L"downy.bmp"); //下柱子
loadimage(&downPillar[1],L"down.bmp");
loadimage(&upPillar[0],L"upy.bmp");
loadimage(&upPillar[1],L"up.bmp"); //上柱子
}
(五)创建小鸟及其各种情况
1.创建小鸟图形
//创建鸟
void drawBird(int x,int y)
{
//透明贴图,需要遮罩图和背景图,SRCAND,SRCPAINT
//SRCAND方式贴遮罩图
putimage(x,y,&mybird[0],SRCAND);
//SRCPAINT方式贴背景图
putimage(x,y,&mybird[1],SRCPAINT);
}
2.小鸟的按键操作
//鸟的按键处理:单击空格是小鸟跳起
void keyDown()
{
char userkey=_getch(); //_getch();用来接收用户按键
BeginBatchDraw();
switch (userkey)
{
case ' ':flyBird.y-=flyBird.speed;//单机空格按键
CreateThread(NULL,NULL,playMusic,NULL,NULL,NULL);//按键时播放相应的背景音乐
break;
default:break;
}
EndBatchDraw();
}
3.小鸟撞击情况判断
(1)撞到地面或者天花板
//鸟撞击天花板或者地板表示游戏失败
int hitFloor()
{
if (flyBird.y<=0||flyBird.y>=512)//坐标
{
CreateThread(NULL,NULL,playMusic1,NULL,NULL,NULL);//撞击时播放相应的背景音乐
return 1;
}
else
return 0;
}
(2)撞到柱子
//定义撞到柱子的情况
int hitPillar(struct Pillar *myPillar)
{
for(int i=0;i<3;++i)
{
if (flyBird.x >= myPillar[i].x && flyBird.x <= myPillar[i].x + 52)
{
if (flyBird.y <= myPillar[i].height || flyBird.y >= (512 - 320 + myPillar[i].height))
{
CreateThread(NULL,NULL,playMusic1,NULL,NULL,NULL);//播放撞击时的背景音乐
return 1;
}
}
}
return 0;
}
(六)创建柱子
//创建柱子:随机出现
void initPillar(struct Pillar myPillar[],int i)
{
myPillar[i].height=rand()%100+160; //随机数范围160~259
myPillar[i].x=228;
myPillar[i].y=0;
}
//画柱子:每根柱子高度320
void drawPillar(struct Pillar myPillar)
{
//上面的柱子
putimage(myPillar.x,0,52,myPillar.height,&downPillar[0],0,320-myPillar.height,SRCAND); //掩码图
putimage(myPillar.x,0,52,myPillar.height,&downPillar[1],0,320-myPillar.height,SRCPAINT);
//下面的柱子
putimage(myPillar.x,512-(320-myPillar.height),52,320-myPillar.height,&upPillar[0],0,0,SRCAND); //掩码图
putimage(myPillar.x,512-(320-myPillar.height),52,320-myPillar.height,&upPillar[1],0,0,SRCPAINT);
}
(七)结束背景图片创建
//定义结束的图片
void actionGameOver()
{
//结束图片的初始位置
int x=50;
int y=608;
while (y>=240)
{
putimage(0,0,&background);
putimage(x,y,&overImg[0],SRCAND);//遮罩图
putimage(x,y,&overImg[1],SRCPAINT);//背景图
y-=50;
Sleep(50);//延迟
}
CreateThread(NULL,NULL,playMusic2,NULL,NULL,NULL);//播放失败时的背景音乐
Sleep(5000); //延迟,5秒后关闭窗口
}
(八)背景音乐创建
要让小鸟跳跃时伴随背景音乐,并且撞击天花板或者地面或者柱子时有撞击和结束背景音乐出现并且有结束动画随之出现。
//多线程使用背景音乐播放
//跳跃时背景音乐播放
DWORD WINAPI playMusic(LPVOID lpParamer)
{ //多线程
/*
mciSendString("指令",0,0,0);
指令:
open:打开
play:播放
pause:暂停
wait:等待
stop:停止
close:关闭
*/
mciSendString(L"open jump.mp3",0,0,0); //需要加L
mciSendString(L"play jump.mp3 wait",0,0,0);
mciSendString(L"close jump.mp3",0,0,0);
return 0;
}
//撞击主子时背景音乐
DWORD WINAPI playMusic1(LPVOID lpParamer)
{ //多线程
mciSendString(L"open hit.mp3",0,0,0); //需要加L
mciSendString(L"play hit.mp3 wait",0,0,0);
mciSendString(L"close hit.mp3",0,0,0);
return 0;
}
//游戏结束时背景音乐
DWORD WINAPI playMusic2(LPVOID lpParamer)
{ //多线程
mciSendString(L"open gameover.mp3",0,0,0); //需要加L
mciSendString(L"play gameover.mp3 wait",0,0,0);
mciSendString(L"close gameover.mp3",0,0,0);
return 0;
}
(九)主函数调用
创建游戏窗口,调用所有的函数。
//主函数
int main()
{
//背景尺寸:288*608
srand((unsigned int)time(NULL)); //随机函数种子
initgraph(WIGHT,HIGHT); //创建窗口
StartMenu(); //菜单
struct Pillar myPillar[3];
for(int i=0;i<3;++i)
{
initPillar(myPillar,i);
//为了让柱子之间有差距
myPillar[i].x=288+i*150;
}
loadResource(); //加载资源
while (true) //无限循环
{
putimage(0,0,&background); //背景图片
drawBird(flyBird.x,flyBird.y);
flyBird.y+=5;
for(int i=0;i<3;++i)
{
myPillar[i].x-=5; //柱子向左移动
if(myPillar[i].x<(-52-150))
{
initPillar(myPillar,i);
}
}
for(int i=0;i<3;++i)
{
//画柱子
drawPillar(myPillar[i]);
}
if(_kbhit())
{
//一定要先判断按键是否按下
keyDown();
}
if(hitFloor()||hitPillar(myPillar))//判断是否撞地或者撞天花板或者撞柱子
{
actionGameOver(); //撞击则结束
break;
}
Sleep(50); //休眠50毫秒
}
_getch(); //防止闪屏
closegraph(); //关闭窗口
return 0;
}
四、游戏进行流程图