帮助了解鼠标算法中的对象

发布于 2024-08-14 17:42:10 字数 530 浏览 2 评论 0原文

我不知道该怎么称呼这个。我正在构建一个基于图块的游戏,用户可以在其中单击图块。 它是一个 2d c++ 瓷砖矢量。现在我有一个算法可以像这样定位它们:

[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]

它们根据它们的大小进行定位,我的图块类保存它们的每个 x 和 y 坐标,并且我有 2 个用于高度和宽度的变量。

基本上我想找到一种算法,可以根据鼠标的位置返回鼠标所在的图块。

例如:如果我的鼠标(相对于游戏窗口)的位置是 37,0 并且每个图块的大小为 10 * 10 并且它们每个图块的宽度分开,那么当我的鼠标超过 37,0 时,它应该返回( 4,1) 表示 x 上的第四个元素和 y 上的第一个元素。我考虑过对每个矩形进行边界框检查,但我认为如果我每秒检查 60 次,将会消耗太多的 cpu。

谢谢

I wasn't sure what to call this. I'm building a tile based game where the user can click on a tile.
it is a 2d c++ vector of tiles. right now I have an algorithm that positions them like this:

[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]
[][][][][][][][][][][]

they are positioned based on their size and my tile class holds each of their x and y coordinates, and I have 2 variables for the height and width.

Basically I'd like to find an algorithm that can return the tile my mouse is on based on the mouse's position.

For example: if my mouse (relative to the game window)'s position is 37,0 and each of my tiles is 10 * 10 in size and they are each tilewidth apart then by having my mouse over 37,0 it should return (4,1) meaning the 4th element on the x and the first element on the y. I thought about doing bounding box checks against each rectangle but I think that will use up too much cpu if i check 60 times / second.

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

〆一缕阳光ご 2024-08-21 17:42:10

根据评论,据称 Allegro 没有鼠标事件。不正确。请参阅鼠标例程

extern void (*mouse_callback)(int flags);

由中断处理程序调用
每当鼠标移动或其中之一
按钮改变状态。这个功能
必须位于锁定内存中,并且必须
执行速度非常!已通过
触发的事件标志
调用,这是一个包含的位掩码
任何值MOUSE_FLAG_MOVE
MOUSE_FLAG_LEFT_DOWN
MOUSE_FLAG_LEFT_UP
MOUSE_FLAG_RIGHT_DOWN,
MOUSE_FLAG_RIGHT_UP
MOUSE_FLAG_MIDDLE_DOWN,
MOUSE_FLAG_MIDDLE_UP,以及
MOUSE_FLAG_MOVE_Z。请注意,即使
鼠标有三个以上按钮,
只能困住前三个
使用回调。

或者,您可以使用 get_mouse_mickeys()以加快您的检查速度。

void get_mouse_mickeys(int *mickeyx, int *mickeyy);

测量鼠标移动的距离
自上次调用此函数以来。
mickeyx 和 mickeyy 的值将
如果鼠标移动则变为负值
分别向左或向上。鼠标
将继续产生运动
米奇即使到达边缘
屏幕的,所以这种形式的输入
对于需要的游戏很有用
鼠标移动的范围无限。

请注意,无限移动可能
不能在窗口模式下工作,因为在
鼠标会离开的一些平台
窗口,并且可能根本无法工作,如果
硬件光标正在使用中。

因此,如果您每秒检查多次,并且此函数为 X 和 Y 分别返回 0,则无需重新检查鼠标所指向的内容,因为它尚未移动。

话虽这么说,使用鼠标回调。这是最有效的方法。

至于如何处理您指出的图块,我会这样处理:在某个时刻您正在渲染像素。要么您正在使用帧缓冲区,要么您应该能够创建一个帧缓冲区。对于每个像素,如果要渲染图块,请在像素映射中存储指向该图块的指针。这意味着每个像素 4 个字节(假设 32 位指针),但在 1280x1024 下,您使用略多于 1 MB 的 RAM 来存储每个 (x,y) 坐标处的图块,并且您的查找速度将非常快。

According to the comments, it's claimed Allegro doesn't have mouse events. Not true. See Mouse routines.

extern void (*mouse_callback)(int flags);

Called by the interrupt handler
whenever the mouse moves or one of the
buttons changes state. This function
must be in locked memory, and must
execute very quickly! It is passed
the event flags that triggered the
call, which is a bitmask containing
any of the values MOUSE_FLAG_MOVE,
MOUSE_FLAG_LEFT_DOWN,
MOUSE_FLAG_LEFT_UP,
MOUSE_FLAG_RIGHT_DOWN,
MOUSE_FLAG_RIGHT_UP,
MOUSE_FLAG_MIDDLE_DOWN,
MOUSE_FLAG_MIDDLE_UP, and
MOUSE_FLAG_MOVE_Z. Note that even if
the mouse has more than three buttons,
only the first three can be trapped
using a callback.

Alternatively you can use get_mouse_mickeys() to speed up your checking.

void get_mouse_mickeys(int *mickeyx, int *mickeyy);

Measures how far the mouse has moved
since the last call to this function.
The values of mickeyx and mickeyy will
become negative if the mouse is moved
left or up, respectively. The mouse
will continue to generate movement
mickeys even when it reaches the edge
of the screen, so this form of input
can be useful for games that require
an infinite range of mouse movement.

Note that the infinite movement may
not work in windowed mode, since under
some platforms the mouse would leave
the window, and may not work at all if
the hardware cursor is in use.

So if you check lots of times a second and this function returns 0 for each of X and Y there's no need to recheck what the mouse is pointing at because it hasn't moved.

That being said, use the mouse callback. It's the most efficient way.

As for how to handle what tile you're pointing out, I would handle it this way: at some point you're rendering the pixels. Either you're using a frame buffer or you should be able to create one. For each pixel, if you're rendering a tile, store a pointer to that tile in a pixel map. That means 4 bytes (assuming 32 bit pointers) per pixel but at, say, 1280x1024, you're using a little over one megabyte of RAM to store what tile is at each (x,y) coordinate and your lookups will be incredibly fast.

暗恋未遂 2024-08-21 17:42:10

如果您不使用基于事件的环境,则确实需要编写自己的对象交叉、鼠标检测等。

以下是您想要获得的伪代码公式:

tile_width = 10;
tile_height = 10;

x_tile = Math.ceil(mousex/tile_width);
y_tile = Math.ceil(mousey/tile_height);

If you're not using an event based environment, you do need to code your own object intersection, mouse detection, etc.

Here's the formula in pseudo code for what you want to get:

tile_width = 10;
tile_height = 10;

x_tile = Math.ceil(mousex/tile_width);
y_tile = Math.ceil(mousey/tile_height);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文