Wednesday 29 May 2013

Update: 1.2.3: Support automatic camera zoom and locate camera in the tiled scene, angry bird demo video below illustrates this feature. Engine have 

fixed error does not properly display the game in different screen resolutions . Additional constants for some TiledScene, to setup some parameters of 

the tiled scene as the targeted size, world size, scale values ​​...

Download: http://xn--lmgameandroid-pdb.vn/engine%201.23.rar
Video: http://www.youtube.com/watch?feature=player_embedded&v=Trg02Gjzl9M

Update: 1.2.2: Additional PhysicsManager initialize and update all physical objects in your game, so you do not have to use a PhysicsScene that can be 

used any scene but using the PhysicsManager to add the game component to the scene. A new interface is IPhysicsObject to identify a physical object 

in the game, so you are not forced to use PhysicsObject class .Every class game component have implement the IPhysicsObject interface can be 

added to PhysicsManager, then it is possible to add PhysicsManager to PhysicsScene as GameComponents.

Demo source code "Angry Birds" has been revised to illustrate the use and PhysicsManager IPhysicsObject.

Update 1.2.1: Update source physics section of engine to simulate "cut the rope" game


Saturday 11 May 2013

Gdx engine v1.2 is available to download!


Updated version 1.2
Download full sourcecode and documment


If you encounter a problem, please read some advice at http://code.google.com/p/gdx-engine/issues/list


Version 1.2: Updated engine's sourcecode to make games from tiled map and create physics games easily.
  • Demo the compound object in "tolem" test package
  • Create and simulate a siege machine in "siege machine" test package
  • Create and simulate game angry birds in "angry birds" test package


I uploaded full projects from eclipse so you can import the projects directly into Eclipse IDE.
If projects miss some library like android sdk or libgdx, please get them from here






Guide to create physics game by GDX Engine

The full source code of engine and the game available in download page


Now I will guide you through creating a simple physics game, I call it a game, "Roll the troll". Basically you rotate the device (tablet, smartphone) or claw fingers to roll the "Troll" that have the grinning face :) to position of the yellow puppet on screen. In the tmx map, i marked the point as a object that have name is “endpoint”.. If you managed to do it, you will be able to go to the next game scene. There is a special point that can shrink the size of the troll, marked by the formation of a cactus. In the tmx map, i marked the point as a object that have name is “shrinker”.

Prepare for game map

AdventureGame Similarly, in game physics, I also used to create the map mapeditor tmx:
Note :
Static layer containing the object of static body is drawn counterclockwise clock using the tool "InsertPolygon" on the toolbar. This is the rectangular area that can not let the Troll pass through.
Object layer contains the object "start" marks the start position of the troll, "end" marks the endpoint for troll should reach to gain the goal. "Shrinker" tile to mark the location of the troll should be shrinked So Troll could drop down to the above small hole)

Create Scene Physics forgame

You should create your physics scene class inherits from the PhysicsTiledScene class that gdx engine has made available.
RollTheTrollScene public class extends PhysicsTiledScene
Because the game have many scenes so you will need a method to load the appropriate scene. You pass the level parameter into the method to specify correctly the level you need:

createLevel public void (int level) {
       
        clear();
       
        loadTileMapRenderer ("physicsgame / map" + String.valueOf (level) + "/ map.tmx", "physicsgame / map" + String . valueOf (level));
        loadStaticBodies ("static");

        endpoint = new Rectangle ();
        shrinkpoint = new Rectangle ();
        TextureAtlas atlas = new TextureAtlas (Gdx.files.internal ("MyDataPacker / FileMoTa.txt"));
        //You load objects of the scene by objects from tmx file.
        //One TiledObjectGroup will response to a group of objects in one layer in map
        //Here we search for an object by its name, not by the layer that contains the object.
        for (TiledObjectGroup objectGroup: tiledMap.objectGroups)
            {for(int i = 0; i <objectGroup.objects.size (); i + +)
                if ("start". equalsIgnoreCase (objectGroup.objects.get (i). name)) {
                    Tr = new TextureRegion TextureRegion (atlas.findRegion ("hinh2/popo02"));
                    troll = new Troll (services, tr);
            troll.setX (objectGroup.objects.get (i). x);
            troll.setY (getMapHeight () - objectGroup.objects.get (i). y);
            addDynamicCircleObject (troll, 32);
} else if ("end". equalsIgnoreCase (objectGroup.objects.get (i). name)) {
                    endpoint.setX (objectGroup.objects.get (i). x);
                    endpoint.setY (getMapHeight () - objectGroup.objects.get (i). y);
                    endpoint.setWidth (objectGroup.objects.get (i). width);
                    endpoint.setHeight (objectGroup.objects.get (i). height);
troll.endpoint =  endpoint;
} else if ("shrinker". equalsIgnoreCase (objectGroup.objects.get (i). name)) {
                    shrinkpoint.setX (objectGroup.objects.get (i). x);
                    shrinkpoint.setY (getMapHeight () - objectGroup.objects.get (i). y);
                    shrinkpoint.setWidth (objectGroup.objects.get (i). width);
                    shrinkpoint.setHeight (objectGroup.objects.get (i). height);
                    troll.shrinkpoint = shrinkpoint;}}}
                
Depending on the tiled object, we will load sprite, or shrinker will corresponding to the endpoint or the sprites in their coordinates.

Users can change the gravity in the game by rotate the device. Of course, you cannot “rotate” the PC, so on the PC , you can roll "Troll" with the mouse (on mobile devices would be smoothed on the screen). We need to handle control code in the update method:

@ Override
    public void update (float gametime)
       
        {floatrotate = Gdx.input.getAccelerometerY ();
        / / Calculategravity
        floatg = (float) (MathUtils.sinDeg (rotate * 18) * 10);
        float gy = (float) (MathUtils.cosDeg (rotate * 18) * -10)
/ / Set gravity for world       
world.setGravity (new Vector2 (gx, gy));
        / / Get the value of the mouse (or clawed hand on the touch screen)
        Gdx.input.getDeltaX float deltaX = ()
        =-Gdx.input.getDeltaY deltaY float ()
        / / EFFECTS determined to troll   
        if ( deltaX! = 0 | | deltaY! = 0)
            {applyForce(troll, new Vector2 (deltaX,
        deltaY));}
        / / inherit this method to update for physic object
        super.update(gametime);
}
   
In Physics Scene, You can override the method renderForeground () to draw into a GUI screen:
@ Override
    public void renderForeground (float gametime)
        {bigFont.setColor(Color.RED)
        if (! win)
        {bigFont.draw
            (getBatch (), "X: "+ Gdx.input.getAccelerometerY (), 200, 150);
            bigFont.draw (getBatch ()," Y: "+ world.getGravity (). x, 200, 100);
            bigFont.draw (getBatch ()," Z: "+ world.getGravity (). y, 200,
        50);}
        else{
        bigFont.draw(getBatch ()," You Won! ", 200, 150);
    }
Method on the display screen and gravity rotate around the y-axis value when you rotate the device (In PC, the “rotation” is not available)

On the Scene, you see the blue rectangle thin strokes of box2dDebugger ... That's because the default physics will be used DebugRenderer. If you do not want to appear this DebugRender (When publish games), you should call the method setDebugRenderEnabled and pass the false value.

Creating objects "Troll"

I recommend your physics class object should be inherited from PhysicsSprite of GDX engine:
public class Troll extends PhysicsSprite {
We should test if the troll collides shrinkpoint or endpoint or neither:
@ Override
    public void update (float gametime)
        {if(this.getBoundingRectangle (). overlaps (endpoint))
        {
            // if reach the troll endpoint, go next scene or game you win!
        RollTheTrollScene scene = (RollTheTrollScene) getGameServices (). getCurrentScene ()
            if (scene.gameLevel <scene.maxLevel)
                {scene.gameLevel+ +;
                scene.createLevel();
            }
            else{
            scene. win = true;
            }}
       
       
        if (shrinkpoint! = null &&! isShrank)
            {// if collides shrinker troll then the size is reduced.
            else if (this.getBoundingRectangle (). overlaps (shrinkpoint)) {
            isShrank= true;
            //make the sprite smaller
            setScale (0677 f);
            //make the shape from fixture of body smaller
CircleShape shape = (CircleShape) getBody (). getFixtureList (.) get (0). getShape ();
    shape.setRadius (shape.getRadius () * 0.677f);
}}}
           
       
   
On above, getBody method () PhysicsSprite of class to get the reference to body of sprite, the body is in box2d world too. This above code help us contract the troll troll if the shrinker point collides and the game would go to the next scene if troll collides endpoint.

Creating a Game class to finish your game physics!

If you came here then you almost complete the first physics game engine using GDX!.
The Game class is similar to other classes in game sample games. The Different is some code to Identify the physics scene and box2d debugger to make them render properly:
@ Override
    public void render ()       
       
        {if(scene == activeScene) {

            // try to get from physics scene tileRenderer
            TileMapRenderer scene.getTiledRenderer tileRender = ();
           
            GDX . gl.glClearColor (0f, 0, 0.3f, 1);
            Gdx.gl.glClear (GL20.GL_COLOR_BUFFER_BIT);
            // render background tile map
           
            tileRender.render (gameService.getCamera ());
   
            gametime = Gdx.graphics.getDeltaTime ();
           
            // Update the active scene
            activeScene.update (gametime);
            camera.update ();
                batch.setProjectionMatrix (camera.combined);
            batch.begin ();
            // Draw active scene
            activeScene.render (gametime);
            batch.end ()
            // draw the foreground of a scene
            scene.renderforeground (gametime);
            // render Box2dDebugger
            scene.renderBox2dDebugger();
       
        } else {
            super.render(); }}
       
    

Game guide: Create Tiled Game Engine using GDX Engine (Part2 - code game)


The document in download post have better format.

Creating the Scene class TiledMap

First you need a map to show the scene, I recommend that you create the scene by extended scene from class TiledScene that GDX has made ​​available for you
for example: public class extends AdvantureSceneTiledScene
We have a constructor of tiled scene so, you need to have a some string parameter that contains the path to the folder containing the file and texture tmx file
tmx.,for example:
public AdventureScene (IGameService gameService, mapfile String, String textureDir)
        {super(gameService, mapfile, textureDir); / / ...
You have used the protected variables inherited from parent class TiledScene map to load objects that you have designed in tiledmap editor. For example, I load the player object as designed in the tmx file:
        player = new Player (services, textureRegion)
        for (TiledObjectGroup objectGroup: tiledMap.objectGroups)
            {for(int i = 0; i <objectGroup.objects.size ( ); i + +)
                if("player".equalsIgnoreCase (objectGroup.objects.get (i). name)) {
                    player.setX (objectGroup.objects.get (i). x);
                    player.setY (getMapHeight () - objectGroup.objects.get (i). y-20);
            addItem
            (player);}

You set the xy coordinates of the player in the position of the object "player" in the tmx file. Then you add to the collection of scenes player in method addItem (...)       
You just need to override the method renderForeground () to draw the player's score on the screen:
@ Override
    public void renderForeground (float gametime)
        {bigFont.setColor(Color. RED);
        bigFont.draw(getBatch(), String.valueOf (player.score), 100,
    100);}
Note: you get the spriteBatch from getBatch method () of TiledScene class. You may not use the method getSpriteBatch() of GameService.

Creating Player object


Player class should be inherited from class DefaultSprite
method isPassPlayer () to check that it is stepping up tile can "pass" is not. If this method returns false then player have come to obstacle tile so player was not able to walk any more.
private isPass boolean ()
    {
       float x = this.getX ();
       float y = this.getY (),
    / / Do not move if exceeded map bound
       if (x <0) return false;
       else if (y <0) return false;
       if (x> tiledMap.getMapWidthUnits ()) return false;
       else if (y> tiledMap.getMapHeightUnits ()) return false;

       ispass boolean = true;
       
        final int w = map.tileWidth;
        Vector2 [] v = new Vector2 [2];
        / / We put 2 points on a test player to pass through the tile:
        v [0] = new Vector2 (x, y )
        v [1] = new Vector2 (v [0]. x + getRegionWidth () / 2, v [0]. y + getRegionHeight () / 2 -5)   
        for (int i = 0; i <v. length, i + +)
        {int
            row = (int) (tiledMap.getMapHeightUnits () - v [i]. y) / w,
            int col = (int) v [i]. x / w;
           
            map.getTileProperty String str = ( noPassLayer.tiles [row] [col], "NoPass")
            / / check if tile attribute "NoPass" or not
            if ("1". equals (str))
            {
                ispass = false;
                break;}
           
           
            str = map.getTileProperty (foodLayer.tiles [row] [col], "Food")
           
            if ("1". equals (str))
            {
                score + +;
                break;
            }
        }
        return
ispass;
}
Player need ramaining to base.update() method used to move and animation updates:
@ Override
    public void update (float gametime) {
       
        animation.isLooping= true;
       
        oldPos.set (getX (), GetY ())
        //Check if user press some direction key to controll the player.
        if (Utils.isKeyDown (Keys.UP))
        {direction
            = UP;
            setY (GetY () + 3);
            checkPosition
        ();}
        else if (Utils.isKeyDown (Keys.DOWN))
        {direction
            = DOWN;
            setY (GetY () - 3);
            checkPosition
        ();}
        else if (Utils. isKeyDown (Keys.LEFT))
        {direction
            = LEFT;
            setX (getX () - 3);
            checkPosition
        ();}
        else if (Utils.isKeyDown (Keys.RIGHT))
        {direction
            = RIGHT;
            setX (getX () + 3 );
            checkPosition
        ();}
        else
            {animation.isLooping=
        false};
        super.update(gametime);
    }

In checkPosition method(), if the player steps into an obstacle tile, we reset its position :

private void checkPosition ()
{
if(! isPass ())
        setPosition(oldPos);   
}

Complete Game by class AdventureGame

AdvantureGame Really not much different from the game class you wrote. However, because this project is to use tilemap, so we'll have to check the current scene is being used could be the render tiledScene or not to make the change in rendering
@ Override
    public void render ()       
       
        {if(scene == activeScene )
            {
// clear the scenegame
            Gdx.gl.glClearColor(0f, 0, 0.3f, 1);
            Gdx.gl.glClear (GL20.GL_COLOR_BUFFER_BIT);
            // Get tileRender from tiledScene
            TileMapRenderer scene.getTileMapRenderer tileRender = ();
           
// render the background by the background layers' s index   
            int [] backgroundLayer = {0,1,4};
            tileRender.render (gameService.getCamera (), backgroundLayer);
   
            gametime = Gdx.graphics.getDeltaTime ();
           
            // Update active active scene
            activeScene.render(gametime);
            batch.end ();
           
           
// render the foreground by the foreground layer 's index
            int [] = {2} foregroundLayers;
            tileRender.render (gameService.getCamera (), foregroundLayers)
            // foreground of a scene render tiled
            scene.renderforeground(gametime);
        }
else
        {
super.render();
        }
   
Note: You should pass the false value into setYdown() method because currently GDX engine still can not use the coordinate system y "down" in the tiled game. This means you will have to use coordinates with the y-axis "up" explicitly.
@ Override
    public void create (){       
        // set the oxygen system have axis-y axis down
        setYdown (false);