Author: dianqingyan
PrefaceIn the previous chapter, we used the easy-to-understand movie shooting process to get a rough idea of the game engine. I hope you can understand what the engine has. Just the next day I posted my post, a friend asked me, "What is the difference between a game framework and a game engine ?". At that time, I was blinded. in a twinkling of an eye, I thought about the relationship between cars and engines. So I replied, "The framework is equivalent to a car, and the engine is equivalent to a car engine ". I don't know if you can understand it. The framework determines the role of the engine. For example, a j2-based game framework cannot run a PC game engine, just as the engine of a car and a passenger car cannot be used universally. Another friend asked me, are you talking about all the things in them a separate class? Please note that abstract composition is inseparable from actual organizations, but there is also a huge gap, just like the difference between a monkey and the Shenzhou 5 ship. The principle is the same, but they have the same huge difference. You must learn and use it.
Section 1 Scenario Manager (World)In PC, we have a large amount of resources available, including various resources. To put it bluntly, there are limits on machines themselves. Even a small file in it may be larger than our j2_game. When making a PC game, we are more concerned with the effects and running speed of the game. We can also use various special effects that we can use. As a result, the Renderer became a major play in the engine. Alas, although we have been excited for PC games for half a day, we are not doing PC games after all. We are doing a better game than PC games. Why is it even better? I dare to ask the PC game that can use 100 k heap to make the game "Tomb shadows" and "cell division" so powerful that gamers can't let it go? 100 k heap. What is this concept? I have learned computer theory and know how big it is.
In this case, we lead to the first fall from heaven: The scenario manager.We still use movies for analysis. In chapter 1, the scene in the small clip is a narrow street. Many items need to be placed in the middle. The "director" constantly asks "drama" to put it here, if the "drama" is smart enough, he must take a more time-saving and effort-saving approach, rather than a trip to the warehouse. However, there are not many places where the project itself can be placed, so how many items can be taken at a time and the utilization of the items determine the labor volume of the "drama. Similarly, we can compare the space that can be controlled by "drama" to heap, and "drama" to "item" to I/O operations in the warehouse. It is necessary to satisfy the "director"'s needs to the greatest extent, and ensure that "time" is too much wasted on the way to the "warehouse" and cannot exceed the space currently under control .... in fact, this is really difficult! Just as a woman asks her to be with her every day, and she wants to make money and rush. The problem arises. We still need to constantly explore how to save the most effort. A good solution is to first master the storage location of "items" in the "warehouse" for "drama". When necessary, you can take it out in one step to save time for searching. As for how to meet the needs of the "director", it is another matter. let's solve this problem. I believe that code is the most direct and effective method in the learning process. To prove my idea, I found an s40 version of "cell division" to study it. (If you have already read my MSN space, you can skip it below.) The first step is from our analysis, we can see that it should be "Mastering the position of items in the warehouse ", this has something to do with our file packages. We need to add some ancillary information to the file. The following is the file operation code of gameloft cell division, which is described in detail in the code. In my opinion, what method does gameloft use. I have probably guessed that it is nothing more than throwing some information about the file into a package, and then recording the data of some files in the package, such as moving the data. My package is just like this, but its disadvantage is obvious: it is necessary to load all resources at a time, not necessary. If it is not the case, load all resources at a time as needed.
To search for the resource location, CPU resources are charged. First, let's look at the first piece of gameloft Code: (decompiled)
Private Static final Boolean B (string S1)
{
Getresourceasstream = S1;
Try
{
Inputstream = I. getclass (). getresourceasstream (S1 );
System. GC (); // here we take two bytes of data and combine them into an integer. If you think about it, it is not difficult to find that this is the number of resources in this package.
Getstate = inputstream. Read () & 0xff;
Getstate + = (inputstream. Read () & 0xff) <8; // What does this mean? + Again *, dizzy. In the end, I will tell you what this is for, mainly based on the data structure.
Hasnextelement = 2 + 4 * getstate;
// Needless to say, this is the allocated space.
Getwidth = new int [getstate];
Indexof = new int [getstate]; // The difficulty is finally reached
For (INT I1 = 0; I1 <getstate; I1 ++)
{
// The following section is the most interesting. I know that I am spelling an integer, but what is the use of an integer? Let's think about it first.
Getwidth [I1] = inputstream. Read () & 0xff;
Getwidth [I1] + = (inputstream. Read () & 0xff) <8;
Getwidth [I1] + = (inputstream. Read () & 0xff) <16;
Getwidth [I1] + = (inputstream. Read () & 0xff) <24;
// It is easy to understand here, that is, there are two integer differences in indexof, * ...... is it... then let's see
If (I1! = 0)
Indexof [I1-1] = getwidth [I1]-getwidth [I1-1];
}
Inputstream. Close ();
Inputstream = NULL;
System. GC ();
}
Catch (exception)
{
Boolean flag = false;
Return flag;
}
Return true;
} This Code does not reflect that the system has loaded a package, but a mess of things. This Code is also a place that has always plagued me, obviously loading things, however, a subinteger is loaded. No way. Let's take a look at it. Maybe the integration will know what to do.
The most sensitive word is byte [], so I found this code Private Static final byte [] addrecord (INT I1)
{
// Oh, you can see that the boundary is being detected at first glance.
If (I1 <0 | I1> = getstate)
Return NULL;
// What is OBJ? Unknown
Object OBJ = NULL;
// Declare the byte array. Hey, find it.
Byte abyte0 [] = NULL;
Try
{// Load the resource getresourceasstream = S1
Inputstream = I. getclass (). getresourceasstream (getresourceasstream );
// Oh, find it. What is the getwidth array just now? Isn't it an integer? Is there something behind the entire file?
// Needless to say, the array records the file offset and the index records the size, so that everything is clear,
Inputstream. Skip (getwidth [I1] + hasnextelement );
Abyte0 = new byte [indexof [I1];
Inputstream. Read (abyte0 );
Inputstream. Close ();
Inputstream = NULL;
}
Catch (exception ){}
System. GC ();
Return abyte0;
}
From the above code, we can easily sum up the advantages of saving the size and position of all "items" first. But he also has its limitations. If you just stick it to your project, you will be miserable, if the "item" is large, such as map data, it can be said that I/O is called for a long time. If it is a small file I/O operation, it will be able to crash the mobile phone. So we should come up with a better solution, that is, let the addrecord accept an array and transfer multiple files without exceeding the heap size. I will not give the code. With the above code, you can easily make it. Maybe it's better than gameloft.
From theory to practice, let's take the first step. I do not advocate that people use people's things just as they do. Some people may say, dizzy, it's so simple, right! It was hard before you did it! As long as you care, you can't do it without thinking of it! The above problem has been solved, but how can we schedule the fastest and fastest time saving? This is an issue that allows an individual to see a demon. Generally, it depends on the needs of the project. If it is an RPG Game with a slow pace, there is no need to load a lot of resources together, only load the required data. However, a story is growing rapidly. We 'd better load "item" resources to the greatest extent possible for Air Combat games with high speed requirements. In my remarks, it seems that there are not many descriptions about the "management" of the scenario manager, and I have also noticed this. In fact, in addition to transferring "items" from the warehouse and adding their own "items" list, the more important task of the scenario manager is to put the items back to the warehouse when appropriate, release the "space" that you can control and delete it from the "item" list. So how can we implement it? This problem is also quite scratching your head. I have made some explorations, but the results are not very satisfactory. My solution is to calculate the frequency of use of each item that can be controlled by the current "drama". If it is used more than 1, if it is not used within a certain frequency, it will be-1, it is released after it is changed to 0, and the effect is not ideal. As a result, the resources are manually reclaimed after each game is completed. Although this is contrary to the purpose of the engine, it is indeed the most efficient. Khan! Although this section describes "scenario manager", you can describe the scheduling of scenario resources for more reasons. In J2EE, the so-called "management" is most likely implemented using arrays, so management is relatively weak, and resource scheduling may be composed of N functions and variables. Previously, I also mentioned the associations and gaps between theory and implementation. But it is certain that the theory drives practical development, which is the way to quickly improve the level of our own. If the theory is incorrect, the direction will be wrong and the detour will become inevitable.