Monday, January 21, 2013

TankGame 03 - Java 2D game development tutorial with Slick, MarteEngine, Lwjgl

Posted by sudheera On 7:50 AM


Now we have configured the environment,(If not, please refer the previous post) so we can create the game world with the entities in it. In my Netbeans project I have several Java classes representing various entities in the game. First we need to setup the "game world" which contains  all the players, blocks etc, 

So for the game application we need several types of java classes to handle various  tasks of the game. In my project I have divided the entire task into four parts. This approach is makes life easy for programmer. I have four software packages in my project.

Communicator package handles the communication and provide interface to get/send data for the rest of program. Configuration package contain all the configuration data including socket numbers foe communication etc. All the entities we have used in the application are list under the entities package. Game world class and other main classes are located inside the other package.

  OK now let's do coding. You can take a look at the code developed so far by me by following this link : github


First Step : Create the game container

The class with the main method (view here)should look like this way. It should extend the StateBasedGame. And in the main method it should initiate a  Application game container like this.


 AppGameContainer app = new AppGameContainer(new TankGametest02_GUI("Tank Game"));  

And then we can set the display mode of the game window, and the refresh rate. after that we can start the application.


 app.setDisplayMode(1280, 650, false);  
 app.setTargetFrameRate(60);  
 app.start();  

When we  start the game we need to initiate some sates, like load some configuration data into the program or load images from storage which we plan to include in the game later. This requirements can be achieved by overriding the method  initStatesList() .


1:    @Override  
2:    public void initStatesList(GameContainer gc) throws SlickException {  
3:      try {  
4:        ResourceManager.loadResources("data/resources.xml");  
5:        config.loadData();  
6:      } catch (IOException ex) {  
7:        Logger.getLogger(TankGametest02_GUI.class.getName()).log(Level.SEVERE, null, ex);  
8:      }  
9:      addState(new GameWorld(GAME_STATE, gc));  
10:      enterState(GAME_STATE);  
11:    }  

In line number 4, I have loaded the images using resource manager, take a look at the resources.xml file here. And  in the 5th line I have initiate the variables in config class using the configuration data entered in configuration property file located inside the configuration folder. take a look. That's all for this class. It just creates the game container and starts it.



Second Step : Create the game world
  
We need a "world" for all these tanks, bricks, stones and all to live in.  So here we create the GameWorld class by extending world class. 

Here in this class we need to override several methods in order to keep up the functionalists of the game world. These methods are called by the game engine so we don't have to worry about it.

1. Enter the game. Here in this example enter method doesn't do anything useful.

   @Override  
   public void enter(GameContainer container, StateBasedGame game) throws SlickException {  
     super.enter(container, game);  
   }  

2. Initi() method can be used to initiate game world details. I have used it here to create the background image(Load from the resource manager) and set up the bricks, stones and water in the tanks game.(non moveable objects)

 @Override  
   public void init(GameContainer gc, StateBasedGame game) throws SlickException {  
     super.init(gc, game);  
     gc.setAlwaysRender(true);  
     gc.setUpdateOnlyWhenVisible(false);  
     //create background  
     createBackground();  
     container.setAlwaysRender(true);  
     try {  
       setup(game);  
     } catch (IOException ex) {  
       Logger.getLogger(GameWorld.class.getName()).log(Level.SEVERE, null, ex);  
       System.out.println("IOException @setup()" + ex.toString());  
     }  
   }  

3. render method will render graphics you can draw images, lines, text etc which will render throughout the game. I rendered the background and the grid.
   @Override  
   public void render(GameContainer gc, StateBasedGame game, Graphics g) throws SlickException {  
     //render background  
     g.drawImage(background, 0, -130);  
     g.drawImage(arenaImage, 20, 20);  
     super.render(gc, game, g);  
     //render Points table  
     setPointsTable(g);  
   }  


4.This is the most important method. The update method will be called by the game engine while the game is running couple of milliseconds apart. Number of milliseconds between two calls to the update method is given by delta, which send as an parameter to the update method by the engine. Inside this method we can specify the thing we want to do during the game time.

   @Override  
   public void update(GameContainer gc, StateBasedGame game, int delta) throws SlickException {  
     super.update(gc, game, delta);  
     String reciveData = com.reciveData();  
     String[] section = reciveData.split(":");  
     if (section[0].equals("C")) {  
       setCoins(section);  
     } else if (section[0].equals("L")) {  
       setLifePacks(section);  
     } else if (section[0].equals("G")) {  
       updatePlayers(section);  
     }  
   }  

All other methods for just keep above four method body clean and simple.

So I guess that's all for this post, we will discuss about entities in the next post... :-)