Методы обнаружения столкновений в C ++ - PullRequest
0 голосов
/ 14 мая 2009

Я новичок в 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;

но это не работает

Есть предложения?

Ответы [ 3 ]

2 голосов
/ 14 мая 2009

Я бы предложил сделать функцию исключительно для обнаружения коллизий в ограничивающей рамке. Это может выглядеть как

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

, в которой вы выполняете проверку на наличие столкновения между изображением 1 и изображением 2. Что касается алгоритма, который вы пытаетесь использовать, посмотрите в этой википедии, например AABB ограничивающий прямоугольник

Особенно эта часть:

В случае AABB этот тест становится простым набором тестов перекрытия с точки зрения осей блока. Для AABB определяется М, N против одного, определенного O, P они не пересекаются, если (Mx> Px) или (Ox> Nx) или (My> Py) или (Oy> Ny) или (Mz> Pz) или (Oz> Nz).

1 голос
/ 14 мая 2009

Я думаю, у вас есть основная идея. Просто проверь свою работу. Вот простая версия, которая компилируется:

#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");

}
0 голосов
/ 14 мая 2009

Прежде всего, я полагаю, вы имеете в виду

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

секунда. Я не знаю, какую платформу вы используете, но часто координаты Y инвертируются. то есть, y = 0 соответствует верхней части экрана. В этом случае ваши сравнения могут не сработать.

проверка третьего столкновения может быстро усложниться, если вы добавите в нее вращающиеся и непрямоугольные объекты. Вам следует рассмотреть возможность использования CGAL или некоторой другой библиотеки алгоритмов вычислительной геометрии, которая может обрабатывать пересечение полигонов.

...