blast a solid black circle

Started by
5 comments, last by Ravyne 9 years, 1 month ago

Hi All,

I'm trying to clone space invader, collision with the green barriers.

Right now I have access to the pixels of the green barrier

I would like to draw a solid black circle around the collision point of the bullet, right now I'm using the following code, but it spread random pixels, not solid black circle and it's center the hitting point


int radius = 44;
for (int y = -radius; y <= radius; y++)
{
for (int x = -radius; x <= radius; x++)
{
if (x*x + y*y <= radius*radius)
{
int j = y + bullet.x;
int i = x + bullet.y;
uint8 pixelOffset = j*4 + i*pitch;
ptr += pixelOffset;
*ptr = 0xff000000;
}
}
}
Advertisement

google "Circle rasterization" for optimal approaches.

For a naive approach, loop over the entire area of the square that covers the circle you want (Your for-loops are right for this), and fill the pixel whenever its distance to the center of the circle is less than the radius (this is what your if-statement does, it appears correct).

Inside your if-statement, I assume that bullet.x and bullet.y transform the circle from its own space into the world-space, where the bullet is. And I assume that pixel offset is calculating the in-memory address of the pixel (again, this appears correct). But its not clear what the variable ptr is, I assume it to be the base address of the framebuffer. If that's the case, your error is here, because you're modifying it every time you do +=.

Instead of the last two lines, do *(ptr + pixelOffset) = 0xff000000; instead.

throw table_exception("(? ???)? ? ???");

By the way, one optimal approach that's easy to adapt to your current code structure would be to leverage the symmetry of the circle to fill entire horizontal spans all in one go.

In this approach, change the second for loop to for(int x = -radius; x <= 0; x++), and then instead of filling a single pixel at that point, fill the entire horizontal line between here and the matching point on the far side of the circle. The point on the far side has an x coordinate of (radius - x). To fill the horizontal line, you can another for loop inside your if statement that fills pixels, where you currently fill just one pixel, and then put a break; statement at the end of your if block to exit the x loop early.

Better still, though, would be to use an optimized span-filler that can write multiple adjacent pixels at once, but it might not make much difference for small circles. You'll get the biggest win by reducing the number of iterations and multiplies; the method I described above does that.

throw table_exception("(? ???)? ? ???");

I'm confused It looks like you are using Marmalade. When you read the screen buffer, writing to the result is not the best route to go.

Why are you doing this type of pixel manipulation of a buffer read back from the display, instead of using the build in drawing functions to draw your circle?

@Frob,

There are no builtin draw circle function, I tried to search but couldn't find it ?

I have also second problem, I'm very confused about marmalade Transform and draw image functions. I wanna set a correct bounding box for all my IW2DImages and it's always wrong.

Can someone show me how would I do it ?

Perhaps you are struggling from a language barrier? They have an arc drawing function. What is the difference between an arc over the full rotation and a circle?

Specifically, it looks like you want this function, Ahmed.

throw table_exception("(? ???)? ? ???");

This topic is closed to new replies.

Advertisement