Thursday 4 April 2013

Introduce to Dropcatch game


This article will help you acquainted with GDX Engine. The best way to learn how the game is started to make a real game! Before you start doing game called "Dropcatch". I presume so you have a better understanding of [ The Engine Architecture ] of GDX Engine, Know about [ Introduction Game Service ], [ Game Asset ] and [ GameSetting ], and [ Overview Manager Object ].
In Dropcatch two basic types of objects: drop are the drops of water fall down from above and bucker that catch the drops are falling. If the drop fall on bucker, the drop will disappear, bucker took a drop, and so player (bucker) earn points. bucker can be controlled using the left and right arrow keys, or by touch on the touch screen of the device. After a certain period of time, the drop will be increased in order to increase the difficulty of the game. For example, after 5s game will have 2 drops, 3 drops after 5s... and rise continuously until the player loses (After omitting too many drop)
Documents of Libgdx framework also has a similar game dropcatch this , you can refer to [here]. Tutorials about game Dropcatch will guide you step-by-step. If you are really starting to step into the field of game development, tutorials really useful to you.

Construction Game Asset

GameAsset is required for Gdx Engine and is always the first step when you create a new project game. I recommend create Asset inherit from DefaultGameAsset.
Public class Asset extends DefaultGameAsset

       {public static TextureRegion dropTexture;
       public static TextureRegion buckerTexture;
       public static BitmapFont bigFont;

       @ Override
       public void load ()
                      
              {if(isLoaded)
                     return;

              dropTexture = loadTextureRegion (loadTexture("dropcatch/drop.png",Format.RGBA4444, true), new Rectangle (0, 0, 32, 32));
              buckerTexture = loadTextureRegion (loadTexture("dropcatch/bucker.png",Format.RGBA4444, true), new Rectangle (0, 0, 64, 64));
              bigFont = loadBitmapFont("data/font16.fnt", "data/font16.png");
             
              isLoaded = true;}
      

       @ Override
       public void dispose ()
              {dropTexture.getTexture (). dispose ();
              buckerTexture.getTexture (). dispose ();
              bigFont.dispose
       ();}}


This code creates two static variables to save the texture region for other objects in game is drop and bucker. A bitmap font to draw the score of the player (bucker) on the screen.
Game Asset using the load () method that is called when the game started and dispose() method that is called at the end of the game, dispose() is used to free the memory which contains the resource of the game.

Make Drop object

Drop is a real object in the game, however the number of drop will increase so to completely control the drop, we will use the Object collection to store the entire drop of the game in it. You can add objects that inherited from Collection item or Game component into Object collection. But to optimize the game, we will use the drop as a Collection item. Collection item without using the render () method, so we will render () all of the drops in the Object collection of drop class, class named DropCollection. However before create DropCollection class, we need to create the Drop class.
Example: Declare and initialize the position, and define the boundaries for the drop:
public class Drop extends CollectionItem
      
       {private Rectangle bound;
       final Vector2 position = new Vector2 ();
      
       public Drop ()
              {super();
              resetPosition ();
              bound = new Rectangle(position.x, position.Medicine,32,
       32);}
       void resetPosition ()
              {position.y = 0;
              position.x = MathUtils.random(Gdx.graphics.getWidth
());}
public
 Rectangle getBound ()
       {bound.
              x = position.x;
              bound.y = position.y;
              return bound;}
      
You can see the drop variable named bound of type Rectangle. bound is a rectangle surrounding the object drop, so the position of the bound will coincide with the position of the drop. On the other hand the length and width of a drop texture is 32 pixels (file drop.png), so the bound will be the size of the other two sides is 32. So methodgetBound() always returns exactly a rectangle surrounding the object drop in game scene.
Method resetPosition ()  will reset the coordinates of the drop, the coordinates y = 0 shows that the drop will appear on the top screen and have a random x coordinate between zero and the length of the screen (random 0 => The ScreenWidth)
Example: Updating drop
@ Override
       public void update(float gameTime) {
              position.y + = 5;
             
              if(position.y > GDX.graphics.getHeight ())
{
    resetPosition();
}
}
      
Drop will drop from top to bottom, that is position-y drop will vary with each game loop. To make this change, you need to Override the method update () method of the Collection item. As the above example, position-y will increase by 5 pixels per GameLoop, this makes water move down. Tha method have code to test the position of drop, if the drop across over the screen, we will reset its position.

Construct DropCollection objects

AfterDrop class, obviously you will need a class DropCollection to manage all drops in the game.
Example: the DropCollection class
public class DropCollection extends ObjectCollection <Drop> implements IService{

       private float timer;

       public DropCollection (IGameService services)
{
      super
(services);
}
       @ Override
       public void initialize (){
              timer =5f;
/ / ...
As you can see, DropCollection inherited from Object collection and implements interface IService. This Means DropCollection can been added to GameService which all objects are supported games services will accessible to the DropCollection from anywhere.
Timer is a float variable, we assume the following 5s will be adding one new drop. if you initialize the timer = 0f, you will have to wait for 5 seconds when the beginning of the game to get the first drop. Set timer = 5f help you not have to wait 5 seconds before seeing the first drops of water: D
Method initialize () is always called when the gameplay Scene is activated. Please rest Assured that this method will Surely be called to at least once when you activate the scene. The code to create the Scene and activate Scene I will mention later.
Example: update and render DropCollection
@ Override
       public void update(float gameTime)
              {/ / call the update () method of all drops
              super.update (gameTime);
              / / Increase timer
              timer + = gameTime;
              / / create a new drop each after 5 seconds for make the game more difficult
              if(timer> 5f)
              {/
                     / reset the timer
                     timer = 0f;
                     / / add new drop into collection
                     addItem(new Drop());
              }
       }
      
       @ Override
       public void render(float gameTime) {
              for(Drop b: objectCollection) {
              if(b.isVisible ()){
getGameService ().drawTextureRegion         (Asset.dropTexture,b.position.x,b.position.y);
              }
       }
Section code super.update(gameTime); in update() method automatically call all update method () of all enabled items in the collection.render part is very simple, loop all the drops and render the textureRegion in the game asset

Construct object Bucket

Bascause the player directly controls bucket using the keyboard or touchscreen so we can call the bucket is ‘Player’.
Bucket need to be rendered to the screen through texture or texture region. Because DefaultSprite class has supported this feature, so to save development time, we will create a Bucket new class Inherits from DefaultSprite
public class Bucket extends DefaultSprite {
       public Bucket (IGameService services, TextureRegion region)
{
super
(services, region);
             
       }
}
Bucket still need to make up the necessary value, it is very simple:
       / / attribute for player game state
       public int score = 0;

score is present the player's score received. Once Gamer control bucket catch a drop, the score will increase by one.
Bucket needs to be initialized, you see:
/ / store reference to DropCollection service.
       DropCollection drops;
       @ Override
       public void initialize ()
              {
score = 0;
             
                     drops = getGameService (). getService(DropCollection.class);
}
In the code above, bucket is set in the middle and bottom of the screen length. drops variables stored reference to variables dropCollection in the the the gameplay Scene. Drops were retrieved using the method getService () method of the object Game Service.
Example: render and update Bucket
@Override
       public void render(float gameTime) {
              super.render(gameTime);
             
              getGameServices().drawText(Asset.bigFont"Score: " + score, 300, getGameServices().getWindowSize().y - 60);
       }
       @Override
       public void update(float gameTime) {

// store position-x from last framefloat oldXPosition = getX();
              // control bucker using keyboard
              if(Utils.isKeyDown(Keys.RIGHT))
              {
                     setX(getX() + 10) ; //move bucker to right
              }
             
              if(Utils.isKeyDown(Keys.LEFT))
              {
                     setX(getX() - 10); //move bucker to left
              }
              // control bucker using touchscreen
              final Vector3 touchPos = new Vector3();
              touchPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
              getGameServices().getCamera().unproject(touchPos);
              setX(touchPos.x - 64 / 2);
              //if bucker out of screen bound, restore its old position
              if(getX() < 0 || getX() > Gdx.graphics.getWidth()- getRegionWidth() )
              {
                     setX(oldXPosition);
              }            
              //Check collides with all drops
              for(Drop drop : drops)
              if(getBoundingRectangle().overlaps(drop.getBound()))
              {
                     //increase score if bucker catch a drop, reset drop’s position
                     score++;
                     drop.resetPosition();
              }
       }
The render () method is very simple, because the class DefaultSprite itself can render the texture or texture region. We add code to render a text containing information about the score of the player the screen.
Method update () contains code to check bucket collision with the bound of the screen and the drops in PlayGameScene.
Overlaps() method  of the class Rectangle checking the collision. Collision Between two objects will take place when two their Rectangle overlaps each object, and the the overlaps method () will return true.

Make class GamePlayScene

After create the drop and bucket, you should take it into a GameScene. Above I mentioned the concept "GamePlayScene" Really this is the Scene of the Game and obvious it must Inherit from BaseGameScene class of GDX Engine. If your game is more professional, it should be many scene as "StartScene", "HighScoreScene", "HelpScene" ... But to make this tutorial simple, we will only create "GamePlayScene" to make the game can play at once.
Public class GamePlayScene extends BaseGameScene {

       Bucket bucket;
       DropCollection drops;
      
       float timer = 10;
      
       public GamePlayScene (IGameService gameService) {
              super(gameService,true);
              / / initialize for player
              bucket = new Bucket (getGameServices () and Asset.bucketTexture);
              addDrawbleObject(bucket);
              / / initialize for more objects...

you see, very simple GamePlayScene. You declare the object (bucket and drops), construct them and add them to Scene by method addDrawbleObject() So bucket and drops will be auto-initialize, auto-update and auto-rendering therefore you do not need to call explicitly these methods in class GamePlayScene! You rest Assured because this time GDX Engine called the method initialize (), update () and render () of the items in GameScene rather for you.
In Bucket class, we used the “DropCollection” service. This service is not available in first the place so you must do two steps to make DropCollection service available.
1.    Ensure DropCollection execute interface IService
2.    uses method addService () of Game object services to make the drops into a game object services and all support services that will use the game DropCollection this service.
The code below will initialize for bullets and make bullets using as game service.
//initialize for bullets
              drops = new DropCollection(getGameServices()); 
              getGameServices().addService(drops);
              addDrawbleObject(drops);

Complete the game with class CatchDropGame

If you really have reached this step, congratulations! you almost had your first complete game using GDX Engine! Here the code of CatchDropGame class
public class CatchDropGame extends Game{

       @Override
       public void create ()     
{
              / / initialize settings and assets
              BaseGameSetting baseGameSetting = new DefaultGameSetting ();
              IGameAsset asset = new Asset ();
             
              / / initialize game service for all scene can use later
              initializeGameService (asset, baseGameSetting);
             
              / / initialize the scene (s) and add them to scenes collection
              IScene scene = new GamePlayScene(this.getGameService ());
              addScene (scene);
              / / Active the gameplay scene , initialize the active scene
              getGameService (). changeScene(classGamePlayScene.);
      
Create () method of the Game class is Called as soon as the game is started. You create the Game Asset and game setting to initialize the game-service, you create the scene, add scene in the game, and activate the scene you wish by calling the method changeScene () from the game services. Since you have initialized Games service, The game services is not null and you will not have common exception "Null Object Reference ..."

No comments:

Post a Comment