Thursday 4 April 2013

Introduce to game SpaceWar


When you read this article, I presume it's you complete the tutorials about basic game: catchdrop in a [ Introduce to Dropcatch game ]. This tutorial Refers to the feature, not a step-by-step as tutorials on game DropCatch.
During this tutorial, I will cover more advanced Techniques when you program a 2D game that GDX Engine support . It Include about the particle effects, load and save the new setting from the serializable data, scrolled background, to create and display a optional menu, limit using the keyword new, create animation ...
This is a real game and there is a number of factors to attract players. In the game you control a ship traveling in the universe. You sail the ship, Avoiding the Meteorites in space to not have them destroyed. You are equipped to actively missile can destroy the meteors that is flying too close. When the asteroid is destroyed, a nice explosion effects will occur to illustrate the clash the between the missile and Asteroids.

Creating particle effects. (File gamePlayScene.java)

GDX engine has class ParticleEffectManager help you Easily manage your particle effects in the game. You can refer to the article [this] to understand the particle effect and particle editor is.
To use particle effects in the game, you need to create an instance of ParticleEffectManager class in a Scene that used as Playing Scene, Add the ParticleEffectManager to Scene's collection and to Game Services.
// initialize for effects
effects = new ParticleEffectManager(getGameServices());
addDrawbleObject(effects);// Add effects to Scene's collection
getGameServices().addService(effects);  / / Add effects to the game service.

ParticleEffectManager class is Manager of all particle effects, you need to add new particle effect to the manager , for example:

effects.
addParticleEffect("explosion", "Spacewar /explosion.pp", "spacewar");

parameters above: string key of particle effects, particle effect files (Created by Particle Editor tool of Libgdx), and the name of the folder containing the image that is used by particle effect.
To use particle effect in a given game object component, you need to take the corresponding service of ParticleEffectManager to variable reference effects:

effects
 = getGameServices (). getService(ParticleEffectManager.class);

Then you call the method invoke () to generate effect
effects.invokeEffect("explosion",x, y); / / In Player.java file
Particle Effects that have key "explosion" will soon be generated in the x and y coordinates passed.

load and save settings from serializable data (File GameData.java)

Now I will show you how to save and load settings from a any serializable object.
First you need To have a class that contains the data you need to save , of course it must have serializable interface.
public class GameData implements Serializable {
       public int[] highscores = {50, 40, 30, 20, 10};
       public boolean PlaySound = false;

The class 
above will have two setting is Highscores and PlaySound. You absolutely add value as you wish such as playerLevel ... playerHealthy ... CurrentPosition ...
You can load gameData from the saved file or create new save file using the default values ​​in the GameData class if the save file is not created. If the file is not existing, loadSetting () method will return null. GameData variable is a static variable in your Game class:
DefaultGameSetting.savefile = ".spacewardata";
BaseGameSetting baseGameSetting = 
new DefaultGameSetting();
gameData = baseGameSetting.loadSetting(GameData.class);
              if(gameData == null)
              {
                     gameData = new GameData();
                     baseGameSetting.saveSetting(gameData);
              }
when you need to save the setting, simply call the game services, game settings and save:
getGameServices (). getGameSetting (). saveSetting (SpaceWar.gameData);
In above example code, saveSetting () method Saves the information from static turn gameData to the saved file named "spacewardata", or create a new file if it does not already exist. gameData is required to make sure that not null.

Creating scrolled background (file Background.java)

technique of creating scrolled background we'll render 2 texture background, this two background will move at the same speed in the same direction, if there is a background beyond the border of the screen, it will be reset to the position so it always would be located in front of the other background and so on. Two background’s position will be exchanged each other.
You need a variable to store the value is calculated position for the background as well as defined time to reset position of background:
    screenheight = GDX.graphics.getHeight ();
           screenwidth = GDX.graphics.getWidth ();
           / / Set the screen position to the center of the screen.
           screenpos = new Vector2 (screenwidth / 2, screenheight / 2);
           / / Offset to draw the second texture, when necessary.
    texturesize = new Vector2 (getRegionWidth (), getRegionHeight ());
    setX
(screenpos.x-screenwidth/ 2);

update the location and render the background
@ Override
       public void update(float gameTime) {
           screenpos.y + = gameTime * 100;
           screenpos.y = screenpos.y % getRegionHeight();
       }
       @ Override
       public void render(float gameTime)
         // Draw the texture, if it is still onscreen.
           if (screenpos.y < screenheight)
           {
              setY(screenpos.y);
              super.render(gameTime);
           }
           // Draw the texture a second time, behind the first,
           // To create the scrolling illusion.
           SetY(screenpos.Y - texturesize.Y);
           super.render(gameTime);
}
      
Because the background is a drawable game component, than you absolutely add it to the collection of the game scene. However the order when you add objects in the scene will decide the order in which the object is to update and render. Their Principle is "First-in first-out" Means that the first object to be added will be the first object to be updated and render. Because this is a background, which means than you need to render the background first then render to the other object. If you do the opposite, the background will render in fornt of other objects and background will completely cover up the other objects that have been rendered before.
// Background is the first the object added into scene
addDrawbleObject
(new Background (getGameServices ()));
// add other stuffs
              addDrawbleObject(player);
              addDrawbleObject(bullets);

Create a optional Menu (File TextMenu.java, TextMenuManager.java)

To create the menu, you need to create two your own classes for MenuItem and MenuManager.
public class TextMenu extends CollectionItem implements IMenuItem {

       public String text;
       public Vector2 position;
       public boolean selected = false;

       public TextMenu(String text,boolean select, Vector2 position) {

              this.selected = select;
              this.position = position;
              this.text = text;
       }
MenuItem simply extends Collection items and have interface IMenuItem as the above code is . Since this MenuItem using bitmap fonts to render text content for the MenuItem, it needs the text String property. If you want to use a texture to render the MenuItem, you simply replace the String text; with a variable like Texture menuTexture; and change the method getContent() return texture valueselected variable Signal the user had selected this item or not.
In TextMenuManager class, you only need to override the render () method. Since this is the text menu, so using the render () method is as follows:
@Override
       public void render(float gameTime) {
              for(TextMenu item : objectCollection)
                     if(item.isSelect())
                     {
                           getGameServices().drawText(Asset.bigFont, item.getContent(), item.getX(), item.getY());
                     } else
                     {
                           getGameServices().drawText(Asset.smallFont, item.getContent(), item.getX(), item.getY());
                     }
       }
If you are doing a texture menu, simply replace the DrawText method () by method drawTexture () method or drawTextureRegion () from Object Game Services and render your menu item.

limit usage of the new keyword

you would normally use new keyword when creating a new object, you call the new keyword before a constructor of the object you want to "new" and then you can use the object it comfortably without having a exception like "Null Object Reference ..." But what is behind the new  keyword?
You knew Java is managed code, which means instead of having to hand the memory for the object you want to create as in native code, Java Virtual Machine (JVM) will automatically allocate memory and recall memory for you, you just need to code code code class, create new object, and then use that an object, and ... not anymore! JVM will automatically freeing memory when it is necessary (for example: lack of device memory). But it would be wiser if you have Capable of Reducing Wasted memory possibly arise in the game, and the easiest way is not to abuse the variable declaration as well as the new keyword.
When you new a object, that is, the JVM will take RAM to store the new object, and you do not have any way to dispose of objects, you just can only wait for the JVM automatically dispose the object. To limit the negative side, objects containing resource as texture, the texture region, Music... in Libgdx was built by native code to optimize program, and can easily and dispose object using the method dispose () of the object to free memory. In GDX Engine, Because it is completely based on Libgdx framework so you can totally do the same.
In spacewar game I have come up with a solution to refrain "new object". You see in class BullectCollection:
public void addOrRecycleBullet(Vector2 position)
       {
              //recycle dead bullet if the dead bullet is available
              for(Bullet b : objectCollection)
              {
                     if(b.isDead())
                     {
                           b.setDead(false);
                           b.position.set(position);
                           return;
                     }
              }
              //add new bullet to collection
              Bullet b = new Bullet(position, -5);
              b.initialize();
              addItem(b);
       }
When the player presses the space key, a bullet will be emitted from the player and only move Vertically upwards. This bullet can created by keyword new or recycled from a dead bullet (bullet can turn dead = true). When bullet recycled, we no need to use the new keyword and therefore not have any more space on the RAM to be assigned for store the bullet. With a the dead bullet, we moved the dead bullet out of the screen, so the dead bullet will not cause any effect on gameplay. When you setDead (true) for a collection item, meaning that enable and visible object of which would be false. Object will not be automatically updated and rendered by Game scene, so it also reduces the CPU load.
For example: method setDead () of the Bullet class: 

public void setDead(boolean value) {
       super.
setDead(value);
              position.x = -100;
              position.y = -100;
}
        

Creating Animation

Here is rotated croped animated textures of Meteor, illustrates the animation of meteor in the file asset/ spacewar / sprite.png. You can see the animation of 8 frames, carry the rotate of the meteor, of course you can render this animation by directly rotate the sprite batch, no need to frame-based animation. However, to illustrate how to create animation, we will not rotate with the sprite batch but we will use the texture animation below.
Easiest way to create your animation on a object is make the object Inherits from class animated sprite, You need an instance of Animation class passed into the constructor of Meteor:
For examplepublic class Meteor extends AnimatedSprite {
public Meteor(IGameService services, TextureRegion region, Animation animation) {
              super(services, region, animation);
              resetPosition();
       }
The Animation class is actually very simple, an animation consists of three variables:
public Animation(boolean isLooping, float frameTime,int numFrame) {
              super();
              this.numFrames = numFrame;
              this.isLooping = isLooping;
              this.frameTime = frameTime;
       }
isLooping Controls the ability to loop the animation, time indicate the during time for moving on to the next frame and the numFrames indicate the total number of frames in the animation.
To control the animation mobe in sole discretion, you just use method playAnimation () of the animated sprite class and pass in the animation object desired. The constructor itself play the animation from animation parameter of AnimatedSprite ‘s constructor that you pass in from the outside. Method playAnimation () will directly change the animation of the object. You can specify the new region on textures in method playAnimation () to correspond the animation that you want to play.
Animated sprite has two events to control your animation easy, that is onFrameChanged () Occurs when the frame of the animation changed and is onAnimationChanged () Occurs when the animation of the animated sprite changed.
For example: Meteor changing region on the texture if the frame changed:
@Override
public void onFrameChanged() {
  setRegion(getRegionX(), 50 * this.frameIndex, getRegionWidth(), getRegionHeight());
}
If you notice in sprite.png files, you will see that the new frame in the animation of the meteor is always below of the current frame, but our position-y 50 pixels apart. The first frame position-y is 0. So the code above will be controlled to animation takes place in accordance with our intentions.
When you write the update() method for Meteor, you must keep the update() method from the Animated Sprite class by remaining the code “super.update (gameTime);” to make object update animation.

No comments:

Post a Comment