670 likes | 1.62k Views
Game Programming (2D Game Programming). 2011. 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
E N D
Game Programming(2D Game Programming) 2011. 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 • Mapping) 256 different tiles, tile: 8x8 pixels each tile 8x8 = 64 = 32 B (using 16 colors) 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 배 차이) 1 2 2 2 3 2 2 3 3 2 2 4 3 4 4 4 4 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 side-scrolling), Zelda(4-way top-down scrolling)
-playerx +screenplayerx; -playery +screenplayery; 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 int screeny=yi*tile_high 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); } } }
256 pixels 64 pixels Cell (0,0) Cell (0,3) Ex: 1x4 Bitmap Template
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 • 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 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); • } • } • } • 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); • } • } • }
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(그림자 표현) • Render the background • Using the transparency index, render the stipple • Render the character • Fog(안개) • Render the background. • Render the character. • 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
// 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); } } Fire Effect
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
Animation Sequence Example 0 1 2 3 4 5 • Condor Frames • indices 0-5 • Condor Living • [0,1,0,2] • Condor Dying • [3,4,5] • Easy way of doing this: 2D data structure • state X frame sequences