Game Programming (2D Game Programming)

Game Programming
(2D Game Programming)
2016. Spring
2D Game Programming
■ On Older Hardware
 Computers were limited by slow CPUs and small memory
sizes
• Ex) 8-bit processor, 48KB RAM
 Many systems did not have “secondary storage”
• Ex) program loader (tapes, cartridges)
 No floating point unit
■ 2D technologies
 Still remain today
• Ex) Handhelds, game-capable telephones, interactive
television
Data Structures for 2D Games
■ Three key elements of classic 2D games
 A way to encode the character graphics
 A way to encode background images
 A way to store the game map
Sprite-Based Characters
■ Cel animation
 Each frame of each character was painted on cellophane
sheets with transparent area
■ 2D games
 Sprite
• Store each character in a rectangular, bitmapped graphic
 Detect transparent areas
 The characters blend seamlessly with the BGs
How to encode the character graphics
Sprites
■ Games that we know and love
 Small graphics that are copied into memory to put on screen
■ Xevious, Time Pilot
Sprite-Based Characters
 black and white
• Store the sprites in black and white (or any two given
colors)
• Ex) 8x8 sprites(8 Bytes), The FG and BG colors are
selected from a 16 color palette (1Byte: 4 bits+extra)
 9 Bytes per sprite
The frame buffer: 256x176 pixels  32 x 22 Sprites 
approximately 6 KB (32x22x9  6,336 Byte)
 16 colors
• Each pixel can be coded to 4 bits
• Around 4 times more space, represent much richer scenes
• Ex) 8x8 sprites  32 Bytes per sprite (=8x8x4 bits)
The frame buffer: 256x176 pixels  take up 23 KB
(32x22x32  22,528 Byte)
Sprite-Based Characters
 256 color per pixel
• These colors usually come from
 A fixed palette or a palette freely defined by the user
• Ex) 8x8 sprites  64 Bytes per sprite (=8x8x8 bits)
The frame buffer: 256x176 pixels  take up 46 KB
the palette table: 256 colors of 24bits(RGB) each
 3Byte(RGB:24bits) x 256 color = 768 Byte
 High-color sprites (16 bits per pixel)
• Two option
 Encode using 5-5-5-1
− 5 bytes  red, green, blue 1 byte  alpha
 Encode using 6-5-5
− Encode the transparency color as one of the color
combinations (a chroma key approach)
 True-color sprites (24 or 32 bits)
• Each pixel: one double word(32 bits)
 R(8), G(8), B(8), A(8)
Sprite-Based Characters
■ Transparency
 Masking approach
• Use a separate 1-bit mask to encode transparent zones
• Simple to code, but take a significant amount of memory
 Ex) a 32x32, 256 color sprite  1 KB (32x32x8 bits)
the mask  128 extra bytes (32x32x1 bits  1024 bits)
 Alternative technique
• Reserve one color in our palette as the “transparent color”
• Lower-color platform  the loss of the one color might be
unacceptable
■ Blitting
 Layering sprites onscreen (25 screen updates per second)
 “blit”  “block image transfer”
Color Key
■ Color to represent transparency
 when a tile or sprite is drawn, pixels with the color key are
ignored
 Why?
• because those pixels should not be drawn
Specify this precise
shade of blue as
color key when:
• reading file
• drawing object
Mapping Matrices
■ Mapping
 Compression technique to make data fit on the very small memory
chips
• divide our game world into a set of tiles
 Each tile represent a rectangular pattern
• no mapping) level: 5x5 screens, screen: 256x200 pixels,
palletized to 16 colors  take up 1.25MB
1
2
2
4
2
2
2
4
2
3
4
4
3
3
3
4
• Mapping) 256 different tiles, tile: 8x8 pixels
each tile  8x8 = 64 = 32 B (using 16 colors)  8x8x4 bits
tile list  32x256 = 8 KB
the size of mapping matrix  160x125 (256x5/8, 200x5/8)
whole table  160x125 = 20000 B (256 possible tiles)
total  tile list + whole table  27.5KB
(매핑하지 않은 방법에 비해 50 배 차이)
Ex) Mario Bros, Zelda, 1942…
Mapping Matrices
■ Tile Tables
 A list of background images that can be tiled and combined
using a mapping matrix to create a complete game map
 Format of Tiles
• Tile size
 Used to be powers of 2  Increased efficiency
− blitting routines  using words (32bits value)
 Whether all tiles will be the same size or not
− Classic games: equal-size tiles for easier screen
rendering
− RTS using isometric view: different tile sizes
• The color format of the tiles
 More colors the better, but more memory, more bus usage,
less performance
How to encode background images
Mapping Matrices
 Memory size of a single tile
Size = bits per pixel * wide * tall
 Number of Tiles
• More tiles means nicer graphics, more memory
• Ex) 256 tiles  unsigned, 8 bit number
300 tiles
 Using 9 bit  512 values, but hard to access
 Using a 16-bit value  take up double the memory, give
simple access
What is a tile (generally speaking)?
■ A building block of a game
board
■ Piece together tiles to create a
world
■ Why use tiles?
 to conserve memory
 graphics reuse
 dynamic content
Why else is graphics reuse important?
■ Because artist time is expensive
■ Level designers can layout a map
How can tiles be dynamic?
■ Random map generator
 adds to game re-playability
 a different game each time you play it
Identify tiles needed
■ Terrain
 grass, dirt, sand, snow, water, mountains, etc.
■
■
■
■
Walls
Roads
Buildings
etc.
■ And don’t forget terrain borders. What’s that?
2D Game Algorithms
■ 2D Game Algorithms




Screen-Based Games
Scrolling Game
Multilayered Engines
Semi-3D approach
• Parallax Scrollers
• Isometric Engines
 Page-Swap Scroller
2D Game Algorithms
■ Screen-Based Games
 The player confronts a series of screens
• screen == gameworld
 No continuity or transition between screens
• Ex) 320x240 screen using 32x32 tiles
#define tile_wide 32
#define tile_high 32
#define screen_wide 320
#define screen_high 240
int xtiles=screen_wide/tile_wide;
int ytiles=screen_high/tile_high;
for (yi=0;yi<ytiles;yi++) {
for (xi=0;xi<xtiles;xi++) {
int screenx = xi * tile_wide;
int screeny = yi * tile_high;
int tileid = mapping_matrix [yi][xi];
blit(tile_table[tileid], screenx, screeny);
}
}
Hold whole game map:
Mapping matrix [roomid] [yi] [xi]
2D Game Algorithms
■ Two- and Four-way Scrollers (= Scrolling Game)
 Create a larger than-screen gameworld that we can
continually explore from a sliding camera
 A continuum, with no screen swapping at all
 More complex than screen-based game
 Ex) 1942(2-way top-down), Super Mario Bros(2-way sidescrolling), Zelda(4-way top-down scrolling)
2D Game Algorithms
■ Scrolling Game (Complete rendering loop)
#define tile_wide 32
#define tile_high 32
#define screen_wide 320
#define screen_high 240
tileplayerx= playerx/tile_wide
tileplayery= playery/tile_high
int xtiles=screen_wide/tile_wide;
int ytiles=screen_high/tile_high;
int beginx= tileplayerx – xtiles/2;
int beginy= tileplayery – ytiles/2;
int endx= tileplayerx + xtiles/2;
int endy= tileplayery + ytiles/2;
for (yi=beginy;yi<endy;yi++){
for (xi=beginx;xi<endx;xi++) {
int screenx=xi*tile_wide -playerx +screenplayerx;
int screeny=yi*tile_high -playery +screenplayery;
int tileid=mapping_matrix [yi][xi];
blit(tile_table[tileid],screenx,screeny);
}
}
player
Gameworld
2D Game Algorithms
■ Multilayered Engines
 Use several mapping matrices to encode the game map
• Need to combine tiles
• Need to move objects over the BG
• Want to give the illusion of depth
• Ex) BG: terrains, another: trees
for (yi=beginy; yi<endy; yi++){
for (xi=beginx; xi<endx; xi++) {
int screenx=xi*tile_wide-playerx+screenplayerx;
int screeny=yi*tile_high-playery+screenplayery;
for (layeri=0;layeri<numlayers;layeri++) {
int tileid=mapping_matrix [layeri][yi][xi];
if (tileid>0) blit(tile_table[tileid],screenx,screeny);
}
}
}
Ex: 1x4 Bitmap Template
256
pixels
64
pixels
Cell (0,0)
Cell (0,3)
Multi-layering Tiles
■ Most worlds require layering. Ex:
 place grass
 place flowers on grass
 place cloud over flowers
■ Other common objects:
 trees
 rocks
 treasure
■ To edit:
 use multiple tiles, one for each layer
 map file may join & order tiles
2D Game Algorithms
■ Semi-3D approach
 Parallax Scrollers
• The illusion of a third dimension by simulating depth
 Storing depth-layered tiles
 Moving them at different speeds to convey a sense of depth
if (pressed the right cursor)
for (layeri=0;layeri<numlayers;layeri++)
playerx[layeri]+=1*(layeri+1);
for (layeri=0;layeri<numlayers;layeri++) {
for (yi=beginy; yi<endy; yi++){
for (xi=beginx; xi<endx; xi++) {
int screenx=xi*tile_wide-playerx[layeri]-screenplayerx;
int screeny=yi*tile_high-playery[layeri]-screenplayery;
int tileid=mapping_matrix [layeri][yi][xi];
if (tileid>0) blit(tile_table[tileid],screenx,screeny);
}
}
}
2D Game Algorithms
■ Semi-3D approach
 Parallax Scrollers
• The illusion of a third dimension by simulating depth
 Storing depth-layered tiles
 Moving them at different speeds to convey a sense of depth
2D Game Algorithms
 Isometric Engines
• Representing an object from raised viewpoint (rotate 45)
 Parallel projection  do not suffer from distortion
• Tiles for an isometric(같은크기) are rhomboids (평행사변형)
 Tend to be wider than they are high
• Ex) Diablo
2D Game Algorithms
■ Page-Swap Scroller
 Without being restricted to a closed set of tiles
• Sector should be loaded into main memory
• The rest are stored secondary media
 Will be swapped into MM as needed
 The mapper resembles a cache memory
 Improve performance
• The velocity of the player ??
Special Effects
■
■
■
■
Palette Effects
Stippling Effects
Glenzing
Fire
Palette Effects
■ Palette Effects
 Implemented by manipulating, not the screen itself, but the
hardware color palette
• Altering the palette was much faster than having to write
to the frame buffer (not depend on the screen resolution)
■ fade in/out
void FadeOut()
{
unsigned char r,g,b;
for (int isteps=0;isteps<64;isteps++)
{
WaitVSync();
for (int ipal=0;ipal<256;ipal++) {
GetPaletteEntry(ipal,r,g,b);
if (r>0) r--;
if (g>0) g--;
if (b>0) b--;
SetPaletteEntry(ipal,r,g,b);
}
}
}
void FadeIn()
{
unsigned char r, g, b;
for (int isteps=0;isteps<64;isteps++)
{
WaitVSync();
for (int ipal=0;ipal<256;ipal++) {
GetPaletteEntry(ipal,r,g,b);
if (r<palette[ipal].r) r++;
if (g<palette[ipal].g) g++;
if (b<palette[ipal].b) b++;
SetPaletteEntry(ipal, r, g, b);
}
}
}
palette rotation
■ if we change some palette entries, we can produce
color changes in sprites that look like real animation.
 Ex) water, lava, fire, neon glows
• Semaphore(신호등)
 four palette entries
 1: Yellow
 2: Black
 3: Green walking char.
 4: Red stop sign
• Animated water(물결)
 Reserve six palettes
 store different hue of water color (Deep blue  light blue)
Stippling Effects
■ Stipple
 A simple patterned texture that combines one color (generally black
or grey) with the transparency index
■ Illusion of shadow(그림자 표현)
1. Render the background
2. Using the transparency index, render the stipple
3. Render the character
■ Fog(안개)
1. Render the background.
2. Render the character.
3. Using the transparency index, render the stipple.
■ illuminate parts of the scene
 Stippling pattern must be colored as the light source (yellow, orange)
■ fog-of-war techniques
 Where only the part of the map where the player has actually
explored is shown, and the rest is covered in fog
• The closer the area, the less dense the fog
Glenzing
■ Stippling
 Nothing but a poor man’s transparency
■ Glenzing
 Really mix colors as if we were painting a partially transparent
object
 Convert a color interpolation into a palette value interpolation
 Better than those achieved by simple stippling
Color = Color_transparent*opacity + Color_opaque*(1-opacity)
Fire Effect
■ Fire Effect
 Can be an animated sprite
 Using 2D particle system
 Using a cellular automata on the frame buffer
• Automata consisting of a number of cells running in
parallel whose behavior is governed by neighboring cells
• Ex) simulate life, create fire
 Fire emitter
− pure white fire color  yellow, orange, red, black
color(x,y) = (color(x,y+1) + color(x+1,y+1) + color(x-1,y+1))/3
Expensive effect: need the whole screen to be recalculated at each frame
 Confine to a specific area
Fire Effect
// generate new sparks
for (int i=0;i<SCREENX/2;i++) {
int x=rand()%SCREENX;
int col=rand()%25;
PutPixel(x,SCREENY-1,col);
}
// emitted by the bottom of the screen
// recompute fire
for (int ix=0;ix<SCREENX;ix++) {
for (int iy=0;iy<SCREENY;iy++){
unsigned char col;
col = (GetPixel(ix-1,iy+1) + GetPixel(ix,iy+1) + GetPixel(ix+1,iy+1)) / 3;
PutPixel (ix,iy,col);
}
}
Animating Sprites
■ As a sprite moves, we must display it using different
“frames of animation”
 this means slightly different images
■ Works just like traditional cartoon animation
■ Animation must be:
 tied to timer
 tied to movement (for main character)
Sprite Data
■ Suppose we wanted to draw an animated Mario, what data might
we need?










position
z-order (huh?)
speed
direction
Texture(s)
• array of Textures if using individual images
• each index represents a frame of animation
possible states of sprite
current state of sprite (standing, running, jumping, dying, etc.)
animation sequences for different states. Huh?
current frame being displayed (an index)
animation speed
0
Animation Sequence Example
1
■ Condor Frames
 indices 0-5
2
■ Condor Living
 [0,1,0,2]
■ Condor Dying
3
 [3,4,5]
■ Easy way of doing this: 2D data structure
4
 state X frame sequences
5