About moving a sprite and updating the background surface

Hi all, as I’m a beginner in SDL I’m quite confused about how to display

a sprite on screen and moving it without destroing the background…

Well I’ve just downloads Aliens sources but I can’t understand so
much…
(I can’t isolate the code that does that).

What I’d like to know is how (and the easiest) move a bmp image (the
sprite)
keeping all updated.

I can just display the sprite and move it, but the backgorund image get
screwed up
by the sprite.

I hope you understand,
Thanks.–

  • @G.Gabriele ---------------+
    | Linux |
    ±--------------- the free philosophy -+

Since we don’t have hardware-sprites it’s your own job to restore the
background. I see two possibilities.

  • If you have only a few small sprites then copy the area, where you will
    draw your sprite, to some backup-surface. The next time you move the
    sprite, first overwrite the old sprite with this saved part of the
    background, and only then draw the new sprite.
  • If you have lots of sprites then it’s simpler (and possibly faster) to
    keep a copy of the whole background saved. If you have displayed all your
    sprites, and want to move them, you copy the whole backed-up (fresh,
    without sprites) surface to your screen, and then the sprites again on top
    of that.

AFAIK there is no automated way to do that in SDL, because it’s to special
and depends on how your game works.

All the best,
robOn Sun, Feb 27, 2000 at 02:45:10PM +0100, G.Gabriele wrote:

Hi all, as I’m a beginner in SDL I’m quite confused about how to display
a sprite on screen and moving it without destroing the background…

I can just display the sprite and move it, but the backgorund image get
screwed up by the sprite.

“G.Gabriele” wrote:

Hi all, as I’m a beginner in SDL I’m quite confused about how to display

a sprite on screen and moving it without destroing the background…

Well I’ve just downloads Aliens sources but I can’t understand so
much…
(I can’t isolate the code that does that).

What I’d like to know is how (and the easiest) move a bmp image (the
sprite)
keeping all updated.

I can just display the sprite and move it, but the backgorund image get
screwed up
by the sprite.

I hope you understand,
Thanks.

Simplest way would be to determine the size of your sprite and where its
going. Then blit a background area the size of your sprite, beginning
at the area where your sprite is supposed to appear to an offscreen
buffer and THEN draw your sprite. After you’re done with that, to erase
your sprite, blit the saved background area back where you got it (clean
background again), and then redraw your sprite at the new location. I
think that there may be more sophisticated ways of doing it, but this is
the cleanest way I know.–

| Rafael R. Sevilla @Rafael_R_Sevilla |
| Instrumentation, Robotics, and Control Laboratory |

College of Engineering, University of the Philippines, Diliman

This “save under” works quite well in some cases, but gets more
complicated in others, depending on order and overlapping of objects.

With one sprite and no over-lapping, it is very simple:
Before putting sprite in first time, copy the background where he will go.
Now blit the sprite there.

To move the sprite:
paste the saved background over the sprite.
save the next spot background
blit the sprite again.

Only problem is, if a sprite walks so that he overlaps another sprite,
you end up saving the sprite under him as the background image.
Depending on the order and how you do it, you may end up erasing the
other sprite… or leaving a trace of a sprite where it shouldn’t be.

I get decent frame-rates by merely updating the entire play-area screen
when needed. When he walks, the screen scrolls anyway. A shift in the
screen requires a full-screen update anyway. When creatures walk, of
course, this isn’t the case…>Simplest way would be to determine the size of your sprite and where its

going. Then blit a background area the size of your sprite, beginning
at the area where your sprite is supposed to appear to an offscreen
buffer and THEN draw your sprite. After you’re done with that, to erase
your sprite, blit the saved background area back where you got it (clean
background again), and then redraw your sprite at the new location. I
think that there may be more sophisticated ways of doing it, but this is
the cleanest way I know.

Only problem is, if a sprite walks so that he overlaps another sprite,
you end up saving the sprite under him as the background image.
Depending on the order and how you do it, you may end up erasing the
other sprite… or leaving a trace of a sprite where it shouldn’t be.
To avoid this you can simply use a three pass method to drawing each
frame.
Pass 1: Draw old "save unders"
Pass 2: Save the new ones
Pass 3: Draw your sprites

Personally, like yourself, I prefer a complete redraw, certainly when the
backgrounds are not static.

Long live the confused,
Akawaka.On Sun, 27 Feb 2000 hayward at slothmud.org wrote:

Bother, said Pooh, as he carved Eeyore’s name into the black candle.

Simplest way would be to determine the size of your sprite and where its
going. Then blit a background area the size of your sprite, beginning
at the area where your sprite is supposed to appear to an offscreen
buffer and THEN draw your sprite. After you’re done with that, to erase
your sprite, blit the saved background area back where you got it (clean
background again), and then redraw your sprite at the new location. I
think that there may be more sophisticated ways of doing it, but this is
the cleanest way I know.

One problem with this is when sprites overlap. You want to make sure that
you create all of your save buffers before drawing anything… then
draw all of your sprites.

In Circus Linux! I do something kind of like this, except I have an
animated background, so I keep the entire background bitmap in memory all
the time.

My first step is to draw pieces of the background based on where all of the
objects currently are. For example:

dest.x = object[i].x;
dest.y = object[i].y;
dest.w = 32;
dest.h = 32;

SDL_BlitSurface(background, &dest, screen, &dest);

Then I move everything:

for (i = 0; i < NUM_OBJECTS; i++)
{
object[i].x = …;
object[i].y = …;
}

Then I draw it all:

dest.x = object[i].x;
dest.y = object[i].y;
dest.w = 32;
dest.h = 32;

SDL_BlitSurface(sprite, NULL, screen, &dest);

Now it’s time to actually make all of this appear. I believe I keep track
of all of the rectangular areas I draw in:

SDL_UpdateRects(screen, rects, num_rects);

If tons more were being drawn on the screen, you probably wouldn’t want to
bother with keeping track of dirty rectangles:

SDL_Flip(screen);

And, since this is how I do it in my game, I now wait for a certain amount
of time so that the next frame is drawn about 1/50th or so of a second
later (rather than “as fast as possible,” which would make the game
impossible on very high-end computers, and which would eat up far too much
CPU):

SDL_Delay(…);

-bill!

All right, I’ve just written some lines to test the thing (thanks for your
tips and help)
as a quick test I did:

for(x=0;x<=100;xpos = xpos+50) blit_SDL_bmp (background, 0, 0), blit_SDL_bmp
(image, xpos, 10);

background is the test background Surface image (640x480);
image is the Surface image that I want to move .

That way I’ve noticed that the test window was flickering a lot…
(probably because the too fast redrawing of images)
then I’ve tried to add a short delay:

for(x=0;x<=100;xpos = xpos+50) SDL_Delay(500), blit_SDL_bmp (background, 0,
0), blit_SDL_bmp (image, xpos, 10);

NO flicker that time.

So i think that when i 'll introduce in the real game the background/sprites redrawing stuff I’ll

should pay attention to timing things… :wink: Is that right ?

Thanks again.–

  • @G.Gabriele ---------------+
    | Linux |
    ±--------------- the free philosophy -+