Porcelated tiles in DirectX: Part 2
By Martin Estevao
Translation: codehunter
Readyers, everyone, welcome to new chapters! In the second part I will continue to discuss the topic of porcelain tiles on the basis of the first part. Due to the lack of time in this article, I only discuss the problem of smoothed scrolling. This may disappoint some people in you, but please understand me, I am a student, I have my own things, my time is growing, I am sorry. Smooth Scroll you to remember the first part of the content, we set a simple tile engine, which uses a 2-dimensional array and paste the tile to the screen with DirectDraw's BLTfast (). We can't just! We will join your game with a large map with scrolling effect. Don't think this step is awkward. Once you understand this principle, it is still very easy. Because some people in us don't understand "smooth scrolling", I have to talk about a tile-based background based on the movement of the movement behind the elf. Although the protagonist (or all what you want to control in your game) is about to move from a plaid to another, it can be drawn to the same location of the screen. Do you know super Marila? It is a very well-smooth scrolling example, I don't want to implement it? The key to the principle is to save the current trajectory of the large map so that which tiles to be drawn to the screen. For example, suppose to press the right arrow keys in the keyboard, the fake of the game will move two tiles to the right. In your painted tile function, you can recognize this change, and draw a series of tiles that have been switched for two tiles, or move the game background to the right 64 pixels. As a result, your elf looks like it has changed. If this explanation is difficult to understand, I am reported, but I hope that you can understand clearly so that we can continue. Next we will create two variables to store changes in the map. These two variables will be used in the final version of the Draw_TILES () function to determine which tiles are drawn to the screen. The principle is these, if you have some ideas about your game, join these technologies to your code. Settings We must define some constants before we override the draw_tiles ().
#define tile_size 32
#define world_size z 20
#define world_sizey 20
#define screen_sizex 12
#define screen_sizey 12
Here we define the size of the tiles of 32 pixels, the size of the map is 20 * 20 tiles, the screen size is 12 * 12 tiles. In this way, we have 12 * 12 (144) tiles to be displayed on the screen at the same time, at the same time, 20 * 20 tiles in my array. We must establish a larger map than the screen visible area, which we can identify the rolling behavior. Note: You set up the DirectX application, which will make you could not see the entire screen filled with tiles. INT World_camerax = 0; I NT World_cameray = 0; I am in principle two variables World_Camerax and World_CameRay mentioned in that season, is to track the current location in the map. They will decide which tiles are to be drawn to the screen. Now, we initialize these two variables of 0, so our current location is (0, 0), or at the top of the map / array. World_camerax will store X position, or to 0 points X-axis distance. World_cameray will store the position of Y, or the Y-axis distance from 0 points. If you have any questions, please review the principle section. If you still have difficulties, then it may be my fault. :) The last thing to do is to define a new map lattice (20 * 20 tiles), which is mostly mostly the map in the wizard. Char map [world_sizey] [world_sizex] = {
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2}, {2, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2),
{2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2},};
Beautiful map plaid is here, with a small message. :) Smooth draws these tiles Now we rewrite draw_tiles () this process
Void Draw_Tiles (Void)
{
Int tile;
INT X, Y;
INT scroll_x, scroll_y; // (new)
INT offset_x, offset_y; // (new)
Rect tile_src;
TILE is used to determine the map [scroll_y] [scroll_x] value, for example, when we traverse the map array, MAP [scroll_y] [scroll_x] will have ID # = 1 or 2. X, Y These two variables determine the tiles in the exact location. Rect tile_src is used to specify the position of each tile corresponding to the image, pointing to the offset of the screen. Scroll_x and scroll_y variables will serve the function than the wizard one, the Y variable service is the same as the Draw_TILES () function. You may ask "Why no longer use x, y?" Asked. The answer is that some of the calculations on the map must use the x, y variable, as shown in the following step, the calculated result will be saved in scroll_x and scroll_y so that we can use the original value of X, Y to draw the tile. OFFSET_X and OFFSET_Y are used to decide to draw the precise position of the tile. These two variables are core variables that smoothed.
FOR (y = 0; y { For (x = 0; x { // (New) Scroll_x = x (world_camerax / tile_size); Scroll_y = y (world_cameray / tile_size); // (New) OFFSET_X = World_Camerax & (Tile_Size - 1); OFFSET_Y = World_CameRay & (TILE_SIZE - 1); Tile = MAP [scroll_y] [scroll_x]; OK, new code is here. First, use a nested dual cycle to spread our map to get the ID # value of each tile. Next, set the scroll_x, the scroll_y value is x, y plus the number of tiles that have been rolled out so far. Then set the drawing offset, what we want to do is to reduce the offset of the final position of the tile. TILE_SRC.LEFT = (TILE - 1) * TILE_SIZE; TILE_SRC.TOP = 0; TILE_SRC.right = Tile * Tile_size; TILE_SRC.BOTTOM = TILE_SIZE; The setting of TILE_SRC RECT depends on the ID stored in MAP [scroll_y] [scroll_x]. // (MODIFIED) BLTFAST ((x * tile_size) - offset_x, (Y * Tile_Size) - Offset_y, lpddsoffscreen, & tile_src, null; } } } Now let's draw a tile to the exact location of the screen, multiplied by the value of X, Y by 32 and then subtract the offset. I use lpddsoffscreen as the name of the DirectX surface, and your surface can use a different name. Conclusion We already have a smooth scrolling engine, then how do we use him in the game? It is very easy. You just do the following things: if (keypress_right) { World_camerax = 8; } IF (KeyPress_up) { World_cameray = 8; } Players can now control the scrolling of the map with the keyboard. Of course, there are still many jobs to do, but I am sure that you can solve it. :) Note: In this Kepress_right, you can use the DirectInput or Win32 API input function. If you find some errors or bugs in the article, please tell me. Not reprint without the same way. Part1