Mobile Tutorial Series (LibGDX & MTX)——第二部分
本系列教程来自MTX(MoribitoTechX)的Tutorial Blog: http://moribitotechx.blogspot.co.uk/
因需科学上网才能访问,且该博客5年多没有更新了(最后更新时间2013.7.27),故这里手打上来留一备份。因为比较长,分成两部分:第一部分
项目地址:https://github.com/moribitotech/MTX
# Series 4 (Fun & Cool Things) This series is for showing nice effects and smart actions for your games and live wallpapers. The best part is, it only requires single line of code to create effects or couple of line of codes for smart actions. Game effects, Menu effects, Information panel effects, Background environments and more can be done in seconds...
4.1 Test_07_EffectCreator
Time to move on to fun stuff like effects. Effects are simply combination of Scene2D actions. In order to prevent code duplication in everywhere. I collected useful effects under EffectCreator class, you can create effects in a single line of code and dispose them from stage if you want. It is very convenient and useful. Everything is so fast and easy to use.

STRUTURE OF EFFECTCREATOR
The structure is very simple, I made shortcuts for method names to prevent long method names
// SC - Scale
// BTN - Back To Normal
// FI - Fade In
// FO - Fade Out
// SHK - Shake
And the methods are like these:
EffectCreator.create_SC(...) // Create scale effect for actor
EffectCreator.create_SC_BTN(...) // Create scale effect and back to normal
EffectCreator.create_SC_SHK_BTN(...) // Create scale effect, then shake, then back to normal
...
And the method parameters are like these:
EffectCreator.create_SC_SHK_BTN(Actor, ...bunch of effect parameters..., stage, isRemoveActor);
* First the actor to apply effects
* Then effect parameters such as duration, effect amount, delay ...
* The if you want to dispose from stage, give the stage and set "isRemoveActor" true, if you do want to dispose, give null to stage and set "isRemoveActor" false
EXAMPLE:

In my example the heart object is my actor (testActor). The effect I chose is scale, then shake, then back to normal.
- The very first parameter is our actor
- Other two parameters (1.5fs) are for scale amounts (Width and Height)
- 15f is for shake angle
- 0 is the original angle of the object, this si for going back to normal angle after shake
- 0.1f is for durtion (0.1 milisconds) for each action
- Null is stage (I do not need to dispose so I gave null)
- False is for isRemoveActor (I do not need to dispose so I gave false)
You can see how simple it is to use and effective. These could be 10s of more combinations to do, if you want more, create your own EffectCreator and expand more and more with useful actions and effects.
4.2 Test_08_SmartModels
This is where thing gets exiting. SmartModel is designed for and easy life fro LibGDX Scene2D and Live Wallpaper developers. Lets talk about it.

TEST SCREEN
Some of the codes are too long, so I separated this test to 2 classes (Test_08_SmartModels will be out UI and Test_08_SmartModelsHelpers will be our manager)
SMART MODELS
SmartModel class simple extends AbstractActor, it adds lots of smart actions to our actor. Each smart action has ability of make their own decision once they completed its action, and a randomizer helps us to make things natural as it can be. don't worry, everything happens in the background, so only thing you need to do is identify your action and give parameters you like to increase variation. Smart actions simply are LibGDX Scene2D Actions which brought together to create effective effects.
For example
- Move actor around the screen freely (Example: background balloons)
- Move actor side to side (Clouds:)
- Move actor to specific direction from one point in a paradox (Example: Snow flakes)
- Rotate actor randomly (Snow flakes rotates)
- Scale actor randomly (Snow flakes scales to give 3D feeling)
- Fade in/out randomly (Snow flakes vanishes to give more natual feeling)
EXAMPLE:
I will not go through each smart action, everything explained in codes, furthermore you can check the codes of SmartAction to see how things are working in the back-end if you want.
First things first
public ArrayList<SmartModel> smartModelList;
I created an array of smart model (each will present a single snow flake, or metal balloon in our example) in my "Test_08_SmartModels" class, and then I pass this list to "Test_08_SmartModelsHelper" class to create the effect.
I will focus on our Snow Flake example


*60 SnowFlakes will be created (NOTE: it may say 20 bats in your code, I forget the fix that comment)
clear(test_08_SmartModels)
This si just for cleaning stage and smartModelList.
int rndSizeWidthHeight = rnd.nextInt(50) + 10;
SmartModel currentSmartModel = new SmartModel(rndSizeWidthHeight, rndSizeWidthHeight, rnd, true);
I want my snow flakes in different sizes and also DIPActive is true for auto-resizing for each different resolution.
int[] topRangeX = {0, (int)AppSettings.WORLD_WIDTH};
int bottomRangeX = {0, (int)AppSettings.WORLD_WIDTH};
currentSmartModel.startActionMoveToDirection(topRangeX, bottomRangeX, (int)AppSettings.WORLD_HEIGHT + 200, -200, 9, 3, true, true);
Our first smart action,t this will move snow flakes in a forever loop.

- TopRangeX, a range of X-axis for start position of a snow flake, each time randomly number will be choosen in this range
- BottomRangeX, a range of X-axis for destination of a snow flake, each time randomly number will be choosen in this range
- (int)AppSettings.WORLD_HEIGHT + 200 is for Y-axis start position
- -200 is for Y-axis end position, this is where the action ends and repeating itself
- 9 is seeped (Duration), 3 is minimum speed (Duration), so it will take a random number between 9 seconds and 3 seconds for a snow flake to reach its destination point
- isTopDown true, so ti will snow top down, in my metal balloon example this is false, so metal balloons moves from down to up like floating bubbles
- last parameter is for randomizing rangeX, to use or not.
currentSmartModel.startActionScale(10, 2f, 2f, 3, true);
currentSmartModel.startActionRotate(5, 360, 2, true);
currentSmartModel.startActionFadeInOut(10, 3, true);
The rest fo actions are for rotating, scaling and fade in/out, just read method description or play around to see different results
Things may not be clear at first, but it will make sense in time, and you will be useing these single line commands for creating many type fo effects for your games and live wallpapers.
Series 5 (Game Manager & WorldScene2D)
Now you have many skills to work with. It is time move beyond the MTX, and look at the structure of games and live wallpapers that can be built with LibGDX Scene2D. How easily we can manager the world, create new layers, control the game state, use effects and so on.
5.1 GameManager
Now lets talk about game/live wallpaper structure/logic that can be built with LibGDX Scene2D. as you know Scene2D consists of Stage/Group/Actors. By using Mtx, I have created objects which extends these Scene2D elements with very useful features.
(AbstractScreen, AbstractWorldScene2D, AbstractActor)

I want my screen is to be start of everything, at the same time I do not give direct responsibility to my screen, thus gameManager is responsible for creating and managing the world. A little bit Cohesion/Coupling of object oriented programming.
Screen (extends AbstractScreen of Mix) - constructing Scene2D Stage
World and WorldLayers (extends AbstractWorldScene2D) - Scene2D Groups
Rest of objects are Scene2D Actors (extends AbstractActors)
SCREEN (ABSTRACTSCREEN)

As you can see, I only construct the gameManager and gameScreenMenu classes in my screen, this is all responsibility of the screen. gameScreenMenu is for creating menu buttons and etc. (For example, play/stop button).
INTERFACES
You may notice that I implemented IScreen and IGameScreen interfaces, I love interfaces. Because, everytime I start a project, I do not need to think about structure or common methods that being used such as "setUpMenu()", so by using interfaces, in a single second, I will know what to do.
GAMEMANAGER

GameManager is responsible of world and world layers and game state (I will talk about in later tutorials), So I create the main world (Scene2D Group) and add world layers to that world. It may sound like worlds in a main world. (Scene2D Groups being added to a single Scene2D Group)
At the end I add to ain world to Scene2D Stage.
TO SUM UP
The structure goes like this:
- Screen creates the stage
- Screen constructs the GameManager and pass stage to GameManager
- GameManager creates the Main World (Scene2D Group) and adds WorldLayers (
Scene2D Groups) - Each world layer has different Scene2D Actors due to their puposes (Clouds, Snows, Emeny objects, etc...)
I hope you gain some understanding of the fundmentals of Scene2D Game/LiveWallpaper structure/logic.
IGameManager
Again an interface that helps me alot
public void setUpWorld();
public void startLevel(int levelNumber);
public void checkGameCondition();
public void update(float delta);
public void saveGame();
public void exitGame();
In each project of mine, I mostly use the methods above, so why not store them in an interface, and easily use it. This is a good practice for your programming skills, saves time and increases efficiency. Furthermore, I can improve it in time.
5.2 World Scene2D
As you know, the GameManager has already created the main world and the world layers, but what are these exactly, how can we use these for games and live wallpapers.

WORLD
Here is my main world that extends "AbstractWorldScene2D" of Mtx (AbstractWorldScene2D also extends LibGDX Scene2D Group). Basicly this is the main Scene2D Group that will hold all other world groups and actors. (Do not worry about GameState, I will talk about on next tutorial). I give reference to gameManager in each my world to provide connection among the world layers whenever is needed.

WORLD LAYERS
World layers basicly same thing with main world (Also extends AbstractWorldScene2D). Here is the example of "WorldLayer1"
- I set the bluish background
- I set bottom soils/grass
- I set the clouds
Order is important, because its being added to this WorldLayer1 (Scene2D Group)

OTHER WORLD LAYERS
WorldLayer order is also important, it defines what comes top/bottom.
WorldLayer2
* I only set flying enemy objects
WorldLayer3
* I only set snow effect
WHY MANY LAYERS
Of course, I could have done everything in a single layer, but I like cohesion/coupling, it gives me flexibility. I give a responsibility to each layer (Background layer, environment layer, enemy layer, player layer, shooting layer, menu layer, etc...). Then everything is easy to improve and maintain. It is best to avoid confusion and do a fast implementation.
SNOW EFFECT ON WORLDLAYER3
Again, I want to talk about my SmartModel for your environments. I believe you noticed that nice snowing effect which is natural and no-stretching in any device.

It look only a minute to set up this snow effect. I wanted my snow to with an angle, so I gave different direction to first half and second half of my snow flakes.
Direction is like:

5.3 Game State
How to manage game state, well thanks to LibGDX Scene2D, it is very easy.

GAME STATE
What manages my game, the GameManager. There is enum class in MTX called GameState, whichhas different states (You can see in the above screenshot)
The GameManager keep tracking the game state, you can set the game state or get the game state with "set/getGameState()" method in GameManager. (Actually it is in the AbstractGameManager of MTX)
WORLD
In my world, I keep track game state and decide to act or not. If I do not act, everything under the world (WorldLayers, actors, etc...) will stop acting. This can be improved and it can be changed, I just wanted to show how can it work.
- If gameState.RUNNING, continue acting

PLAY/PAUSE BUTTON and GAME MANAGER
If you tried the play/pause button on the test project you will notice everything stops moving (acting). In my GameScreen, I constructed GameManager and GameScreenMenu classes.
In my GameScreenMenu, I have reference to Screen (which has GameManager). I created a toggle button, which changes game state.

Basically I have one GameManager, and it has references everywhere (Screen, worlds, layers...)
Well, this may not be ultimate approach or best solution, but it works great and performance is very good. At the moment, I cannot ask no more.
Series 6 (Flame Words Game with MTX v2.1 BETA)
You get the idea, you are alright. Now it is time to jump to game development from A to Z. This will be sample game created in around 2 weeks time with basic principles for you to understand. You must finish the tutorial series 1,2,3,4,5 before starting this series. I also suggest you to look at "Show Us The Good" tutorial series for advanced menu creations with unlimited flexibility.
I will be making and publishing tutorials day by day...
6.1 (2.1+) Flame Words - The Project

FLAME WORDS
I had this game idea very long before, I also made very simple prototype called "Dark Flame Words", but in that time I got bored :)) and left that project. The game is simple, just guess the shufled lettered words without touching fire, so you will not be punished, also there are an extinguisher to get rid of flames etc...
PROJECT TIME
Around 2 weeks at most (8-9 days coding, 2 days graphics, 2 days test and deployment) I did all the coding myself and I prepared %80 of graphics. I got the animations from "Pow Studios" (many thanks to them) and the wonderfull 3 Jazz Music from Kevin Macleod (very greatful to him).
PERFORMANCE
The game runs smoothly in most of device with +50FPS and all other devices is fix 60FPS, quite good results. You may think it is a simple game, but it is not actually. There are 60 sparkles constantly moving (60 Smart Actors) and 40 animated mini fire that become the bottom fire, and each of them being scaled almost to screen size if you guess the word wrong. So it means there are 100 actors with scaling and animations non-stop. Also there are other UI elements etc...
FUTURE UPDATES
"FIXME" you will see this everywhere in the game codes, because I did not make a perfect game here, even like this works superp through, thanks to LibGDX. I noted a lot of fixme that improve game performance and memory in the future.
MTX 2.1+ BETA
I refactored classes and structured most of packages, more optimized and more performance achieved at the moment. Still there are test needs to be done, also some classes not implemented at the moment but everything works just fine as you can see the Game Flame Words.
LICENSE
The project is under license Creative Commons Attribution 3.0 (All codes can be used freely Personal/Commercial). However the assets (Graphics, Sounds, Musics, Animations, etc...) that created by us are cannot be used anywhere. Of course the musics/sounds from Kevin Macleod and animations from Pow Studios can be used as long as the credit given to those respectful owners..
PROMO

6.2 (2.1+) Flame Words - The Structure

GENERAL STRUCTURE
First of all, this may not be the greatest game structure of all or perfect idea of game foundations. I will admit that I have unique style of my own. I worked many other game structures, MVC styles and so on. They have all pros and cons, but at the end I ended up with my own unique structure which works fine for me. In future, I will adapt to new structures, I will learn from my mistakes, all in all, I am newbie guy that graduated from university recently and tries to find a path in game programming world.
TELL ME
Tell me what is bad or good about the structure, what can be changed for future. I will think more on them. I will create better foundations in future. I am here to learn and experience, you will find strong ideas in my games and structures as well as weak and stupid ideas :Dloll...
LETS LOOK AT THE STRUCTURE
Before GameManager
Everything should be clear. We have screens and screen helpers. I use screen helpers to divide the tasks of menus (More cohesive approach in OOP), this gives me incredible flexibility and maintainability for my games, I can honestly make any game menu you can imagine with this approach. I do not stack all game menu elements in a screen or in a class, I divide them into objects and use effects on them.
Sub Manager of GameManager
I have around 8-9 sub managers (HintM, AchievementM, PuzzleM, PunishmentM, NotificationM, SwarmM, EffectM, TutorialM, etc...) Why so managers? Simple, again choseion off OOP. I have single duty for all my managers, if have a problem about hints, I look into hint manager, if I need a new feature I will make a new manager, if I need to update a manager, I know where it is. Very very very flexible and maintainable approach for future and very easy to develop the game. All these managers communicates with World and GameManager without problems.
GameIOManager, Data Obejcts, Database
I have very simple database (textfiles), database can be anything XML, Server, a JSON file or TextFile. I simple read and write textfiles through GameIOManager. I get data from text file and put them into DataObjects (GameData, PlayerData, PuzzleLevel). What are these data: fire level, meter level, current level, etc...
GameInputManager
When you touch a letter or fire many things happens logically. It was the best idea create a input manager for it. So, I can easily work on it, for example you touch a letter and many things happens: play audio , run effect, update word, update guess box on top, if word finished, check game condition, update blue water meter etc...
EffectManager
This was a great idea, this is the EffectCenter (Static class) of the game which managers all the Scene2D actions. For example, runNewWordEffect, runGenerealButtonEffect, runNewHintEffect, runToggleButtonEffect, runMenuEffect, etc... For any effect, I know where to look and I know what to change. This is also god to prevent code duplications, for example button effects managed from a single place.
ANDROIDOBJECT
I have single android object that comes from android (MainActivity) and this the king of classes. It has many sub interfaces and it can be added many sub interfaces and it can be added many other interfaces. At the moment it has IAdController which controls advertisements and IAndroidIntents which start intents.
MORE OOP NEEDED
This was a experimental game, more oop and database management needed in future. For example, factory classes could be good or xml/json as database management could be great. I will think more on those in future.
6.3 (2.1+) Flame Words - MainStarter/AbstractGame
ABSTRACT GAME
Our MainStarter is extends the AbstractGame which is inital point of our game. This is constructed once and used until we exit the game, all screens managed by the game class.
SETTING APP SETTINGS
This is so important, AppSetting is our info depo which we get all static info about sizes. It is used in Scene2D Stage creation in AbstractScreen class. Also the we store the word and target world size to calculate DIPActive and use in World constructions.
It has 3 setUp() methods in it, you can just read the descriptions for those. You either use my DIPActive - anti stretch formula or you just use regulat libgdx development style which ends up scaling the stage due to device res. DIPActive is okay formula, but not awsome, for pixel/position perfect games it should be avoided, but it is very handy for live wallpapers.
Just use each setUp() method and run the game 480x320 and 960x540 resolutions in desktop, you will see the what I mean about stretching.
DATABASE
We create 2 text files as mini database after first install, and thats it.
Show Us The Good Series
This series is for showing real power of LibGDX Scene2D and Mtx. Cool Gaming Menus, Partial Gaming Codes, Animations and Effects, High Quality Live Wallpaper Techniques and so on...
It is essential to finish Free Tutorial Series 1,2,3,4 to fully understand "Show Us The Good" series.
Jungle Game Menu
You have completed your awesome game (2D/3D or anything else) in LibGDX in your way. Now its time to polish it with interactive stuff like a charming game menu. Lets see how can we do that only 1 day.

FIRST THINGS FIRST
You should know about Mtx which is built over LibGDX Scene2D (please complete the free tutorial series 1,2,3,4), because I will not talk about erery detail or Mtx related-classes, I will explain the general idea.
ACTORS BECOMES BUTTONS
What I love about LibGDX Scene2D is the actors, they can be anything you can image. In my case I took my SmartModel (which extends AbstractActor) and make it button, "JungleGameButton" class is my button model.
ALL INTERACTIVENESS IN SAME SCREEN
I have only one screen in this tutorial which is responsible for splash/loading, game menu and instructions. I did not create screens for each one of them.
This way, it is much more impressive, animations, effects, transitions, movements and the composition is much better.
The life-cycle is like:
- First show splash/loading screen and start background effects like green balloons at the same time
- Send menu elements in
- Swipe for instructions and send menu elements away, and get instructions
- Swipe for menu and send instructions away, and get menu

SCREEN STRUCTURE
All elements (buttons, flowers, gamename, etc) are in the Screen class, so the screen is like little fields container/database and main manager.

Screen is the main manager, it is the king who controls other managers, so the real workers are
JungleMainMenuScreenButtons jungleMainMenuScreenButtons;
Set up menu buttons, send them in and away with animations and effects
JungleMainMenuScreenEnvironment jungleMainMenuScreenEnvironment;
Set up menu background and name (balloons, gamename, flower), and send them in and away
JungleMainMenuScreenInstructions jungleMainMenuScreenInstructions;
Set upinstructions and send them in and away
MANAGEMENT
Screen will manage all the things it will check if splash is completed or not (I made a fake splash, normally you may use assetmanager of LibGDX)

When the splash is completed, screen will command to "jungleMainMenuScreenButtons" to send main menu buttons, social buttons and swipe buttons. Screen will also command to jungleMainMenuScreenEnvironment" to send the game name in Screen is also manages the swipes if you swipe UP and DOWN, Screen will command to "jungleMainMenuScreenButtons" and "jungleMainMenuScreenEnvironment" for sending all the necessary stuff in or away. Please check the "setUpSwipeListener()" method for more detail on this.
So, I beileve you understood the fundementals of interactive menus/screen. One manager manages all other small manager, command them to do things necesssary.
OUR LITTLE MANAGERS (REAL WORKERS)
JungleMainMenuScreenButtons jungleMainMenuScreenButtons;
Set up menu buttons, send them in and away with animations and effects
JungleMainMenuScreenEnvironment jungleMainMenuScreenEnvironment;
Set up menu background and name (balloons, gamename, flower), and send them in and away
JungleMainMenuScreenInstructions jungleMainMenuScreenInstructions;
Set up instructions and send them in and away
All methods in this classes have parameter for the screen, so they can easily reach the element in screen class such as buttons, flowers and etc...
Method structure
-
setUp.....(Screen screen) - set up something, construct it, set position and hide if necessary while waiting splash, set origin, add to stage and etc... This also where to specifiy buttons to do something by using ActorGestureListeners (touchUp/touchDown)
-
sendIn.....(Screen screen) - send something in to screen, it may also scale things or fade in things by using animations or screen, so this is the place does all that cool transitions, animations
-
sendAway.....(Screen screen) - exact opposite of sendIn.....()
I wont explain what are in the methods, it is very easy and upto your imagination/composition. By using Effect Creator, I made some cool animations, transitions, in some places I used Actions directly instead of EffectCreator.
With this tutorial and the source code, now you can easily do many things for your game. You can use the code anyway you want and also graphics I made for this tutorial are free to use.