Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Scrolling and Panning CIS 487/587 Bruce R. Maxim UM-Dearborn.

Similar presentations


Presentation on theme: "1 Scrolling and Panning CIS 487/587 Bruce R. Maxim UM-Dearborn."— Presentation transcript:

1 1 Scrolling and Panning CIS 487/587 Bruce R. Maxim UM-Dearborn

2 2 How do you get the background to move as viewpoint changes? Page scrolling engines blit each off screen image onto the display as it is needed [0][0] [max X][max Y] Page 0 Page 4 Page 5Page 6Page 7 Page 1 Page 2 Page 3 Display [Page 1]

3 3 LaMothe Examples

4 4 BOB Animation #include // directX includes #include "T3DLIB1.H" // include the library header // demo globals BOB skelaton; // the player skelaton // animation sequences for bob int skelaton_anims[8][4] = { {0,1,0,2}, {0+4,1+4,0+4,2+4}, {0+8,1+8,0+8,2+8}, {0+12,1+12,0+12,2+12}, {0+16,1+16,0+16,2+16}, {0+20,1+20,0+20,2+20}, {0+24,1+24,0+24,2+24}, {0+28,1+28,0+28,2+28}, };

5 5 Game_Init( ) // initialize directdraw DDraw_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP); // load in each page of the scrolling background for (index = 0; index<3; index++) { // build up file name sprintf(filename,"LANDSCAPE%d.BMP",index+1); // load the background Load_Bitmap_File(&bitmap8bit, filename); // create and load the reactor bitmap image Create_Bitmap(&landscape[index], 0,0, 640, 480); Load_Image_Bitmap(&landscape[index],&bitmap8bit,0,0, BITMAP_EXTRACT_MODE_ABS); Unload_Bitmap_File(&bitmap8bit); } // end for index // set the palette to background image palette Set_Palette(bitmap8bit.palette);

6 6 Game_Init( ) // load in all the frames for the skelaton!!! if (!Create_BOB(&skelaton,0,0,72,74,32, // 56x72 BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_ANIM,DDSCAPS_SYSTEMMEMORY)) return(0); // load the frames in 8 directions, 4 frames each each set of frames has a walk // and a fire, frame sets are loaded in counter clockwise order looking down // from a birds eye view or the x-z plane for (int direction = 0; direction < 8; direction++) { // build up file name sprintf(filename,"QUENSP%d.BMP",direction); // skelsp // load in new bitmap file Load_Bitmap_File(&bitmap8bit,filename); Load_Frame_BOB(&skelaton,&bitmap8bit,0+direction*4,0,0,BITMAP_EXTRACT_MODE_CELL); Load_Frame_BOB(&skelaton,&bitmap8bit,1+direction*4,1,0,BITMAP_EXTRACT_MODE_CELL); Load_Frame_BOB(&skelaton,&bitmap8bit,2+direction*4,2,0,BITMAP_EXTRACT_MODE_CELL); Load_Frame_BOB(&skelaton,&bitmap8bit,3+direction*4,0,1,BITMAP_EXTRACT_MODE_CELL); // unload the bitmap file Unload_Bitmap_File(&bitmap8bit); // set the animation sequences for skelaton Load_Animation_BOB(&skelaton,direction,4,skelaton_anims[direction]); } // end for direction

7 7 Game_Init( ) // set up stating state of skelaton Set_Animation_BOB(&skelaton, 0); Set_Anim_Speed_BOB(&skelaton, 4); Set_Vel_BOB(&skelaton, 0,0); Set_Pos_BOB(&skelaton, 16, 256); // right above the floor // set clipping rectangle to screen extents so mouse cursor // doens't mess up at edges RECT screen_rect = {0,0,screen_width,screen_height}; lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect); // hide the mouse ShowCursor(FALSE);

8 8 Handling Terrain and Scrolling // global declarations // default screen size #define SCREEN_WIDTH 640 // size of screen #define SCREEN_HEIGHT 480 #define SCREEN_BPP 8 // bits per pixel #define START_GLOW_COLOR 152 // starting color index to glow #define END_GLOW_COLOR 159 // ending color index to glow #define FLOOR_COLOR 116

9 9 Game_Main( ) // test direction of motion if (KEY_DOWN(VK_RIGHT)) { // move skelaton skelaton.x+=2; dx=2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_EAST) Set_Animation_BOB(&skelaton,SKELATON_EAST); } // end if

10 10 Game_Main( ) else if (KEY_DOWN(VK_LEFT)) { // move skelaton skelaton.x-=2; dx=-2; dy=0; // set motion flag player_moving = 1; // check animation needs to change if (skelaton.curr_animation != SKELATON_WEST) Set_Animation_BOB(&skelaton,SKELATON_WEST); } // end if

11 11 Game_Main( ) // apply downward gravity to player, so player follows terrain skelaton.y+=1; // only animate if player is moving if (player_moving) { Animate_BOB(&skelaton); } // end if // lock surface, so we can scan it DDraw_Lock_Back_Surface(); // call the color scanner with FLOOR_COLOR, the color of the glowing floor // try to center the scan on the feet of the player, make sure feet stay // in contact with floor while(Color_Scan(skelaton.x+16, skelaton.y+24, skelaton.x+skelaton.width-32, skelaton.y+skelaton.height-12, FLOOR_COLOR, FLOOR_COLOR, back_buffer,back_lpitch)) { // push the skelaton upward, to keep it on the floor skelaton.y -= 1; } // end while // done, so unlock DDraw_Unlock_Back_Surface();

12 12 Game_Main( ) // draw the skelaton Draw_BOB(&skelaton, lpddsback); // this performs the animation for the glowing rock static int glow_count = 0; // increment action counter and test if (++glow_count > 5) { // rotate the colors Rotate_Colors(152,159); // reset the counter glow_count = 0; } // end if // animate the floor glow.peGreen = rand()%256; Set_Palette_Entry(FLOOR_COLOR, &glow);

13 13 Game_Main( ) // test for page flip right if (skelaton.x > SCREEN_WIDTH - (skelaton.width >> 1)) { // bump back regardless skelaton.x-=dx; // test for page flip if (curr_page < 2) { // scroll to next page to right curr_page++; // reset character to left edge of screen skelaton.x = -(skelaton.width >> 1); } // end if } // end if

14 14 Game_Main( ) else // page flip right? if (skelaton.x > 1)) { // bump back regardless skelaton.x=-(skelaton.width >> 1); // test for page flip if (curr_page > 0) { // scroll to next page to left curr_page--; // reset character to right edge of screen skelaton.x = SCREEN_WIDTH - (skelaton.width >> 1); } // end if // flip the surfaces DDraw_Flip(); // sync to 30 fps Wait_Clock(30);

15 15 BOB Functions Several functions defined to make blitting faster by using DirectDraw surfaces –Create_BOB – Destroy_BOB –Draw_BOB –Load_BOB –Animate_BOB Drawing BOB’s off screen is more efficient than using secondary memory since they are on flippable pages

16 16 BOB Process Set up DirectDraw Load 256-color map Create blank BOB Load image into BOB Draw BOB Destroy BOB when finished

17 17 Smooth Scrolling One way to achieve smooth scrolling would be creating a “huge” DirectDraw offscreen surface and use the blitter to display a sliding portion of it blitter backbuffer primary

18 18 Smooth Scrolling Another approach is to use lots of homogeneous (and small) tiles that can be fit together like building blocks You might also decide to create an index to help you decide which tile to display

19 19 Tiling | 3 3 9 8 | world [4][4] = | 1 6 6 0 | | 3 5 9 7 | | 4 6 7 9 | 0 1 2 3 4 pic Viewport contains clipped and rendered bitmaps

20 20 Tiling Demo Uses 9 bit maps for tiles (textures) World is 21 by 31 Most of the work is done in Game_Init( ) and Game_Main( )

21 21 Globals BOB textures; // texture memory int world_x = 0, world_y = 0; // current position of viewing window // use an array of string pointers, could have used an characters '0' - '9‘ // represent bitmaps 0-9 in some texture memory char *world[21] = { "111111111111111111111111111111", "100000000000000000000000000001", "100002222220000000000000077701", "100002222223333333333000077701", "100002222227777777773000070001", … "100000666666666666666666600001", "100000800000000000000000800001", "100000000000000000000000000001", "111111111111111111111111111111", };

22 22 Game_Init( ) // initialize directdraw DDraw_Init(SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP); // load in texture maps Load_Bitmap_File(&bitmap8bit, "SCROLLTEXTURES.BMP"); // set the palette to background image palette Set_Palette(bitmap8bit.palette); // create the texture bob if (!Create_BOB(&textures,0,0,64,64,10, BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,DDSCAPS_SYSTEMMEMORY)) return(0); // load each texture bitmap into the texture BOB object for (index = 0; index < NUM_TEXTURES; index++) Load_Frame_BOB(&textures,&bitmap8bit,index,index%4,index/4, BITMAP_EXTRACT_MODE_CELL); // unload the texture map bitmap Unload_Bitmap_File(&bitmap8bit); // set clipping rectangle to screen extent so mouse cursordoens't mess up at edges RECT screen_rect = {0,0,screen_width,screen_height-32}; // 32 pixels at the bottom for controls lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect);

23 23 Game_Main( ) // clear the drawing surface // check for movement (scrolling) // compute starting map indices by dividing position by size of cell start_map_x = world_x/64; // use >> 6 for speed, but this is clearer start_map_y = world_y/64; // compute end of map rectangle for best cast i.e. aligned on 64x64 boundary end_map_x = start_map_x + 10 - 1; end_map_y = start_map_y + 7 - 1; // now compute number of pixels in x,y we are within the tile offset_x = -(world_x % 64); offset_y = -(world_y % 64); // adjust end_map_x,y for offsets if (offset_x) end_map_x++; if (offset_y) end_map_y++;

24 24 Game_Main( ) int texture_x = offset_x; // set starting position of first upper lh texture int texture_y = offset_y; // draw the current window for (index_y = start_map_y; index_y <= end_map_y; index_y++) { for (index_x = start_map_x; index_x <= end_map_x; index_x++) { textures.x = texture_x; // set position to blit textures.y = texture_y; textures.curr_frame = world[index_y][index_x] - '0'; // set frame // draw the texture Draw_BOB(&textures,lpddsback); // update texture position texture_x += 64; } // end for map_x // reset x postion, update y texture_x = offset_x; texture_y += 64; } // end for map_y

25 25 Enormous Sparse Worlds What happens with huge worlds and objects that are far apart? If most of the world has a common simple background (e.g. black for space shooter) you might try sparse matrix techniques For each sector of space, you might have a list of viewable objects stored with their coordinates You then position and display each BOB when the viewport overlaps its sector coordinates

26 26 Sparse Worlds Most of the work will be done in Game_Init( ) and Game_Main( ) Here is the global world declaration // demo globals BOB generator, // the generator BOB alien, // a little alien ship BOB beacon; // a beacon BOB int world_x = 0, // current position of viewing window world_y = 0; SPARSE_OBJ world[NUM_OBJECTS_UNIVERSE]; // world consists of 256 objects placed in a 10x10 universe

27 27 Game_Init( ) // load in the generator bob image Load_Bitmap_File(&bitmap8bit, "GENS4.BMP"); // set the palette to the palette of the generators Set_Palette(bitmap8bit.palette); // create the generator bob if (!Create_BOB(&generator,0,0,72,84,4, BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,DDSCAPS_SYSTEMMEMORY)) return(0); // load each bitmap into the generator BOB object for (index = 0; index < 4; index++) Load_Frame_BOB(&generator,&bitmap8bit,index,index%4,index/4, BITMAP_EXTRACT_MODE_CELL); // set up stating state of bob Set_Animation_BOB(&generator, 0); Set_Anim_Speed_BOB(&generator, 4); // unload the map bitmap Unload_Bitmap_File(&bitmap8bit);

28 28 Game_Init( ) // load in the alien bob image Load_Bitmap_File(&bitmap8bit, "ALIENS0.BMP"); // create the alien bob if (!Create_BOB(&alien,0,0,56,30,8, BOB_ATTR_VISIBLE | BOB_ATTR_MULTI_FRAME,DDSCAPS_SYSTEMMEMORY)) return(0); // load each bitmap into the alien BOB object for (index = 0; index < 8; index++) Load_Frame_BOB(&alien,&bitmap8bit,index,index%5,index/5, BITMAP_EXTRACT_MODE_CELL); // set up stating state of bob Set_Animation_BOB(&alien, 0); Set_Anim_Speed_BOB(&alien, 4); // unload the bitmap Unload_Bitmap_File(&bitmap8bit);

29 29 Game_Init( ) // set clipping rectangle to screen extents RECT screen_rect = {0,0,screen_width,screen_height}; lpddclipper = DDraw_Attach_Clipper(lpddsback,1,&screen_rect); // hide the mouse ShowCursor(FALSE); // now generate the sparse universe for (index = 0; index < NUM_OBJECTS_UNIVERSE; index++) { // set random position world[index].x = rand()%MAX_UNIVERSE_X; world[index].y = rand()%MAX_UNIVERSE_Y; // set type world[index].type = rand()%3; // 0, 1, 2 generator, alien, beacon } // end for index

30 30 Game_Main( ) BOB_PTR object_ptr; // the object that is going to be rendered // check of user is trying to exit // start the timing clock // clear the drawing surface // check for movement (scrolling) // based on current world position which defines the viewport, i.e, // world_x, world_y to world_x+640-1, world_y+480-1, scan the object // list determine any object in that region translate it to screen // coords and render it // compute extents based on width,height x1 = x0 + width - 1; y1 = y0 + height - 1; // do trivial clip // animate all the bobs Animate_BOB(&generator); Animate_BOB(&beacon); Animate_BOB(&alien);


Download ppt "1 Scrolling and Panning CIS 487/587 Bruce R. Maxim UM-Dearborn."

Similar presentations


Ads by Google