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 / Logical Collision

Author
Message
Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 18th Oct 2011 22:20 Edited at: 18th Oct 2011 23:18
Im currently developing a 2d platformer in my spare time and having some issues with object collision along the X axis. My collion techniques work but the feedback can be quite erroneous. Im stuck trying to find a logical way to get around it. For example...



If the player collides with the wall, it detects the collision fine but if you want to back away from the wall it will change your iDir (direction) and imediatly alter your xPos (position along x axis) to the oposite side of the object. One way i thought to counter this was to...



but that will do the obvious. Any one have any other techniques for object collision along x axis?

EDIT - Found a way, instead of using 1 object as a 'wall' and testing collisions from both angles, make 1 wall for left collisions and 1 for right collisions.



For platforms, make 2 images, 1 for the platform its self, 200 x 20, and another 1 x 20. Place the first image at say x100 y200, then place the second image twice @ x98 y200 and x301 y200 and test 2 seperate dbSpriteCollision, one for the left wall and one for the right wall to avoid the flaws that i got on my first attempt. If any one has any other methods feel free to share and if any one is having issues with thiers let me know and i will try my best to assist.


-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 18th Oct 2011 23:34
Um, you could click the signature.
This method determines which side the object should be on based on its current position relative to the other object. it works quite well. Although, there are a few things you could do to make it even more reliable for collision between small fast moving objects, but I haven't had a problem.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 21st Oct 2011 02:00
DeadTomGC, i had a look at your example not long ago, but at that time i hadn't used c++ in months as i wasnt at uni at the time, so it was a bit of a mess but i sat down and had a real read through yesterday it and your collision system works great for my game. So far i only have movement, basic gravity and collisions but so far they seem to be working almost flawlessly. Thank you very much.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 21st Oct 2011 07:36 Edited at: 21st Oct 2011 07:38
Sorry about the sloppy code.
I was going to fix it up, but uhh.. college took all my time.
Then when I have had free time I haven't felt like working on something that few if any people would look at.
Well, I guess it's time to clean it up a bit.

BTW, when I said "fast" I meant FAST, faster than your average projectile would go. (And you wouldn't need these collisions on a projectile)

Also, here is a picture sort of demonstrating how an improvement could be made.

The red squares and circles are the points being compared to see which side the object should be on.


Attachments

Login to view attachments
Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 21st Oct 2011 17:25 Edited at: 21st Oct 2011 17:27
Yeah i know what you mean, the Y collision i had setup before, the player moved so fast when falling he just fell straight through, but its fixed now thanks to your help. The projectiles i plan to have included wont be moving much faster than the player.

As for your improvement, i am already using it, i had some issues last night with it but after about 4 hours of staring at my code i remembered i set my offsets to x + (dbSpriteWidth / 2). I hate coding some times .

Also, i have a cleaned up version of your code if you would like me to upload.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 21st Oct 2011 21:37 Edited at: 21st Oct 2011 21:43
Sure, why not have someone else do all the work for me?

EDIT: I hope you didn't think the picture was insulting. It was late, and I couldn't think strait enough to describe the improvement with words, so I drew a picture.

BTW, Will I'm thinking about it I may as well say that one more thing somebody could do to make the collisions work at any speed is have the objects movement be limited to the objects length/2 per collision check and then check collisions as many time as necessary to cover the desired distance per refresh.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 21st Oct 2011 21:58 Edited at: 25th Oct 2011 21:23
Ok there is the header file, i organised it because it worked and it was hard to read so i sat for about 10 mins pressing backspace and tab And no, the picture made perfect sense.

Now im having an issue with key presses. Atm, you can hold down the jump or shoot key and it will spam it, how can i prevent this? I want it so the player cannot jump again for another 1000ms after landing or not able to shoot again for a set period. I remember with Actionscript 2.0 you could have key release instead of key press, same with VB, but i cant seem to find any thing for dgdk c++, any ideas?

-Stephen

Attachments

Login to view attachments
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 22nd Oct 2011 06:25
Thanks!
What I typically do is have a bool variable that tracks if the key of interest is being pressed. I update this variable after I check to see if the player wants to perform the action. While I am checking to see if the player wants to perform the action, I choose not to let him if the variable is set to true.

This forces the key to be pressed and then released before firing again.

If you want a slow firing automatic gun, then you could create the same structure as above, except the variable will be an int that will be incremented every loop and then returned to zero when the var reaches a number n. Then the action will be performed whenever the var is zero.

You could also return the var to zero when the button is not pressed(dbMouseClick()==0), but this would let the player potentially fire faster by spamming the button.

Anyway, that is how I would do it.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 22nd Oct 2011 16:56
Thanks, i figured out the bool variable last night shortly after i posted this, as for the firing, i am going to have to have a play around with this soon, thanks for the help.

-Stephen
Mister Fuzzy
13
Years of Service
User Offline
Joined: 27th Feb 2011
Location: XNA
Posted: 23rd Oct 2011 19:12
Quote: "Although, there are a few things you could do to make it even more reliable for collision between small fast moving objects"

For collisions, I usually use WHILE loops to move an object one pixel at a time X times, rather than moving it X pixels at a time: That way I can check collisions MUCH more accurately than if I just repositioned my sprite AFTER it was detedcted to be overlapping another object. Just a thought.
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 24th Oct 2011 04:28
@Mister Fuzzy
Also, a working solution, but really only required on objects of size 3 or smaller. Otherwise, you could be just as accurate with fewer checks. Unless you want to have some really accurate physics or something like that. I'm not sure what to do then.


DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 25th Oct 2011 06:00 Edited at: 25th Oct 2011 06:01
@Stephen Young
Um... I Didn't really have time to look at the header you uploaded until now, and... it is actually the main.cpp.
So... Ya, if you could upload the header, that would be great.
Or I could just do it myself *sigh*


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 25th Oct 2011 21:25 Edited at: 25th Oct 2011 23:38
Fixed*

What would be the best way to handle dbSprite? for example im reserving 1-99 for game objects like player and hitboxes and stuff then 100+ for platforms and another section for projectiles and another for enemies, is there a better way of doing this that i have missed or is this it?

EDIT - DeadTom, if i email you a .zip of my project could you take a look at it, im having another issue with my collision and i just cant see the problem, this always happens then someone will instantly spot the problem where as im just reading straight past it. Im not sure if ive messed up a math problem or the logic of it all is wrong now.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 26th Oct 2011 19:08 Edited at: 26th Oct 2011 19:17
Ok, I actually looked at it this time. Thank you!

There are other things you could do to track sprites. For instance, what I use in the example program is an array (blocks) that keeps track of which sprites are blocks. This way I can categorize sprites as block or baddies or whatever just by putting the ID in the appropriate array.
Then these blocks or baddies are updated as needed by category.

Now of course not all levels would be the same length, and you will not always have the same number of baddies and projectiles in the game at the same time. Yet, arrays are fixed size. So, what you can do is have a var for each array that tells you how many items are in that array.
Now you can program it to only update that many items in the array.
When you make a new item you can increment the var, and when you delete an item you can take the end item (location var-1) and put it where the one that was deleted was and put the deleted one where the end one was and then decrement the var.

When you create a new item and you have initially set all values in the array to zero, you can check to see if the value in the spot you are about to use is zero. If it is you must find a new sprite ID. This can be found using a var that always hold the next higher available sprite ID. (It would simply increment every time you create a new sprite with ID of nextsprite.) If, on the other hand, you found that the next spot you were going to use is not zero, you can simple reuse that sprite ID.

This should use the minimum number of sprite IDs and it should not do any unnecessary updates of non existent sprites.

This Also lets you not have to worry about when you declare sprite and how many you use in each category because if you see that you may exceed the limit of your arrays you can just make them bigger!
That's it!

Quote: "someone will instantly spot the problem where as im just reading straight past it"

The best reason for having someone else look at your code.

You could email me that zip if you want at


Don't worry, It's not my main email.

Edit: I gave you credit for cleaning up the code in the codebase entry. Thanks for that!


DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 27th Oct 2011 03:33 Edited at: 27th Oct 2011 04:01
Ok, so I have noticed a problem, and I will edit this post when I have an update on problems I have found.

1: your vely is an int, it needs to be a float or double.

2: same for the position

3: in player1.cpp I believe that this
should look like this



Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 27th Oct 2011 15:52
Well that fixed my jumping problem . Ive created a new project that is basically a stripped down version of the one i sent and im just adding in the important things / or rewriting them, like movement jumping and collisions, so its easier to test. If i cant get your collision system working, im gonna have a try at one i thought of last night that tests player Y < wall Y && players X is < and > than the walls X boundaries, that will prevent the player from clipping the wall from above and thinking its a horizontal collision and shifting him off to the side.

-Stephen
vitinho444
13
Years of Service
User Offline
Joined: 12th Oct 2010
Location:
Posted: 27th Oct 2011 16:04
i got a collision system that dont fails:

store a x and y for the object 1(player), then store a x + player.width and a y+player.height. then just do the same for any object.

then check if each movement. like this for left:

//player left movement
if( (x + player.width) > object.x) { //collision =D }


//end of movement for left

its kinda hard for create, but if you put that on a function then its easier...

Just trying to help =D

C++ Medium 3.5/5
VB6 Advanced: 4/5
VB.NET Advanced: 4/5
Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 27th Oct 2011 19:15
Assuming your using dbSpriteCollision before this, it kinda makes it useless, easier to just test the x position of player and x position of object.

Your method will constantly check if x and y values are < or > the objects, so as soon as the program starts the collision is activated, even before it touches any thing, unless im missing something.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 28th Oct 2011 06:16
A few other problems in the same file.

this
should look like this
.
Also, you want to keep the updating of the movement in the different dimension separate.
So, this
should be right before the horizontal check along with an update on the actual sprite position.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 29th Oct 2011 02:17
Yes i have corrected all those now, jumping works fine on my new project but im still trying to figure out how both your X and Y collisions work, i even did mine the same way with the while loop instead and it still doesnt work.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 31st Oct 2011 02:02
Sorry I haven't been able to post in a while, my power has been out because of the wicked snow storm that hit Bethlehem. I won't be able to post much for the next couple days because the power is still not on. (It went out early yesterday and it is 8:00pm now)
Right now I am working on an asm program for school using the power of a dorm that somehow still has power. So, I'll probably be busy when I do have power until power is restored to where I live.


DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 6th Nov 2011 01:54 Edited at: 6th Nov 2011 01:54
I'm back


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 6th Nov 2011 15:14 Edited at: 6th Nov 2011 21:51
Fantastic Ive sorta worked around this problem for the time being just so i can continue working on other stuff like scrolling backdrop and enemies ect. I will however once i have other stuff completed, come back to this collision thing and fix it properly. I have a feeling that detecting players X and Y position alone isnt going to cut it, as once it detects the Y position, it will imediatly detect the X position and port the player to the left/right of the object. There will be some simple way of getting around this but ive tried all sorts of things.

EDIT: So i have my tile map working and scrolling file, but its a tad bit slow, game runs @ 60fps when standing still, as soon as you start moving the world starts scrolling and fps is halfed. Im trying to think of a way to increase performance, would dbHideSprite on all sprites currently not on screen help? Or is there a better method.

-Stephen
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 8th Nov 2011 05:22
Quote: "EDIT: So i have my tile map working and scrolling file, but its a tad bit slow, game runs @ 60fps when standing still, as soon as you start moving the world starts scrolling and fps is halfed. Im trying to think of a way to increase performance, would dbHideSprite on all sprites currently not on screen help? Or is there a better method."

Ok, so I just tested the fps of the demo on my 2.0 GHz dual core laptop and got an fps that didn't drop below 59. That was running the collisions for 200 sprites as if they were all capable of hitting the player. So, unless your computer isn't very good, I would think that the bad performance is caused by something other than rendering and collisions. (unless you are doing something other than just calling dbSync() for rendering).

I'm not sure what you want to do, but if you want to send me the entire project, that would help considering that I had a hard time getting your source to work last time.

In the mean time, I'm going to make my code more versatile so that it might be more reliable when implemented in other people's games.

This way we won't have to worry about code placement order and the like.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 8th Nov 2011 19:41
Sounds great, running AMD Phenom II X4 @ 3.3ghz, 8gb DDR3 ram, 1.3tb HDD, ATI HD Raedon 5750, Windows 7 Ult 64bit. And im running a 64 x 32 tile map with 32x32px sprites, and once the scrolling starts the fps halfs. As for doing something other than just calling dbSync(), i think thats all im doing.



My newest project has been emailed to you, thanks for the help Tom.
DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 8th Nov 2011 23:36 Edited at: 9th Nov 2011 01:47
hmm... 64x32 tile map, that's over 2000 sprites.
Are you really using all those? If you are making a sidescroller you should probably look for a way to have the least number of sprites possible. So, give yourself the ability to make sprites bigger so that you can use fewer sprites. Really, 200 sprites would make a pretty long mario level.

Now, your program probably doesn't actually use 2000 sprites, but still, while using unit blocks for level design is a helpful, using units for actual sprite placement doesn't seem to be vary efficient.

I would suggest making a level designer that lets you visually create your levels by placing and resizing blocks. Of course, you could include short cuts to making unit blocks and positioning blocks in appropriate unit slots, etc.(or blah, blah, blah. if you're from England? Is that common?) This way, you can make nice, unit based levels that use as few sprites a possible.

There should be some threads around here talking about level design and loading.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 9th Nov 2011 21:27
I get you, instead of having the same block over and over to make the floors, you would just have 1 larger block etc.

And 200 sprites at 32x32 is.... very small. See i was planning on making an open-ended RPG platformer, but i think i understand what you mean, just try use the least number of sprites possible. I was going to create all my design tools in visual basic seeing as it will all be saved to a .txt file or something like that.

Also, whats wrong with this? this worked fine in my progamming concepts final assignment last year, it dont seem to work.

DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 10th Nov 2011 00:35
I think you need to have this
.

I haven't done this
in awhile. So, I don't remember if that's right. In fact I don't even remember if that can be done in C++.


Stephen Young
16
Years of Service
User Offline
Joined: 23rd Feb 2008
Location: UK
Posted: 10th Nov 2011 14:03
Yea that made no difference, it just isnt adding values to the array like it does on my assignment program. And
should be
, i was just testing for the hell of it when i posted that.
jason p sage
16
Years of Service
User Offline
Joined: 10th Jun 2007
Location: Ellington, CT USA
Posted: 10th Nov 2011 17:45 Edited at: 10th Nov 2011 17:46
I forget whether sprite collision is pixel perfect but (forgive me coming in and scanning the codez kinda fast etc) but if you store where your sprite is, the move it, then check for sprite collision, and then set it back to where it was (if you want to to not go through a sprite "tree" or something...) that might help.

The other thing is I'd recommend timer based movement - even for sprites, especially since at times your FPS dips.. which will more notably "slow down" to the game player. I know sprites don't exactly have "float precision" but I think you could still use a float to calculate whether you should move your sprite 1 pixel, 2 or 3 auto-magically almost.

One way to accomplish this, it to keep your OWN x,y for the sprite as float, and use the "whole number" portion for your ployying (simple typecast should do).

How this sort of thing is usually done is you find a "multipler" that works - often called speed.

// Pseudo code - don't have sprite commands memorized


I hope this is remotely helpful (B^)>


[edit]forgot a bracket[/edit]

DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 12th Nov 2011 05:21
@jason p sage We have been doing using the whole type cast idea(or at least that was my plan) but not the whole idea of making the movement time based. really though we don't want to have to use that.

@Stephen Young what are you trying to store in the array?
No matter what you should be able to use a simple loop to load the values automatically.

BTW I have restructured the sample program. and it is going to be very easy to implement. However, while working on this I noticed a few limitations of the program. So, those issues had to be taken care of, and so now I searching for and fixing bugs.


DeadTomGC
13
Years of Service
User Offline
Joined: 11th Aug 2010
Location: LU
Posted: 5th Dec 2011 17:34
Sorry its been so long. You still working on this?


Login to post a reply

Server time is: 2024-04-25 09:39:50
Your offset time is: 2024-04-25 09:39:50