From scratch android game programming (second edition) Chapter 7 genie, Frame Animation and Collision Detection

Source: Internet
Author: User
Tags gety
Chapter 7 genie, Frame Animation and Collision Detection

After learning from the previous chapters, you should have a preliminary concept of using bitmap and accepting user control. You can also use this knowledge to complete simple mini games. In this chapter, we will establish a basic framework for the most important part of the game-graphics processing, which is not yet a game engine, however, many of these methods can be used as a reference for readers to create their own game engines in the future. This chapter involves a lot of content, including the basic theory of 2D games and complex code. Especially for the code section, I am afraid it will take a lot of space to explain it in detail. Therefore, we will only explain the key functions, so that readers can use the Code flexibly in the future (all source code can be downloaded together with the content in this chapter ).

This framework is completely designed according to the javax. microedition. lcdui. Game package in MIDP:

Classes

Gamecanvas

Layer

Layermanager

Sprite

Tiledlayer

There are five classes in the game package. layer is an abstract class that defines graphic display. Taking our target game tank wars as an example, there are some graphic elements in the game: Our and enemy tanks, tank bullets, ground, walls, Water Bunker, etc. Although these elements have different appearances, they are essentially very similar: They all display one or more bitmaps at a specific position at a specific size. Some bitmap positions will change, and the layer defines the positions, dimensions, display, and other related functions. The reason is called layer.Layered MapThe concept is related. Let's take a look at what a layered map is: or the tank war. When our tanks are running on a common ground, the tank image must have covered the ground, in this way, we can see tanks. When a tank is traveling to the bunker, we will find that the image of the bunker covers the image of the tank ,:

In fact, in the program, we only need to first display the image of the ground, then the image of the tank, and finally the image of the bunker (the image of the bunker is hollow out) to achieve this effect, this is a layered map. Generally, we call the bottom layer the ground layer, the middle layer the Object layer, and the top layer the sky layer. We will talk about the map so much. Here we will only introduce the layering in the graphic sense to help you understand the meaning of layer. For more information about maps, see Chapter 10.

First, let's take a look at the definition of the abstract class layer:

PackageOrg. yexing. Android. Games. Common;

ImportAndroid. Graphics. Canvas;

Public Abstract ClassLayer {

IntX = 0; // the abscissa of the layer

IntY = 0; // y coordinate of the layer

IntWidth = 0; // Layer Width

IntHeight = 0; // Layer Height

BooleanVisible =True; // Whether the layer is visible

Layer (IntWidth,IntHeight ){

Setwidthimpl (width );

Setheightimpl (height );

}

/**

* Set the display position of the layer.

*

*@ ParamX

* Abscissa

*@ ParamY

* Y coordinate

*/

Public VoidSetposition (IntX,IntY ){

This. X = X;

This. Y = y;

}

/**

* Move the layer relative to the current location

*

*@ ParamDX

* Amount of X-axis variation

*@ ParamDy

* Amount of ordinate changes

*/

Public VoidMove (IntDX,IntDy ){

X + = DX;

Y + = Dy;

}

/**

* Obtain the horizontal coordinates of the layer.

*

*@ ReturnHorizontal coordinate value

*/

Public Final IntGetx (){

ReturnX;

}

/**

* Obtain the vertical coordinates of a layer.

*

*@ ReturnOrdinate Value

*/

Public Final IntGety (){

ReturnY;

}

/**

* Obtain the layer width.

*

*@ ReturnWidth value

*/

Public Final IntGetwidth (){

ReturnWidth;

}

/**

* Obtain the layer height.

*

*@ ReturnHeight

*/

Public Final IntGetheight (){

ReturnHeight;

}

/**

* Set whether the layer is visible.

*

*@ ParamVisible

* True layer visible, false layer invisible

*/

Public VoidSetvisible (BooleanVisible ){

This. Visible = visible;

}

/**

* Checks whether the layer is visible.

*

*@ ReturnTrue layer visible, false layer invisible

*/

Public Final BooleanIsvisible (){

ReturnVisible;

}

/**

* The layer must be reloaded.

*

*@ ParamC

*/

Public Abstract VoidPaint (canvas C );

/**

* Set the layer width.

*

*@ ParamWidth

*/

VoidSetwidthimpl (IntWidth ){

If(Width

Throw NewIllegalargumentexception ();

}

This. Width = width;

}

/**

* Set the layer height.

*

*@ ParamHeight

*/

VoidSetheightimpl (IntHeight ){

If(Height

Throw NewIllegalargumentexception ();

}

This. Height = height;

}

}

There are not many layers of code. You can know the functions of the layer based on the function name, mainly the setting and acquisition of the layer size and position. The most important method is the virtual method. The layer image is displayed through this method. Therefore, all classes inherited from the layer must implement this method.

Sprite inherits from the layer and adds Frame Animation, graphic transformation, and collision detection functions. Sprite is the focus of this chapter. First, let's take a look.Genie. The term Sprite is very common in 2D games. It generally refers to individual elements with independent appearances and attributes in the game. Such as the main character, NPC, treasure chest, bullets, etc. These are all genie.

Let's create a Sprite class and inherit it from the layer. When the creation is complete, the IDE prompts that the paint method must be implemented. But at this time we will find that the painting method should display those images? No. Therefore, we need to add a bitmap variable for sprite to store the image to be displayed by painting. At the same time, we need to create a constructor to initialize this bitmap variable.

PublicSprite (bitmap image ){

Super(Image. getwidth (), image. getheight ());

Initializeframes (image, image. getwidth (), image. getheight (),False);

Initcollisionrectbounds ();

This. Settransformimpl (Trans_none);

}

Although this constructor has only a few rows, it involves a lot of knowledge. Needless to say, what does initializeframes do? This should be mentionedFrame Animation. What is frame animation? For example, we can see a group of stars (4 16x16 bitmaps)

This is the case when we display these images consecutively at the same position at a certain interval.

We can see that the stars are shining, and this is frame animation. That is, several key frames in a continuous screen are obtained. These frames are displayed consecutively at a certain interval to form an animation. The initializeframes function is to initialize these key frames. So why is initialization required? Generally, multiple frames of an animation are stored in the same image file (such as stars) to save space and facilitate management ). In this way, the entire image cannot be displayed, but only a part of the image can be displayed. Therefore, we need to calculate the position of each frame on the entire image for correct display. Let's take a look at the definition of initializeframes.

Private VoidInitializeframes (bitmap image,IntFwidth,IntFheight,

BooleanMaintaincurframe)

Initializeframes first retrieves a bitmap and calculates the number of frames included in the bitmap based on the width and height of a single frame set by the user. For example, the star image we just saw (64x16 pixels) has only one frame when the width and height of a single frame are the same as those of the image. However, when the width and height of a frame are both 16 pixels, the entire image can be divided into four frames. At this time, the function calculates the vertex coordinates of each frame. For example, the vertex of the first frame is (0, 0), the vertex of the second frame is (16, 0), and so on. This function can also handle more complex situations, such:

The function saves the vertices of the calculated frames in two arrays (framecoordsx [], framecoordsy []). the next time we use the sequence number of the frame to access each frame (in the painting), we can quickly find its corresponding bitmap area.

In this sprite constructor, initializeframes uses image. getwidth () and image. getheight () as the height and width of a frame, so this Sprite is destined to have only one frame. Sprite constructor also has other styles, such

PublicSprite (bitmap image,IntFramewidth,IntFrameheight)

At this time, we can specify the width and height of the frame and define the Sprite with multiple frames.

After completing initializeframes for Frame Animation initialization, let's look at the next function, initcollisionrectbounds.

Private VoidInitcollisionrectbounds (){

Collisionrectx = 0;

Collisionrecty = 0;

Collisionrectwidth =This. Width;

Collisionrectheight =This. Height;

}

There are not many codes for this function. The name is translated as "initialize collision rectangular edge ". This leads to another important concept in the game-collision detection. In our target game tank wars, collision detection is indispensable. It is a collision when our bullets hit the enemy tank. Only a collision detection can trigger this hit event, otherwise, we will not be able to destroy the enemy's tanks. There are several kinds of Collision Detection in 2D games. The simplest ones are rectangular Collision Detection and complicated ones include polygon detection and pixel detection. Here we will only introduce the rectangle detection.

We take the rectangular outer frame of the tank and the bullet. When the two rectangles overlap, they are considered as collision. The initcollisionrectbounds function is to set the sprite rectangular box. Like the principle of the previously initialized frame, we need this function to determine the size of a frame in the image composed of multiple frames.

Now we have the last line of code in the constructor:

This. Settransformimpl (Trans_none);

This line of code sets the sprite graphics conversion method. There are eight types of transformations, which are defined as follows:

Public Static Final Int Trans_none= 0;

Public Static Final Int Trans_rot90= 5;

Public Static Final Int Trans_rot180= 3;

Public Static Final Int Trans_rot270= 6;

Public Static Final Int Trans_mirror= 2;

Public Static Final Int Trans_mirror_rot90= 7;

Public Static Final Int Trans_rj_rot180= 1;

Public Static Final Int Trans_rj_rot270= 4;

The so-called conversion is to rotate images and images, which is equivalent to adding graphics resources.

Each tank requires four groups of pictures to display the tanks that are driving in four directions. If we use the rotation and transformation function, only one set of images is required for each tank. Other images can be obtained by rotation. It should be noted that the rotation is around reference pixel. If the setrefpixelposition function is not used to set the reference point, the reference point is (0, 0) by default ). Therefore, if we use the trans_rot90 Rotation Parameter, the image should be like this.

At this time, you must note that after rotation, the return values of getx and Gety will change.

At this point, there are enough theories in this chapter. We must make a conclusion:

This chapter describes graphic display. We have created two classes of layer and sprite according to the games package in j2_m2. This section focuses on sprite-related knowledge, including ghost animation, collision detection, and Rotation Transformation. Let's take a look at a group of Sprite application instances:

In the first example, a Sprite with an animated animation is displayed on the screen.

Let's take out the source code of the previous tank and add layer. Java and Sprite. Java to the source code.

(We will introduce tiledlayer in detail when explaining the map)

Copy image bore.png to the image resource directory.

Open gameview. Java, add a Sprite type variable S, and initialize s in the constructor.

// Obtain system resources

Resources res = context. getresources ();

// Obtain the bitmap

Bitmap BMP bore = bitmapfactory.Decoderesource(Res, R. drawable.Bore);

// Create a Sprite object. Use the bitmap BMP, and the width and height of the watermark are both 16 pixels.

S =NewSprite (BMP bore, 16, 16 );

// Display at location 150,150

S. setposition (150,150 );

// Display 0th bytes, 1st bytes, and 3rd bytes

S. setframesequence (New Int[] {0, 1, 3 });

The sprite is displayed in the run function of gamethread.

Synchronized(Surfaceholder ){

C = surfaceholder. lockcanvas ();

// Display genie

S. Paint (C );

// Display the next Region

S. nextframe ();

Thread.Sleep(200 );

}

Running the program, we can see a small star flashing on the screen

In the second example, the sprite Rotation Transformation.

Since the previous use of a program, it was impossible for the stars to rotate, so here we use the system as the program icon.png.

First, we define a Sprite array.

Sprite [] Ss =NewSprite [8];

And initialize the array in the constructor.

Bitmap BMP icon = bitmapfactory.Decoderesource(Res, R. drawable.Icon);

// Create a Sprite and set it to a different rotation Mode

For(IntI = 0; I

Ss [I] =NewSprite (BMP icon );

Ss [I]. settransform (I );

}

Then it is displayed in the run function.

For(IntI = 0; I

Ss [I]. setposition (100, I * 40 );

Ss [I]. Paint (C );

}

Thread.Sleep(200 );

Run the command to check the effect.

Finally, let's take a Collision Detection example. This example is a little more complicated. Let's talk about the design concept:

This is a small game. In the 320x320 region, our tanks are in the middle. From top to bottom, there are four sides with enemy tanks attacking the middle. Our tanks can launch bullets in four directions, use the arrow keys to change the direction, and use the space key to launch the bullets. At the same time, only two bullets can be fired. There are three types of enemy tanks, including ordinary tanks, which are twice the speed of normal tanks. The speed is the same as that of normal tanks, but they must be hit twice to be destroyed.

First, we need to introduce several graphic files.

They are bullets, enemy tanks, explosion effects, and our tanks.

Declare variables in gameview

// Background color

Paint P =NewPaint ();

// Text

Paint pnttext =NewPaint ();

Sprite player; // Our tank

......

Perform initialization in the gameview constructor.

// Initialize our tanks

Player =NewSprite (bitmapfactory.Decoderesource(Res,

R. drawable.Player1), 16, 16 );

Player. setframesequence (New Int[] {0, 1 });

......

Add button RESPONSE event

Public BooleanOnkeydown (IntKeycode, keyevent event)

Finally, the game logic is completed in the run function of gamethread. For details, see the code in this chapter. The Code contains detailed comments.

This chapter sample program http://u.115.com/file/f1fd539783

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.