Ask how to delete in SDL

Started by
5 comments, last by bombon18 13 years, 3 months ago
I'm programming Pacman game ( I use C++ and SDL ), but when Pacman collided with a coin then I don't know how to delete or hide that coin. This is interface of my game:

pacman_coin.jpg

If you know how to solve it, I hope you help me.
Thanks a lot.
Advertisement
You would have something like a rectangular array of bools (std::vector< std::vector<bool> > would probably be more robust solution). You would have a bool with a particular index correspond to a location on the screen. So if you had

bool coin_grid[HEIGHT][WIDTH];
// set all coin 2d array elements to true here...

// you would draw like this:
for(int i = 0; i < HEIGHT; i++) {
for(int j = 0; j < WIDTH; j++) {
if( coin_grid[j] ) {
DrawCoinAt(i, j);
}
}
}


The key idea is to have an internal representation of the grid and then decide what to draw based on that representation. You might use a std::map, a std::vector, an array. You might use a bool, enum, or int as the value stored in the container. It all depends on what you exactly want to do.

C++: A Dialog | C++0x Features: Part1 (lambdas, auto, static_assert) , Part 2 (rvalue references) , Part 3 (decltype) | Write Games | Fix Your Timestep!

What could do is use delete to remove that instance of the coin after collision detection, which in turn calls the destructor of your coin class. From there what you want to do is use SDL_FreeSurface() and pass in the surface of the coin to free it from memory and uninitialize any variables and/or delete any other objects that may be contained in that class. That is an overly simplified explanation, but SDL_FreeSurface() is the SDL function you are looking for to free up an SDL_Surface. Just look up the documentation to get the full description.

You would have something like a rectangular array of bools (std::vector< std::vector<bool> > would probably be more robust solution). You would have a bool with a particular index correspond to a location on the screen. So if you had

bool coin_grid[HEIGHT][WIDTH];
// set all coin 2d array elements to true here...

// you would draw like this:
for(int i = 0; i < HEIGHT; i++) {
for(int j = 0; j < WIDTH; j++) {
if( coin_grid[j] ) {
DrawCoinAt(i, j);
}
}
}


The key idea is to have an internal representation of the grid and then decide what to draw based on that representation. You might use a std::map, a std::vector, an array. You might use a bool, enum, or int as the value stored in the container. It all depends on what you exactly want to do.

I have still not understood yet. Can explain me more clearly?
I just delete coin in definite location. When I used SDL_FreeSurface, all coins on screen were deleted.
How many times do you load the image? If once, then it should not be freed until the game/level is over (or you can otherwise detect there is noone using it). If you load it multiple times, then it must be freed each time an object using it is deallocated. Generally, you don't want to have multiple copies of images in memory. However, designing this can be a little more complex until you are used to dealing with ownership semantics.

The solution to your problem is to not draw the additional coins. So you can remove them from your data structure, NULL them out, or set an "alive" or "active" flag to false. The real answer lies in how you are currently managing your coin data.
If you're loading the image multiple times, you're wasting memory. I'm surprised it's been mentioned without some sort of recommendation not to do it.

As for how to hide them; it's simple: stop rendering the image there.
How do you know when to stop rendering the image there? When Pac-Man covers the coin.
How do you know when Pac-Man covers the coin? A very basic collision engine.

Circular collision is easy. A circle is only two things: a point and a radius. It could be represented as such:

typedef struct ACircle
{
int x;
int y;
int radius;
} ACircle;

You're not looking to do actual collision testing in this case, since you're looking for Pac-Man to cover the coin rather than for Pac-Man to merely touch the coin (I assume; but then I was never big on pacman so I don't know what they did).
The most basic way to check for this is to use the bounding rectangles of the graphics, but this has inaccuracies. All you'd need to do is check to see if the coin's rectangle was contained by pacman's rectangle, with such simple math you should have no effort figuring it out yourself.
The proper way to do this would be to ensure that the circle the coin makes is within the circle that Pac-Man makes. You can use a pixel-perfect solution or an advanced mathematical formula; I recommend the latter although without decent geometric grounding it may be beyond you. The following is an explanation of the formula:

Truth: A point is contained within a circle if a line drawn from the point to the center of the circle is less than the radius of the circle.
.: Truth: A circle is contained within another circle if the distance between their centers plus the radius of the contained (coin) circle is smaller than the radius of the containing (pac-man) circle.

To find the distance between the center of the two circles from 2D coordinates, you'll need to use the Pythagorean Theorem, which states that the square of the length of the hypotenuse of a right-triangle is equal to the sum of the squares of the other two sides. The two sides would be the absolute values of the horizontal and vertical differences between the centers of the circles. The hypotenuse would then be the distance between them. The C math library has all functions required for using this formula.

Then you simply add the smaller radius to the resulting hypotenuse, and compare to the larger radius. If the larger radius is larger than the combined smaller radius and hypotenuse, then the coin should not be rendered again. Otherwise, the coin should still be drawn.

Simple, right?

(The funny thing about programming is... half of it's math, and the other half is logic, which is also tightly linked to math. :P )
I have solved that problem. I used way of nobodynews, which is very effective but there was a few limitations( I think so!)
Thank you all very much!

This topic is closed to new replies.

Advertisement