Saturday 11 May 2013

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(); }}
       
    

No comments:

Post a Comment