如何做多窗口固定座标游戏(划掉

· · 科技·工程

本篇文章是基于easyx图形库的,可以先搜索一下相关用法再回来。

我们在用C++开发游戏项目时,可能会有透明窗口的需求,但是众所周知,easyx图形库的窗口只能是矩形的,无法看到桌面,这时应该怎么办呢?

putimage()?好像可以,只要让它持续绘制桌面的截图就可以了,但是现在有一个很大的问题:

怎么确定函数执行的坐标?

emmm,其实也很简单,先贴代码:

short GetWindowXPos(HWND hWnd) {
    RECT rect;
    GetWindowRect(hWnd, &rect);
    return rect.left;
}
short GetWindowYPos(HWND hWnd) {
    RECT rect;
    GetWindowRect(hWnd, &rect);
    return rect.top;
}

现在解释函数

有了这些函数,现在思路就很明确了,我们无非就是要把桌面图像put在桌面坐标(0,0)的位置,所以就可以

putimage(0-GetWindowXPos(hWnd),0-GetWindowXPos(hWnd),&img);

此时你可能会发现,还是没有和桌面对齐...

我的电脑测试了以后发现图像缩放到66%,XY坐标分别-10就差不多了,自己的电脑还是自己算吧

有了上面的思路,我们还可以画一个在桌面上固定的小球:

//GUI.h:很久以前抄的按钮代码,但是忘了在哪了,作者看到的话可以在评论区吱一声。
#include <graphics.h>
#include <easyx.h>
#include <bits/stdc++.h>
#include <windows.h>
using namespace std;
struct mouse_events
{
    short x,y;
    char z;
    mouse_events(short x=0,short y=0,char z='m')
    {
        this->x=x;
        this->y=y;
        this->z=z;
    }
};
inline mouse_events check_mouse_event()
{
    if (MouseHit())
        {
            MOUSEMSG msg = GetMouseMsg();

            if (msg.uMsg == WM_MOUSEMOVE)
            {
                return {msg.x,msg.y,'m'};
            }
            else if (msg.uMsg == WM_LBUTTONDOWN)
            {
                return {msg.x,msg.y,'l'};
            }
            else if (msg.uMsg == WM_RBUTTONDOWN)
            {
                return {msg.x,msg.y,'r'};
            }
        }
}
class Button{
    public:
        int x,y,width,height;
        IMAGE image;
        mouse_events mouse;
        Button(int x,int y,int width,int height,mouse_events mouse)
        {
            this->x=x;
            this->y=y;
            this->width=width;
            this->height=height;
            this->mouse=mouse;
        }
        Button(int x,int y,int width,int height,LPCTSTR FILE,mouse_events mouse)
        {
            this->x=x;
            this->y=y;
            this->width=width;
            this->height=height;
            loadimage(&image,FILE);
            this->mouse=mouse;
        }
        void draw_button(string STYLE="CLASSIC")
        {
            if(STYLE=="CLASSIC")
            {
                setfillcolor(RGB(0,0,0));
                    fillrectangle(x-(width/2),y-(height/2),x+(width/2),y+(height/2));
            }
            else if(STYLE=="DEFAULT")
            {
                setfillcolor(RGB(255,255,255));
                    bar(x-(width/2),y-(height/2),x+(width/2),y+(height/2));

            }
            else if(STYLE=="IMAGE")
            {
                putimage(x-(width/2),y-(height/2),&image);
            }
    }
    bool left_clicked()
    {
        mouse=check_mouse_event();
        return (mouse.x>=x-(width/2)&&mouse.x<=x+(width/2)&&mouse.y>=y-(height/2)&&mouse.y<=y+(height/2)&&mouse.z=='l');
    }
    bool right_clicked()
    {
        mouse=check_mouse_event();
        return (mouse.x>=x-(width/2)&&mouse.x<=x+(width/2)&&mouse.y>=y-(height/2)&&mouse.y<=y+(height/2)&&mouse.z=='r');
    }
    bool mouse_over()
    {
        mouse=check_mouse_event();
        return (mouse.x>=x-(width/2)&&mouse.x<=x+(width/2)&&mouse.y>=y-(height/2)&&mouse.y<=y+(height/2));
    }
    void set_image(LPCTSTR FILE)
    {
        loadimage(&image,FILE);
    }
};

//WindowMove.h:
#include <bits/stdc++.h>
using namespace std;
void MoveWindowToPosition(HWND hWnd,int x,int y)
{
    RECT rect;
    GetWindowRect(hWnd,&rect);
    int width=rect.right-rect.left;
    int height=rect.bottom-rect.top;
    MoveWindow(hWnd,x,y,width,height,TRUE);
}//可以不用,但不能没有
short GetWindowXPos(HWND hWnd)
{
    RECT rect;
    GetWindowRect(hWnd,&rect);
    return rect.left;
}
short GetWindowYPos(HWND hWnd)
{
    RECT rect;
    GetWindowRect(hWnd,&rect);
    return rect.top;
}

//main.cpp:
#include "GUI.h"
#include "WindowMove.h"
#include <fstream>
using namespace std;
struct Ball
{
    string type;
    int x;
    int y;
    int r;
};
int sttoi(const string &s)
{
    int ret=0;
    for(char c:s)//报错就改一般循环 
    {
        if (!isdigit(c)) throw invalid_argument("non-digit character found");
        ret=ret*10+(c-'0');
    }
    return ret;
}
int main()
{
    initgraph(300,300);
    setbkcolor(BLACK);
    Button but(150,150,300,300,{0,0,'m'});
    HWND hWnd=FindWindowA(NULL,"multy-window test"); 
    if(!hWnd)
    {
        MessageBoxA(NULL,"找不到窗口!","错误",MB_OK);
        return 1;
    }
    BeginBatchDraw();//防闪屏双缓冲 
    //写入文件(可改成已有文件)
    fstream file("data.txt",ios::in|ios::out );
    if (!file)
    {
        MessageBoxA(NULL,"无法打开文件!","错误",MB_OK);
        return 1;
    }
    //写入一个球
    file<<"circle 800 800 40\n";
    file.flush();
    vector<Ball> balls;
    MoveWindowToPosition(hWnd,600,600);
    while (true) {
        cleardevice();
        balls.clear();
        //读取文件每行数据
        file.clear();
        file.seekg(0); //回到文件开头
        string arg,x1,y1,r;
        while (file>>arg>>x1>>y1>>r)
        {
            Ball b;
            b.type=arg;
            b.x=sttoi(x1);
            b.y=sttoi(y1);
            b.r=sttoi(r);
            balls.push_back(b);
        }
        int win_x=GetWindowXPos(hWnd);
        int win_y=GetWindowYPos(hWnd);
        if(but.left_clicked())
        {
            file.clear();
            file.seekp(0,ios::end);
            file<<"circle "<<win_x+150<<" "<<win_y+150<<" 40\n";
            file.flush(); 
        }
        // 绘制所有球
        for (const auto &b:balls)
        {
            int draw_x=b.x-win_x;
            int draw_y=b.y-win_y;
            char info[128];
            sprintf(info,"%s: (%d,%d)",b.type.c_str(),draw_x,draw_y);
            outtextxy(0,20*(&b-&balls[0]),info); //每个球的信息单独一行
            if (b.type=="circle")
            {
                setfillcolor(RED);
                solidcircle(draw_x,draw_y,b.r);
            }
        }
        FlushBatchDraw();
    }
    file.close();
    EndBatchDraw();
    return 0;
}

肥肠好玩

什么?编译错误?emmm

喂给AI!!!!!!