Archive for the ‘Game development’ Category

Last games I made were all top-down, this had quite some advantages, for one you only need one set of animations/graphics for all directions and with an  isometric view, sprites can overlap.

I solved this in my code to seperate the static content from the dynamtic content (static vegetation, vs moving units/agents).  In my case there are less agents than vegetation. So I loop through the static objects and see what it’s y positions is. This makes sure you only have to sort your static objects once on their y position, and you’ll only have to keep track of the y position of your moving agents. Besides sorting agents on the same level, I’ve also got different Z levels for rendering, this what keeps the tree canopy above the trunk of tree with a higher Y value.

public void draw(Graphics graphics) throws SlickException 
{
 
 Iterator iter = agentViews.values().iterator();
 float agentY = 0;
 AgentView agView = null;
  // Get the first agent
 if(iter.hasNext())
 {
   agView = (AgentView) iter.next();
   agentY = agView.getModel().getY();
 }
 // Loop through all the static objects on the same level
 boolean processingAgents;
 for(AgentView vegView : vegetiationViewsL0) 
 {
 
 float y = vegView.getModel().getY();
 
 if(agView != null)
 {
    // As long as the y  of the static object is higher (so lower on the screen) it will draw it first
 if(y >= agentY )
 {
   vegView.draw(graphics);
 }
 else
 {
    // Else draw the agent and check if there are other agents with a higher y than the current static object
   agView.draw(graphics);

 processingAgents = true;
 while(processingAgents)
 {
   if(iter.hasNext())
   {
     agView = (AgentView)iter.next();
     agentY = agView.getModel().getY();
     if(agentY > y)
     {
       agView.draw(graphics);
     }
     else
     {
        processingAgents = false;
     } 
   }
   else
   {
     agView= null;
     processingAgents = false;
   } 
 }
 vegView.draw(graphics);
 //System.out.println("Tree" + y); 
 }
 }
 else
 {
 vegView.draw(graphics);
 }
 
 }

fhZLR3P
Advertisements

And… It’s been a while. I’m still here, but there are so many side projects I’m working on I didn’t get to do much on Battlelance lately. I’ve been playing Dominions 4 a lot currently, while I’m not working at my day work. If you like turn based strategy games and can look past the old fashioned graphics, Dominions 4 is the game is for you. You create a pretender god, select a race (out of more than 75) based on our worlds mythologies and off you go! You fight to become the dominant religion in the world, after the previous god has left the world. In game the possibilities are almost endless. Do you want to turn a simple goat, who was donated to your temple by a poor farmer, into a death mage, riding the winds on his magical carpet all the while wielding a battleaxe with a copper arm you mounted on its body and commanding an army of frost-giants? Well, with this game you can! With more than 2000 different units and monsters, over 800 different spells and over 300 different kinds of items you can do about anything! Have a look here: http://www.illwinter.com/dom4/

We’re hosting our own private dedicated servers, so we created our own web interface to keep track of our turns, Dominions Orchestra. We’ll release it in due time 🙂

On a different note, I’ve been putting in some work in a procedural world generator, based on Perin Noise. I found this wonderful example on how to create your own height maps: http://www.float4x4.net/index.php/2010/06/generating-realistic-and-playable-terrain-height-maps/

This in combination with some nice colouring and fading results into the following landmasses:

Perin noise world

 

 

As said in my last blog post, I’m working on an inventory system. Before all Battlelance characters where just a bunch of stats, from now on they’ll be stats and items! Ain’t that cool.

I’ve already got some work into a proof of concept of the inventory system I discussed earlier, and I have the basics working in game.

Each unit has a “Backpack” and a few equipment slots (to be determined). Some items have effects if they sit in your backpack, such as the health potion in the next example. Others give abilities and effects if they are equipped, such as the warhammer and full-plate armour in the said example.

Here are some screenshots on demonstrate my meaning:

Items in backpack

Items in backpack

Items equiped

Items equiped

In this blog I don’t want to just ‘praise’ my games, but I would like to give some technical insights in how they technically work. Mind you, the solutions that I’m using are not in any way the perfect solution to certain problems. They work for my situation and if you’re looking to copying it, that’s fine but a different context might require a different solution.

Another warning, I’m neither a great writer nor is my first language English. So I might become a bit incoherent as I jump from one subject to another.

Today I want to talk about save games. There are different ways to implement saving/loading in your game. One way to do it is to save all the current agents (characters and other ingame objects), but this means you’ll have to save all the effects and the current state of them as well. Like an invisibility spell that wears off in one more turn.

Battlelance saves its games by first of all saving the initial setup, which is just an object with a few arrays to record per playable character the player ID, player name, class, team number and some game master attributes like spawns, traps and abilities. With this information and the map the game can be set to its start position.

Once the players start the game all kind of data is being transferred over the network, to make sure this all happens in the right order and no threads access the same resources at once, each event that the game receives (movement, damage, summons, end turn, etc. etc.) is being push into a queue and afterwards processed. I’ll go more into this in another blog about the multiplayer aspect of the game. Sufficient to say is that these events constitute the consequences off all the actions that have taken place. So if somebody attacks, only the damage (if any) that’s done is enough to reconstruct the events that have happened.

Once the event is processed it’s stored in a savegame queue and once the game is saved this entire queue with the initial setup, and by replaying each event in turn the game is progressed to the same state as before.

Here is a snipplet of code of how the Save game object is written to a file and how it’s retrieved.

public static void SaveGame(GameContainer container, ConcurrentLinkedQueue<Object> saveGame)
{
  try
  {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    ObjectOutputStream oos = new ObjectOutputStream(baos);
    SaveGame game = new SaveGame(saveGame, container.getInitialState(), container.getMap2(), container.getGameName());
    oos.writeObject(game);
    oos.flush();
    byte[] binary = baos.toByteArray();
    String text = Base64.encodeBase64String(binary);
    PrintWriter out = new PrintWriter("save/" + container.getGameName() + ".btl");
    out.println(text);
    out.flush();
    out.close();
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
}

public static SaveGame LoadGame(String file)
{
  try
  {
    String text = readFile(file);
    byte[] binary = Base64.decodeBase64(text);
    ByteArrayInputStream baos = new ByteArrayInputStream(binary);
    ObjectInputStream oos = new ObjectInputStream(baos);
    return (SaveGame)oos.readObject();
  }
  catch (Exception e)
  {
    e.printStackTrace();
  }
  return null;
 }