Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Perfect Pixel Collision Completed!!!!

Author
Message
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 5th Apr 2010 06:18 Edited at: 20th Apr 2010 20:14
--------------------------
UPDATE: 4/20/10 1:09PM
--------------------------
-Added Demo (source code and files for examples...compile and run)
-ADDED FUNCTION fixCollisions() BETA //This will run slower if multiple collisions or detections take place...keyword, BETA
->Allows user to have an auto fix for any collision (depending on situation). See documentation.

-Currently working on fix for sprites with no/some outline
-Just sped up collisions by 60x (or whatever your sync was). This was due to sprite masks being created 60x per sec and then checking for a collision. Fix for this was to just build sprite masks at beginning of code (initialization) and then send sprite mask to pixel collision.
->This is not included in current demo....works great...but code is really sloppy right now

-When testing out the demo, please feel free to try out multiple sprites! I want you to see that it works with all shapes and sizes!


HINT:
When using multiple animations for a sprite(such as loading multiple bitmaps for 1 character), be sure and take a good look at the demo. I've created a for loop that detects collisions w/ the character and all objects in level. Before this, I set what direction he was going as a boolean value. This way, when you use dbHideSprite(), the collision is not gonna be tested for each individual sprite (visible or not). This will speed up the collisions by 4x.


DOWNLOAD -------------------------------->

Attachments

Login to view attachments
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 5th Apr 2010 08:22 Edited at: 6th Apr 2010 07:08
EDIT: download above.
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 5th Apr 2010 16:08 Edited at: 6th Apr 2010 07:59
Things to look out for:

1. Be sure that when using this function, all parts of the character outline are same color! You must realize that this function will detect the most singled out pixel. I have had characters get stuck in objects because they did not have a single outline color.

2. This will detect any and all collisions related with sprites, but....its up to you as the programmer to decide what happens when the collision is detected.

Until I figure out how to work with the key colors, please ask any questions!
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 6th Apr 2010 03:33
Have you tried dbMakeMemblockFromImage() to get to your pixels and build your bitmask? Just make sure you delete the memblock when you are done with it because you are limited to only 256 (I believe).

JTK
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 6th Apr 2010 05:51
Nope, haven't tried that yet. I will though! Currently i'm creating a function to add in the header files that will allow your sprite (after collision) to move out of collision (no matter what direction you are moving in).

Oh yeah, and thank you for helping me with the coding for this project. That helped tremendously!
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 7th Apr 2010 03:40
@JTK

What would be the purpose of calling dbMakeMemblockFromImage()? I know that it would help get the pixel color and all....but were you talking at the time of the collision or during initialization? My only problem right now is making the bitmask without the outline color. Because of initially setting the key color, when I get the bitmasks, the background of the sprite is "invisible" and therefor I would get whats behind the picture (I've tested this myself) and hence a bitmask only of 1's and zero 0's.
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 7th Apr 2010 06:26
At initialization! Remember in the code snippet I put out for you says that ideally, you should get the bitmask once - and that would preferrably be at initialization.

You could check the memblock for color (if memory serves me, DX uses Transparent-black for transparency checks).

Here's some code I've put together way back when (early 2001 or so) that *may* be of some help to you...

NOTE: Long code listing(s) but may help you. Not sure just how relevant they are to today's DX9 stuff, but should at least be a starting point... (i hope)...

types ending in:

_PTR = pointer type (*)
_REF = reference type (&)
_CONST = const

and IMAGE_PTR was taken from:


(you can take it from there)

GraphicFunctions.h


GraphicsFunctions.cpp


Misc. macro definitions


You probably won't be able to compile any of this code right off, but at least you can see *how* i have done things in the past. I still use alot of this code as a reference point - although, admittedly, I don't do to many things that way anymore since I'm trying to migrate away from 2D and into 3D - it appears that alot of stuff changes, but with 2D basics, 3D is making more sense to me (somewhat).

Anyway, what I was getting at with my response to pixel format being D3D_X8R8G8G8 before would be better understood with the macros/functions used to RipColor/MakeColor etc... Format matters and you have 3-bytes per pixel which seemed to me to be incorrect for the XRGB format - but then again, this code is nearly 10-years old, so what do I know... lol

Anyway, I hope this stuff helps you, you'll have to follow the code as I've removed most of the comments for brevity... (Not to brief though, is it?)

I'll be here for any further questions that you (or anyone for that matter) may have. I'll help if I can...

JTK
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 7th Apr 2010 06:54 Edited at: 12th Apr 2010 07:41
Oh yeah, when I posted that code, I was trying out different byte sizes for a pixel....it's 4. Code works great though, I had to make a few changes to work. Looking into your post now as well as trying to figure out camera for 2d games (centering on character and such).
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 11th Apr 2010 04:31
I think i'm gonna take your advice on building the sprite masks only once. I got the world to move around my character and with the collisions, its rather slow. This way I wont be building masks that contain 40,000+ integers 60x a sec.
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 11th Apr 2010 05:18
Lol...

I knew this day would come... But truly though, I didn't expect you to see *the light* this soon... It took me well over a month to see it myself...

Your BuildSpriteMask function seemed like it'd do the trick, only with being called every frame (um'teen times per frame) I knew it would be slow, but alas, I *don't* know what you do - and so you *could* have come up with a way to improve things that I was just waiting to learn about... I mean, I don't know ALL - even though I may think that I do...

Just think where you'd be w/o my other suggestions (er, teachings) already....

We've *ALL* been there, and now I feel I'm there in the 3D aspect of things... ;(

Oh, BTW, how's my old code treating you, with the line-clipping and such? Have you had a chance to look at that yet?

JTK
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 12th Apr 2010 07:38
Wow, i'm a few days off. I kept looking for updates on the posts but didn't see your response lol.

I have not got a good chance to look at your code yet...got a big exam on thursday i'm studying for. Currently creating classes for my world objects and player so when the objects are instantiated, the sprite masks are built only once.

I was thinking about making the top-down rpg w/ darkGDK's 3D header files...but i'm kinda lost there. I just came across a decent tile editor too that i'm trying out.

I've got plans for the game and all...writing them down on paper when I can so I don't forget. But hopefully this weekend i'll be able to look more at your code and be finished with the sprite masks
replax
14
Years of Service
User Offline
Joined: 25th Oct 2009
Location:
Posted: 17th Apr 2010 23:27
hey xbandages,

as I was interested in Pixel Perfect sprite collision for darkgdk, i came across your code. so i downloaded it an ran the example and it worked out of the box.

so i started to investigate your code and try it with selfwritten examples, and i came across this line:
it is located in the beginning of the sprite mask building and everytime i try to run a self written example with the collision and two objects are about to collide, that line is throwing exeptions. i am still to find out why exactly and what my error is but i couldnt find it yet.
the exact message is:

do you know what could be the cause of that error? unfortunatly, i am not very familar with directx.

thank you very much!

yours sincerely,

replax
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 18th Apr 2010 21:02
xbandages I am having errors when adding your pixel_collision.cpp and including the h file, and trying to call Pixel_collision inside my code, I am getting 3 unresolved externals Please explain what could be wrong here are the errors:

Linking...
libcpmtd.lib(xdebug.obj) : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other libs; use /NODEFAULTLIB:library
pixel_collision.obj : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function "public: int const & __thiscall std::_Vector_const_iterator >::operator*(void)const " (??D?$_Vector_const_iterator@HV?$allocator@H@std@@@std@@QBEABHXZ)
libcpmtd.lib(stdthrow.obj) : error LNK2001: unresolved external symbol __CrtDbgReportW
libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __malloc_dbg referenced in function "void * __cdecl operator new(unsigned int,struct std::_DebugHeapTag_t const &,char *,int)" (??2@YAPAXIABU_DebugHeapTag_t@std@@PADH@Z)
libcpmtd.lib(xdebug.obj) : error LNK2019: unresolved external symbol __free_dbg referenced in function "void __cdecl operator delete(void *,struct std::_DebugHeapTag_t const &,char *,int)" (??3@YAXPAXABU_DebugHeapTag_t@std@@PADH@Z)
Debug\Dark GDK - 2D Game1.exe : fatal error LNK1120: 3 unresolved externals

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
Hassan
15
Years of Service
User Offline
Joined: 4th May 2009
Location: <script> alert(1); </script>
Posted: 18th Apr 2010 21:06
try Project -> /*name*/ properties -> configuration properties -> C/C++ -> code generation -> Runtime library, change it to Multi-Threaded ( MT ) instead of Multi-Threaded Debug ( MTd )

StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 18th Apr 2010 21:45
OK, that fixed that issue, now I am running into one other issue..

I am getting an unhandled exception on collision, unable to lock surfaces??? I am moving the sprites inside a while loop in which I check the return value of pixelcollision to ensure it is still false, if it is false, then I continue on moving it..

Here is a screen shot attached...

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]

Attachments

Login to view attachments
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 18th Apr 2010 22:24 Edited at: 18th Apr 2010 22:41
Here is my shootball code showing how I check for collision etc..

void ShootBall(int BallImgNum, int BallID, float BallSpeed)
{
float offsetx, offsety;

// Setup the Current Angle equal to the Player Angle...
float curAngle = dbSpriteAngle(3);

// figuring out the offsetx&y vars where the balls will be launched from @ end of arrow rotated...
offsety = 40 * dbSIN(curAngle+90);
offsetx = 40 * dbCOS(curAngle+90);

// Setup New Ball Sprite X&Y Coords. based on passed in information...
dbSprite(BallID,400 - offsetx,560 - offsety,BallImgNum);
dbOffsetSprite(BallID,20,20);

// Rotate the ball to match PlayerArrow angle of Rotation...
dbRotateSprite(BallID,curAngle);

// PixelCollision( int s1, int s2, int R, int G, int B)
while ((PixelCollision(BallID,2,39,39,39)==false)&&(PixelCollision(BallID,4,39,39,39)==false)&&(PixelCollision(BallID,5,39,39,39)==false))
{
//dbPasteImage(1,0,0);
// Start Ball Moving @ BallSpeed.
dbMoveSprite(BallID,2);
//dbPasteImage(1,0,0);
dbSync();
}
fixCollision(BallID, 2, 2, 39, 39, 39);
}


I am just a step away from going back to using allegro, it shouldn't be this hard to code a simple 2d game...

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 19th Apr 2010 05:17 Edited at: 19th Apr 2010 05:20
Um...

From what I can see of your code, sprites 'BallId', 2, 4 or 5 may not exist anymore. Maybe you have *it* being deleted outside the scope of your ShootBall() function? Check for any unexpected dbDeleteSprite() calls.

NOTE: I just had a similar bug in my code where I was encapsulating GDK Objects in my classes; my base class was calling a virtual method UnloadObject() in its destructor. So, as a temp variable somewhere else, I created a new object to work with (copy constructor and assignment operators did not work with dbCloneObject() version). Upon return from that function that uses the copied object version of my object's instance, the destructor was called and deleted my object from existence (since it was not dbCloned()... This took me 7 full-days to find! I was certain that GDK was messing things up... Ultimately, I removed the call to UnloadObject() from my object's destructor and manually call it myself when I'm done with the original...

Maybe you have the same thing going on...?

And finally, perhaps your Collision that was detected wasn't between the BallID and sprite 2. You are only calling FixCollision() for sprite 2 but you are testing sprite 4 and 5 as well and if either of those fail, you still fix the collision with sprite 2 - which of course, didn't happen... (just an observation).

Hope this helps,
JTK
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 19th Apr 2010 06:16 Edited at: 19th Apr 2010 06:17
No its not getting removed, the dbDeleteSprite doesn't get called until after the user presses escape just like in the default 2d project for dark gdk... so I can't understand what is going on, I noticed another user had exactly the same results right above where I posted my error...

His name is Replax...

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 19th Apr 2010 07:10
Ok... I think I know what's going on here...

He's calling dbGetImagePointer() which retrieves the LPDIRECT3DTEXTURE9 object for a dbImage - not a dbSprite. So, it would appear as though your sprite 2 does not use image 2; where if image 2 was destroyed you would get that error...

Now, for a fix... Not sure but I believe the following modifications to the PixelCollision() function should do the trick!



Let me know if it works, perhaps xbandages should make the change official...

JTK
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 19th Apr 2010 21:32 Edited at: 19th Apr 2010 21:41
I am using Image #2 as well, and I am pretty sure I am not deleting it either, until escape is pressed, then both the images and the sprites are deleted... I think really what is going on here, is that the image he is grabbing to do the testing on, is not locked first, you must first lock a surface in directx before you can mess with it.. I will try your changes I already added the changes to his code, now I just have to swap out my function names again.. I did write my own functions that work pretty good as long as the ball speed isn't to fast, for some reason when I set the ball speed to like 10 for instance, it gets stuck inside the elevator, instead of stopping as it reaches the elevator, and I know my checking routines are spot on, because if I set the speed to 2 it works perfectly.. I am using the circle -> square / rectangle proximity testing method.. one that I derived from square / square and circle / circle, so I just fibbed it into thinking that both the ball and the elevator were squares...

Same Exact error on collision... I know I'm not deleting the image or the sprite first, because I wrote my own collision routines using these images and sprites as well, and called them from the same place I called his from... so I think that since I am not the only one with this error, that there is something bigger going on with his library / function library... I am about to give this up, and just either code it in DBPro or Blitz3D using the nSprite Pro Library, really is it worth all this, I mean you would think that TGC would have DGDK on par with DbPro since according to the book I have, DBPro was made from a C++ Library, Dark Basic Pro Game Programming 2nd Edition. If they make DBPro from a C++ Library, how can dark gdk not have the features that dbpro does? If this was a major 3d game then I would understand some of the problems, but a simple 2d puzzle game, should not be this hard... I know it works find in dbpro because I have seen the sourcecode to two other games exactly almost like my game written in dbpro in a super short time frame..

Please help, Bandages, can you fix this, or is the version of PixelCollision you used in your example different from the one you released or what? Something is up, because his example works fine, perfectly, but ours doesn't... ????

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 19th Apr 2010 21:56 Edited at: 20th Apr 2010 01:15
UPDATE* I think I have figured something out... He doesn't use dbMoveSprite in his example, he merely updates the x&y coords on keypresses, and then hides and shows sprites depending on keypresses, and on each keypress he is re-creating the sprite with the new x&y coords using the same image / sprite num.. I am wondering if the dbSpritemove causes the surface to mess up somehow.. I will try to re-write my example game using his method of sprite moving by moving the X&Y seperately, and recreating the sprites on the fly... I will keep you guys posted, as this may be a major find, for the problems facing us..

btw: what exactly is fixcollisions doing for us? Please explain what it is supposed to do, and why we need it..

Any sprites that are updated outside of the Darkgdk_loop I think is what is causing the issue...
if it is updated, and / or checked for collision by calling his routine outside the darkgdk_loop like inside an outside function such as shootball, is what is causing the error locking the bitmap..

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 20th Apr 2010 07:33
Hey everyone! Sorry I haven't been replying lately, its the end of the semester and exams are being thrown at me left and right!

I will have time to read into your messages tomorrow as well as your code.

Thanks a bunch! will keep in touch!
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 20th Apr 2010 19:50
Alright, I looked into your code and yes, because you were calling dbMoveSprite() that would cause an error.

Also, the fixCollision() function is supposed to move your sprite out of the object its colliding with (since overlap occurs). This function only works for examples like mine (notice the background doesn't move...just the sprite).

I wrote a new fixCollision() function that fixes the collision for games like top down rpgs like zelda. The new function is called fixWorldCollision(). This would move the level and not the character. Both functions are essentially needed for a game like that since the "camera" can either be centered on the character in the world, or just a small room that the character moves around in.

Please if you are still having issues with your code, feel free to send me what your working on. I'll take a look at it.

p.s. Just please forgive me, since it is the end of the semester. I'll try to respond/fix any code with the little free time I have.
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 21st Apr 2010 07:01
Hey Bandages, I forgive you, and I don't blame you at all, you have done something really good for the community here. I was just fried mentally when I wrote the comments, coding for hours day in and day out will do that to you, as you know I'm sure...

I am in the process of reworking my game completely where I will not be using dbMoveSprite at all, but instead update the x&y coords, such as you do, only I will be using Angular Movement, based on the angle of the players arrow object using sin and cos for updating the x&y coord, along with multiplying it times an overall ball speed for the game..

I just have to make sure and not use movesprite anymore.. Ok, so if I understand you though, I don't have to do the collision detection inside the darkgdk main loop, but can still use external functions for checking movement and collision, as long as I don't use the dbMoveSprite function... I will just have to hide the sprite, update the coords, then show it again / or create the sprite all over again, like you did.

Please let me know if I am understanding correctly.. Thanks for your help, it is very much appreciated, even if we (as programmers) aren't very good at showing it sometimes.. ;')

Thanky Buddy,

StOrM3 aka Ken

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]
xbandages
14
Years of Service
User Offline
Joined: 30th Mar 2010
Location: Michigan
Posted: 21st Apr 2010 20:50
The check for the collision detection will be done in the main loop no matter what. It is the game loop and therefore any functions you call will be done from there. What can be outside of the darkGDK main loop is building of the sprite masks.

BUT....the code i've provided only works if you build the masks inside the loop unless you add another argument to the pixelColllision() that receives a vector that contains the sprite mask. I've already modified code myself for this but its kinda dirty and I don't want to offend anyone lol. Still need to make a "cleaner" way to do this

You don't have to use the fixCollision() function for your game to make the check work, the PixelCollision() function just checks to see if at least one pixel from each sprite/image are overlapping. If there is an overlap, you can do whatever, I was just writing the fixCollision() function for anyone who wanted an example or got lazy :b
replax
14
Years of Service
User Offline
Joined: 25th Oct 2009
Location:
Posted: 22nd Apr 2010 15:32
thanks a lot xbandages!

by the way, the fix that JTK proposed works like a charm. I do not tend to give my sprites and images the same ID...

anyway, it says in the first post that you updated your great collision, however the attached download is still the old version. if you got some time to spare, i would appreciate if you uploaded the most recent version.

thanks for the needed addition to darkgdk

yours replax
StOrM3
20
Years of Service
User Offline
Joined: 24th Sep 2003
Location: Cyberspace
Posted: 6th May 2010 07:44
Bandages, Can you upload or send me the version you did that takes the vector argument, so I can build the masks outside the main loop ? I know its annoying, but I'm trying to modularize as much of the game as I can, putting everything into external functions to make it easy to understand what is going on when... I just like the idea of being able to code my own classes, and member functions / normal functions and get away from the Top-Down basic code style.

Thanks Man.

Just shoot it to my email: storm3 at twlakes dot net

if you don't want to post it here.. thanks again.

[PKE] Pain Killa Entertainment(tm) [PKE]
Pain Brings Reality...
[PKE] Pain Killa Entertainment(tm) [PKE]

Login to post a reply

Server time is: 2024-07-07 01:20:07
Your offset time is: 2024-07-07 01:20:07