By AlexQ ([email protected])

Project hosting here:GitHub

What's libGDX?
libGDX is a cross-platform Java game development framework based on OpenGL (ES) that works on Windows, Linux, Mac OS X, Android, your WebGL enabled browser and iOS.Copy the code

Gifs are large and may take a long time to load or to view the video directly

Introduction:libGDX

LibGDX is a well-known cross-platform game development engine. Here are a few things we'll cover: Why we chose libGDX to develop particle effects for the Android FrameWork (why not cocoa2D); 2. How do we introduce a game development engine into our native Android App without any friction? 3. What problems we encountered during the introduction and how to solve them? 4. Are there any side effects and how should we treat them? 5. Recommend 6Copy the code


Choose libGDX

Meet libGDX

The reason for my work is that I wanted to make a special effect of fireworks. The original plan was to play Gif or draw frame animation by myself. However, the drawback of this plan is that the animation effect is rigid, the playing elements cannot be replaced, and the occupation of resources for space is probably a big hidden danger in the future. Then consider the particle effect code to achieve, particle effect is easier to find some Java layer implementation of the case or framework, but for computing density of such a large particle effect, the effect is terrible, poor some of the machine (CPU performance) above the effect is worse than no. The next step is to find a high performance platform (so layer implementation, drawing directly with OpenGL and so on). Particle effects are common in games, shooting bullets, shooting flames, floating clouds are all particles. So the question is…

Choose libGDX

The mainstream 2D game development engine is Cocoa2D, but what do we need right now, and can it help us get there? We need to display a particle effect in the FrameWork of an Android APP. Cocoa2D can’t do that. It implements all the UI and everything in its own ecosystem. In terms of presentation, we want to start a game with a black interface, and then continue with all the UI and interoperation work, which is not useful (although this is not Cocoa, they are not used for this).

We searched for her and found libGDX (is there any other way to implement it?

Episode: libGDX learning

Insert a little bit here, how do we learn libGDX? Is it expensive? How do you get started? First of all, libGDX is a complete game development engine. As you can imagine, the code is quite large. https://github.com/libgdx/libgdx.git is probably closer to 180 m, long wiki documentation is at least a few hundred knowledge, to do their own game development (no matter what platform, used what engine), many concepts should be very familiar with, Only mobile application development experience of the us, but for a lot of knowledge point is don’t have to dig, the full text books and video tutorials of the most recommended below is all in Chinese, for a comprehensive understanding, mining libGDX purposes friend can taste carefully, I was a zero base took about 3 weeks or so of free time to master the knowledge in the books and video tutorials, roughly I think it’s worth it as a developer to find a high-performance technology that’s hard to replace. Check out my other short introduction to libGDX.

performance

LibGDX implements particle effects, both computations (running on C) and drawing (OpenGL) are extremely efficient.

Let’s take the example of running CrazyMode in the sample code on the Mi Note:

Memery performance:

CPU performance:

Again, take running CrazyMode in the sample code on Nexus5:

Memery performance:

CPU performance:

Core knowledge

If you are interested in the examples in this article, as well as technical points, so many relatively simple, first of all, please carefully look at the video tutorial, especially the actor, stage and resource loaders, sound effects, the Action class, the particle editor this several parts, on the whole, there is a understanding, in addition to read master wiki above a few key points:

*The application framework

*2d particle effects

*2D Particle Editor

Leading to thelibGDX

Can libGDX give us what we want? Can. Despite the long wiki, API, javadoc, libGDX provides two classes (AndroidApplication & AndroidFragmentApplication), let’s see

public class AndroidApplication extends Activity implements         AndroidApplicationBase {
...
}Copy the code

.

public class AndroidFragmentApplication extends Fragment implements AndroidApplicationBase {
...
}Copy the code

Ok, look at their base class Activity&Fragment, which is our gateway between the Android FrameWork and the libGDX world.

  • AndroidApplication can create a separate Activity, imagine what you can do with it, I guess you can make a cool start screen page, this can be a common parallax animation, video and so on a powerful supplement, why? Code control, ever-changing ah.
  • AndroidFragmentApplication may establish a fragment, can take him to do the special effects, blend in libGDX UI layer to the Android App.

Introduced into the APP to achieve special effects

The last bit of ‘Here comes the hero libGDX’ is a little bit of a lead-in to just inheriting them and wanting to blend in without disobedience?

so young so simple.

So what should be done? Let’s take a look at the pseudocode and take a quick look at the structure of the code.

It may be difficult to read the code here because it ignores a lot of business code and non-core code, and it is not exactly the same as in the demo. Take a quick look at the structure of the code

 public class GiftParticleFragment extends AndroidFragmentApplication implements InputProcessor {

//hide bussiness logic code

.

Private GiftParticleEffectView // particleEffectView; //libGDX private LinearLayout mContainer; Private Boolean isDestorying = false;

/ @override public void onPause() {super.onpause (); / @override public void onPause() {super.onpause (); if (! isDestorying) super.onResume(); }

@Nullable

@Override

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

m_view = inflater.inflate(R.layout.lf_layout_giftparticle, null);

ParticleEffectView = new GiftParticleEffectView(); View effectview = CreateGLAlpha(particleEffectView); mContainer = (LinearLayout) m_view.findViewById(R.id.container); mContainer.addView(effectview); / / set the input and mobile phone back key to monitor etf has input the setInputProcessor (this); Gdx.input.setCatchBackKey(true);

return m_view;

}

Private View CreateGLAlpha(ApplicationListener Application) {// GLSurfaceView transparent correlation AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration(); cfg.r = cfg.g = cfg.b = cfg.a = 8;

// initializeForView = initializeForView(application, CFG); GLSurfaceView glView = (GLSurfaceView) graphics.getView(); glView.getHolder().setFormat(PixelFormat.TRANSLUCENT); glView.setZOrderMediaOverlay(true); glView.setZOrderOnTop(true); }

return view; }}

Copy the code

XML configuration super simple <? The XML version = "1.0" encoding = "utf-8"? > <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:id="@+id/container" android:layout_margin="0dp" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" ></LinearLayout> </LinearLayout>Copy the code

 

/The following is pseudocode/

public class GiftParticleEffectView implements ApplicationListener {

//libGDX draw Sprite

SpriteBatch mBatch;

//Asset manages resource loading

AssetManager mAssetManager = new AssetManager();

// Particle effect generator

ParticleEffect mParticle;

@Override public void create() { mBatch = new SpriteBatch(); mParticle = new ParticleEffect(); . Public void render() {Override public void render() {Override public void render() {Override public void render() { GlClearColor (0, 0, 0, 0); Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT); / / start drawing TextureRegion currentTextureR = particleInfo. BeginAnimation. GetKeyFrame (particleInfo stateTime, false); mBatch.begin(); mBatch.draw(currentTextureR, xpos, yPos, mWidth, mWidth); mBatch.end(); // There is a lot of logic to integrate with our own animation... } // Private void playParticle(...) If (gdx.files.internal (particleFileName).exists()) {if (gdx.files.external (extentPath).exists()) mParticle.load(Gdx.files.internal(particleFileName), Gdx.files.external(extentPath)); } else Log.e(TAG, "storePath is not exists:" + extentPath); Private void initResource(ParticleInfo) {}Copy the code

}

Copy the code

LibGDX is the android Framework that supports libGDX. LibGDX is the android framework that supports libGDX. LibGDX is the android framework that supports libGDX. LibGDX is the android framework that supports libGDX. It’s probably up to you to find out for yourself. So let’s go back and fill in the holes that need to be filled in (also the key point, libGDX doesn’t officially have or intend to solve).


Introduction of libGDX into the Application Framework

1. The CreateGLAlpha AndroidFragmentApplication subclass, connect the two worlds

The CreateGLAplha function has two functions:

 

private View CreateGLAlpha(ApplicationListener application) {

// GLSurfaceView transparent correlation

AndroidApplicationConfiguration cfg = new AndroidApplicationConfiguration();

cfg.r = cfg.g = cfg.b = cfg.a = 8;

View view = initializeForView(application, cfg);

if (view instanceof SurfaceView) {

GLSurfaceView glView = (GLSurfaceView) graphics.getView();

glView.getHolder().setFormat(PixelFormat.TRANSLUCENT);

glView.setZOrderMediaOverlay(true);

glView.setZOrderOnTop(true);

}

return view;

}

Copy the code

  1. Connecting two Worlds

    InitializeForView initializeForView initializeForView initializeForView initializeForView initializeForView initializeForView initializeForView Give it a layer of libGDX and return a view.

  2. Set transparency and hierarchy (hierarchy problem solved, cross out again)

    LibGDX drawing is directly above the OpenGL, from the current inherited from AndroidFragmentApplication fragments to retrieve GLSurfaceView instance, set its display to the top, and set the transparency. So that our particle effects look like they blend perfectly with the native app. SetZOrderMediaOverlay glView.setZOrderOnTop is to make sure that no matter what views are on the layer above the fragment, we can see the examples in the fragment. Look at GLSurfaceView, and see the next one for why.

# # # # 2. AndroidFragmentApplication subclasses of XML fragments should be put in the bottom (the most difficult problem)

Ok, so that’s it. So let’s review, what problem did we solve? We’ve reached the point where touch events can be handled by views on top of the framework, and whatever is on top of the fragment is guaranteed to be visible in the Render layer. ~ ~

The operation of the core is as follows:

  • Place the fragment at the bottom of the layout (XML configuration or code Settings);
  • From the current inherited from AndroidFragmentApplication fragments to retrieve GLSurfaceView instance, set it to the top, and set the transparency;

3. Inherited from AndroidFragmentApplication subclasses of onPause processing, manual call super, onResume, in the case of I should and can see the special effects, animation won’t be frozen, continuous play

 

@Override

public void onPause() {

Log.d(TAG, "onPause");

super.onPause();

if (! m_isDestorying && ! isScreenLock())

super.onResume();

}

Copy the code





4. Inherited from AndroidFragmentApplication subclasses of onStop processing, manual call delete the view, rebuild, in I should not and could not see the special effects, let animations don’t shut off

 

@Override

public void onStop() {

Log.d(TAG, "onStop");

m_isStoping = true;

if (! isScreenLock()) {

mContainer.removeAllViews();

m_isNeedBuild = true;

}

else

{

m_isNeedBuild = false;

}

super.onStop();

}

Copy the code


5. Using the new version of libGDX, I took a detour

In fact, the particle effects about half a year before I realized, but before I use libGDX does not provide AndroidFragmentApplication class, but only provides, we mentioned earlier that inheritance under a small child AndroidApplication Activity, As a last resort, I put the particle effects on an Activity that inherits from the AndroidApplication, which is a Dialog style and completely transparent. Very imperfect fulfillment of requirements, why not perfect?

The general points are as follows:

  1. First of all, it is an activity. The particle effect layer attached to it must be at the top. Visually, it will cover everything.
  2. The interaction between business logic (the gesture logic on the view&activity that is overlaid by the activity) and the activity is really weird.
  3. What do we do if we’re playing A particle effect, that is, the activity that’s implementing the effect, and the user wants to exit the acitivity of A? OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory = OnDestory One day, I found that libGDX was updated to support the fragment. I guessed that the problem could be solved. After trying, sure enough, I avoided many disadvantages caused by the activity. Quickly realized, after so many twists and turns, is also want to write this article a cause. I don’t like to hear “IOS can do it, Android can’t do this and android can’t do that”. Maybe we don’t pay enough, maybe our knowledge is still limited, don’t limit the technology, don’t limit yourself.

Then think back to have to go through the detours, in fact, carefully taste, if now implement a special effect start screen page, or some requirements are independent in the activity, then detours are not detours, and learning libGDX process, Mastering some basic ideas of game development is helpful for me to do Android development and learn other knowledge, for example: separation of stage, actors and other purely drawing concepts, highly abstract to improve code reuse; Render mechanism and our Win32 and Android draw what is different, and so on, in fact, every time to learn, there are harvest.


Side effects

With improvements to the Activity-to-fragment system, all structural issues have been eliminated, and now you can display particles using libGDX just as easily as using the native fragment. If you want to use libGDX particle effects, you will need to introduce a V7 SO and two JARS, which will add about 1.8m space to your APK, I think this is a side effect of using this engine.


recommended

  1. The bibliography

    LibGDX Game Development Primer

  2. libGDX

  3. LibGDX Development Tutorial – Struggle with little Potatoes


The next step

I previously implemented a collision effect based on the JBox2D package.

Since drawing and collision calculations (the Java layer) are not efficient enough to allow too many objects to collide at the same time, around 20 objects would be the limit, otherwise the CPU would be too heavy, so libGDX also provides Box2D as a matter of course, so I will implement this effect based on that. It will also be published.