飞翔的小鸟--easyx版

简介: 飞翔的小鸟--easyx版

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

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

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

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

#include
#include  //便于引入easyx窗口及其函数
#include     //按键控制  
#include      //便于生成随机函数
#include//这是包含多媒体设备接口头文件
#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;
}

加油

游戏相关代码的掩码图和背景图:屏幕截图 2023-07-28 164638.png

屏幕截图 2023-07-28 164740.png

相关文章
|
2月前
easyX实现自由落体小球
本文介绍了使用easyX图形库实现自由落体小球的编程方法,包括匀速下落和加速下落,以及如何处理小球的反弹和边界条件。
46 0
|
7月前
|
C语言
|
Python 容器
星际争霸之小霸王之小蜜蜂(六)--让子弹飞
星际争霸之小霸王之小蜜蜂(六)--让子弹飞
|
7月前
|
算法 C语言
三子棋小游戏(可改棋盘大小)
三子棋小游戏(可改棋盘大小)
81 0
|
数据可视化 编译器 程序员
【好一朵美丽的玫瑰花】(C++代码实现+EasyX图形化界面)
【好一朵美丽的玫瑰花】(C++代码实现+EasyX图形化界面)
123 0
|
程序员 C语言
趣味益智小游戏 三子棋+五子棋 优化版(可任意选择棋盘大小)
趣味益智小游戏 三子棋+五子棋 优化版(可任意选择棋盘大小)
125 0
|
Java
【Java实现小游戏】飞翔的小鸟(源码)
【Java实现小游戏】飞翔的小鸟(源码)
222 0
|
小程序 开发工具
樱花飘落模拟器-情人节祝你表白成功
看着樱花缓缓的飘落,然后不觉间竟下起了绵绵的细雨。因为今天我所在的城市正下着小雨,所以就在这个小应用中增加了阵阵的细雨功能。 下面我们就学习一下如何实现一个这样温暖的小程序。 首先准备一下素材。一个粉色的背景,两个樱花花瓣,一个模拟雨滴的长方形,以及两句要显示的话。
138 0
|
Python
圣诞树代码
python写圣诞树
251 0
圣诞树代码
三子棋小游戏(万字详解)可以自定义棋盘大小(下)
三子棋小游戏(万字详解)可以自定义棋盘大小(下)
111 0
三子棋小游戏(万字详解)可以自定义棋盘大小(下)