macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Basics of Offscreen Buffering
Pages: 1, 2

Lesson 3: Using Offscreen Buffers

Displaying the art file was a simple lesson to get your feet wet using the Tk image library. Now let's explore another important video game programming concept, the offscreen buffer. Our goal is to animate video game cells called sprites. When we animate directly to the game player's screen, the animation can appear a bit sloppy. To provide a smoother illusion of animation, video game programmers use a technique called offscreen buffering.

The idea behind offscreen buffering is to perform all of the game action updating on a screen that is not visible to the game player. Once your program has completed the rendering offscreen, it is then displayed to the game user. The end result is the game player never sees the rendering taking place, and this provides the illusion of smooth video game graphics.

Figure 3
Figure 3. Using offscreen buffering to animate sprites

Figure 3 helps illustrate the technique we're going to use. Using the Tk image library, we're going to load the entire art file into a Tk image we're calling sprites. We're going to create an offscreen buffer using Tk image library and call this offscreen. The image offscreen has precisely the same dimensions as our canvas .video_game_window. The goal is to render to the Tk image offscreen buffer using the sprites from the Tk image sprites. Let's take a look at the code that does this:

# create the game console window
set video_game_width 640
set video_game_height 480

canvas .video_game_window \
   -width $video_game_width -height $video_game_height -background black
pack .video_game_window -side top -expand yes -fill both

# load the art file
set filename "/game_dev/game_art.gif"
set sprites [image create photo -file $filename]

# create a blank offscreen image
set offscreen [image create photo \
-height $video_game_height -width $video_game_width]

The above code creates the video game window, with resolution 640 pixels wide by 480 pixels tall. We load our game art into the Tk image, sprites, and we create an image, offscreen, that is 640 pixels wide by 480 pixels tall, just like our video game window. We have the components we need in place to experiment with some simple animation concepts.

Copying the Background to the Offscreen Buffer

We now have two Tk images created: sprites, which contains all of our game art, and offscreen, which is blank. What needs to be accomplished now is the copying of images -- our background and sprites -- to the offscreen buffer. The copying of image pixels from one image to another is called blitting in computer graphics. Let's copy the background scene from the image sprites over to the image offscreen.

# copy the background mountains image
$offscreen copy $sprites -from 0 0 639 479 -to 0 0 639 479

Image blitting is carried out using rectangular boundaries. Our art file is 640 pixels wide by 1256 pixels tall. The background image we want to use is 640 pixels wide by 480 pixels tall, just the same size as our video game window. The top 640 by 480 pixels in the art file is the background art we want to blit to our offscreen buffer. This explains why we need -from and -to coordinates in the above statement.

To get a true feel of what we're doing, use an image editor, such as Photoshop, and open the game_art.gif file. Move the mouse around and look at the coordinates of the boundary of the background scenery. Then you'll get a true understanding of where these rectangular boundaries are and of how you obtain them from the art file.

Blitting Sprites

We have our background art copied over to the offscreen buffer and now we need a cell of animation -- our sprite. Using my image editor, I located a sprite to copy to the offscreen buffer. It is a single animation frame of the monster jumping. I am going to grab a sprite from the sprite image whose rectangular boundary in the sprite image is 256, 767, 328, 800. The sprite cell is going to be copied to the center of our game window. The character sprites are all 64 pixels wide and tall. The center of the game window is 320, 240. If I create a window for my sprite cell, I will need the following destination rectangle to blit to: 320, 303, 383, 366. The blit operation is as follows,

# copy the jumping monster sprite
$offscreen copy $sprites \
-from 265 737 328 800 -to 320 303 383 240

Figure 4
Figure 4. Sprite copied to offscreen buffer

Figure 4 shows the jumping monster sprite copied over the background image in the offscreen buffer. Our simple blit operation is done and our rendering is completed. Now we need to update the game screen.

# update the video game window 
.video_game_window create image 0 0 -image $offscreen -anchor nw

Voilà! You have your animated video game sequence. Not exactly a shippable product, but you get the idea of what needs to take place for your game animation.

The Script

# create the game console window
set video_game_width 640
set video_game_height 480

canvas .video_game_window \
   -width $video_game_width -height $video_game_height -background black
pack .video_game_window -side top -expand yes -fill both

# load the art file
set filename "/game_dev/game_art.gif"
set sprites [image create photo -file $filename]

# create a blank offscreen image
set offscreen [image create photo \
-height $video_game_height -width $video_game_width]

# copy the background mountains image
$offscreen copy $sprites -from 0 0 639 479 -to 0 0 639 479

# copy the jumping monster sprite
$offscreen copy $sprites \
-from 265 737 328 800 -to 320 303 383 240

# update the video game window 
.video_game_window create image 0 0 \
-image $offscreen -anchor nw

The Tip of the Iceberg

We've only covered the tip of the iceberg for video game animation. You have the basic concepts here for how to use an offscreen buffer. Games like Unreal and Quake Arena may use as many as two offscreen buffers when fast rendering is required. The idea behind two offscreen buffers is that you render to offscreen buffer A, while offscreen buffer B is being copied to the game display. Then offscreen buffer B is used for rendering while offscreen buffer A is copied to the game display.

Now it's time to go ahead and experiment. If you're really adventurous, I recommend that you Google search for "mega man sprites" or "sonic the hedgehog sprites." A lot of game sprites from old commercial games are all over the Web and at your disposal.

Michael J. Norton is a software engineer at Cisco Systems.


Return to the Mac DevCenter