Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Perfect Collision Detection and explanation of functions  (Read 11106 times)

0 Members and 1 Guest are viewing this topic.

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« on: December 16, 2010, 05:26:34 pm »
Hello, recently I found some free time to start adding basic functions to my game, now I want to create my own Perfect Collision Detections alogirthm, I don't want to use a coded one. What basically do I need to know about it? Which SFML function would I need?
I want to have semi-good performance so first I will test if rectangle-rectangle is found and then if it is I will process to pixel perfect collision detection, right?

And also I don't know what for really are following functions:
What is context? Like sfContext_Create?
sfImage_Bind ?
What are mutexs?
What is PostFX?
What is BlendMode?
sfShape_TransformToGlobal ?
sfShape_TransformToLocal ?
How excatly works setting HalfSize and Center of Views?

Thanks in advance for answers.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Perfect Collision Detection and explanation of functions
« Reply #1 on: December 16, 2010, 06:05:59 pm »
Quote
And also I don't know what for really are following functions:
What is context? Like sfContext_Create?
sfImage_Bind ?
What are mutexs?
What is PostFX?
What is BlendMode?
sfShape_TransformToGlobal ?
sfShape_TransformToLocal ?
How excatly works setting HalfSize and Center of Views?

Did you first read the tutorials and documentation? I can't believe you have so many questions if you read them.
Laurent Gomila - SFML developer

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #2 on: December 16, 2010, 09:18:44 pm »
Sorry for late respond, but yeah I have written tutorials + documentation.

I still don't know what Context is.
I still don't know for what purpose I can use sfImage_Bind
I know what are mutexs.
I know what are PostFS.
Not sure about Blending
Not sure about sfShape_TransformToGlobal
Not sure about sfShape_TransformToLocal
TransformToGlobal and Local set a point in the sprite, shape etc by which I can manage other than standard rotations etc? Like I can set it somewhere down in Shape and then I will get other rotation look than when using standard one?

I am not sure about it.

And if any of You guys could help me with PixelPerfect Detection please post some informations.

Silvah

  • Guest
Perfect Collision Detection and explanation of functions
« Reply #3 on: December 16, 2010, 09:26:23 pm »
Quote from: "darekg11"
I have written tutorials + documentation.
You've written tutorials and documentation but you don't know what were you writing about? :D

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #4 on: December 16, 2010, 09:31:28 pm »
I mean I have read my error >.>

Lupinius

  • Jr. Member
  • **
  • Posts: 85
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #5 on: December 16, 2010, 11:08:23 pm »
Quote
I still don't know what Context is.

A context has to be created so you can make OpenGL calls (or SFML drawing stuff).
Quote
I still don't know for what purpose I can use sfImage_Bind

Bind is used internally and necassery when you want to draw the image AFAIK.
Quote
Not sure about Blending

Doesn't even exist in SFML AFAIK.
Quote
Not sure about sfShape_TransformToGlobal
Not sure about sfShape_TransformToLocal
TransformToGlobal and Local set a point in the sprite, shape etc by which I can manage other than standard rotations etc? Like I can set it somewhere down in Shape and then I will get other rotation look than when using standard one?

When you rotate/scale/move a Object the local coordinates don't get changed, the global coordinates do. So internally a moved/scaled/rotated object never really changes. When you want to know, where these local coordinates are globally, you can use TransfromToGlobal (and TransformToLocal if you want a global point to be local).

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #6 on: December 17, 2010, 07:54:53 am »
Thank You.

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #7 on: December 17, 2010, 04:36:42 pm »
Okay, let's talk about collision detection, I read that BitMask are really helpful durning pixel perfect collision.
Now let's take the picture from which I take subrects and create animations, it looks like:

Subrect without sfImage_CreateMaskFromColor:

Subrect with sfImage_CreateMaskFromColor:

And a for exmaple big type of object to test collision (it has already made transparency in Gimp):


Now, how should I manage all that? At first Sprite will be ofcourse show with MaskFromColor. I understand that BitMask of image is basically a white or black pixel depends on is there a white space or space filled with other colour? Like:
http://wiki.allegro.cc/index.php?title=File:Spritesbitmask.gif ?
If my image has black background then I should treat black space as white space and give it like a white pixel in BitMask because it is not a part of image that needs to be showed? Second BitMask would be a array of bools? Like if there is a colour other than background set it to 1 and if not to 0? And then I need to check if any 1 value of one array collide with any 1 value of other array? Like if Player BitMask array collide with Stone BitMask?

In alogirthm I should first test AABB and if AABB exists then do perfect pixel collision?

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #8 on: December 19, 2010, 09:54:37 am »
Hello, I made a function which take Sprite and fill dynamic allocated 2D bool array with 1 or 0 depends on if Alpha channel is bigger than 0.f or equals 0.f.
1 = bigger than 0.f, 0 = equals 0.f. It works great.
Now I still trying to figure way to check collision depend between two rectangles two sprites. First I need to change two sprites into rectangles and check for intersects, if intersects exist then I fill overlaping rectangle with new sfIntRect and check there for pixel collision? But how do I check it? I change it's global coordinates into local and run throught 2D array and if it gets to 1*1 then return collision happend?

Plus I got problem with views:
When I don't use view sfIntRect_Intersects checks collision perfectly but if I use view then it's showing that two rectangles collide no metter where I am except being before the rectangle, minimal code:
Code: [Select]
extern "C"
{
//#include <SFML/System.h>
#include <SFML/Graphics.h>
#include <SFML/Window.h>
#include "AniSprite.h"
#include "Kolizje.h"
}
#include <iostream>
#include <stdlib.h>
void Instaluj(sfSprite* duszek, sfImage* zdjecie, char* sciezka);
char* tabela[4] = {"natesty.jpg", "natesty2.jpg", "natesty3.jpg"};
char* tabela2[2] = {"wykrzyknik.png", NULL};
int main()
 {
sfIntRect jajebie; //overlapped rectangle
sfBool zobaczymy;
sfIntRect uj;
sfIntRect uj2;
bool** Macha;
sfImage* Kamien = NULL;
sfSprite* sKamien = NULL;
sKamien = sfSprite_Create();
Kamien = sfImage_CreateFromFile("kamol.png");
sfSprite_SetImage(sKamien, Kamien);
sfView* Widok = NULL; //Creating view from rectangle
sfFloatRect prostychuj; //
prostychuj.Bottom = 600; //
prostychuj.Left = 0; //
prostychuj.Right = 800; //
prostychuj.Top = 0; //
Widok = sfView_CreateFromRect(prostychuj); //
sfClock* zegar; //Used for animation time
zegar = sfClock_Create(); //Used for animation time
float czas = 0; //Used for animation time
sfInput* Wejscie; //Input of window
sfColor Kolor; //Mask for Character picture
Kolor = sfColor_FromRGB(0,0,0); //Mask for Character picture
AniSprite test; //Structure of ainmated char
AniSprite* wsk= &test; //Structure of ainmated char
ZerujDane(wsk); //Structure of ainmated char
wsk->clock = sfClock_Create(); //Structure of ainmated char
wsk->duszek = sfSprite_Create(); //Structure of ainmated char
wsk->zdjecie = sfImage_CreateFromFile("Kubac.png"); //Structure of ainmated char
//sfImage_CreateMaskFromColor(wsk->zdjecie, Kolor, 0); //Mask
sfSprite_SetImage(wsk->duszek, wsk->zdjecie); //Structure of ainmated char
SetFrameSize(47,64,wsk); //Structure of ainmated char
SetLoopSpeed(10, wsk); //Structure of ainmated char
     sfWindowSettings Settings = {24, 8, 0}; //Settings of window
     sfVideoMode Mode = {800, 600, 32}; //Settings of window
     sfImage* Image = NULL; //Background image
     sfSprite* Sprite = NULL; //Background image
     sfEvent Event;
Sprite = sfSprite_Create(); //Background image
     /* Create the main window */
sfRenderWindow* App;
     App = sfRenderWindow_Create(Mode, "SFML Testy", sfClose, Settings);
Instaluj(Sprite, Image, tabela[0]); //Assign background image to sprite
sfRenderWindow_SetFramerateLimit(App, 60);
sfSprite_SetPosition(sKamien,100,0); //Sets position of obsatcle rectangle
     /* Start the game loop */
     while (sfRenderWindow_IsOpened(App))
{
uj = SpriteNaRect(sKamien); //Creates rectangles from sprite
uj2 = SpriteNaRect(wsk->duszek); Creates rectangles from sprite (function which does it below
zobaczymy = sfIntRect_Intersects(&uj, &uj2, &jajebie); //Checks for intersects
if (zobaczymy) //If exists
{
std::cout << "Nachodza" << std::endl;
std::cout << jajebie.Left << std::endl;
std::cout << jajebie.Top << std::endl;
std::cout << jajebie.Right << std::endl;
std::cout << jajebie.Bottom << std::endl;
}
else std::cout << "Nienachodza" << std::endl; //if not
Wejscie = sfRenderWindow_GetInput(App); //Input
sfBool Prawo = sfInput_IsKeyDown(Wejscie, sfKeyD);
sfBool Lewo = sfInput_IsKeyDown(Wejscie, sfKeyA);
sfBool Gora = sfInput_IsKeyDown(Wejscie, sfKeyW); /
sfBool Dol = sfInput_IsKeyDown(Wejscie, sfKeyS); /
float Offset = sfRenderWindow_GetFrameTime(App) * 70.f; //Speed of moving character

float OffsetX = 0.f; //
    float OffsetY = 0.f; //
float OffsetXWidoku = 0.f; //Offset of view
float OffsetYWidoku = 0.f; //Offset of view
         /* Process events */
         while (sfRenderWindow_GetEvent(App, &Event))
         {
             /* Close window : exit */
             if (Event.Type == sfEvtClosed)
                 sfRenderWindow_Close(App);
}
czas = sfClock_GetTime(zegar); //DO ANIMACJI
 if (Prawo == sfTrue && Lewo == sfFalse && Gora == sfFalse && Dol == sfFalse) //If You pressed D
{
OffsetXWidoku +=Offset;
OffsetX += Offset;
sfView_Move(Widok, OffsetXWidoku, 0);
sfSprite_Move(wsk->duszek, OffsetX, 0);
if (czas > 0.4f)
{
PlayUstalone(4,8,wsk);
sfClock_Reset(zegar);
}
}
 if (Gora == sfTrue && Lewo == sfFalse && Prawo == sfFalse && Dol == sfFalse) //If You pressed W
{
OffsetYWidoku = -Offset;
OffsetY = -Offset;
sfView_Move(Widok,0,OffsetYWidoku);
sfSprite_Move(wsk->duszek, 0, OffsetY);
if (czas > 0.4f)
{
PlayUstalone(0,4,wsk);
sfClock_Reset(zegar);
}
}
if (Lewo == sfTrue && Prawo == sfFalse && Gora == sfFalse && Dol == sfFalse) //If You pressed A
{
OffsetXWidoku = -Offset;
OffsetX = -Offset;
sfView_Move(Widok, OffsetXWidoku,0);
sfSprite_Move(wsk->duszek, OffsetX, 0);
if (czas > 0.4f)
{
PlayUstalone(12,16,wsk);
sfClock_Reset(zegar);
}
}
if (Dol == sfTrue && Gora == sfFalse && Prawo == sfFalse && Lewo == sfFalse) If You pressed S
{
OffsetYWidoku = +Offset;
OffsetY = +Offset;
sfView_Move(Widok, 0, Offset);
sfSprite_Move(wsk->duszek,0, OffsetY);
if (czas > 0.4f)
{
PlayUstalone(8,12,wsk);
sfClock_Reset(zegar);
}
}
if ((Lewo == sfTrue) && (Prawo == sfTrue)) //All way down it makes sure that character moves when only one key is pressed
{
Stop(wsk);
}
if ((Dol == sfTrue) && (Gora == sfTrue))
{
Stop(wsk);
}
if ((Prawo == sfTrue) && (Gora == sfTrue))
{
Stop(wsk);
}
if ((Prawo == sfTrue) && (Dol == sfTrue))
{
Stop(wsk);
}
if ((Lewo == sfTrue) && (Gora == sfTrue))
{
Stop(wsk);
}
if ((Lewo == sfTrue) && (Dol == sfTrue))
{
Stop(wsk);
}
if ((Prawo == sfFalse) && (Lewo == sfFalse) && (Gora == sfFalse) && (Dol == sfFalse))
{
Stop(wsk);
}

         /* Clear the screen */
sfRenderWindow_SetView(App, Widok); //Sets view
         sfRenderWindow_Clear(App, sfBlack); /
         /* Draw the sprite */
sfRenderWindow_DrawSprite(App, Sprite); //Draw bkacground
sfRenderWindow_DrawSprite(App, sKamien); //Draw obstacle
sfRenderWindow_SetView(App,
sfRenderWindow_GetDefaultView(App)); //Change view to default
Update(wsk); //Updates animation
sfRenderWindow_DrawSprite(App, wsk->duszek); //Draw animation
         /* Update the window */
         sfRenderWindow_Display(App);
     }
 
     /* Cleanup resources */
sfSprite_Destroy(wsk->duszek);
sfSprite_Destroy(sKamien);
sfSprite_Destroy(sHUD);
sfImage_Destroy(HUD);
sfImage_Destroy(Kamien);
sfImage_Destroy(wsk->zdjecie);
sfClock_Destroy(wsk->clock);
sfClock_Destroy(zegar);
sfClock_Destroy(zegar2);
     sfSprite_Destroy(Sprite);
     sfImage_Destroy(Image);
sfView_Destroy(Widok);
     sfRenderWindow_Destroy(App);
 
     return EXIT_SUCCESS;
 }



Function to change sprite to rectangle:
Code: [Select]

sfIntRect SpriteNaRect(sfSprite* &duch)
{
sfIntRect Prostokat;
float x,y;
sfSprite_TransformToGlobal(duch, 0,0,&x, &y);
Prostokat.Top = (int) y;
Prostokat.Left = (int) x;
Prostokat.Bottom = (int)(y + sfSprite_GetHeight(duch));
Prostokat.Right = (int)(x + sfSprite_GetWidth(duch));
return Prostokat;
}


So far I know that doesn't work because when I use view there is like another ratio fo pixel because sKamien instead of 305 widht it has like 50 when I move my view and when I finally reach 405 pixel by moving my character then it says that rectangles doesn't collide.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #9 on: December 19, 2010, 02:08:29 pm »
I can't really answer your questions, as I haven't done any sprite-collision yet.

But I why are you creating that bool array, and not using GetPixel (or GetPixelsPtr) in sf::Image to do the check?
It seems a little wasteful, as each bool will take up at least 8 bits.

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #10 on: December 19, 2010, 08:53:29 pm »
Because from one image(character image) I create subrects by using sfSprite_SetSubRect so I need to know pixels of that subrect and not pixels of whole image.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #11 on: December 19, 2010, 10:12:33 pm »
Sure, but can't you just index into the image, then?

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #12 on: December 20, 2010, 07:38:32 am »
Not sure what You mean.

model76

  • Full Member
  • ***
  • Posts: 231
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #13 on: December 20, 2010, 09:13:39 am »
Let's say that you want to access the pixel at 10, 25, and your sprite's subrect starts at 100, 100 in the image.

This can be achieved by simply checking 110, 125 in the image, or pixel X + subrect X, pixel Y + subrect Y.

darekg11

  • Full Member
  • ***
  • Posts: 127
    • View Profile
Perfect Collision Detection and explanation of functions
« Reply #14 on: December 20, 2010, 02:32:05 pm »
Will this speed up or minimalize memory usage?

And still looking for anwser to my question about that inersections, I will provide You guys more info(some coords of moving sprite, view, objects) later so maybe You can help me solve this.

EDIT: Problem with views is solved, I putted sfRenderWindow_DrawSprite in wrong place, now it calcute intersections without problems, I will try to do right pixel collision now.