专栏文章

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

科技·工程参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioblmzh
此快照首次捕获于
2025/12/02 16:32
3 个月前
此快照最后确认于
2025/12/02 16:32
3 个月前
查看原文
本篇文章是基于easyx图形库的,可以先搜索一下相关用法再回来。
我们在用C++开发游戏项目时,可能会有透明窗口的需求,但是众所周知,easyx图形库的窗口只能是矩形的,无法看到桌面,这时应该怎么办呢?
putimage()?好像可以,只要让它持续绘制桌面的截图就可以了,但是现在有一个很大的问题:
怎么确定函数执行的坐标?
emmm,其实也很简单,先贴代码:
CPP
short GetWindowXPos(HWND hWnd) {
	RECT rect;
	GetWindowRect(hWnd, &rect);
	return rect.left;
}
short GetWindowYPos(HWND hWnd) {
	RECT rect;
	GetWindowRect(hWnd, &rect);
	return rect.top;
}
现在解释函数
  • 参数:HWND是windows窗口句柄的变量类型,通过它可以获取窗口的信息
  • RECT:我也不会,就理解为窗口变量就行
  • GetWindowRect():通过句柄获取窗口
有了这些函数,现在思路就很明确了,我们无非就是要把桌面图像put在桌面坐标(0,0)的位置,所以就可以
CPP
putimage(0-GetWindowXPos(hWnd),0-GetWindowXPos(hWnd),&img);
此时你可能会发现,还是没有和桌面对齐...
我的电脑测试了以后发现图像缩放到66%,XY坐标分别-10就差不多了,自己的电脑还是自己算吧
有了上面的思路,我们还可以画一个在桌面上固定的小球:
CPP
//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!!!!!!

评论

0 条评论,欢迎与作者交流。

正在加载评论...