Jump to content

  • Log In with Google      Sign In   
  • Create Account


Basic Questions on animating tile based games & frameworks/engines


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
13 replies to this topic

#1 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 09 October 2012 - 08:18 AM

Hello,

I've been working on making a simple prototype in java (netbeans) for a game for the last few months. The game is a tile & turn based strategy/RPG in the vein of JA, X-Com, Fallout.

I've built the majority of the game logic - the character system (Stats, skills, perks, levels, inventory), the TB combat system (with melee and ranged), some basic A.I.s , simple GUIs, a system for loading enemies and PCs, and a fair bit of the content: weapons (40 or so), armour, equipment, enemies. The plan was to get all the basics working and then recruit a graphics and sound person to help, when I'm fairly sure I'll be able to finish the game.

The main problem is my lack of knowledge on manipulating images. The current set up for the map (which I strongly suspect is not a good one), is a 16*30 arraylist of buttons with imageIcons. Characters (which are just portraits ATM) can be selected and moved around this grid, and the button Arrays imageIcons are changed appropriately. My main question at this point is: 1) can a simple level of animation be achieved with imageIcons - i.e. walking between tiles/buttons, crouching, firing weapons, melee attacks be easily done, even in straight down 2d? If so, how?

Here are some other thoughts/questions - please feel free to comment on any, or recommend reading.

2) Does anyone know how animation was achieved in the likes of JA, X-Com, Fallout, which all appear to be tile based?

3) I've considered some other ideas like putting a graphical layer on top of the buttons (not sure how), and somehow corresponding the upper graphical layer to what is happening beneath on the button array. Could this be achieved, and how difficult would it be.

4) The other thing I am considering is discarding the button array creating a single map for the level, and putting a set of coordinates on it which characters can move to. Would this be any good?

5) Finally, is there a better engine/framework I could use for the project? Definitely not opposed to moving to something else if it would allow me to handle the graphical end more easily. Any recommendations?

If I haven't provided enough detail, or have been unclear, please feel free to ask. Thanks for your help!

Sponsor:

#2 Arthur Souza   Members   -  Reputation: 1398

Like
1Likes
Like

Posted 09 October 2012 - 08:44 AM

I wouldn't know exactly what framework to use with Java, but you sure are better looking for one, such as XNA on c#, PyGame on Python, etc.

Specially since you are on the beginning, and thinking about prototyping, try to lookup some java game frameworks.

A.

Lotus - Action RPG In development http://www.gamedev.n...die-rpg-engine/ |
Personal blog In Portuguese: lotuzgames.wordpress.com |


#3 Bartley   Members   -  Reputation: 121

Like
1Likes
Like

Posted 09 October 2012 - 09:15 AM

Thanks Arthur. Doing some XNA tutorials at the minute, seems much better for handling graphics. Might try Unity afterwards and hopefully will have a solution by then!

Daithi

#4 Arthur Souza   Members   -  Reputation: 1398

Like
0Likes
Like

Posted 09 October 2012 - 10:20 AM

Good to see that you are platform agnostic! :P Good luck on your projects, any questions regarding XNA, just shoot (on the XNA board of course, haha)

A.

Lotus - Action RPG In development http://www.gamedev.n...die-rpg-engine/ |
Personal blog In Portuguese: lotuzgames.wordpress.com |


#5 !Null   Members   -  Reputation: 380

Like
1Likes
Like

Posted 09 October 2012 - 02:09 PM

If you are using Java + Netbeans have you had a look at Slick2D.
http://slick.cokeandcode.com/

I've used it for many 2d tile based game project. It has support for tiled maps and makes animation easy.
If you wan't more info you should have a look at it and you can send me a message or something. or ask more questions here.
/********************************************************************************\
/**********************He Who Dares, Wins**********************************\
/********************************************************************************\

#6 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 09 October 2012 - 02:54 PM

Thanks !Null. I did have a look on the site earlier, but it seemed like it hasn't been updated in a while. Is it still usable with the current version of java?

My main worry at the moment is that I have made a bad choice with how I created the map. It's a panel with gridlayout, and each element of the grid has a button with an imageIcon. I will probably use bird's eye 2d, rather than iso, as this is my first attempt at a serious game. The bit that troubles me most is animating movement (i.e. a character walking between between buttons). Would this be done by simultaniously updating the button at the current location and the destination button several times, to show the character leaving one button and entering the other?

I am prepared to develop on something else (maybe XNA, or Unity) if it would simplify implementing the graphics, but I'm far more familiar with java. Any advice on this?

Thanks a lot, this has been giving me a real headache!

#7 !Null   Members   -  Reputation: 380

Like
1Likes
Like

Posted 09 October 2012 - 03:38 PM

Oh yeah Slick2D is up to date. You just need to download the Nightly build (as that's always the most recent update)

I'm just a bit confused as to why you have a grid of buttons. Do you want to select characters with the mouse or whatever and have them move to that point (animating while moving?)

If so there are easy ways of doing this. Also you can used Tiled editor to make your tiled maps and loads them into java with the Slick2D methods
/********************************************************************************\
/**********************He Who Dares, Wins**********************************\
/********************************************************************************\

#8 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 09 October 2012 - 05:03 PM

I'm just a bit confused as to why you have a grid of buttons.


It may not be a very good set up. I mainly used it because I already had used something similar to make a battleships game. Each button corresponds to a tile object, which stores among other things the ID of the actor (-1 if vacant).

Do you want to select characters with the mouse or whatever and have them move to that point (animating while moving?)


Yep, that's it. You click to select the actor within, then click again to move. It works, but it looks bad. There are lines separating the buttons (which can probably be removed), and animating movement between buttons is a worry. Can I ask how you built the map for your games? Thanks again

#9 Arthur Souza   Members   -  Reputation: 1398

Like
2Likes
Like

Posted 09 October 2012 - 06:51 PM

I use an array of integers that stores the id of a texture, which is a 32x32 image. Also store the width and height of the map. Then I transform that array into a 2d array which is basically the map, a cartesian map of tiles, each one being a texture drawn on screen.

Google "tile engine nick gravelyn" and youll find a series of XNA tutorials on this.

A.

Lotus - Action RPG In development http://www.gamedev.n...die-rpg-engine/ |
Personal blog In Portuguese: lotuzgames.wordpress.com |


#10 !Null   Members   -  Reputation: 380

Like
1Likes
Like

Posted 10 October 2012 - 05:29 AM

Okay. The simplest way to do a tiled map with textures (images) is simple
You have your width of your window and the height of the window (say 640x480)
and then you want to assign a tile size. this will be the size you want the 'environment' to be (not the characters or enemies etc) so trees,grass all that stuff.
I usually pick either 16x16, 32x32 or 64x64 for my tiles. Then (if we are not using slick and tiled maps) we do the following below.
static final int WIDTH = 640;
static final int HEIGHT =480;
int tileSize = 32;
int map[][] map;
Random rand = new Random();
public void init()
{
	 map = new int[WIDTH / tileSize][HEIGHT / tileSize]
	 for(int i = 0; int i < map.length; i++)
	 {
		  for(int j = 0; j < map[i].length; j++)
		  {
			  map[i][j] = rand.nextInt(2);
		  }
	 }
}
}
we create a 2D array for our map (just like a matrix) and the size is basically how many tiles across and down your map is. So 640 / 32 = 20. 480 / 32 = 15. (you can obviously create your own maps and load them in from a text or something but That's too much detail for the moment.
after that all you have to do if loop through the code. if the element at index i,j = 0 we draw nothing (or a default tile) and if the element at index i,j = 1 we draw something interesting
for(int i = 0; int i < map.length; i++)
	 {
		  for(int j = 0; j < map[i].length; j++)
		  {
			   switch(map[i][j])
			   {
				    case(0):
						 g.drawImage('your default tile',i*32,j*32);
						 break;
				    case(1):
						 g.drawImage('your interesting tile',i*32,j*32);
						 break;
				    default:
						 g.drawImage('default tile',i*32,j*32);
						 break;
				 }
			   }
		  }
	 }
and this will draw out your tile map. after which you draw your player after you draw you map, so that the player is rendered on top of the map and not behind. then when you want to move a player between somewhere on the map. you can just to tile movement (eg move it by a tile at a time rather than pixels at a time)
The slick2D way is a lot easier in my opinion though.
If you make a 2D map using Tiled map editor. you can load and display the map very quickly like this
import org.newdawn.slick.*;
public class Game extends BasicGame
{
	 private TiledMap map;
	 public Game()
	 {
		  super("This is where you put the title");
		  map = new TiledMap("location")   //and some other parameters I can't remember off the top of my head. Check the javadock for slick
	 }
    public static void main(String[] args)
    {
		  AppGameContainer gc = new AppGameContainer(new Game());
		  gc.setDisplayMode(640,480,false);
		  gc.start();
    }
@Override
public void init(GameContainer container) throws SlickException
{

}
@Override
public void update(GameContainer container, int delta) throws SlickException
{

}
@Override
public void render(GameContainer container, Graphics g) throws SlickException
{
	 map.render();
}

}
Simples ;). and you can still do your gird movement and stuff the same way.
Sorry if this is a long winded explanation. if something is unclear just ask. hope this helps
/********************************************************************************\
/**********************He Who Dares, Wins**********************************\
/********************************************************************************\

#11 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 10 October 2012 - 07:14 AM

Thanks a lot !Null! I'm going to try this out now!

#12 !Null   Members   -  Reputation: 380

Like
0Likes
Like

Posted 10 October 2012 - 07:15 AM

Sweet. be sure to let us know how you get on
/********************************************************************************\
/**********************He Who Dares, Wins**********************************\
/********************************************************************************\

#13 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 11 October 2012 - 09:29 AM

** CODE PROVIDED BY !NULL**

Getting somewhere with it, but hindered by limited knowledge of the graphics class.

This is the launcher class:

package graphicstester;
import javax.swing.JFrame;
public class GraphicsLauncher
{
	public static void main(String[] args)
	{
		GraphicsTester gt = new GraphicsTester();
		gt.setTitle("Graphics Tester");
		gt.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		gt.setVisible(true);
	  
	}
}

This is the first attempt at the tester. The frame loads, but doesn't draw the images. This may be because the paint method is automatically by the frame too early.

package graphicstester;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.ImageIcon;

public class GraphicsTester extends JFrame
{
	static final int WIDTH = 640;
	static final int HEIGHT = 480;
	int tileSize = 32;
	int map[][];
	Random rand = new Random();
	Image tile1;
	boolean imagesLoaded;
	Graphics g;
  
  
/* CONSTRUCTOR */
  
	public GraphicsTester()
	{
		setSize(WIDTH, HEIGHT);
		loadImages();
		init();
	  
		setVisible(true);
	  
	}
/* METHODS */
  
	public void init()
	{
		map = new int[WIDTH / tileSize][HEIGHT / tileSize];
	  
		// Assigns an integer value to each tile
		for(int i = 0; i < map.length; i++)
		{
			for(int j = 0; j < map[i].length; j++)
			{
				map[i][j] = 0;
			}
		}
	}
  
	// Loads Images
	public void loadImages()
	{
		tile1 = new ImageIcon("c:\\My Folder\\Game Development\\Testing\\Graphics Testing\\Graphics Tester\\Graphics\	ile1.jpg").getImage();
	  
		if(tile1 != null)
		{
			imagesLoaded = true;
			System.out.println("GraphicsTester.loadImages(): Images loaded = " + imagesLoaded);
		}
	}
  
	// Draws the map according to the assigned integer values
	public void paint(Graphics g)
	{
		//Graphics g2 = (Graphics2D)g;
		// Works through the rows
		for(int i = 0; i < map.length; i++)
		{
			// Works through the columns
			for(int j = 0; j < map[i].length; j++)
			{
				switch(map[i][j])
				{
					case(0):
						g.drawImage(tile1,i*32,j*32, null); // Problem, graphics hasn't been initialised
						break;
//					case(1):
//						g.drawImage('your interesting tile',i*32,j*32);
//						break;
					default:
						g.drawImage(tile1,i*32,j*32, null);
						break;
				}
			}
		}
	}
}

This is the second attempt. It throws a null pointer at 78, probably because the graphics object hasn't been initialised. Did some tutorials on drawing images, but not sure how to draw from a loop. Any hints on solving this? At any rate, I'm going to have to learn more about the fundamentals. Time for a trip to the library!

package graphicstester;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.ImageIcon;

public class GraphicsTester extends JFrame
{
	static final int WIDTH = 640;
	static final int HEIGHT = 480;
	int tileSize = 32;
	int map[][];
	Random rand = new Random();
	Image tile1;
	boolean imagesLoaded;
	Graphics g;
  
  
/* CONSTRUCTOR */
  
	public GraphicsTester()
	{
		setSize(WIDTH, HEIGHT);
		loadImages();
		init();
		drawMap();
		setVisible(true);
	  
	}
/* METHODS */
  
	public void init()
	{
		map = new int[WIDTH / tileSize][HEIGHT / tileSize];
	  
		// Assigns an integer value to each tile
		for(int i = 0; i < map.length; i++)
		{
			for(int j = 0; j < map[i].length; j++)
			{
				map[i][j] = 0;
			}
		}
	}
  
	// Loads Images
	public void loadImages()
	{
		tile1 = new ImageIcon("c:\\My Folder\\Game Development\\Testing\\Graphics Testing\\Graphics Tester\\Graphics\	ile1.jpg").getImage();
	  
		if(tile1 != null)
		{
			imagesLoaded = true;
			System.out.println("GraphicsTester.loadImages(): Images loaded = " + imagesLoaded);
		}
	}
  
	// Draws the map according to the assigned integer values
	public void drawMap()
	{
		//Graphics g2 = (Graphics2D)g;
		// Works through the rows
		for(int i = 0; i < map.length; i++)
		{
			// Works through the columns
			for(int j = 0; j < map[i].length; j++)
			{
				switch(map[i][j])
				{
					case(0):
						g.drawImage(tile1,i*32,j*32, null); // Problem, graphics hasn't been initialised
						break;
//					case(1):
//						g.drawImage('your interesting tile',i*32,j*32);
//						break;
					default:
						g.drawImage(tile1,i*32,j*32, null);
						break;
				}
			}
		}
	}
}

Edited by Bartley, 11 October 2012 - 09:33 AM.


#14 Bartley   Members   -  Reputation: 121

Like
0Likes
Like

Posted 12 October 2012 - 08:48 AM

Figured it out, for what that's worth. Posting incase it's of any use to the next guy!

import javax.swing.*;
import java.awt.*;
import javax.swing.ImageIcon;
public class ImageLoader extends JFrame
{
   
/* INSTANCE FIELDS */
   
    private Image sand;
    private Image grass;
    private final int tileSize = 64;
    private final int WIDTH = 256;
    private final int HEIGHT = 192;
    private int [][] map;
   
/* CONSTRUCTOR */
    public ImageLoader()
    {
	    setSize(WIDTH, HEIGHT);
	    loadImages();
	    prepareMap();
	    printMapIntegers();
	    setVisible(true);
	    repaint();
    }
/* METHODS */
   
    // Loads Images
    public void loadImages()
    {
	    sand = new ImageIcon("C:\\My Folder\\Game Development\\Testing\\Graphics\\sandTile.png").getImage();
	    grass = new ImageIcon("C:\\My Folder\\Game Development\\Testing\\Graphics\\grassTile.png").getImage();
    }
   
    // Sets an Integer for each tile, representing whether it is grass or sand
    public void prepareMap()
    {
	    map = new int [HEIGHT / tileSize][WIDTH / tileSize]; // R = 3 / C = 4
	    for(int r = 0 ; r < 3 ; r++)
	    {
		    for(int c = 0 ; c < 4 ; c++)
		    {
			    // Is a SAND TILE
			    if(c > 0 && c < 3)
			    {
				    map[r][c] = 0;
			    }
			   
			    // Is a GRASS TILE
			    else
			    {
				    map[r][c] = 1;
			    }   
		    }
	    }
    }
   
    // Prints Integer Values for tiles
    public void printMapIntegers()
    {
	    for(int r = 0 ; r < 3 ; r++)
	    {
		    for(int c = 0 ; c < 4 ; c++)
		    {
			    System.out.print("" + map[r][c]);
		    }
		    System.out.println("");
	    }
    }
   
    // Paints the map
    public void paint(Graphics g)
    {
	    for(int r = 0 ; r < 3 ; r++)
	    {
		    for(int c = 0 ; c < 4 ; c++)
		    {
			    // If integer value is 0, draw SAND
			    if(map[r][c] == 0)
			    {
				    g.drawImage(sand, c*64, r*64, null);
			    }
			   
			    // Else, draw GRASS
			    else
			    {
				    g.drawImage(grass, c*64, r*64, null);
			    }
		    }
	    }
    }
}





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS