C++ 中的碰撞检测方法

发布于 2024-07-20 08:46:37 字数 1278 浏览 7 评论 0原文

我是 C++ 新手,我一直在一个小游戏程序中练习碰撞,该程序什么也不做,我只是无法正确碰撞

所以我使用加载到变量中的图像

background = oslLoadImageFile("background.png", OSL_IN_RAM, OSL_PF_5551);
sprite = oslLoadImageFile("sprite.png", OSL_IN_RAM, OSL_PF_5551);
bush = oslLoadImageFile("bush.png", OSL_IN_RAM, OSL_PF_5551);

虽然有像这样存储的变量

sprite->x = 3;

if ( (sprite->x + spritewidth > bush->x) && (sprite->x < bush->x + bushwidth) && (sprite->y + spriteheight > bush->y) && (sprite->y < bush->y + bushheight) ) 
{
         bushcol = 1;               
}
else
{
        bushcol = 0;      
}

所以当我按下按钮时

if (osl_keys->held.down)
{
if (bushcol == 1) 
{
sprite->y = bush->y + 38;
}
else
{
sprite->y += 3;
}
}
if (osl_keys->held.up)
{
if (bushcol == 1) 
{
sprite->y = bush->y - 23;
}
else
{ 
sprite->y -= 3;
}
}
if (osl_keys->held.right)
{
if (bushcol == 1) 
{
sprite->x = bush->x - 28;
}
else
{ 
sprite->x += 3;
}
}
if (osl_keys->held.left)
{
if (bushcol == 1) 
{
sprite->x = bush->x + 28;
}
else
{ 
sprite->x -= 3;
}
}

我是想到类似的事情

sprite->y = bushheight - 24;

,但它不起作用

有什么建议吗?

I am new to c++ and I have been practicing collision in a small game program that does nothing and I just can't get the collision right

So I use images loaded into variables

background = oslLoadImageFile("background.png", OSL_IN_RAM, OSL_PF_5551);
sprite = oslLoadImageFile("sprite.png", OSL_IN_RAM, OSL_PF_5551);
bush = oslLoadImageFile("bush.png", OSL_IN_RAM, OSL_PF_5551);

While there are variables stored like

sprite->x = 3;

if ( (sprite->x + spritewidth > bush->x) && (sprite->x < bush->x + bushwidth) && (sprite->y + spriteheight > bush->y) && (sprite->y < bush->y + bushheight) ) 
{
         bushcol = 1;               
}
else
{
        bushcol = 0;      
}

So when i press a button

if (osl_keys->held.down)
{
if (bushcol == 1) 
{
sprite->y = bush->y + 38;
}
else
{
sprite->y += 3;
}
}
if (osl_keys->held.up)
{
if (bushcol == 1) 
{
sprite->y = bush->y - 23;
}
else
{ 
sprite->y -= 3;
}
}
if (osl_keys->held.right)
{
if (bushcol == 1) 
{
sprite->x = bush->x - 28;
}
else
{ 
sprite->x += 3;
}
}
if (osl_keys->held.left)
{
if (bushcol == 1) 
{
sprite->x = bush->x + 28;
}
else
{ 
sprite->x -= 3;
}
}

i was thinking of things like

sprite->y = bushheight - 24;

but it doesnt work

Any suggestions?

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

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

发布评论

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

评论(3

桜花祭 2024-07-27 08:46:37

我建议创建一个仅用于边界框碰撞检测目的的函数。
它可能看起来像

IsColiding(oslImage item1, oslImage item2) 
{ 
  /* Perform check */
} 

您执行图像 1 和图像 2 之间是否存在冲突的检查。
至于您尝试使用的算法,请查看此维基百科,例如 AABB 边界框

特别是这一部分:

对于 AABB,此测试
变成一组简单的重叠测试
就单位轴而言。 对于 AABB
由 M,N 定义的相对于由
O,P 如果 (Mx>Px) 它们不相交
或(Ox>Nx)或(My>Py)或(Oy>Ny)或
(Mz>Pz)或(Oz>Nz)。

I'd suggest making a function solely for the purpose of bounding box colision detection.
It could look like

IsColiding(oslImage item1, oslImage item2) 
{ 
  /* Perform check */
} 

in which you perform the check if there is a collision between image 1 and image 2.
As for the algorithm you're trying to use check out this wikipedia for example AABB bounding box

Especially this part:

In the case of an AABB, this tests
becomes a simple set of overlap tests
in terms of the unit axes. For an AABB
defined by M,N against one defined by
O,P they do not intersect if (Mx>Px)
or (Ox>Nx) or (My>Py) or (Oy>Ny) or
(Mz>Pz) or (Oz>Nz).

梅倚清风 2024-07-27 08:46:37

我想你已经有了基本的想法。 只要检查一下你的工作就可以了。 这是一个可以编译的简单版本:

#import <stdlib.h>

typedef struct {
    // I'm going to say x, y, is in the center
    int x;
    int y;
    int width;
    int height;
} Rect;

Rect newRect(int x, int y, int w, int h) {
    Rect r = {x, y, w, h};
    return r;
}

int rectsCollide(Rect *r1, Rect *r2) {
    if (r1->x + r1->width/2 < r2->x - r2->width/2) return 0;
    if (r1->x - r1->width/2 > r2->x + r2->width/2) return 0;
    if (r1->y + r1->height/2 < r2->y - r2->height/2) return 0;
    if (r1->y - r1->height/2 > r2->y + r2->height/2) return 0;
    return 1;
}

int main() {
    Rect r1 = newRect(100,200,40,40);
    Rect r2 = newRect(110,210,40,40);
    Rect r3 = newRect(150,250,40,40);

    if (rectsCollide(&r1, &r2))
        printf("r1 collides with r2\n");
    else
        printf("r1 doesnt collide with r2\n");

    if (rectsCollide(&r1, &r3))
        printf("r1 collides with r3\n");
    else
        printf("r1 doesnt collide with r3\n");

}

I think you have the basic idea. Just check your work. Here is a simple version which compiles:

#import <stdlib.h>

typedef struct {
    // I'm going to say x, y, is in the center
    int x;
    int y;
    int width;
    int height;
} Rect;

Rect newRect(int x, int y, int w, int h) {
    Rect r = {x, y, w, h};
    return r;
}

int rectsCollide(Rect *r1, Rect *r2) {
    if (r1->x + r1->width/2 < r2->x - r2->width/2) return 0;
    if (r1->x - r1->width/2 > r2->x + r2->width/2) return 0;
    if (r1->y + r1->height/2 < r2->y - r2->height/2) return 0;
    if (r1->y - r1->height/2 > r2->y + r2->height/2) return 0;
    return 1;
}

int main() {
    Rect r1 = newRect(100,200,40,40);
    Rect r2 = newRect(110,210,40,40);
    Rect r3 = newRect(150,250,40,40);

    if (rectsCollide(&r1, &r2))
        printf("r1 collides with r2\n");
    else
        printf("r1 doesnt collide with r2\n");

    if (rectsCollide(&r1, &r3))
        printf("r1 collides with r3\n");
    else
        printf("r1 doesnt collide with r3\n");

}
病女 2024-07-27 08:46:37

首先,我想你的意思是

sprite->y = Bush->**y** - 3;

其次,我不知道你正在使用什么平台,但通常 y 坐标是倒。 即,y=0 对应于屏幕顶部。 在这种情况下,您的比较可能不起作用。

当您向其中添加旋转和非矩形对象时,第三次碰撞检查很快就会变得复杂。 您应该考虑使用 CGAL 或其他一些计算几何算法库,它们可以处理多边形相交。

First of all i suppose you mean

sprite->y = bush->**y** - 3;

second i dont know what platform you are using, but often times the y-coordinates are inverted. i.e., y=0 corresponds to top of the screen. In that case your comparisons might not work.

third collision checking can quickly become complicated when you add rotation and non-rectangular objects to it. You should consider using CGAL or some other computational geometry algorithms library, which can handle polygon intersection.

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