飞翔的小鸟--easyx版

 (创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

今天我们来尝试一下用easyx窗口创建飞翔的小鸟游戏

(相关游戏图片我已在末尾给出,欢迎大家保存收藏)

首先与之前的打砖块游戏一样,先引用相关头文件,这里的头文件在我之前的博客中都有讲到,大家可以打开我之前的头文件进行查阅

#include<stdio.h>
#include<graphics.h>  //便于引入easyx窗口及其函数
#include<conio.h>     //按键控制 
#include<time.h>      //便于生成随机函数
#include<mmsystem.h>//这是包含多媒体设备接口头文件
#pragma comment(lib,"winmm.lib")//加载静态库

为了使游戏动画变得更加逼真 ,我上网查阅了很多图片,如果与需要,大家可以联系我,我可以发给大家

定义相关图片(关于图片操作如果有明白的可以查阅http://t.csdn.cn/YJX2h

IMAGE background;//背景图片
IMAGE bigbird[2];//两张鸟的照片
IMAGE endimg[2];//结束照片
IMAGE down[2];//上边管道的照片
IMAGE up[2];//下边管道的照片

void load()//加载相关图片
{
    loadimage(&background, "../background.bmp");//加载图片
    loadimage(&bigbird[0], "./birdy.bmp",48,48);//照片大小
    loadimage(&bigbird[1], "./bird.bmp",48,48);
    loadimage(&endimg[0], "./end.bmp");
    loadimage(&endimg[1], "./end.bmp");
    loadimage(&down[0], "./downy.bmp");
    loadimage(&down[1], "./down.bmp");
    loadimage(&up[0], "./upy.bmp");//管道宽度为52,高度为320
    loadimage(&up[1], "./up.bmp");

接下来就是对鸟的相关数据进行定义了

struct bird
{
    int x;//鸟的x,y坐标
    int y;
    int speed;//鸟的速度
};
struct bird mybird = { 70,1,70 };

接下来就是对鸟进行绘制 ,这里我们用两张图片对鸟进行绘制,这样的话才能更好得实现动态图画,减少图片背景的影响

 void drawbird(int x, int y)//画鸟
{
    putimage(x, y, &bigbird[0], SRCAND);//SRCAND贴掩码图
    putimage(x, y, &bigbird[1], SRCPAINT);//SRCPAINT贴背景图
}

然后就是如何控制鸟,这里的每一个函数我之前在easyx基础中都有讲到,这里我就不多做解释了,如果有需要,可以查阅我之前的easyx键盘控制博客(http://t.csdn.cn/KkFwU

void keybird()//控制鸟
{
    char input = _getch();
    if (input == 72)//暂停功能,便于暂停游戏
    {
        while (_getch() != 72);
    }
    switch (input)//移动鸟
    {
    case ' ':
        mybird.y -= mybird.speed;
        CreateThread(NULL, NULL, playMusic, NULL, NULL, NULL);//开辟多线程,防止音乐使游戏变卡
        break;
    default:
        break;
    }

}

 这里我们讲到的多线程,是因为在运行过程中音乐的存在会使游戏变得卡顿,所以在此之前我们先创建一个多线程

DWORD WINAPI playMusic(LPVOID pVoid)
{
    mciSendString("open ./jump.mp3", 0, 0, 0);//打开音乐
    mciSendString("play ./jump.mp3 wait", 0, 0, 0);//播放音乐
    mciSendString("close ./jump.mp3", 0, 0, 0);//关闭音乐
    return 0;
}

接下来就是对管道进行定义

struct pillar//定义管道
{
    int x1 = 288;
    int x2 = 288 + 190;
    int y1 = rand() % 250;
    int y2 = rand() % 250;
    int vx = -2;
}pillar; 

 //碰撞边界或者管道
int hitfloor()
{
    if (mybird.y <= 0 || mybird.y > 512||
        (mybird.x>=pillar.x1&&mybird.x<=(pillar.x1+52)&&(mybird.y<=(pillar.y1+20)||mybird.y>=(pillar.y1+160)))||
        (mybird.x >= pillar.x2 && mybird.x <= (pillar.x2 + 52) && (mybird.y <= (pillar.y2 + 20) || mybird.y >= (pillar.y2 + 160))))
        return 1;
    return 0;
}

 //结束动画
void gameover()
{
    int x = 60;
    int y = 608;
    while (y >= 240)
    {
        putimage(0, 0, &background);
        putimage(x, y, &endimg[0], SRCAND);
        putimage(x, y, &endimg[1], SRCPAINT);
        y -= 50;
        Sleep(50);
    }
    HWND hwnd = GetHWnd();//获得窗口句柄
    MessageBox(hwnd, "gameover", "提示", MB_OK);//弹出窗口
}

 在上面我们加载了相关的图片,现在我们将其进行输出

void drawpillar()//输出相关图片
{
    putimage(pillar.x1, pillar.y1-300, &down[0], SRCAND);
    putimage(pillar.x1, pillar.y1-300, &down[1], SRCPAINT);
    putimage(pillar.x1, pillar.y1 + 160, &up[0], SRCAND);
    putimage(pillar.x1, pillar.y1 + 160, &up[1], SRCPAINT);
    putimage(pillar.x2, pillar.y2 - 300, &down[0], SRCAND);
    putimage(pillar.x2, pillar.y2 - 300, &down[1], SRCPAINT);
    putimage(pillar.x2, pillar.y2 + 160, &up[0], SRCAND);
    putimage(pillar.x2, pillar.y2 + 160, &up[1], SRCPAINT);

接下来就是管道的移动以及不断循环了,因为我们上面只定义了两组管道,所以需要不断循环才能实现管道的不断输出 

 void movepillar()//移动管道
{
    pillar.x1 += pillar.vx;
    pillar.x2 += pillar.vx;
    if (pillar.x1 <= -52)//管道循坏处理
        pillar.x1 = pillar.x2 + 190;
    if (pillar.x2 < -52)
        pillar.x2 = pillar.x1 + 190;
}

最后就是将其集中在主函数之中,主函数的相关细节在我之前的easyx基础中均有涉及,欢迎大家查阅 

 int main()
{
    srand((unsigned int)time(NULL));//生成随机数种子
    initgraph(288,608);//创建主窗口
    load();
    while (1)
    {
        cleardevice();//清屏函数,防止图片加载卡顿
        putimage(0, 0, &background);//输出图片,坐标,地址
        drawbird(mybird.x, mybird.y);
        drawpillar();
        movepillar();
        if (hitfloor())
        {
            gameover();
            break;
        }
        mybird.y += 10;
        //如果不加kbhit,图像在不按键时就不会动
        if (_kbhit())//判断是否有按键,有按键才处理,无按键就不处理
        {
            keybird();
        }
        Sleep(50);
    }
    getchar();//防止闪退
    closegraph();
    return 0;
}

总体代码就是这样,如果大家发现bug或者有更好的方法 ,欢迎大家一起来讨论


#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<graphics.h>  //便于引入easyx窗口及其函数
#include<conio.h>     //按键控制 
#include<time.h>
#include<mmsystem.h>//这是包含多媒体设备接口头文件
#pragma comment(lib,"winmm.lib")//加载静态库
IMAGE background;//背景图片
IMAGE bigbird[2];//两张鸟的照片
IMAGE endimg[2];//结束照片
IMAGE down[2];//上边柱子的照片
IMAGE up[2];//下边柱子的照片
//定义鸟的变量
struct bird
{
	int x;//鸟的x,y坐标
	int y;
	int speed;//鸟的速度
};
struct bird mybird = { 70,1,70 };
void load()//加载相关图片
{
	loadimage(&background, "../background.bmp");//加载图片
	loadimage(&bigbird[0], "./birdy.bmp",48,48);//照片大小
	loadimage(&bigbird[1], "./bird.bmp",48,48);
	loadimage(&endimg[0], "./endy.bmp");
	loadimage(&endimg[1], "./end.bmp");
	loadimage(&down[0], "./downy.bmp");
	loadimage(&down[1], "./down.bmp");
	loadimage(&up[0], "./upy.bmp");//管道宽度为52,高度为320
	loadimage(&up[1], "./up.bmp");
}
void drawbird(int x, int y)//画鸟
{
	putimage(x, y, &bigbird[0], SRCAND);//SRCAND贴掩码图
	putimage(x, y, &bigbird[1], SRCPAINT);//SRCPAINT贴背景图
}
DWORD WINAPI playMusic(LPVOID pVoid)
{
	mciSendString("open ./jump.mp3", 0, 0, 0);//打开音乐
	mciSendString("play ./jump.mp3 wait", 0, 0, 0);//播放音乐
	mciSendString("close ./jump.mp3", 0, 0, 0);//关闭音乐
	return 0;
}
void keybird()//控制鸟
{
	char input = _getch();
	if (input == 72)//暂停功能
	{
		while (_getch() != 72);
	}
	switch (input)//移动鸟
	{
	case ' ':
		mybird.y -= mybird.speed;
		CreateThread(NULL, NULL, playMusic, NULL, NULL, NULL);//开辟多线程,防止音乐使游戏变卡
		break;
	default:
		break;
	}

}
struct pillar//定义柱子
{
	int x1 = 288;
	int x2 = 288 + 190;
	int y1 = rand() % 250;
	int y2 = rand() % 250;
	int vx = -2;
}pillar;
//碰撞边界
int hitfloor()
{
	if (mybird.y <= 0 || mybird.y > 512||
		(mybird.x>=pillar.x1&&mybird.x<=(pillar.x1+52)&&(mybird.y<=(pillar.y1+20)||mybird.y>=(pillar.y1+160)))||
		(mybird.x >= pillar.x2 && mybird.x <= (pillar.x2 + 52) && (mybird.y <= (pillar.y2 + 20) || mybird.y >= (pillar.y2 + 160))))
		return 1;
	return 0;
}
//结束动画
void gameover()
{
	int x = 60;
	int y = 608;
	while (y >= 240)
	{
		putimage(0, 0, &background);
		putimage(x, y, &endimg[0], SRCAND);
		putimage(x, y, &endimg[1], SRCPAINT);
		y -= 50;
		Sleep(50);
	}
	HWND hwnd = GetHWnd();//获得窗口句柄
	MessageBox(hwnd, "gameover", "提示", MB_OK);//弹出窗口
}
void drawpillar()//输出相关图片
{
	putimage(pillar.x1, pillar.y1-300, &down[0], SRCAND);
	putimage(pillar.x1, pillar.y1-300, &down[1], SRCPAINT);
	putimage(pillar.x1, pillar.y1 + 160, &up[0], SRCAND);
	putimage(pillar.x1, pillar.y1 + 160, &up[1], SRCPAINT);
	putimage(pillar.x2, pillar.y2 - 300, &down[0], SRCAND);
	putimage(pillar.x2, pillar.y2 - 300, &down[1], SRCPAINT);
	putimage(pillar.x2, pillar.y2 + 160, &up[0], SRCAND);
	putimage(pillar.x2, pillar.y2 + 160, &up[1], SRCPAINT);
} 
void movepillar()//移动管道
{
	pillar.x1 += pillar.vx;
	pillar.x2 += pillar.vx;
	if (pillar.x1 <= -52)//管道循坏处理
	{
		pillar.x1 = pillar.x2 + 190;
		pillar.y1 = rand() % 250;//使每一次管道的位置都不一样
	}
	if (pillar.x2 < -52)
	{
		pillar.x2 = pillar.x1 + 190;
		pillar.y2 = rand() % 250;
	}
}
int main()
{
	srand((unsigned int)time(NULL));//生成随机数种子
	initgraph(288,608);//创建主窗口
	load();
	while (1)
	{
		cleardevice();
		putimage(0, 0, &background);//输出图片,坐标,地址
		drawbird(mybird.x, mybird.y);
		drawpillar();
		movepillar();
		if (hitfloor())
		{
			gameover();
			break;
		}
		mybird.y += 10;
		//如果不加kbhit,图像在不按键时就不会动
		if (_kbhit())//判断是否有按键,有按键才处理,无按键就不处理
		{
			keybird();
		}
		Sleep(50);
	}
	getchar();//防止闪退
	closegraph();
	return 0;
}

加油 

游戏相关代码的掩码图和背景图:

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小周不想卷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值