Rewrite kok1 from scratch (King of Kings 1) -- (1) allows a character to run with the mouse on the map

Source: Internet
Author: User

It has been two months since fetion's bare words, because of the love for games and the dream of making fun games. The book "Windows game programming master skills" (hereinafter referred to as "master") has been read, and the demo has also been clarified. In order to truly master the 2D game technology, I decided to complete a complete demo of kok1 cutting-edge artist Qian Keng. It was also an additional demo of my resume when I stepped into the game development industry. [Advertisement] For games with loving gaming companies (Beijing) and lack of people (2D/3D game programmers), please pull me away at any time. This series of articles will record 1.1 drops in the development process of this demo. If you don't talk nonsense, go to the topic.

 

0. Current feature

(1) you can right-click a character to control the movement on the map.

(2) A map can be rolled up without exceeding the boundary.

(3) A character will have corresponding animations when standing and running

(4) When standing and running, a person will face the appropriate direction.

(5) The mouse has an animation and cannot be moved out of the window.

 

:

 

You can directly run the version> download page address <

 

1. Development Tools and languages

When learning "master", he mainly implemented it in C, and interspersed with some assembly code in performance-sensitive locations. My example was originally written in C, in addition, the author implements the practice of using more global variables. However, when the logic becomes more complex, too many functions and global variables have greatly affected the development efficiency, so I use C/C ++ to write this demo. The main objects are encapsulated by class. I don't pay too much attention to the performance. I will refactor and optimize it later. The development environment in this article is vs2010, DirectX 8.1 SDK, and directdraw7 is used in the graphics section.

 

2. Main object

The current demo mainly has the following objects:

Gamescreen-game screen is the customer area of the user window. This class provides game screen-related attributes, such as width and height, coordinates of the world map in the upper left corner, and a video controller.

Map-game map. This class provides map-related attributes, such as the width and height of each small graph block, map data array, and the number of horizontal and vertical small graph blocks. There are also map initialization (init), each frame draw (draw), release (release) methods.

Player-players: This class provides player-related attributes, such as the width and height of the player bitmap, the coordinates in the upper left corner of the screen, the coordinates in the world map, the running speed, and the target coordinates, it also provides initialization (init), drawing every frame (draw), and release (release) methods.

Bitmap24-24 bitmap. This class provides the ability to read 24-bit bitmaps, adjust the byte order to the positive order, and change it to the 32bpp format. For detailed implementation methods, see the previous two articles: pixel operations for 24-Bit Bitmap in 32bpp window mode (1) and pixel operations for 24-Bit Bitmap in 32bpp window mode (2 ).

Videomanger-video manager. This class encapsulates operations related to directdraw7, such as creating a surface, cropping a surface, and retrieving elements from a bitmap.

Mousemanager-mouse manager. This class encapsulates operations related to directinput to obtain the latest mouse information. The detailed implementation method is described in the previous article: use the relative mode of the dinput mouse to achieve absolute positioning.

Controller-operation manager, which separates user operations from game logic. Controller: processrequest () is called at each frame to process user operations and call related logical operations encapsulated by this manager, such as playermove ().

 

3. Global Process

(1) The process is very simple. The first step is to create a window and adjust the size and position of the window. Why should we adjust it? The reasons and solutions are described in this article: determine the issues in the actual user area of the window.

(2) initialize the required objects after the window is created and before the main message loop starts.

Gamescreen. init (screen_width, screen_height, hwnd, titlesize, bordersize, 100,100); <br/> gamemap. init (& gamescreen); <br/> player. init (& gamescreen); <br/> mouse. init (& gamescreen );

(3) then start the main message loop. Here, pay attention to using peekmessage and remove it after peek. Otherwise, it will not be a real-time game loop. Execute our game logic in the main message loop.

Gamescreen. video. fillsurface (gamescreen. video. lpddsoffscreen, 0); <br/> mouse. refreshdata (& gamescreen); <br/> controller. processrequest (& gamescreen, & gamemap, & player, & mouse); <br/> gamemap. draw (& gamescreen); <br/> player. draw (& gamescreen); <br/> mouse. draw (& gamescreen); <br/> gamescreen. video. flipsurface (); <br/> sleep (100 );

 

(4) release all resources after the main cycle exits.

Gamescreen. Release (); <br/> gamemap. Release (); <br/> player. Release (); <br/> mouse. Release ();

 

4. Role animation implementation

The drawing of mouse animation is very simple. Please download and read the source code. The map implementation method is to place a piece on a large surface in the video memory, which is also very simple, I will not go into details here.

 

A role animation involves eight orientations and two States (standing and running. Therefore, we need to prepare (8 * standing animation frames + 8 * running animation frames) surfaces with two animated index arrays. After preparation, we can consider that the realization of role animation cannot be to judge which of the above multiple surfaces should be written to the video memory in the current game frame. There are 3 factors:

(1) Direction-Orientation

(2) animationindex-current animation Index

(3) status-whether the character is standing or running

 

First, analyze the orientation of the person. The orientation of a character is changed only after the target moving instruction is given by the player. Therefore, you can consider modifying this value when the Controller: playermove () is executed.

Int Controller: playermove (gamescreen * Gs, map * map, player * player, mousemanager * mouse) <br/>{< br/> If (player-> MapX = player-> targetx & player-> mapy = player-> targety) <br/>{< br/> player-> Status = 0; <br/> return 1; <br/>}</P> <p> // adjust player-> direction <br/> If (player-> MapX = player-> targetx & player-> mapy <player-> targety) <br/> player-> direction = 0; <br/> else if (player-> MapX> player-> targetx & player-> mapy <player-> targety) <br/> player-> direction = 1; <br/> else if (player-> MapX> player-> targetx & player-> mapy = player-> targety) <br/> player-> direction = 2; <br/> else if (player-> MapX> player-> targetx & player-> mapy> player-> targety) <br/> player-> direction = 3; <br/> else if (player-> MapX = player-> targetx & player-> mapy> player-> targety) <br/> player-> direction = 4; <br/> else if (player-> MapX <player-> targetx & player-> mapy> player-> targety) <br/> player-> direction = 5; <br/> else if (player-> MapX <player-> targetx & player-> mapy = player-> targety) <br/> player-> direction = 6; <br/> else if (player-> MapX <player-> targetx & player-> mapy <player-> targety) <br/> player-> direction = 7; </P> <p> // adjust GS-> MapX (y) <br/> If (player-> MapX <player-> targetx) <br/>{< br/> If (player-> targetx-player-> MapX <= player-> runspeed) <br/> player-> MapX = player-> targetx; <br/> else <br/> player-> MapX + = player-> runspeed; <br/>}</P> <p> If (player-> MapX> player-> targetx) <br/>{< br/> If (player-> MapX-player-> targetx <= player-> runspeed) <br/> player-> MapX = player-> targetx; <br/> else <br/> player-> MapX-= player-> runspeed; <br/>}</P> <p> If (player-> mapy <player-> targety) <br/>{< br/> If (player-> targety-player-> mapy <= player-> runspeed) <br/> player-> mapy = player-> targety; <br/> else <br/> player-> mapy + = player-> runspeed; <br/>}</P> <p> If (player-> mapy> player-> targety) <br/>{< br/> If (player-> mapy-player-> targety <= player-> runspeed) <br/> player-> mapy = player-> targety; <br/> else <br/> player-> mapy-= player-> runspeed; <br/>}</P> <p> Gs-> MapX = player-> MapX-GS-> screenwidth/2; <br/> Gs-> mapy = player-> mapy-GS-> screenheight/2; </P> <p> return 1; <br/>}

 

Next is the character animation index. This can be processed when the character is drawn. After each painting, add 1 to the index.

 

The last is status. This is simpler and must be modified after the user makes the operation.

Int Controller: processrequest (gamescreen * Gs, map * map, player * player, mousemanager * mouse) <br/>{< br/> If (mouse-> rbutton) <br/> {<br/> player-> Status = 1; <br/> player-> targetx = GS-> MapX + mouse-> X; <br/> player-> targety = GS-> mapy + mouse-> Y; <br/> If (player-> targetx> map-> tilewidth * map-> mapwidth-GS-> screenwidth/2-1-player-> runspeed) <br/> player-> targetx = map-> tilewidth * map-> mapwidth-GS-> screenwidth/2-1-player-> runspeed; <br/> If (player-> targetx <GS-> screenwidth/2-1 + player-> runspeed) <br/> player-> targetx = GS-> screenwidth/2-1 + player-> runspeed; <br/> If (player-> targety> map-> tileheight * map-> mapheight-GS-> screenheight/2-1-player-> runspeed) <br/> player-> targety = map-> tileheight * map-> mapheight-GS-> screenheight/2-1-player-> runspeed; <br/> If (player-> targety <GS-> screenheight/2-1 + player-> runspeed) <br/> player-> targety = GS-> screenheight/2-1 + player-> runspeed; <br/>}</P> <p> If (player-> Status = 1) <br/> {<br/> playermove (GS, MAP, player, mouse); <br/>}< br/> return 1; <br/>}

 

Because all the above three factors already belong to each frame, we only need to draw the corresponding surface based on the three factors.

Int PLAYER: Draw (gamescreen * GS) <br/>{< br/> rect dest_rect = {drawx, drawy, drawx + width, drawy + height }; <br/> lpdirectdrawsurface7 drawsurface; </P> <p> If (status = 1) <br/>{< br/> If (animationindex> = runanimationdatacount) <br/> animationindex = 0; <br/> drawsurface = runsurfaces [runanimationdata [animationindex] + direction * runanimationframecount]; <br/>}< br/> else <br/> {<br/> If (animationindex> = standanimationdatacount) <br/> animationindex = 0; <br/> drawsurface = standsurfaces [standanimationdata [animationindex] + direction * standanimationframecount]; <br/>}</P> <p> ++ animationindex; <br/> Gs-> video. lpddsoffscreen-> BLT (& dest_rect, drawsurface, null, ddblt_wait | ddblt_keysrc, null); <br/> return 1; <br/>}

 

5. Summary

At this point, all functions are implemented in this issue, but there are still the following main shortcomings:

(1) currently, the movement of a role is to compare the coordinates of the current role with those of the target, and then add runspeed to both X and Y. In reality, it is to find the vector and add runspeed to the vector. In this way, the speed of role movement is more logical.

(2) because the demo images are all from the game (PS For A Long Time ~~), Therefore, the number of frames is quite low.

 

6. Download source code

> Page <resource score: 1. If you are interested or sincere, click it.

 

7. In the next phase, in addition to the rendering of the current surface image, we will also draw on the map to block the guardrail, stone and other objects of the character, as well as the path-finding logic that the character can automatically bypass the obstacle.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.