We are preparing to start designing the game core.
Usually, the game and desktop Windows program are different (except for desktop games such as mine), it cannot rely on message drivers because the game usually has only one picture and requires high speed update. Therefore, the game can only be driven by the clock. Most games renders a frame of screen when a clock is driven. In addition, the game needs to receive user input, handle game events (such as collision detection, etc.), may also need AI calculations, these tasks must be cleverly handled in two screen switches, therefore, an efficient and flexible scheduling The server is the core of the game process.
The scheduler consists of the clock driver and task manager.
The clock driver is responsible for providing accurate virtual time to the scheduler at need, when the virtual time passes, the game is running, when the virtual time is stopped, the game is suspended, the virtual time can be slower or fast than the real time, in order to adjust the game running speed All tasks rely on virtual times, and they don't know if the clock is suspended, which greatly simplifies the time representation and operation, we can suspend clock at any time to easily debug.
Task Manager maintains a list of tasks and knows what the next is about to run. There are 3 tasks:
Rendering Task: During the game run, the update screen is executed at the end point of time at each frame. Frame Task: Perform a task in each frame period, such as drawing the background. Time task: Trigger at the specified time point and time period, execute once or more, is deleted after completion.
The action of the scheduler is to divide the virtual time provided by the clock, divide a fixed time period (such as 20ms), in a period of time, sequentially scheduled all frame tasks and timing tasks, and finally perform the rendering task, thereby completing one Complete frame.
Why don't we use multithreading to implement these tasks, give the scheduling function to the operating system? First, there will be many tasks in the game, and create a thread for each task is not economical and inefficient. Many tasks are only executed, and a lot of overhead is spent on the creation and destruction of threads, and we are difficult to control more Thread synchronization. Second, since the operating system is usually a pre-priority multitasking, we cannot know whether an task is interrupted by another task or can be completed within one frame.
The scheduler is like simulating a thread manager, which must be very flexible. First, the scheduler sequentially executes the task in the queue, and can accurately calculate the time spending each task. If the user's hardware configuration is not high, the time to perform a complete frame cost is more than the budget, you can skip unnecessary tasks in the next frame (such as shutting off special effects, the effect task is the skipped), if you do a complete The time takes less than the budget, you can perform some tasks, such as multi-painted some special effects or more AI calculations, etc., all of which are automatically adjusted by the scheduler.
Another function of the scheduler is to achieve smooth adding and deleting tasks, and the task updates in the game are usually frequent. If you use multiple threads, the creation of threads will consume a lot of time.
The scheduler performs a frame of frame as follows:
Get a virtual time from the clock drive; execute time tasks; perform frame tasks; perform rendering tasks; get virtual times from the clock drive and calculate this frame execution time; execute cleaning tasks, including deleting an expired task from the task manager.
Since I only need to use a small API, I decided to write the kernel with J2SE, so that it is easy to debug, and the test is correct and then transplanted on the MIDP.
Reference: Marshall: "Game Programming Gems 3"