c语言使用easyX图形库制作打气球小游戏

大一c语言使用easyX图形库制作打气球小游戏

 

       如果你是入门easyX图形库,那么这个打气球小游戏将会是和不错的入门项目选择,easyX开创了可视化窗口,使用户更加直观的了解到对象的变化,总代码附在文章底下。

       该可视化程序需下载easy图形库插件:https://easyx.cn/

ps:如报错,需根据自己的音乐和背景路径位置自行调整!!!

首先我们来看一下效果图

c语言使用easyX图形库制作打气球小游戏

这是我们的程序结构脑图

c语言使用easyX图形库制作打气球小游戏

 

下面附上代码

#include<stdio.h>
#include<math.h>
#include<time.h>
#include<stdlib.h>
#include<Windows.h>      //双缓冲
#include <graphics.h>      //easyX图形库
#include <process.h>        //使用进程处理函数需要用到该头文件,包含过程控制的函数(给鼠标开辟线程会用到)

#include<mmsystem.h>               //这两个是载入音乐的头文件
#pragma comment(lib,"winmm.lib")   //

#define NUM 15


int x, y;    //炮口坐标
DWORD t1, t2, tt1, tt2;   //给一个时间限定
int score = 0;
char strscore[5];     //设置存储分数的数组 0-9999
MOUSEMSG msg = { 0 };     //定义鼠标信息    设为全局变量,主函数里开辟新的线程


//子弹的结构(结构体数组)
struct Bullet
{
    int x, y;         //子弹坐标
    double vx, vy;    //速度分量
    int r;            //子弹半径
    int color;        //子弹颜色
    int flag;         //子弹是否存活
}bullet[NUM];

//气球的结构(结构体数组)
struct  Balloon
{
    int x, y;   //气球坐标
    int color;  //气球颜色
    int flag;   //气球是否存在的标识

}balloon[NUM];

int main()
{
    void gamepaint();
    void GameInit();
    void CreateBullet(double a);
    void MoveBullet();
    void CreatBalloon();
    void MoveBalloon();
    void Boom();
    void HideCursor();    //双缓冲 
    void Mouse();


    initgraph(720, 480);    //创建窗口(宽720,高480)
    srand((unsigned int)time(NULL));            //种下随机数种子。 固定那些地方产生哪些颜色

    mciSendString("opne ./music.mp3", 0, 0, 0);  //打开音乐
    mciSendString("play music.mp3", 0, 0, 0);    //播放音乐

    GameInit();

    t1 = GetTickCount();   //获取系统时间
    tt1 = GetTickCount();


    _beginthread((_beginthread_proc_type)Mouse, 0, 0);  //Mouse函数开启了一个线程,Mouse是鼠标函数的地址(调用了Mouse函数),相当于main函数和鼠标函数同步执行
    while (1)
    {
        sprintf_s(strscore, "%d", score);   //将分数写入到界面. sprintf不安全,课考虑用sprintf_s
       
        gamepaint();


        tt2 = GetTickCount();
        if (tt2 - tt1 > 500)
            CreatBalloon();   //产生气球

        t2 = GetTickCount();
        if (t2 - t1 > 20)        //t1-t2>20ms
        {
            MoveBullet();   //子弹移动
            MoveBalloon();  //气球移动
            Boom();         //子弹气球碰撞爆炸
            t1 = t2;
        }
    }
    HideCursor();      //双缓冲函数调用

    getchar();
    return 0;
}

//游戏绘制函数
void gamepaint()
{
    BeginBatchDraw();      //开始绘制
    setlinestyle(PS_SOLID, 2);  //设置线条样式与宽度 (实线,像素2)
    setlinecolor(WHITE);    //设置线条颜色
    setfillcolor(RGB(177, 173, 175));  //右边菜单栏
    fillrectangle(640, 0, 719, 479);

    IMAGE img;			   //创建IMAGE对象     //左边游戏区
    loadimage(&img, "E:\\c语言\\气球小游戏\\图片素材\\sky.jpg", 640, 479);//绝对地址载入图片  
    putimage(0, 0, &img);
    /*setfillcolor(RGB(149, 206, 245));
    fillrectangle(0, 0, 640, 479);*/

    circle(320, 460, 60);    //圆心(320,460)  r=60

    setlinecolor(BLACK);   //线条颜色
    setfillcolor(BLACK);   //填充颜色
    fillcircle(320, 460, 10);  //炮台(小圆)

    setlinestyle(PS_SOLID, 8);   //(实线,像素8)
    line(x, y, 320, 460);    //炮口

    setbkmode(0);  //透明字体
    outtextxy(650, 100, "Score:");      //要将项目->属性->字符集设置为多节字符集
    outtextxy(650, 150, strscore);     //分数
    outtextxy(650, 300, "Author:");
    outtextxy(650, 350, "王烁");  //作者



    //设计气球
    setlinestyle(PS_SOLID, 2);  //(实线,像素2)
    setlinecolor(WHITE);    //设置线条颜色

    for (int i = 0; i < NUM; i++)
    {
        if (balloon[i].flag == 1)
        {
            setfillcolor(balloon[i].color);    //(画图工具里的红绿蓝三色)
            fillellipse(balloon[i].x, balloon[i].y, balloon[i].x + 30, balloon[i].y + 50);   //(圆心(100,100),宽度30,高度50)
            arc(balloon[i].x + 5, balloon[i].y + 5, balloon[i].x + 25, balloon[i].y + 45, 0, 1.2);   //圆弧(()位置,()宽度和高度,弧度0—1.2π)
            arc(balloon[i].x + 15, balloon[i].y + 35, balloon[i].x + 35, balloon[i].y + 65, 3.14, 4.4);
        }
    }



    //子弹画出来
    for (int i = 0; i < NUM; i++)
    {
        if (bullet[i].flag == 1)
        {
            setlinecolor(bullet[i].color);   //设置线条颜色
            setfillcolor(bullet[i].color);   //设置填充颜色
            fillcircle(bullet[i].x, bullet[i].y, bullet[i].r);  //子弹色位置和大小
        }
    }

    EndBatchDraw(); //结束绘制
}


//游戏的初始化函数
void GameInit()
{
    //子弹
    int i;
    for (i = 0; i < NUM; i++)
    {
        bullet[i].r = 5;
        bullet[i].color = RGB(rand() % 257, rand() % 257, rand() % 257); //子弹颜色随机
        bullet[i].flag = 0;  //不存货(闲置);
    }

    //气球
    for (int i = 0; i < NUM; i++)   //先给10个气球
    {
        if (i < 10)
        {
            balloon[i].x = rand() % 610;  //气球显示,边界窗口宽-气球宽 640-30
            balloon[i].y = rand() % 430;  //480-50
            balloon[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            balloon[i].flag = 1;  //气球存在了
        }
        else     //剩下5个气球
        {
            balloon[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);
            balloon[i].flag = 0;  //气球没存在界面内
        }
    }

}


//产生子弹
void CreateBullet(double a)
{
    //数组
    for (int i = 0; i < NUM; i++)
    {
        if (bullet[i].flag == 0)
        {
            bullet[i].x = x;
            bullet[i].y = y;
            bullet[i].vx = 15 * cos(a);    //15就是发射速度
            bullet[i].vy = 15 * sin(a);
            bullet[i].flag = 1;   //锁住内存,相当于子弹打出去,还没捡回来,没子弹了。
            break;
        }
    }
}


//子弹移动
void MoveBullet()
{
    for (int i = 0; i < NUM; i++)
    {
        if (bullet[i].flag == 1)
        {
            bullet[i].x += bullet[i].vx;
            bullet[i].y -= bullet[i].vy;
        }
    }

    //移动之后,飞出场外   flag=0
    for (int i = 0; i < NUM; i++)
    {
        if (bullet[i].flag == 1)
        {
            if (bullet[i].x < 0 || bullet[i].x>640 || bullet[i].y < 0 || bullet[i].y>480)
            {
                bullet[i].flag = 0;
            }
        }
    }

}


//产生气球
void CreatBalloon()
{
    for (int i = 0; i < NUM; i++)
    {
        if (balloon[i].flag == 0)
        {
            balloon[i].x = rand() % 610;   //新产生x坐标气球随机
            balloon[i].y = 480;          //新产生气球y坐标永远在最底下;
            balloon[i].flag = 1;   //锁住内存,相当于气球在界面内
            break;
        }
    }
}


//气球移动
void MoveBalloon()
{
    //移动
    for (int i = 0; i < NUM; i++)
    {
        if (balloon[i].flag == 1)
        {
            balloon[i].y -= 2;    //往上移动

            if (rand() % 2 == 0)   //气球实现左右移动。  rand()%2 = =0,概率1/2;
                balloon[i].x += 1;
            else
                balloon[i].x -= 1;
        }
    }

    //出界
    for (int i = 0; i < NUM; i++)
    {
        if (balloon[i].flag == 1)
        {
            if (balloon[i].x + 30 < 0 || balloon[i].x > 640 || balloon[i].y + 50 < 0)  //下边界不算,因为总会飘上来
            {
                balloon[i].flag = 0;
            }
        }
    }
}


//打气球,爆炸
void Boom()
{
    for (int i = 0; i < NUM; i++)   //遍历气球
    {
        if (balloon[i].flag == 1)   //选在界面里边的气球
        {
            for (int j = 0; j < NUM; j++)   //遍历子弹  
            {
                if (bullet[j].flag == 1)
                {
                    if (bullet[j].x > balloon[i].x && bullet[j].x<balloon[i].x + 30 && bullet[j].y>balloon[i].y && bullet[j].y < balloon[i].x + 50)  //判断子弹是否与气球重合
                    {
                        bullet[j].flag = 0;
                        balloon[i].flag = 0;
                        score += 10;
                    }
                }
            }
        }
    }
}

void Mouse()
{
    while (1)
    {
        if (MouseHit())    //如果有鼠标信息
        {
            msg = GetMouseMsg();   //获取鼠标信息到msg
            double a = atan2(460.0 - msg.y, msg.x - 320);
            x = 320 + 70 * cos(a);
            y = 460 - 70 * sin(a);

            if (msg.uMsg == WM_LBUTTONDOWN)   //点击鼠标左键
            {
                CreateBullet(a);
            }
        }
    }
}



//双缓冲
void HideCursor()
{
    HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_CURSOR_INFO CursorInfo;
    GetConsoleCursorInfo(handle, &CursorInfo);//获取控制台光标信息
    CursorInfo.bVisible = false; //隐藏控制台光标
    SetConsoleCursorInfo(handle, &CursorInfo);//设置控制台光标状态
}



       我们还可以根据以上描述气球、子弹的思想,添加炸弹函数,计时功能等,添加更多有趣好玩的功能模块。也可将炮台,子弹,气球等使用图片形式看着效果更加好。

希望可以对您有所帮助!!!

上一篇:aaa


下一篇:讲诉从酒店服务业到IT行业的心酸取经路,另附拙作 ASP.net(C#)利用SQL Server实现注册和登陆功能