Author: Atlas
Source: http://www.hgechina.com/
Preface: |
I accidentally discovered the HGE Chinese community, listened to my friend's introduction, met the HGE, started to study it, and used the HGE to start making the game. Because the materials I have obtained are basically from the selfless translation of experts, I plan to make some contributions and write a basic HGE tutorial here, for the research and study of friends who are new to HGE. Some errors may occur in the tutorial. Please correct them in time. Because I am also a beginner, including C ++, and I am also a beginner, the quality of the tutorials may not be high. Please forgive me. In addition, the basic knowledge of C ++ is required to learn this tutorial, you only need to know basic knowledge about function calling, struct, enumeration, constants, variables, classes, function pointers, and so on. |
Reprinting:
This tutorial can be reproduced everywhere, so my name will not be used. However, please refer to the famous hgechina Chinese Forum: http://www.hgechina.com/. Thank you for your attention.
The compiler I use:
The compiler I use is Microsoft's Visual C ++ 2005, but VISUAL C ++ 6.0, Visual C ++ 2003, and other visual Studio C ++ compilers can all use HGE. In addition, borlandC ++ can also use HGE. In this tutorial, we will use Visual Studio 2005 to explain to you. If there are any differences in Compiler problems, please search or ask for a solution.
Chapter 1 of HGE basic Tutorial: First knowledge of HGE
C ++ has an idea. I remember what I saw when I read c ++ primer, that is, code writing and using it everywhere. So, such as DLL, lib and other code libraries that are easy to use. The idea is to package the written code, and then you can use the code written in DLL or lib by linking lib or DLL in the project, it creates unprecedented convenience for resource sharing. Therefore, HGE is also a library that implements this idea. It encapsulates DirectX for your convenience. Because using DirectX directly requires direct access to hardware, it is not conducive to entry, the emergence of HGE makes efficient Graphic programming simple.
For free:
HGE is a completely free and open-source engine, so we can use it in our own commercial or non-commercial projects. Here, we also pay tribute to HGE's authors.
Exciting moment: the first HGE program.
Create a project:
Create a Win32 project in Visual C ++ and select the Win32 console Program/Win32 console to name your project. Select a directory to save your project, and click OK-next.
Select a Windows application and select "Empty Project"/"Empty Project ". Click OK. After the project is created, the project file and code are saved in the directory you just selected.
Project Settings:
After creating the project, we need to make some settings. In the solution manager on the left, right-click your project name and choose property R]
Open the Properties window, click C/C ++, and set the additional include directory on the right to the directory where you store the HGE engine header file. Generally, after downloading the HGE engine to decompress it, in the include directory under the HGE directory.
After the configuration is complete, double-click the linker on the left, open the sub-options, click general, and select the LIB/VC/directory under the HGE directory from the additional library directory on the right.
Click "input" on the left and add dependency items to the right: HGE. lib and hgehelp. Lib.
In this way, the project is set up.
Well, we will first create a. cpp file with any name. Run the following code:
Another explanation: I will not write it. The program is very short and the comments are very clear. After compilation, you can create the first HGE program. How is it? It's easy!
Code: write: |
# Include "HGE. H" // contains the HGE header file HGE * HGE = 0; // create a pointer to the HGE class. Bool renderfunc () // draws a function. After the program starts, HGE will continuously call it. { Return false; // if the program is normal, false is always returned. If true is returned, it will be executed from system_start. } Bool framefunc () // logic function. After the program starts, HGE will call it continuously. Some logic judgment or processing can be written here. { Return false; // always return false } Int winapi winmain (hinstance, hinstance, lpstr, INT) // winmain function, program entry. { HGE = hgecreate (hge_version); // use the hgecreate function to create the HGE interface. The parameter must pass the correct hge_version, which is defined in HGE. h. HGE-> system_setstate (hge_screenwidth, 800); // set the screen width to 800 HGE-> system_setstate (hge_screenheight, 600); // set the screen height to 600 HGE-> system_setstate (hge_framefunc, framefunc); // set the logic function to framefunc. HGE-> system_setstate (hge_renderfunc, renderfunc); // you can specify renderfunc as the rendering function. HGE-> system_setstate (hge_title, "My first HGE program"); // set the window title to "my first HGE program" HGE-> system_setstate (hge_cmdwed, true); // you can specify the window mode. HGE-> system_setstate (hge_usesound, false); // set not to use sound (we will not explain the sound and image knowledge in the first program) If (HGE-> system_initiate () // use the system_initiate () method of the HGE class to check whether an error occurs during initialization. { HGE-> system_start (); // if no problem exists, use the system_start method to start the program. } HGE-> system_shutdown (); // stop the program HGE-> release (); // release the memory occupied by HGE. } |
The above code should be relatively simple and easy to understand, so I should pay attention to some small things.
I. Please note that the HGE headfile and DLL versions match each other. If the versions of the two things do not match, the program will fail. For example, if you use the header file of HGE 1.7, when the DLL of HGE 1.8 is used, an error is reported.
2. If you find that the program starts to have an HGE logo, you don't have to worry about it. It doesn't need to be paid to release it. We just need to add this sentence: h-> system_setstate (hge_showsplash, false); the HGE logo starting with the program can be removed.
3: For the returned values of framefunc and renderfunc, renderfunc must always return false. This seems to be a rule of HGE and must be written in this way, but framefunc is different. If true is returned, the program will continue to run under the HGE-> system_start (); function and run shutdown, and the program will end. Therefore, sometimes returning true is a good way to end the program, rather than throwing the system_shutdown and system_release functions anywhere.
HGE basic tutorial Chapter 2: What you can see-Image Display
Image Display is an essential part of all programs, including the Windows operating system. The code writer (programmer) displays the images drawn by the artist to the program, allows users to see program intent more intuitively. I don't want to talk much about it. Here we will talk about how to display images in HGE. I believe that, like me, most of my friends are most concerned about this part when they first came into contact with an image engine. OK. Let's take a look.
Htexture:
This is a data type defined in HGE to save the loaded image. Texture means "texture". To put it bluntly, it is an image. Of course, when your program becomes more and more complex, you will be happy to accept such a standard name. Now, we only need to know that this is a data type. As for how to load, release, and display images, we will go one by one below.
On-screen genie-hgesprite class:
Genie, a name that looks interesting, but very simple. It is a tool for rendering images. Each genie has some attributes, including its images, you can find comprehensive information about the hgesprite class in the top posts. And the code is appended.
Soul part: Code
If so much is said, it is better to use a piece of code. Similarly, I will keep the above concise and clear code style so that you can easily understand it and have a detailed comment:
In addition, replace the red part in the Code with specific parameters.
Code: write: |
# Include "HGE. H" # Include "hgesprite. H" HGE * HGE = 0; // create an HGE pointer Hgesprite * SPR; // create a Sprite class pointer Htexture Tex; // defines a texture (texture) objectBool renderfunc () // draws a function. After the program starts, HGE will continuously call it. { HGE-> gfx_beginscene (); // start Rendering HGE-> gfx_clear (0xff000000); // clear the screen in a certain color, oxff000000 is the black with a transparency of 0 SPR-> render (display position X, display position y); // display the genie at the specified position HGE-> gfx_endscene (); // end Rendering Return false; // always return false } Bool framefunc () // logic function. After the program starts, HGE will call it continuously. Some logic judgment or processing can be written here. { Return false; // if the program is normal, false is always returned. If true is returned, it will be executed from system_start. } Int winapi winmain (hinstance, hinstance, lpstr, INT) // winmain function, program entry. { HGE = hgecreate (hge_version); // use the hgecreate function to create the HGE interface. The parameter must pass the correct hge_version, which is defined in HGE. h. HGE-> system_setstate (hge_screenwidth, 800); // set the screen width to 800 HGE-> system_setstate (hge_screenheight, 600); // set the screen height to 600 HGE-> system_setstate (hge_framefunc, framefunc); // set the logic function to framefunc. HGE-> system_setstate (hge_renderfunc, renderfunc); // you can specify renderfunc as the rendering function. HGE-> system_setstate (hge_title, "show image"); // set the window title to "show image" HGE-> system_setstate (hge_cmdwed, true); // you can specify the window mode. HGE-> system_setstate (hge_usesound, false); // set not to use sound (we will not explain the sound knowledge in the second program) If (HGE-> system_initiate () // use the system_initiate () method of the HGE class to check whether an error occurs during initialization. { Tex = HGE-> texture_load ("image path and suffix, here is the relative directory, VC ++ 2005 is the DEBUG directory"); // load the image according to the path If (Tex) // check whether the image is successfully loaded SPR = new hgesprite (Tex, image display start position X, start position y, image width, Image Height); // initialize the sprite SPR and specify tex as its texture HGE-> system_start (); // if no problem exists, use the system_start method to start the program. } HGE-> texture_free (Tex); // release the texture Delete SPR; // release the genie HGE-> system_shutdown (); // stop the program HGE-> release (); // release the memory occupied by HGE. } |
After compiling and running the code, do you see that the image you specified is displayed on the screen? It's easy. The first step in game production was easily taken out by us.
Atlas sub-words: Am, exhausted me, I found that writing tutorials is not the most tiring, the most tiring is typographical ......
HGE basic tutorial Chapter 3: audible-sound playback
Heffect:
This is a data type in HGE, just like htexture, but it is used to save the loaded sound, while htexture is used to load the saved texture (image. Based on the above chapter, we know that the texture_load function is required to load textures. Therefore, for the heffect data type, there is also a function used to specifically load sound.
Effect_load Function
This is a function with a returned value. The returned value is a heffect data. Therefore, we can write: snd = effect_load ("Source/music.pdf ");
Effect_free Function
This is a function with no return value. The function name is free, that is, release. It is easy to understand that the function releases the loaded sound data, which is basically equivalent to delete.
Effect_play Function
The return value of this function is a strange data type. This data type is called hchannel. What does it mean? It means audio tracks. We know that if there are five music that play at the same time but do not affect each other, they are on five different audio tracks. Then, a sound track will be returned, so that we can operate the files played on this audio track, such as "pause, play, continue, stop.
Instance code:
The above briefly lists several basic functions to be used for sound playback. Of course, we can let the program speak out first, and then consider such things as variable adjustment, variable speed, or multi-track mixing.
Code: write: |
# Include "HGE. H" HGE * HGE = 0; // create an HGE pointer Heffect SND; // defines an effect (sound effect) object. Bool renderfunc () // draws a function. After the program starts, HGE will continuously call it. { Return false; // always return false } Bool framefunc () // logic function. After the program starts, HGE will call it continuously. Some logic judgment or processing can be written here. { If (HGE-> input_getkeystate (hgek_a) // checks whether the key is pressed. HGE-> effect_play (SND); // If the key is pressed, the music SND is played. Return false; // if the program is normal, false is always returned. If true is returned, it will be executed from system_start. } Int winapi winmain (hinstance, hinstance, lpstr, INT) // winmain function, program entry. { HGE = hgecreate (hge_version); // use the hgecreate function to create the HGE interface. The parameter must pass the correct hge_version, which is defined in HGE. h. HGE-> system_setstate (hge_screenwidth, 800); // set the screen width to 800 HGE-> system_setstate (hge_screenheight, 600); // set the screen height to 600 HGE-> system_setstate (hge_framefunc, framefunc); // set the logic function to framefunc. HGE-> system_setstate (hge_renderfunc, renderfunc); // you can specify renderfunc as the rendering function. HGE-> system_setstate (hge_title, "Playing Sound"); // set the window title to "Playing Sound" HGE-> system_setstate (hge_cmdwed, true); // you can specify the window mode. HGE-> system_setstate (hge_usesound, true); // sets the sound usage. If (HGE-> system_initiate () // use the system_initiate () method of the HGE class to check whether an error occurs during initialization. { SND = HGE-> effect_load ("sound path and suffix, here is the relative directory, VC ++ 2005 is the DEBUG directory"); // load the sound according to the path If (SND) // checks whether the sound has been loaded successfully. HGE-> system_start (); // if no problem exists, use the system_start method to start the program. } HGE-> effect_free (SND); // release Audio Resources HGE-> system_shutdown (); // stop the program HGE-> release (); // release the memory occupied by HGE. }
|
This is basically the simplest sound playing. Based on the above knowledge, I will write a few more things to pay attention to. Chapter 3 is over:
1: when using the hgesprite class, htexture, and heffect data types, do not forget to release them when they are not needed or when the program ends.
2: Check whether the resource is loaded before using the resource. Otherwise, the program will exit when the resource operation function is used. (For example, if (Tex)... in the above Code )....)
HGE basic tutorial Chapter 4: display the order of the arbitration -- Z-Buffer
Z-buffer:
Z-buffer is also known as a deep buffer. Do not think it is esoteric. I will break through its secrets one by one. In 2D space, we get used to the coordinates of the X and Y axes. A wise friend may know at a glance what Z is used for. That's right, since we have to add a zcoordinate axis to the 2D space, so its function is to determine the order of the objects in the 2D space, and block the objects in the front. Some people have said: it is not good to directly change the drawing sequence. The answer is: such a program is determined at compilation, while Z is determined at runtime, this means that the flexibility of the program will have another qualitative leap. Which one do you think is better?
Enable the third axis in the 2D space:
It is not hard to find that either hgesprite or hgefont has a method: setz (float Z); so some friends may have tried it. why not use it? You may ignore this step: Enable the Z-buffer function. How to open it? It is very easy to add the following sentence at the beginning:
HGE-> system_setstate (hge_zbuffer, true );
In this way, the Z-buffer function is enabled.
Z-buffer range:
Although Z-buffer is a float, its effective range is only between 0.0 and 1.0. I don't know why. I need to ask DirectX. In the range of 0.0-1.0, objects with smaller Z values will be drawn in front of them. For example:
Two genie, spritea and spriteb, whose Z values are 0.1 and 0.2 respectively.
In this case, no matter what the order of your render is, their coverage order is spritea covering spriteb.
Why use Z-buffer:
I was already sleepy and planned to write it again tomorrow, but I thought about it. There are not many things in this section. Let's just finish it!
Well, back to the question. In addition to the "compile-time decision" and "RunTime decision-making" mentioned just now, the use of Z-buffer has another advantage, that is, it can optimize the speed. Taking spritea and spriteb as examples,
If we use our old idea, if we want a to overwrite B, we will draw the following sequence: renderb, rendera, from far and near, from far first, near back, the close-to-close coverage of a distant image becomes an image with the correct order of coverage. Now that we have Z-buffer, I have to overturn this theory. We have to first rendera and then renderb. Why? Because when you rendera renderb again, DirectX will judge by itself that there is already a in some places, so B does not need to draw anything in those places and skip it directly, what if it is a big image of two full screens? How much FPS is saved? This method is called the reverse painter algorithm. However, the reverse painter algorithm is not used casually and must support Z-buffer. And, most importantly, the Z-buffer sequence should be set correctly. For example, if a overwrites B, the Z value of A is smaller than B, that is, a is more advanced, and then the normal draw order is reversed, we achieved our goal of optimization.
At this point, some people have asked, to what extent can we optimize it? Let me talk about my experiment. A full screen of 800*600, the first 5000 50*100 animated little people kept moving, in addition, it is a real-time refresh of all clear screens every time. I am a geforce go 7200 video card, and the FPS reaches 30 + FPS. Compared with the HGE example, I tried it on my Machine and Its villain is smaller than mine. By 2000, it was 30fps, and then it got stuck to death, of course, there has not been any optimization. In this case, the comparison has come out.
I have tried my best to understand the above. If you still cannot understand it, please reply to the question! Besides, I am also a newbie, so do not laugh!
Chapter 5 of HGE basic Tutorial: More
Common hgesprite methods -- sethotspot:
Sprite, translated as a Sprite, is a class for us to present texture. At first, I used this class in the code when the image is displayed, this is something we often use when displaying images. You may not know much about it in many ways. I am talking about a few useful methods. First of all, we know that the position of the image displayed on the screen is usually controlled by a coordinate, which is relative to the left and top edges of the screen. What about the image relative to the image? Some people may think that the coordinates of the image are the position in the upper left corner of the image relative to the image. However, some people are used to taking the center of the image as the point that determines the position, hgesprite will meet our requirements. No matter how harsh it is, it is the sethotspot method. With this method, you can set a hotspot for your genie, it not only determines the position of the display coordinate relative to the image, but also determines the center of the rotation, which is very practical.
Common hgesprite methods -- setcolor:
You can see the name and set the rendering color. If you set a red rendering color, the image is displayed with the red rendering effect, which is very simple and easy to set, it is a DWORD value, which can be understood as long. The format is 0xff00ff00. In addition to 0x, the first two FF values are transparency. Here they are hexadecimal values, the next six digits are R, G, B, and FF, which is equivalent to 255 of our average time. However, this seems too inconvenient. Then we use the system function: argb () and pass it to the function A, R, G, and B, it will return a corresponding hexadecimal number, so we can look like this: setcolor (argb (alpha, R, G, B); this looks like, is it much simpler? Well, let's talk about the two.
What if I re-load texture?
We can see that hgesprite is used together with htexture, htexture is data, and hgesprite is responsible for presenting them. What if the image is reloaded? Some friends will habitually learn how to use new and delete, that is, to change, first call HGE-> texture_free (Tex) to release texture, and then delete the genie, in fact, this is not necessary. I wrote it like this at first, but after being instructed by the webmaster vicky_lh, we can write it like this: first, when changing texture, you only need Tex = HGE-> texture_load (PATH), and do not need to be free. Second, the genie does not need to delete any more. Only when the object is uninstalled, or at the end of the program, you need to do so.
Program errors may occur, but I want to write errors to my files.
If we set logfile, HGE will write all the error records to this log. If we have our own needs, how can we intercept the error messages sent by HGE? Use this method: HGE-> system_geterrormessage (), which returns a char *, a C-style string, which is the last error message generated by the program until now. Is it convenient?
I know how to play music, but how can I get the length, pause, continue, and so on?
It's easy. You may have noticed that there are channel_getlength, channel_isplaying, and other methods. How can this problem be solved? A friend asked me this question. I will explain how to solve it. For example, if we load a heffect data and play it, we are using HGE-> effect_play () when the method is used, it will regret an hchannel data, which is the audio track data. It returns the audio track played by your music. to manipulate this music, we need to operate it by the audio track, view the code snippet (this is a code snippet that cannot be directly compiled and executed ):
Reference: |
Heffect SND; // audio data Hchannel;SND = HGE-> effect_load ("Music path"); // load music data Channel = HGE-> effect_play (SND); // play music data and record the returned audio streams using the channel. HGE-> channel_setvolume (Channel, "sound size"); // you can specify the channel track sound size. // It looks very simple! Haha, the goal is achieved! |
Ending:
There are not many things in this chapter, that is to say, some small people do not often pay attention to or are prone to mistakes, and they stay up late to write tutorials. The New Year is coming soon and you will have a happy new year.