Android game guidance (3. Model Management of the graphic engine)
In the previous section, we built a world of our own scenarios. Some basic elements can be drawn internally. I would like to talk about Paster in this section. Let's take a break and let us have an episode, think about model management and game engine-related things. These things are very similar to cocos2d, probably because cocos2d is commonly used in the iPhone. We can use mature and successful things.
Download source code: Click me
Table of contents
- 1. Object-oriented
- 2 Model parent-child chain: Tree
- Layer-3 Screen Management
- 4 game engines
- 5. Code Implementation
- 6. Draw an android Robot
1. Object-oriented
Based on the progress of the tutorial, if we want to meet several primitive models, we need to explicitly draw them in ondrawframe. Based on the object-oriented thinking, we know that the model we draw is only a rendering unit, and our ondrawframe operation is only an OpenGL access. Therefore, based on the interface, one of our rendering model classes was born.
2 Model parent-child chain: Tree
You may say that too many models to be rendered are too messy. Think of this, it means that you are still a qualified programmer and have a perfect attachment. Instead of manual management, let the program manage it on its own. Think about it. If it is a complex model, such as a person, it is composed of many small models, such as the head, arm, leg, and so on, and the head has a nose, ears, mouth and other components. Haha, This is a tree structure. Let's look at the structural features:
- A parent node has 0 or more child nodes.
- One byte point can have at most one parent node.
The parent-child relationship of an object is as follows:
Currently, most games adopt tree-like model management and are also highlighted in the GUI system. With tree management, we can easily install a type of nose on different people's heads without repeatedly inventing the wheel.
Now, the form in our ondrawframe is like this. The model object on the right is an encapsulated unit and may contain many internal subnodes.
Layer-3 Screen Management
In the end, we need to plot the model to the screen. Let's think about the following questions:
- Many models need to be rendered on the screen. For example, a person walks in the grassland. In summary, there are human models, grassland, sun, and rivers.
- The models on the screen can be classified into different categories. The grassland, the sun, and the river are backgrounds. The people we control are the foreground.
As a result, layer-based management comes. Our rendering root node is called scene, which is divided into different layers, and the specific model is mounted on each layer. See it, (note: From the cocos2d-python Documentation)
To highlight an ondrawframe interface, scene and layer are also rendering model units.
Let's take a look at the effect of layer-based Screen Management. After we add all the things we want to draw to a scenario, we can directly perform glvisit () on this scenario node:
Each model highlights a glvisit (). The main function of this function is to call its own drawing function draw () and then call glvisit () One by one for each byte ().
4 game engines
The design of a game engine follows the principle that the logic should be separated from the rendering, and OpenGL should be minimized at the underlying level. The upper layer should not touch the underlying API whenever possible, try to make the core code principle Android system APIs. The minimum set of components should contain the following types:
- Graphics engine, which we discussed above
- In the event Dispatch System, mobile apps are independent of touch events (in fact, they are also a scheduler)
- In addition to touch time, the game also has its own time events, such as animations.
Other components that may be used include the collision detection system, input system, and path search algorithm.
The richness of the game engine will be gradually added in later tutorials. Today, this section is the beginning, with a simple graphics engine, the functions and interfaces will also be enriched as needed. To facilitate relief from Android-related code, add a single-piece gamesystem class:
Public class gamesystem {Private Static gamesystem instance _ = new gamesystem (); public static gamesystem getinstance () {return instance _ ;}// scenario private globject runningscene _ = NULL; private int width = 0; // OpenGL scenario size private int Height = 0; Public void setwindowsize (INT width, int height) {This. width = width; this. height = height;} public int get1_wwidth () {return this. width;} public Int getaskwheight () {return this. height;} // set the scenario public void setscene (globject scene) {runningscene _ = scene;} // public void glvisit (gl10 GL) {If (runningscene _! = NULL) runningscene _. glvisit (GL );}}
We can insert it to three places in the android code:
- In the oncreate method of activity, set windowsize: setwindowsize. Set the initial scenario setscene.
- In Renderer's ondrawframe method, glvisit is used to access gamesystem game scenarios.
5. Code Implementation
In addition to the interface above, the coordinates are added on the screen, and the relative coordinates are stored. The coordinates are used to describe the model position relative to the parent node. This coordinate point cannot be understood as the vertex coordinate in the vertex array. In this way, you can move the paint brush to the coordinate point and draw it based on the vertex array. The code is long and omitted. You can download the source code.
Public class globject {protected globject parent = NULL; // parent node protected comment list <globject> Children = new comment list <globject> (); // byte point private Boolean visible = true; // accessible (for GL) float x = 0; float y = 0; // The Parent-Child Link Management Public void addchild (globject OBJ) {children. add (OBJ); obj. parent = This;} public void removechild (globject OBJ) {obj. parent = NULL; children. remove (OBJ);} public void setparen T (globject p) {If (parent! = NULL) parent. removechild (this); p. addchild (p);} public globject getparent () {return parent;} // coordinate float getx () {return X;} float Gety () {return y ;} void setxy (float X, float y) {This. X = x; this. y = y;} // visible public void setvisible (Boolean v) {visible = true;} public Boolean getvisible () {return visible ;} // external GL access interface public void glvisit (gl10 GL) {If (! Visible) return; GL. glpushmatrix (); GL. gltranslatef (X, Y, 0); this. draw (GL); For (globject child: Children) child. glvisit (GL); GL. glpopmatrix ();} // draw itself: subclass override this method public void draw (gl10 GL) {}////////////////////////////////////// //////////////////////////////////////// /////////// some common elements for drawing // draw a square public static void drawquater (gl10 GL, float left, float top, float right, float bottom) {// slightly} // draw a triangle public static void drawtriangle (gl10 GL, float onex, float oney, float twox, float twoy, float threex, float threey) {// slightly} // draw a sector public static void drawarc (gl10 GL, float length, float startangle, float sweepangle) {// omitted} // draw a straight line public static void drawline (gl10 GL, float onex, float oney, float twox, float twoy) {// omitted }}
6. Draw an android Robot
The code is still in the past, drawing elements, but after the baptism of this chapter, code encapsulation and scalability have improved. A robot consists of the following structures:
- Body
- Header
- Leg * 2
- Arm * 2
- Set the initial game scenario for gamesystem:
Public class glgame extends activity {/** called when the activity is first created. */@ override public void oncreate (bundle savedinstancestate ){//.... Slightly // initialize the game system ://... screen size {displaymetrics dm = new displaymetrics (); getwindowmanager (). getdefadisplay display (). getmetrics (DM); gamesystem. getinstance (). setwindowsize (DM. widthpixels, DM. heightpixels );}//... set the initial scenario gamesystem. getinstance (). setscene (New androidscene ());//..... setcontentview code }}
2. Add a scenario class androidscene as our canvas on which we will draw robots
Public class androidscene extends globject {androidrobot robot = new androidrobot (); Public androidscene () {super (); // draw a robot in the center of the screen. setxy (gamesystem. getinstance (). getdomainwwidth ()/2, gamesystem. getinstance (). getwindowheight ()/2); addchild (robot );}}
3. Add a robot rendering model androidrobot. The code is too long and collapsed:
Public class androidrobot extends globject {glcolor color = new glcolor (); // a simple class public androidrobot () {super () that encapsulates the four elements of rgba (); // The color is green color. set (0, 1, 0); // body // 2 arms // 2 leg // head: 2 eyes, 2 line, face arm arms [] = new arm [2]; leg legs [] = new leg [2]; head; body; // arms for building body parts [0] = new arm (); arms [1] = new arm (); legs [0] = new leg (); legs [1] = new leg (); Head = new head (); body = new body (); // adjust the body part position body. setxy (0, 0); // The body is the center head. setxy (0,-65); arms [0]. setxy (-55,0); arms [1]. setxy (55, 0); legs [0]. setxy (-20, 60); legs [1]. setxy (20, 60); // install the body part addchild (body); addchild (head); addchild (arms [0]); addchild (arms [1]); addchild (legs [0]); addchild (legs [1]);} public void draw (gl10 GL) {// set the color to GL. glcolor4f (color. red, color. green, color. blue, color. alpha);} // arm class arm extends globject {public void draw (gl10 GL) {drawquater (GL,-10,-68, 10, 50 );}} // leg class leg extends globject {public void draw (gl10 GL) {drawquater (GL,-15,0, 15, 40 );}} // body class body extends globject {public void draw (gl10 GL) {drawquater (GL,-40,-60, 40, 60 );}} // header class head extends globject {public head () {eye eyes [] = new eye [2]; eyes [0] = new eye (); eyes [1] = new eye (); eyes [0]. setxy (-20,-10); eyes [1]. setxy (20,-10); addchild (new face (); addchild (new antenna (); addchild (eyes [0]); addchild (eyes [1]);} // eye class eye extends globject {public void draw (gl10 GL) {// eye hole GL. glcolor4f (0, 0, 0, 0); drawquater (GL,-4,-4, 4); // restores the color GL. glcolor4f (color. red, color. green, color. blue, color. alpha) ;}}// face class face extends globject {public void draw (gl10 GL) {drawarc (GL, 40, 0,180 );}} // antenna class antenna extends globject {public void draw (gl10 GL) {drawline (GL, 0, 0,-50,-50); drawline (GL, 0, 0, 50, -50 );}}}}
Well, this time I am here to learn happily.