基于EasyX和Raylib的鼠标操作

EasyX 提供的鼠标操作需要结合 Windows API 使用, 比较简陋。官方示例用法是在 // https://codebus.cn/yangw/mouse-operation。
Raylib 可以提供强大的多的鼠标操作。不过为了程序迁移的无痛感, 这里用 Raylib 重新实现了 "鼠标操作“ 这个例子程序。主要不同点是, Raylib 直接在背景上绘制会出现频繁的闪烁, 需要改为创建 texture 作为 canvas(镶嵌在窗口上), 然后每一帧在 canvas 上绘制。

基于 EasyX

// 程序名称:鼠标操作演示
// 编译环境:Visual C++ 6.0~2022,EasyX_20220901
// https://easyx.cn
//
#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;
}

基于 Raylib

// https://codebus.cn/yangw/mouse-operation
#include "raylib.h"
#include "raylib_helper.hpp"
#include <stdio.h>

#define WIDTH 640
#define HEIGHT 480

class Action
{
public:
    Vector2 d; // mouse delta
    Vector2 m; // mouse position
    bool is_control_pressed;
    bool is_mouse_left_button_pressed;

    void init()
    {
        d = GetMouseDelta();
        m = GetMousePosition();
        is_mouse_left_button_pressed = IsMouseButtonPressed(MOUSE_BUTTON_LEFT);
        is_control_pressed = IsKeyDown(KEY_LEFT_CONTROL);
    }

    void draw(RenderTexture2D target)
    {
        BeginTextureMode(target);
        if (d.x != 0 || d.y != 0)
        {
            DrawPixel(m.x, m.y, RED);
        }
        else if (is_mouse_left_button_pressed)
        {
            if (is_control_pressed) // big rect
            {
                DrawRectangleLines(m.x - 10, m.y - 10, 20, 20, WHITE);
            }
            else // small rect
            {
                DrawRectangleLines(m.x - 5, m.y - 5, 10, 10, WHITE);
            }
        }
        EndTextureMode();
    }
};

int main()
{
    InitWindow(WIDTH, HEIGHT, "Mouse Operation");

    // Create a RenderTexture2D to use as a canvas
    RenderTexture2D target = LoadRenderTexture(WIDTH, HEIGHT);

    // Clear render texture before entering the game loop
    BeginTextureMode(target);
    ClearBackground(BLACK);
    EndTextureMode();

    SetTargetFPS(120);

    int cnt = 0;
    while (!WindowShouldClose())
    {
        cnt++;
        Action act;
        act.init();

        BeginDrawing();
        {
            ClearBackground(BLACK);

            DrawTextureRec(target.texture, make_rectangle(0, 0, (float)target.texture.width, (float)-target.texture.height), 
                make_vector(0, 0), 
                WHITE
            );

            act.draw(target);
        }
        EndDrawing();
    }

    UnloadRenderTexture(target);    // Unload render texture
    CloseWindow();

    return 0;
}
posted @ 2023-01-26 14:52  ChrisZZ  阅读(218)  评论(0编辑  收藏  举报