How to Use libgdx to compile a simple game (I)-Prototype

Source: Internet
Author: User
Tags gety libgdx

Write these articlesArticleMainly reading this series of articles: http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial

This series mainly describes how to use cocos2d to write simple games. Reading a bit is good, so I want to write a libgdx version.

This article describes how to write basic content, including displaying characters, monsters, and darts.

The final effect is as follows:

Obtain libgdx

You can download the package from the libgdx official website.CodeI downloaded version 0.98.

 

Of course, you can also get the latest version from the GIT code repository, or the previous version you are used to, such as 0.97.

Create a project

You can create libgdx projects in multiple ways. I recommend using setup-UI. Ease of use saves a lot of trouble, especially the classnotfound problem after the ADT upgrade.

If the package is downloaded, GDX-setup-UI is included by default. You can double-click it.

Fill in some basic information and select the ZIP file 0.98.zip you downloaded later. Here I only generate one desktop project and one android project.

Desktop projects facilitate debugging, while Android projects are last released. During the entire development process, I always use desktop project debugging because it is fast and easy to troubleshoot. At the same time, it is periodically tested on the android real machine.

Click Generate project and import it in eclipse.

Generally, the android project has some problems after being imported. Modify the project. properties file and androidmanifest. xml configuration file.

The running effect is as follows:

Preparations

The image used in this example is as follows:

Use GDX-texturepacker to package a large image.

The entire example uses the stage mode. So its coordinate origin is in the lower left corner. If it is drawn directly using spirte, the origin is in the upper right corner.

Copy the packaged album to the pack folder created in assets.

Then we started construction. First, we deleted the redundant code generated by setup-UI and sorted out the dartsshasha. Java file as follows:

Package COM. cnblogs. htynkn; import COM. badlogic. GDX. applicationadapter; import COM. badlogic. GDX. GDX; import COM. badlogic. GDX. graphics. gl10; import COM. badlogic. GDX. scenes. scene2d. stage; public class dartsshasha extends applicationadapter {stage; @ overridepublic void create () {stage = new stage (480,320, true);} @ overridepublic void dispose () {stage. dispose () ;}@ overridepublic void render () {GDX. GL. glclearcolor (1, 1, 1, 1); GDX. GL. glclear (gl10.gl _ color_buffer_bit); stage. act (); stage. draw ();}}

At this time, the running effect is a white screen.

Note This sentence

 
Stage = new stage (480,320, true );

Because I want the auto-adaptation of the screen to be completed automatically by stage, the coordinates can basically be written to death.

We need to add a real FPS tag first. I want this label to be displayed in the lower right corner of the screen.

Add

Labelstyle = new labelstyle (New bitmapfont (), color. black); // create a label style, and use the default black font label Label = new label ("FPS:", labelstyle); // create a label and the displayed text is FPS: label. setname ("fpslabel"); // set the label name to fpslabellabel. sety (0); // set Y to 0, which is displayed in the bottom label. setx( 480-label. gettextbounds (). width); // set the X value. The last word is displayed near the rightmost stage of the screen. addactor (Label); // Add the label to the stage

 

Update the FPS value in the render Method

 
Label Label = (Label) stage. getroot (). findactor ("fpslabel"); // obtain the label named fpslabel. settext ("FPS:" + GDX. graphics. getframespersecond (); label. setx( 480-label. gettextbounds (). width); // update the X value to ensure that the display position is correct.

 

The effect is as follows:

Add ninja

Now let's add our main character. I hope the main character will be displayed in the center of the left side of the screen. Therefore, its X value must be 0, but its Y value is not half of 320, but 160 minus half of the Image Height.

Because the x and y values we specify are relative to the lower left corner of the image. Therefore, add unnecessary or insufficient parts.

In fact, the main character is an image, and there is not much special effect, so I use the image class.

First obtain the Atlas

 
Textureatlas Atlas = new textureatlas ("pack/Default. Pack ");

 

Obtain player.png from the image list and create an image object.

 
Image man = new image (Atlas. findregion ("Player"); // obtain player.png from the image and create the image object man. setx (0); man. sety (160-man. getheight ()/2); // set the Y value to display the stage in the middle. addactor (man); // Add the main character to the stage

The effect is as follows:

Add monsters

Then let's add several monsters. Monsters should appear randomly from the right of the screen and move straight to the left of the screen.

At the same time, we also need to detect the life values of monsters or other effects, so to facilitate processing, we have set up a group to manage monsters.

Create a targetgroup class and integrate the Group class.

Package COM. cnblogs. htynkn; import COM. badlogic. GDX. graphics. g2d. textureatlas. atlasregion; import COM. badlogic. GDX. scenes. scene2d. group; import COM. badlogic. GDX. scenes. scene2d. UI. image; public class targetgroup extends group {public targetgroup (atlasregion region) {super ();}}

Because you also need to input images of monsters, the parameter atlasregion region is retained in our creation method.

The Y value of the monster is random, but cannot exceed the screen. Therefore, a random number is used for generation. Mathutils of libgdx provides related methods.

 
Int miny = 0; int Maxy = (INT) (320-region. getregionheight (); int Tempy = mathutils. Random (miny, Maxy );

There is another issue that should be noted here, that is, there should be no blocking between monsters, so you still need to judge the generated y value.

Suppose we want to generate three monsters, the code should be as follows:

 

Int Tempy = 0; For (INT I = 0; I <3; I ++) {image = new image (region); image. setx (480-image. getwidth (); // starts to judge whether the Y value meets the requirements. boolean flag = false; do {flag = false; Tempy = mathutils. random (miny, Maxy); // generate y value actor [] actors = This. getchildren (). begin (); // obtain the existing monster object for (Int J = 0; j <this. getchildren (). size; j ++) {actor tempactor = actors [J]; If (Tempy = tempactor. gety () {// If the Y value is equal, such as coincidence, discard and regenerate flag = true; break;} else if (Tempy <tempactor. gety () {// If the generated y value is smaller than the Y value of the current monster, determine whether the generated y value is suitable if (Tempy + region. getregionheight ()> = tempactor. gety () {flag = true; break;} else {// If the generated y value is greater than the Y value of the current monster, then, determine whether the IF (Tempy <= (tempactor. gety () + region. getregionheight () {flag = true; break ;}}}while (FLAG); image. sety (Tempy); this. addactor (image); // Add to group

Add

Targetgroup group = new targetgroup (ATLAS. findregion ("target"); stage. addactor (group );

The effect is as follows:

At present, monsters cannot be moved. Here we need a simple animation effect. Actions in libgdx can be used.

Considering that the monster moves horizontally, that is, the value of Y remains unchanged, and the value of X decreases.

So add a method

 
Public void addmove (actor, float time) {actor. addaction (actions. moveTo (0, actor. Gety (), time ));}

The moving speed of monsters is also random. The Code is as follows:

 
Image. sety (Tempy); this. addmove (image, mathutils. random (3f, 8f); // This. addactor (image); // Add to group

The effect is as follows:

Add weapon

Naturally, our leading role cannot fight against monsters with bare hands. Now we can add some darts.

Assume that after you touch the screen, the main character emits a dart at the touch position.

Because the number of darts is not certain, I will create a dedicated class projectilefactory here for processing.

The first reason is the creation of the darts, which is the same as that of the monster group. I still want a dedicated group for management.

Create a dedicated method to create a dart

 
Public static image createprojectile (atlasregion region, actor man, vector3 target) {image = new image (region); image. setx (man. getx () + man. getwidth ()/2); image. sety (man. gety () + man. getheight ()/2); image. addaction (actions. moveTo (target. x, target. y, 2f); // sets the return image of the dart ;}

 

 

 

 

Make some changes in the main class so that they can get the screen touch.

First, modify the class declaration

 
Public class dartsshasha extends inputadapter implements applicationlistener

 

In fact, both interfaces can be implemented, mainly because I think it is uncomfortable.

Override the touchdown method

Public Boolean touchdown (INT screenx, int screeny, int pointer, int button) {vector3 vector3 = new vector3 (screenx, screeny, 0); stage. getcamera (). unproject (vector3); // coordinate conversion projectiles. addactor (projectilefactory. createprojectile (Atlas. findregion ("projectile"), man, vector3); // Add a new dart to the dart group and return true ;}

 

Add a new group in the create method and set the input response.

 
Stage. addactor (projectiles); // Add the dart group to stage inputmultiplexer multiplexer = new inputmultiplexer (); // multiplexer for Multiple Input receivers. addprocessor (this); // Add itself as receiving multiplexer. addprocessor (stage); // Add stage GDX. input. setinputprocessor (Multiplexer); // you can specify multiple input receivers as receivers.

 

The effect is as follows:

Improved darts

Although the darts have been added, the darts have not turned... And the dart does not automatically disappear after it reaches its destination.

Now let's add the rotation effect. libgdx provides the rotateby method.

Add

 
Image. addaction (actions. Repeat (50, actions. rotateby (360, 0.5f); // set the rotation of the dart

 

This is inconvenient and the effect will not be displayed.

Now let's consider how to make the dart disappear after it reaches the goal. First, let's take a look at our image object. It contains two actions, one being rotating the action and the other moving the action.

We can check the number of actions. If there is only one action, we can determine that the darts are only rotated and have reached the destination. In this case, you can delete it.

Add a special method to determine whether the dart should be removed

 
Public static Boolean checkalive (actor projectile) {If (projectile. getactions (). size = 1) {return false;} return true ;}

Add processing code in the render Method

// Escape the dart operator [] projectile = projectiles. getchildren (). begin (); // obtain the actor array for (Int J = 0; j <projectiles. getchildren (). size; j ++) {// remove the judgment actor = projectile [J]; If (! Projectilefactory. checkalive (actor) {projectiles. removeactor (actor );}}

 

The effect is as follows:

Now the darts can be automatically removed and rotated. However, the rotation effect is strange. It does not rotate along the center, but along the lower left corner.

Reset Center

 
Image. setorigin (image. getwidth ()/2, image. getheight ()/2 );

Now everything is normal.

Collision Detection and attack

Of course, the purpose of issuing a dart is to defeat the enemy. Now we can add this function immediately.

We can take the monster into a rectangle, that is, it is effective to hit any position. The darts are represented by the heart.

Create attackalive

Public static Boolean attackalive (actor target, actor projectile) {rectangle = new rectangle (target. getx (), target. gety (), target. getwidth (), target. getheight (); // create a rectangle return rectangle. contains (projectile. getx () + projectile. getwidth ()/2, projectile. gety () + projectile. getheight ()/2); // determines whether it is in the matrix, that is, whether it is hit}

Modify in the render Method

// Start processing the dart actor [] projectile = projectiles. getchildren (). begin (); actor [] targets = targetgroup. getchildren (). begin (); For (INT I = 0; I <projectiles. getchildren (). size; I ++) {actor = projectile [I]; for (Int J = 0; j <targetgroup. getchildren (). size; j ++) {actor target = targets [J]; If (projectilefactory. attackalive (target, actor) {targetgroup. removeactor (target); projectiles. removeactor (actor); B Reak ;}}// if the Dart has flown, the cursor is excluded from Projectile = projectiles. getchildren (). begin (); For (Int J = 0; j <projectiles. getchildren (). size; j ++) {actor = projectile [J]; If (! Projectilefactory. checkalive (actor) {projectiles. removeactor (actor );}}

The effect is as follows:

Conclusion

Although the implementation is rough, there are still many problems after a closer look, and further modifications will be mentioned in the following articles. Including logical improvements, sound effects, pre-loading, background rendering, and integration of third-party social media and advertising.

You can download the corresponding demo of this article from here.

Http://pan.baidu.com/share/link? Consumer id = 328840 & UK = 4127624209

I used the 2.2 SDK to compile the SDK. The earlier version is not tested. My mobile phone is ZTE v880 and fps50.

PS: testin test result is pass rate100.00%

PS: code uploaded to GitHub, address https://github.com/htynkn/DartsShaSha

The tag of the code corresponding to the article is page 1.

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.