Эта статья наврядли научит вас правильно отслеживать столкновения, ведь спрайты редко бывают идеально круглыми..
.. но сейчас представим что в мире всё иначе и спрайты действительно только в форме круга.
Не буду описывать стандартные для sdl функции. Можете поискать информацию о них на єтом сайте
Для отслеживания столкновения нужно ещё и считать:
#include <SDL/SDL.h>
#include <cmath>
Зададим размер и заголовок константами:
const int WINDOW_WIDTH = 640;
const int WINDOW_HEIGHT = 480;
const char* WINDOW_TITLE = «SDL HOWTO»;
Оприделим функцию для обработки столкновений:
bool box(SDL_Rect one,SDL_Rect two);
В функции main:
int main(int argc, char **argv){
Стандартно для SDL приложения (подробнее в предыдущих статьях):
SDL_Init( SDL_INIT_VIDEO );
SDL_Surface* screen = SDL_SetVideoMode( WINDOW_WIDTH,
WINDOW_HEIGHT, 0,
SDL_HWSURFACE | SDL_DOUBLEBUF );
SDL_WM_SetCaption( WINDOW_TITLE, 0 );
SDL_ShowCursor(SDL_DISABLE);
SDL_Surface* bitmap = SDL_LoadBMP(«sprite.bmp»);
SDL_SetColorKey( bitmap, SDL_SRCCOLORKEY, SDL_MapRGB(bitmap->format,0, 0, 0) );
SDL_Rect source;
source.x = 0;
source.y = 0;
source.w = 120;
source.h = 120;
Всё также в цикле ожидания действий:
SDL_Event event;
bool run = true;
while(run) {
while ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_MOUSEMOTION:
SDL_Rect fill;
fill.x = 0;
fill.y = 0;
fill.w = WINDOW_WIDTH;
fill.h = WINDOW_HEIGHT;
SDL_FillRect(screen,&fill,SDL_MapRGB(bitmap->format,0, 0, 0) );
SDL_Rect destination;
destination.x = event.motion.x — 60;
destination.y = event.motion.y — 60;
destination.w = 120;
destination.h = 120;
После этого начинаются немного новые вещи:
Рисуем круг «враг». Он будет стоять на месте:
SDL_Rect target;
target.x = 100;
target.y = 100;
target.w = 120;
target.h = 120;
SDL_BlitSurface(bitmap, &source, screen, &target);
Пользуемся нашей функцией для определения столкновения:
if (!box(destination,target)) {
SDL_BlitSurface(bitmap, &source, screen, &destination);
SDL_Flip(screen);
}
Дальше опять всё стандартно:
break;
case SDL_QUIT:
run = false;
}
}
}
SDL_FreeSurface(bitmap);
SDL_Quit();
return 0;
}
Старался не пропускать ничего, такчто извените за такие куски кода.
Теперь остановимся на функции box:
bool box(SDL_Rect one,SDL_Rect two) {
int oneX,oneY,twoX,twoY;
oneX = one.x + one.w/2;
oneY = one.y + one.h/2;
twoX = two.x + two.w/2;
twoY = two.y + two.w/2;
int width1 = one.w/2;
int width2 = two.w/2;
int rad = width1 + width2; //сумма радиусов
int rad2 = sqrt(pow((oneX — twoX),2)+(pow((oneY — twoY),2))); //расстояние между центрами
if (rad > rad2)
return true;
else
return false;
printf(«%d :: %dn»,rad,rad2 );
}
Её суть в том, что объекты (круги) сталкиваются если расстояние между их центрами (красный) меньше суммы их радиусов (синий/чёрный).
Будем считать, что радиус спрайта равен половине его ширины (width1 и width2), а центр находится путём добавления половины ширины спрайта к его Х координате и высоты к Y.
После нахождения координат центров находим расстояние между ними по школьной формулe:
В случае если объекты пересекаются будет возвращено true, иначе false.
Учтите, что это очень простая функция и вести себя адекватно она будет только с круглыми спрайтами и только при условии, что они касаются краями граници (тоесть ширина = 2 радиуса). В других условиях процедура похожа, но необходимо считать не радиусы, а ту часть спрайта (прямоугольника) которая является картинкой, а не пустым местом…
Скачать пример
Источник: