c语言graphics图形库的使用之实现代码雨效果

⌚Time: 2022-12-12 18:19:58

👨‍💻Author: Jack Ge

效果:


使用到easyx库

EasyX Graphics Library 是针对 Visual C++ 的免费绘图库,支持 VC6.0 ~ VC2022,简单易用,学习成本极低,应用领域广泛。目前已有许多大学将 EasyX 应用在教学当中。

下载地址

https://easyx.cn/

下载完成后解压


压缩包

 ├ include <文件夹>

 │ └ graphics.h     // 程序需要引用的头文件

 ├ lib <文件夹>

 │ ├ amd64 <文件夹>

 │ │ ├ graphicsw.lib  // VC2008 / VC2010 MBCS 库文件(x64)

 │ │ └ graphicswu.lib // VC2008 / VC2010 Unicode 库文件(x64)

 │ ├ graphics.lib    // VC6 MBCS 库文件

 │ ├ graphicsu.lib    // VC6 Unicode 库文件

 │ ├ graphicsw.lib    // VC2008 / VC2010 MBCS 库文件(x86)

 │ └ graphicswu.lib   // VC2008 / VC2010 Unicode 库文件(x86)

 ├ EasyX_Help.chm     // 帮助文件

 └ Setup.hta        // 安装程序

使用vs2005新建一个项目,项目属性,c/c++,城轨,附加包含目录,添加easyx的头文件目录

链接器,常规,附加库目录,添加easyx的lib文件夹目录

链接器,输入,附加依赖项添加链接的静态库


实现思路:

使用结构体储存每个代码流的代码和位置,大小,亮度,速度等信息


struct CodeRain{

    TCHAR ch[100];//显示的字符

    int size;//大小

    int length;//长度

    int light;//亮度

    int speed;//速度

    int posX;//x位置

    int posY;

};

通过移动函数对代码流进行下落移动


void move_code_rain(){

    for (int i=0;i<CODE_RAIN_NUMBER;i++)

    {

        codeRain[i].posY += codeRain[i].speed;

        if (codeRain[i].posY>WINDOW_HIGHT+100)

        {

            restart_code_rain(i);

        }

    }

}

绘制代码流


void draw_code_rain(){

    for (int i=0;i<CODE_RAIN_NUMBER;i++)

    {

        setfont(codeRain[i].size,0,L"Courier");

        for (int j=0;j<codeRain[i].length;j++)

        {

            int tempLight = 100+155/5*codeRain[i].light - 20*j;

            if (tempLight<0)

            {

                tempLight = 0;

            }

            setcolor(RGB(0,tempLight,0));//后面的代码逐渐暗淡

            outtextxy(codeRain[i].posX,codeRain[i].posY-j*20,codeRain[i].ch[j]);

        }

    }   



}

通过使用 BeginBatchDraw();FlushBatchDraw();EndBatchDraw();三个函数实现双缓冲绘图,避免闪烁屏幕


错误:

对于VC6,编译运行如果报错

error LNK2019: 无法解析的外部符号 __iob,需要在文件最开始添加


#include <stdio.h>

extern "C" {

    FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};

}

如果提示

warning LNK4006: "int __cdecl getwidth(void)" (?getwidth@@YAHXZ) 已在 graphics.lib(graphics.obj) 中定义;已忽略第二个定义

重定义错误,在项目属性,链接器,命令行中加入开关/FORCE

完整代码


#include <graphics.h>

#include <time.h>

#include <conio.h>

#include <stdio.h>

extern "C" {

    FILE _iob[3] = {__iob_func()[0], __iob_func()[1], __iob_func()[2]};

}

//定义项

#define WINDOW_WIDTH 800

#define WINDOW_HIGHT 600

#define CODE_RAIN_NUMBER 50



struct CodeRain{

    TCHAR ch[100];//显示的字符

    int size;//大小

    int length;//长度

    int light;//亮度

    int speed;//速度

    int posX;//x位置

    int posY;

};

struct CodeRain codeRain[CODE_RAIN_NUMBER];

void restart_code_rain(int id){

    for (int i=0;i<100;i++)

    {

        codeRain[id].ch[i] = 65 + rand()%26;//A-Z

        //codeRain[id].ch[i] = 48 + rand()%2;//01

    }

    codeRain[id].size = 6 + rand()%14;

    codeRain[id].length = 5 + rand()%10;

    codeRain[id].light = 1 + rand()%5;

    codeRain[id].speed = 2 + rand()%5;

    codeRain[id].posX = rand()%WINDOW_WIDTH;

    codeRain[id].posY = rand()%WINDOW_HIGHT/5;



}

void init_code_rain(){

    for (int i=0;i<CODE_RAIN_NUMBER;i++)

    {

        restart_code_rain(i);

    }

}

void move_code_rain(){

    for (int i=0;i<CODE_RAIN_NUMBER;i++)

    {

        codeRain[i].posY += codeRain[i].speed;

        if (codeRain[i].posY>WINDOW_HIGHT+100)

        {

            restart_code_rain(i);

        }

    }

}

void draw_code_rain(){

    for (int i=0;i<CODE_RAIN_NUMBER;i++)

    {

        setfont(codeRain[i].size,0,L"Courier");

        for (int j=0;j<codeRain[i].length;j++)

        {

            int tempLight = 100+155/5*codeRain[i].light - 20*j;

            if (tempLight<0)

            {

                tempLight = 0;

            }

            setcolor(RGB(0,tempLight,0));//后面的代码逐渐暗淡

            outtextxy(codeRain[i].posX,codeRain[i].posY-j*20,codeRain[i].ch[j]);

        }

    }   



}

int main(void)

{

    initgraph(WINDOW_WIDTH,WINDOW_HIGHT);

    //随机数种子

    srand((unsigned int)time(0));

    //初始化代码雨

    init_code_rain();

    BeginBatchDraw();

    while(1){

        cleardevice();

        move_code_rain();

        draw_code_rain();

        FlushBatchDraw();

        Sleep(15);

        if (kbhit())

        {

            break;

        }

    }

    EndBatchDraw();

    closegraph();

    return 0;

}