【C++】开源:Windows图形库EasyX配置与使用

news2024/12/23 22:35:29

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍Windows图形库EasyX配置与使用。
无专精则不能成,无涉猎则不能通。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. 项目介绍
    • :blush:2. 环境配置
    • :satisfied:3. 使用说明
      • 窗口绘制圆的示例:
      • 获取鼠标和键盘事件示例:
      • 鼠标操作与绘制示例:
      • 贪吃蛇示例:

😏1. 项目介绍

官网:https://easyx.cn/

EasyX是一个基于Windows的简单图形库,它提供了一个易于使用的图形绘制接口,适用于初学者和爱好者进行图形编程。下面是EasyX库的一些特点和功能:

1.易于学习和使用:EasyX采用了简单的图形绘制接口,使得初学者可以快速上手。它提供了一些基本的绘图函数,如画线、画圆、绘制文本等,使用户能够轻松创建图形界面和动画效果。

2.轻量级和快速:EasyX是一个轻量级的图形库,不需要复杂的安装和配置过程。它使用GDI(图形设备接口)来进行图形绘制,具有较快的绘图速度和相对较低的系统资源占用。

3.图形界面设计:EasyX提供了一些常用的图形界面控件,如按钮、文本框、滚动条等,使用户可以轻松创建交互式的图形界面。

4.动画和游戏开发:EasyX支持实时动画和游戏开发,提供了帧动画、双缓冲技术等功能,使用户能够创建流畅的动画效果和简单的游戏。

5.跨平台:EasyX主要针对Windows平台,支持Windows XP及以上版本。然而,EasyX也可以在部分Linux环境下使用,如Wine模拟器。

😊2. 环境配置

我这里用的Clion + mingw,EasyX的下载地址:https://easyx.cn/download/easyx4mingw_20220901.zip

CMakeLists.txt示例:

cmake_minimum_required(VERSION 3.19)
project(easyx_demo)

set(CMAKE_CXX_STANDARD 14)

include_directories("D:/develop/easyx4mingw_20220901/include")
link_directories("D:/develop/easyx4mingw_20220901/lib64")

add_executable(easyx_demo main.cpp)
target_link_libraries(easyx_demo -leasyx)

😆3. 使用说明

官网也提供了函数使用的文档,并给出了一些示例:https://docs.easyx.cn/zh-cn/char-matrix

窗口绘制圆的示例:

#include <graphics.h>
#include <conio.h>

int main()
{
    initgraph(640, 480);  // 创建一个640x480的绘图窗口

    circle(320, 240, 100);  // 在窗口中心画一个半径为100的圆

    getch();  // 等待用户按下任意键

    closegraph();  // 关闭绘图窗口
    return 0;
}

获取鼠标和键盘事件示例:

#include <graphics.h>
#include <conio.h>
#include <stdio.h>

int main()
{
    initgraph(640, 480);  // 创建一个640x480的绘图窗口

    while (true)
    {
        // 监听键盘事件
        if (kbhit())
        {
            char ch = getch();  // 获取键盘按键
            if (ch == 'q' || ch == 'Q')
                break;  // 如果按下了Q键,退出循环
        }

        // 监听鼠标事件
        if (MouseHit())
        {
            MOUSEMSG mouseMsg = GetMouseMsg();

            if (mouseMsg.uMsg == WM_MOUSEMOVE)
            {
                int x = mouseMsg.x;
                int y = mouseMsg.y;
                // 在控制台输出鼠标移动的坐标
                printf("Mouse move: x = %d, y = %d\n", x, y);
            }
            else if (mouseMsg.uMsg == WM_LBUTTONDOWN)
            {
                int x = mouseMsg.x;
                int y = mouseMsg.y;
                // 在控制台输出鼠标左键按下的坐标
                printf("Left button down: x = %d, y = %d\n", x, y);
            }
            else if (mouseMsg.uMsg == WM_LBUTTONUP)
            {
                int x = mouseMsg.x;
                int y = mouseMsg.y;
                // 在控制台输出鼠标左键释放的坐标
                printf("Left button up: x = %d, y = %d\n", x, y);
            }
        }
    }

    closegraph();  // 关闭绘图窗口
    return 0;
}

鼠标操作与绘制示例:

#include <graphics.h>

int main()
{
    // 初始化图形窗口
    initgraph(640, 480);

    ExMessage m;		// 定义消息变量

    while(true)
    {
        // 获取一条鼠标或按键消息
        m = getmessage(EX_MOUSE | EX_KEY);

        switch(m.message)
        {
            case WM_MOUSEMOVE:
                // 鼠标移动的时候画红色的小点
                putpixel(m.x, m.y, RED);
                break;

            case WM_LBUTTONDOWN:
                // 如果点左键的同时按下了 Ctrl 键
                if (m.ctrl)
                    // 画一个大方块
                    rectangle(m.x - 10, m.y - 10, m.x + 10, m.y + 10);
                else
                    // 画一个小方块
                    rectangle(m.x - 5, m.y - 5, m.x + 5, m.y + 5);
                break;

            case WM_KEYDOWN:
                if (m.vkcode == VK_ESCAPE)
                    return 0;	// 按 ESC 键退出程序
        }
    }

    // 关闭图形窗口
    closegraph();
    return 0;
}

贪吃蛇示例:

#include <graphics.h>
#include <conio.h>
#include <time.h>

const int CELL_SIZE = 20;  // 每个单元格的尺寸
const int WIDTH = 800;  // 窗口宽度
const int HEIGHT = 600;  // 窗口高度
const int ROWS = HEIGHT / CELL_SIZE;  // 行数
const int COLS = WIDTH / CELL_SIZE;  // 列数

struct Point  // 坐标点结构体
{
    int x, y;
};

enum Direction  // 移动方向枚举
{
    UP,
    DOWN,
    LEFT,
    RIGHT
};

void DrawCell(int x, int y, COLORREF color)
{
    setfillcolor(color);
    setlinecolor(color);
    fillrectangle(x * CELL_SIZE, y * CELL_SIZE, (x + 1) * CELL_SIZE, (y + 1) * CELL_SIZE);
}

void DrawSnake(Point* snake, int length)
{
    for (int i = 0; i < length; i++)
    {
        if (i == 0)
            DrawCell(snake[i].x, snake[i].y, RGB(0, 255, 0));  // 绘制蛇头
        else
            DrawCell(snake[i].x, snake[i].y, RGB(0, 200, 0));  // 绘制蛇身
    }
}

void GenerateFood(Point* snake, int length, Point& food)
{
    while (true)
    {
        food.x = rand() % COLS;
        food.y = rand() % ROWS;

        bool overlap = false;
        for (int i = 0; i < length; i++)
        {
            if (snake[i].x == food.x && snake[i].y == food.y)
            {
                overlap = true;
                break;
            }
        }

        if (!overlap)
            break;
    }

    DrawCell(food.x, food.y, RGB(255, 0, 0));  // 绘制食物
}

void UpdateSnake(Point* snake, int& length, Direction direction, bool& gameOver)
{
    Point head = snake[0];
    Point newHead = head;

    switch (direction)
    {
        case UP:
            newHead.y--;
            break;
        case DOWN:
            newHead.y++;
            break;
        case LEFT:
            newHead.x--;
            break;
        case RIGHT:
            newHead.x++;
            break;
    }

    if (newHead.x < 0 || newHead.x >= COLS || newHead.y < 0 || newHead.y >= ROWS)
    {
        gameOver = true;  // 越界,游戏结束
        return;
    }

    for (int i = length - 1; i > 0; i--)
    {
        snake[i] = snake[i - 1];
    }

    snake[0] = newHead;

    for (int i = 1; i < length; i++)
    {
        if (snake[i].x == newHead.x && snake[i].y == newHead.y)
        {
            gameOver = true;  // 撞到自己,游戏结束
            return;
        }
    }
}

int main()
{
    initgraph(WIDTH, HEIGHT);  // 创建一个指定宽高的绘图窗口

    srand(static_cast<unsigned int>(time(nullptr)));  // 初始化随机数种子

    Point* snake = new Point[ROWS * COLS];  // 蛇的坐标数组
    int length = 1;  // 蛇的初始长度
    Direction direction = RIGHT;  // 蛇的初始移动方向
    bool gameOver = false;  // 游戏是否结束

    // 初始化蛇的初始位置
    snake[0].x = COLS / 2;
    snake[0].y = ROWS / 2;

    Point food;  // 食物的坐标

    GenerateFood(snake, length, food);  // 生成食物

    while (!gameOver)
    {
        // 监听键盘事件
        if (kbhit())
        {
            char ch = getch();
            switch (ch)
            {
                case 'W':
                case 'w':
                    if(direction != DOWN)
                        direction = UP;
                    break;
                case 'S':
                case 's':
                    if (direction != UP)
                        direction = DOWN;
                    break;
                case 'A':
                case 'a':
                    if (direction != RIGHT)
                        direction = LEFT;
                    break;
                case 'D':
                case 'd':
                    if (direction != LEFT)
                        direction = RIGHT;
                    break;
            }
        }

        cleardevice();  // 清空绘图窗口

        UpdateSnake(snake, length, direction, gameOver);  // 更新蛇的位置

        if (snake[0].x == food.x && snake[0].y == food.y)
        {
            length++;  // 蛇吃到食物,长度增加
            GenerateFood(snake, length, food);  // 生成新的食物
        }

        DrawSnake(snake, length);  // 绘制蛇

        DrawCell(food.x, food.y, RGB(255, 0, 0));  // 绘制食物

        Sleep(100);
    }

    delete[] snake;  // 释放内存

    closegraph();  // 关闭绘图窗口

    return 0;
}

在这里插入图片描述

以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

RabbitMQ 死信队列应用

1. 概念 死信队列&#xff08;Dead Letter Queue&#xff09;是在消息队列系统中的一种特殊队列&#xff0c;用于存储无法被消费的消息。消息可能会因为多种原因变成“死信”&#xff0c;例如消息过期、消息被拒绝、消息队列长度超过限制等。当消息变成“死信”时&#xff0c;…

对付勒索病毒,复杂的往往无法落地

一道道复杂门墙防护安全&#xff0c; 还是一个精密的锁更安全&#xff1f; &#x1f447;&#x1f447;&#x1f447; 在网络数据安全问题频发的当下&#xff0c;除了常规的备份、灾备措施以外&#xff0c;企业是否有做好应对最坏情况的准备&#xff1f;一旦病毒绕过了一道道…

极限的运算法则【高数笔记】

【定理】 1. 无穷小量 * 有界 无穷小量 简单理解为&#xff1a;0 乘以任何数都等于 0 &#xff0c;因为常数 0 是无穷小量 2. 设 lim f&#xff08;x&#xff09; a , lim g (x) b 加减&#xff1a;lim[f(x) g(x) ] lim f(x) g(x) a b 乘&#xff1a;lim[f(x)…

[Visual Studio] vs 2022中如何创建空白的解决方案

在Visual Studio 2022中创建一个空白的解决方案非常简单。请按照以下步骤操作&#xff1a; 打开Visual Studio。 在启动页面上&#xff0c;选择“创建新的项目”。 在“创建新项目”的对话框中&#xff0c;搜索“空白”。 在中间搜索结果中&#xff0c;选择“空白解决方案”…

同时添加多个的远程桌面工具,Windows远程桌面设置多用户同时登录

Windows Server 版本上的 Windows 远程桌面服务 (RDS) 允许多个用户同时登录。 但是&#xff0c;在标准的Windows桌面版本&#xff08;例如Windows 10&#xff09;上&#xff0c;默认情况下&#xff0c;远程桌面是为单个用户一次登录而设计的。 这被称为“管理远程桌面”模式。…

蓝桥杯2024/1/31----第十届省赛题笔记

题目要求&#xff1a; 1、 基本要求 1.1 使用大赛组委会提供的国信长天单片机竞赛实训平台&#xff0c;完成本试题的程序设计 与调试。 1.2 选手在程序设计与调试过程中&#xff0c;可参考组委会提供的“资源数据包”。 1.3 请注意&#xff1a; 程序编写、调试完成后选手…

vmware读取坏掉的虚拟磁盘vmdk文件

vmware centos 7系统挂了&#xff0c;开不了机&#xff0c;重新安装ubuntu22系统&#xff0c;挂载centos7的vmdk文件。 1.找到坏掉的系统的vmdk文件 2.新系统添加硬盘 选择刚才旧系统的vmdk文件&#xff1a; 完成以后&#xff0c;看到多了一块硬盘&#xff1a; 3.读取新硬盘 &…

计算机毕业设计 | springboot 多功能商城 购物网站(附源码)

1&#xff0c; 概述 国家大力推进信息化建设的大背景下&#xff0c;城市网络基础设施和信息化应用水平得到了极大的提高和提高。特别是在经济发达的沿海地区&#xff0c;商业和服务业也比较发达&#xff0c;公众接受新事物的能力和消费水平也比较高。开展商贸流通产业的信息化…

SpringMVC-基本概念

一、引子 我们在上篇文章Spring集成Web中抛出了一个问题&#xff1a;为什么我们一直在自用Java Web阶段使用的Servlet来承接客户端浏览器的请求呢&#xff0c;我们熟知甚至是已经在日常开发中经常使用的Controller又与之有什么关系呢&#xff1f;我们将在本篇文章解答读者的这…

GitHub的使用操作

记得看目录哦&#xff01; 1. 创建仓库2. 下载desktop3. 把创建的库克隆到本地4. 文件拷贝到本地仓库![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/7171ac6c4ca14e3b8d22717121f79c9e.png)5. 在网址后面加/compare进行比较6. 给系统添加功能 1. 创建仓库 2. 下载…

C练习——插入有序数组

题目&#xff1a; 编写一个函数&#xff0c;实现在一个升序数组中查找x应插入位置&#xff0c;将x插入数组中&#xff0c;并使其入仍升序 解析&#xff1a; 插入是数组基本操作&#xff0c;从第零位遍历数组与x比较&#xff0c;x小于或等于arr[i]时&#xff0c;从arr[i]开始…

SD-WAN和MPLS的区别以及如何选择?

网络连接技术的选择对企业来说至关重要。SD-WAN&#xff08;软件定义广域网&#xff09;和MPLS&#xff08;多协议标签交换&#xff09;是两种备受关注的网络连接方案。它们在架构、带宽、成本和管理等方面存在显著区别&#xff0c;企业应了解清楚这些区别再进行选择。 SD-WAN采…

openharmony开发版应用安装签名

配置签名信息 应用/服务在真机设备上运行&#xff0c;需要提前为应用/服务进行签名&#xff0c;DevEco Studio为开发者提供了自动化签名方案&#xff0c;可以一键完成应用/服务签名。具体操作如下&#xff1a; 单击File > Project Structure > Project > Signing Con…

神经网络与深度学习Pytorch版 Softmax回归 笔记

Softmax回归 目录 Softmax回归 1. 独热编码 2. Softmax回归的网络架构是一个单层的全连接神经网络。 3. Softmax回归模型概述及其在多分类问题中的应用 4. Softmax运算在多分类问题中的应用及其数学原理 5. 小批量样本分类的矢量计算表达式 6. 交叉熵损失函数 7. 模型预…

leetcode刷题(剑指offer)54.螺旋矩阵

54.螺旋矩阵 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;ma…

【数据库数据恢复】Oracle数据库ASM磁盘组数据恢复案例

oracle数据库故障&分析&#xff1a; oracle数据库ASM磁盘组掉线&#xff0c;ASM实例不能挂载。数据库管理员尝试修复数据库&#xff0c;但是没有成功。 oracle数据库数据恢复过程&#xff1a; 1、将oracle数据库所涉及磁盘以只读方式备份。后续的数据分析和数据恢复操作都…

帆软报表简单插入多个图表和表格

前言 帆软报表支持在一个普通报表&#xff08;*.cpt&#xff09;中插入多个图表或者文字表格。 系统环境 操作系统为 Windows 11 家庭版。帆软报表版本为 FinReport 9 &#xff0c; 数据库为 Oracle 11C 。 操作步骤 1、新建 cpt 报表 注意选择 “普通报表” 不是其他类型…

10个React状态管理库推荐

本文将为您推荐十款实用的React状态管理库&#xff0c;帮助您打造出高效、可维护的前端应用。让我们一起看看这些库的魅力所在&#xff01; 在前端开发中&#xff0c;状态管理是至关重要的一环。React作为一款流行的前端框架&#xff0c;其强大的状态管理功能备受开发者青睐。…

Maven的Docker镜像二次打包,再次推送至Harbor中

之所以如此操作&#xff0c;主要原因是&#xff0c;官版的镜像中默认的setting.xml已内置好&#xff0c;不容易修改&#xff0c; 重新二次打包&#xff0c;可以指定我们自己的setting.xml配置&#xff0c;配置自己的私服地址以及解决默认Maven仓库国内下载速度慢的问题 一、创…

elk之基础概念

写在前面 本文一起看下es的基础概念&#xff0c;比较枯燥的内容说&#xff0c;但不看又不行。开始。 1&#xff1a;document 文档&#xff0c;是es搜索存储数据的最小单元&#xff0c;相当于是MySQL的一行记录&#xff0c;但es中是一个json&#xff0c;如下是一个通过logsta…