CHRONICLES OF A VIDEOGAME IN JAVA – 6. NPCs

Previously on the Chronicles of a Videogame in Java: Collision Detection for Dummies.

The code discussed below is already available on my GitHub page at theBoyWithNoName (“npcs” branch). Please feel free to download it to take a better look. Ask me anything about it.

dsads
Welcome back to the journey of “The Boy With No Name”, a 2D platform game that I’m coding from scratch in Java. Today I’m going to talk a bit about NPCs, acronym that stands for Non-Playable Character. For those of you who may not know, NPCs in videogames are basically characters that you meet but can’t directly control. In my experience, there can be three types of NPC in a videogame:

The unavoidable one is a part of the story. The main character is forced to interact with him in order to move forward in the game. (example: Professor Oak in the Pokémon series)

The helpful one helps the main character through his journey giving him wise words or even objects to overcome adversities. (example: the merchant from Resident Evil 4)

The useless one is really just a piece of furniture. He may even speak two or three words in a row but there’s no purpose in those words. They don’t help you finish the game. (example: the citizens in Zanarkand at the beginning of Final Fantasy X)

The kind of NPCs that I’m adopting for “The Boy With No Name” is the second one, the helpful kinda guy. Here’s how it works: all the secondary characters in the game will wait idle in a specific place of a specific level and, only if talked to, they will suggest something or maybe give something to the main character. They will not be unavoidable though: the player will be perfectly able to just walk past them and go on with his adventure. Pretty simple.

npcs

At this point we have delined the standard behaviour of the NPCs in the game. Now it’s time to put this thoughts to code.

From an architectural point of view, I found inconvenient to use some sort of map or bidimensional array for the positioning of the secondary characters in the stage. Do you remember the tiled map we used to position blocks of terrain? Well we could have used the same concept to store current NPCs, but to me that’s a crazy thing to do if you don’t plan to put hundreds of secondary little characters in the game.

So yeah, the NPCManger class stores all of the stage’s Non-Playable Characters in a simple array of objects. Informations about where to put the NPC and what the NPC has to say is stored in text files that the NPCManager consults accordingly to the level currently played by the user. So here’s what the class looks like:

public class NPCManager {
	public NPCManager(int currentLevel){
		this.currentLevel=currentLevel;
		currentNPCs=new ArrayList<NPC>();
		loadInformations();
	}
	
	public void initializeStage(int currentLevel) {
		currentNPCs.clear();
		this.currentLevel=currentLevel;
		loadInformations();
	}
	
	private void loadInformations() {
		InputStream is=this.getClass().getResourceAsStream("/npc_info/level"+String.valueOf(currentLevel)+".txt");
		if(is==null){
			return;
		}
		BufferedReader reader=new BufferedReader(new InputStreamReader(is));
		String line=null;
		String[] singleNPCInfo;
		try {
			while((line=reader.readLine())!=null){
				singleNPCInfo=line.split(" ");
				currentNPCs.add(new NPC(singleNPCInfo[0],Integer.valueOf(singleNPCInfo[1]),
						Integer.valueOf(singleNPCInfo[2]),Integer.valueOf(singleNPCInfo[3]),currentLevel));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public ArrayList<NPC> getNPCs() {
		return currentNPCs;
	}
	
	//returns the closest enemy within two tiles of distance (which is 
	//the maximum distance allowed for an interaction with a NPC)
	public NPC closestNPC(int boyRow, int boyCol) {
		NPC closestNPC=null;
		int currentDistance;
		for(int i=0; i<currentNPCs.size(); i++){
			if(boyRow!=currentNPCs.get(i).getRow()){
				continue;
			}
			if((Math.abs(currentNPCs.get(i).getCol()-boyCol))<=MAXIMUM_TALKING_DISTANCE){
				currentDistance=Math.abs(currentNPCs.get(i).getCurrentX()-(boyCol*Tile.TILE_SIZE));
				if(closestNPC==null){
					closestNPC=currentNPCs.get(i);
				} else {
					if(currentDistance<Math.abs(closestNPC.getCurrentX()-boyCol+Tile.TILE_SIZE)){
						closestNPC=currentNPCs.get(i);
					}
				}
			}
		}
		
		return closestNPC;
	}	
	
	private static final int MAXIMUM_TALKING_DISTANCE=2;
	private ArrayList<NPC> currentNPCs;
	private int currentLevel;
}

As you may notice there’s a closestNPC() function that, as you can imagine, is called every time you try to interact with a non playable character. This function finds the closest Non-Playable-Character given the protagonist’s position. But the character can’t interact with people further than 2 tiles, and that’s the reason of the control at line 46 based on the constant MAXIMUM_TALKING_DISTANCE.

An instance of the NPCManager class is stored in the GameManager, the main thread of the game which also controls a set of currently pressed keys and reacts to them in the proper way via the manageKeys() function. Here’s what the manageKeys() function will look like if we bound the <enter> key to the interaction with an NPC:

private void manageKeys() {
		[...]
		if(currentKeys.contains(KeyEvent.VK_ENTER)){
			NPC tempNpc;
			//find the closest npc according to the character's position
			if((tempNpc=npcManager.closestNPC(boy.getRow(),boy.getCol()))!=null){
				
				//if the npc is already talking, keep talking...
				if(tempNpc.isTalking()){
					if(!(tempNpc.continueTalking())){
						listening=false;
					}
				
				//otherwise interact with the npc
				} else {
					tempNpc.interact();
					
					//put the character in &amp;amp;amp;lt;idle&amp;amp;amp;gt; status when he's talking
					boy.stop();
					
					//prevent the character from moving when talking
					listening=true;
				}
			}
			currentKeys.remove(KeyEvent.VK_ENTER);
		}
		
	}

Now what remains to be seen is the actual NPC class, but to be honest there’s not much to explain here. The NPC is similar to the Protagonist (class Boy) in the sense that it has a couple of pixel coordinates and a couple of “tile-coordinates” that identify the position of the secondary character in the tiled map. The pixel coordinates are really just the tile-coordinates multiplied by the size of a tile (which in my case is 64) but you know, it’s handy and a lot more polished to have them stored separately.

What really makes the difference in the NPC class are these guys:

	private boolean talking=false;
	private String[] sentences;
	private int currentSentence=0;
	private int numberOfSentences;	

If the talking boolean is false the game will not display any of the speech balloons associated with the NPC. If true it will display a specific speech depending on how many times the player has talked to this NPC. The times you talk to an NPC are stored in the currentSentence variable, that increments each time you press in front of the guy you want to talk to. The currentSentence integer is also used to iterate over the sentences array, which contains all the lines the NPC is supposed to say in that specific spot of that specific level. The PlayPanel (the JPanel that shows the actual game) will draw the speech balloons accordingly to the NPC position and will fill the speech balloon with the words defined by sentences[currentSentence].

So yep, this is probably the easiest approach you can have to build a working NPC system. But it works:

Aaaaaaand that would be all for today’s diary. Once again, remember that this is not a proper tutorial, but just a “how I make things” kind of thing. So if you have suggestions or you don’t understand what I say, please comment below or get in touch with me on twitter. I’m also on tumblr, drawing stuff. See you soon guys!

Advertisements
CHRONICLES OF A VIDEOGAME IN JAVA – 6. NPCs

Chronicles of a Videogame in Java – 5. Collision detection for dummies

Previously on the Chronicles of a Videogame in Java: Bulding a tiled map.

The code discussed below is already available on my GitHub page at theBoyWithNoName (“collisions” branch). Please feel free to download it to take a better look. Ask me anything about it.

Hi guys and welcome back to our beautiful journey through the development of a 2D platform-game in Java Swing. Today we’re gonna talk about collisions, maybe one of the trickiest topics in the making of a bidimensional game.

Before we start I want to make sure that you remember what a Block object is in my project. A Block object has two important features:

  • It is not movable.
  • It doesn’t involve interactions with the player whatsoever.

Pretty basic stuff. So how did I approach collisions with blocks in my code? Well, what we know is that there are essentially three cases in which you can collide with an immovable block in a 2D platform, and those are: you’re running left, running right or jumping/falling in the air. Now, remember those rectangles we built around each and every object of the game? The bounding boxes? Well, those rectangles are the foundation of collision detection. Here’s a simple picture that explains why:

collisionNoCollision

See the red rectangle around our chill protagonist? That’s his bounding box. The block object you see next to the main character in the picture above has its own bounding box, visually represented by a blue outline. If two bounding boxes intersect, a collision happens.

On the left you can see a situation where the character and the block do not collide. On the right side of the picture, instead, they are colliding pretty hard I’d say. And that’s a situation we don’t want to happen in the game. If the Character is running right and faces a Block object, his bounding box must never intersect the Block’s one.

Now let’s put it to code.

	public void checkBlockCollisions(){
		[...]
		//if last direction was right..
		if(last_direction==KeyEvent.VK_RIGHT){
			
			//get the left side of the bounding box
			int footX=(int)boundingBox.getMinX();
			
			//get the tile position (in the tiled map) 
			//relative to the tile in front of the character
			int tileInFrontOfFootRow=((footY-1)/Tile.TILE_SIZE);
			int tileInFrontOfFootCol=(footX/Tile.TILE_SIZE)+1;
			
			if(tileInFrontOfFootCol<World.COLS){
				//if the tile in front of the character contains a block..
				if(World.tiledMap[tileInFrontOfFootRow][tileInFrontOfFootCol] instanceof Block){
					//..and the character's bounding box intersect the block's one
					if(boundingBox.intersects(World.tiledMap[tileInFrontOfFootRow][tileInFrontOfFootCol].getBoundingBox())){
						//push the character away and re-set its position
						currentX-=DISPLACEMENT;
						boundingBox.setLocation(currentX, currentY);
						currentCol=currentX/Tile.TILE_SIZE;
					}
				}
				
				if(World.tiledMap[currentRow][currentCol] instanceof Block){
					//if the tile the character finds himself in contains a block, act like above
					if(boundingBox.intersects(World.tiledMap[currentRow][currentCol].getBoundingBox())){
						currentX-=DISPLACEMENT;
						boundingBox.setLocation(currentX, currentY);
						currentCol=currentX/Tile.TILE_SIZE;
					}
				}
			}
		} else {
			//the same thing you see above happens here for the left direction 
			[...]	
		}
	}

Notice that when the character runs left or right and his bounding box intersects a Block’s one, he’s pushed away of an amount of pixels equals to the number of pixels he covers with a single step (the DISPLACEMENT value). This way the character’s bounding box can never intersect the Block.

The code you see above works perfectly for side collisions, but it doesn’t help much if our little protagonist is jumping and slamming his head on a block that is placed above him.

As for jump collisions I had to rethink the jump mechanic I talked about in one of my previous posts. “How” you say? Well, first thing I did was splitting the ascending phase and the descending phase of the jump. In particular, when the character is going up we have that the jumping boolean is set to true and the falling is set to false. When the character is going down we have the opposite setting of those variables. To have a specific falling state is really helpful even in other situations: for example I can set it to true when the character doesn’t have a Block object under his feet. This way I can make character fall (increment y position) while falling=true. But collision-wise, we have that the character’s head can only collide if he’s in ascending phase. So here’s how I dealt with the problem:

		
		//if the character is jumping, his head must not touch a block;
		//if it touches a block, stop the ascending phase of the jump (start falling)
		if(jumping){
			
			//row position of the cell above the character's head (in the tiled map)
			int upRow=(int)((boundingBox.getMinY()-1)/Tile.TILE_SIZE);
			
			//tile position relative to the upper-left corner of the character's bounding box
			int upLeftCornerCol=(int)(boundingBox.getMinX()/Tile.TILE_SIZE);
			
			//tile position relative to the upper-right corner of the character's bounding box
			int upRightCornerCol=(int)((boundingBox.getMaxX())/Tile.TILE_SIZE);

			if(currentRow>=0){
				if(World.tiledMap[upRow][upLeftCornerCol] instanceof Block){
					//if the upper-left corner stats intersecting a block, stop the jumping phase
					//and start the falling phase, setting the jump_count to 0
					if(World.tiledMap[upRow][upLeftCornerCol].getBoundingBox().intersects(boundingBox)){
						jumping=false;
						jump_count=0;
						falling=true;
						return;
					}
				}
				if(World.tiledMap[upRow][upRightCornerCol] != null){
					//if the upper-right corner stats intersecting a block, stop the jumping phase
					//and start the falling phase, setting the jump_count to 0
					if(World.tiledMap[upRow][upRightCornerCol].getBoundingBox().intersects(boundingBox)){
						jumping=false;
						jump_count=0;
						falling=true;
						return;
					}
				}
			}
		
		}

This chunk of code you see above is still part of the checkBlockCollision() function we saw earlier, so now we have all the stuff we need to make the character move around the screen, jump on blocks, collide with blocks and well, even die…if he falls too deep.

Aaaaaaand that would be all for today’s diary. Once again, remember that this is not a proper tutorial, but just a “how I make things” kind of thing. So if you have suggestions or you don’t understand what I say, please comment below or get in touch with me on twitter. I’m also on tumblr, drawing stuff. See you soon guys!

Chronicles of a Videogame in Java – 5. Collision detection for dummies

Chronicles of a Videogame in Java – 4. Building a tiled map

Previously on the Chronicles of a Videogame in Java: How to Make the Character Jump.

Here we are again ladies and gentlemen! Today we’re going to see how to build a tiled map for our still not so beautiful platform game. But first, let’s see what a tiled map is and especially what a single tile is.

There’s not a one-way definition of “tile”, as the term applies to both data structures and images. Let’s look at this picture to understand the concept:

tiledMap

Ok, the entire grid you see in the screenshot above it’s called a tiled map. The tiled map for this game has 9 rows and 20 columns for a total of 180 cells that will contain single static elements of the game. Here’s an example: the red square in the picture above contains a piece of terrain, so it is infact a static element of the game because it is placed there forever. From a logic kind of perspective then, that piece of terrain is a tile placed in the 7th row and 7th column of the tiled map. Pretty easy uh?

What do we place in a tiled map? Usually just terrain, blocks on which you may jump, spikes, maybe doors and other static elements. Don’t be misleaded by the image above though, the trees you see behind the characters are not part of the tiled map, contrariwise that’s just a background image. We have basically three layers in the world of the picture:

  1. The first and stupidest thing is the background. It is just a plain png image we draw on the background of the panel where the game is played. It does not involve interactions with the player whatsoever.background1
  2. The second layer you see is the one with the terrain tiles. Here’s now how the image above looks like if we add the tiled map with all the tiles (for now just terrain pieces). The terrain tiles do involve an interaction, for example the character can walk on terrain tiles and collide running towards them. terraintiles
  3. The last things are the characters and enemies moving on the world. They do not need to stay inside the tiled map of course, indeed I would say it is hugely inconvenient do put the main character inside a tiled map. Our protagonist just needs to be drawn above the other layers and the class representing him in the code should always reference the position of the character inside the tiled map (in terms of row and col).terraintiles

Now let’s put it all to code. First the Tile class, which is an abstract class as we do not want to istantiate a generic Tile, but rather specific types of tiles that behave in different ways.

public abstract class Tile {
	public Tile(int i, int j){
		this.row=i;
		this.col=j;
		initializeStuff();
	}
	
	protected abstract void initializeStuff();
	
	protected abstract void loadInformations();
	
	public BufferedImage getImage(){
		return image;
	}
	
	public Rectangle getBoundingBox() {
		return boundingBox;
	}
	
	protected int row;
	protected int col;
	protected BufferedImage image;
	protected Rectangle boundingBox;
	public static final int TILE_SIZE=64;
}

The piece of terrain we discussed earlier is a Block object in the code. The Block class extends Tile: you can think of a block as any piece of material you can walk on and collide with. Its bounding box occupies the entire perimeter of a cell in the tiled map grid.

public class Block extends Tile {

	public Block(String imgName,int i, int j) {
		super(i,j);
		this.imgName=imgName;
		loadInformations();
	}

	@Override
	protected void initializeStuff() {
		x=col*TILE_SIZE;
		y=row*TILE_SIZE;
		boundingBox=new Rectangle(x,y,TILE_SIZE,TILE_SIZE);
	}
	
	protected void loadInformations() {
		try {
			image=ImageIO.read(getClass().getResource(&amp;quot;../images/&amp;quot;+imgName+&amp;quot;.png&amp;quot;));
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private String imgName;
	private int x;
	private int y;
}

All the tiles of the current stage are stored in the bidimensional array named “tiledMap” in the World class. As you may notice the tiledMap is public, that’s because there’s no need to hide informations about the world as you see it and, even more important, it is really convenient to be able to grab te tiled Map from anywhere in the code. The world class actually loads the current disposition of tiles from a simple text file.

public class World {
	public World(){
		tiledMap=new Tile[ROWS][COLS];
	}
	
	public void initializeStage(String stageName){
		try {
			CURRENT_BACKGROUND=ImageIO.read(getClass().getResource(&amp;quot;../images/background1.png&amp;quot;));
		} catch (IOException e1) {
			e1.printStackTrace();
		}
		InputStream is=this.getClass().getResourceAsStream(&amp;quot;/levels/&amp;quot;+stageName+&amp;quot;.txt&amp;quot;);
		BufferedReader reader=new BufferedReader(new InputStreamReader(is));
		String line=null;
		String[] tilesInLine=new String[ROWS];
		try {
			int i=0;
			while((line=reader.readLine())!=null){
				tilesInLine=line.split(&amp;quot; &amp;quot;);
				for(int j=0; j&amp;lt;COLS; j++){
					if(!tilesInLine[j].equalsIgnoreCase(&amp;quot;empt&amp;quot;)){
						tiledMap[i][j]=newTileInstance(tilesInLine[j],i,j);
					} else {
						tiledMap[i][j]=null;
					}
				}
				i++;
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private Tile newTileInstance(String name, int i, int j) {
		switch (name) {
			case "ter0":
				return new Block("ter0", i, j);
			case "ter1":
				return new Block("ter1", i, j);
			case "terR":
				return new Block("terR", i, j);
			case "terL":
				return new Block("terL", i, j);
			case "terQ":
				return new Block("terQ", i, j);
			case "terP":
				return new Block("terP", i, j);
			case "term":
				return new Block("term", i, j);
		}
		return null;
	}

	public static BufferedImage CURRENT_BACKGROUND;
	public static Tile[][] tiledMap;
	public static final int ROWS=9;
	public static final int COLS=20;
}

Finally here’s what the .txt representation of a level looks like:

empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt empt
ter0 ter1 ter0 ter1 ter0 ter1 ter0 ter1 terR empt terL ter1 ter0 ter1 ter0 ter1 ter0 ter1 ter0 ter1
term term term term term term term term terQ empt terP term term term term term term term term term

Yep, I know I know. It looks barely readable. But if you look closely and you relate this text to the first picture of the post you’ll notice the parts with no terrain tiles (or tiles of any sort) are represented by the “empt” keyword and the several types of terrain tiles are “ter0” or “ter1” or ter+something_else.

Aaaaaaand that would be all for today. I’m sorry for this very theoretical post but the tiled-map one is really a concept you want to fully understand before you go on and code the funny things. Once again, remember that this is not a proper tutorial, but just a “how I make things” kind of thing. So if you have suggestions or you don’t understand what I say, please comment below or get in touch with me on twitter. I’m also on tumblr, drawing stuff.

In the next episode…we will die!

Chronicles of a Videogame in Java – 4. Building a tiled map

Chronicles of a videogame in Java – 2. How to make the character move + simple animation

The code discussed below is already available on my GitHub page at theBoyWithNoName. Please feel free to download it to take a better look. Ask me anything about it.

Hello again guys! So today we’re going to see how to move the main character of a 2D platform around the screen in Java. We’re also going to add a little animation to make the guy properly run.

Oh, by the way, before we start: I’m calling the game The Boy With No Name. Not that the title means anything, I just needed a name for the project and couldn’t come up with a better name. Soooo, yup.

Screenshot n.1

Anyways, if you’re a Java programmer you should already be aware of the concepts of JPanel, JFrame and Thread. If you’re not you can easily look up this stuff on the internet, the first two of those are pretty easy to use if you have any programming experience.Threads are a little tricky, but you don’t really need that much knowledge to understand the code I’m about to let you see.

Let’s start with the KeyboardController class. The KeyboardController is a KeyListener, meaning it can listen to the keys you press on your keyboard (DUH!). Here’s what it looks like:

public class KeyboardController implements KeyListener{

	public KeyboardController(){
		activeKeys=new HashSet&lt;Integer&gt;();
	}
	
	@Override
	public void keyPressed(KeyEvent e) {
		activeKeys.add(e.getKeyCode());
	}

	@Override
	public void keyReleased(KeyEvent e) {
		activeKeys.remove(e.getKeyCode());
	}

	@Override
	public void keyTyped(KeyEvent e) {
	}
	
	public static HashSet&lt;Integer&gt; getActiveKeys(){
		return activeKeys;
	}
	
	private static HashSet&lt;Integer&gt; activeKeys;
}

Basically the keys you press are stored into the HashSet called “activeKeys“. The HashSet is really the best data structure to store this kind of data because it automatically handles duplicates. In this way you don’t need to worry about having multiple “LEFT_ARROW_KEY” characters inside activeKeys, because the add(element) function of HashSet will only add the element if not already contained in the set.

The GameManager is the main thread of the game. It basically operates a sequence of instructions again and again until the game is over (either you die or exit the game). Here’s how I wrote the main functions of the GameManager:

@Override
	public void run() {
		while(gameIsRunning){
			//manage the keys currently pressed
			manageKeys();
			
			gamePanel.repaintGame();
			
			try {
				Thread.sleep(MAIN_SLEEP_TIME);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	
	//the function manages the keys currently pressed associating concrete
	//actions to them
	private void manageKeys() {
		//get the currently pressed keys from the KeyboardController
		HashSet&amp;amp;lt;Integer&amp;amp;gt; currentKeys=KeyboardController.getActiveKeys();
		
		//manage the two possible run direction
		if(currentKeys.contains(KeyEvent.VK_RIGHT)){
			//move right
			boy.move(KeyEvent.VK_RIGHT);
		} else if (currentKeys.contains(KeyEvent.VK_LEFT)){
			//move left
			boy.move(KeyEvent.VK_LEFT);
		} else if(currentKeys.isEmpty()){
			//if the player is not pressing keys, the protagonist stands still
			boy.stop();
		}
		
		
	}

As you can see in the run method, the GameManager continuosly checks what is in the set of currently pressed keys by calling the manageKeys private function. This last function is pretty straightforward: if the user is pressing a right key (KeyEvent.VK_RIGHT) or a left key (KeyEvent.VK_LEFT), it calls the move function on the boy (the name I gave to the character) object, passing the direction as a parameter. If the player is not milking any key, manageKeys calls the stop() function on the boy, which basically only serves a graphic purpose turning the current moving frame of the boy into an “idle” frame.
After the managefunction(), the main cycle of the GameManager (that you can see in the run() method) thread simply repaints the game, making the position changes visible on screen, and then sleeps for 18ms.

And finally here comes the main character, the hero, or as I call him, the boy. Before I show you the code let’s just point out that the most important variable in the Boy is its boundingBox. A boundingBox is just a rectangle, built around the character’s sprite, that moves with the character following him anywhere like a shadow. The bounding box is really important because very soon we’ll be using it for collision detection, probably the hardest topic that we’ll see in this diary/tutorial/thing I’m doing. Now take a look at the important methods of the Boy class:

//function called by the GameManager's manageKeys() function
	public void move(int direction) {
		switch (direction) {
			//in case you have to move left..
			case KeyEvent.VK_LEFT:
				//update the character's position
				currentX=currentX-DISPLACEMENT;
				
				//update the character's bounding box position
				boundingBox.setLocation(currentX, currentY);
				
				//change the current frame in animation
				setFrameNumber();
				currentFrame=run_L[currentFrameNumber];
				
				//set the left direction as the last one 
				last_direction=KeyEvent.VK_LEFT;
				break;
			
			//in case you have to move right..
			case KeyEvent.VK_RIGHT:
				//update the character's position
				currentX=currentX+DISPLACEMENT;
				
				//update the character's bounding box position
				boundingBox.setLocation(currentX, currentY);
				
				//change the current frame in animation
				setFrameNumber();
				currentFrame=run_R[currentFrameNumber];
				
				//set the right direction as the last one 
				last_direction=KeyEvent.VK_RIGHT;
				break;
				
			default:
				break;
		}
		moveCounter++;
	}
	
	//sets the current frame when the boy is moving - we have a total of 5 frames for 
	//each run direction. The variable moveCounter is incremented each time the gameManager
	//calls the move function on the Boy. So according to moveCounter we can choose the current
	//frame. The frame changes every MOVE_COUNTER_THRESH increments of the moveCounter variable.
	//In this case MOVE_COUNTER_THRESH is set to 5. The use of "6" instead of a variable is temporary
	//because I still don't know how many frames will be used in the final animation
	private void setFrameNumber() {
		currentFrameNumber  = moveCounter/MOVE_COUNTER_THRESH;
		currentFrameNumber %= 6;
		
		if(moveCounter>MOVE_COUNTER_THRESH*6){
			moveCounter=0;
		}
	}

The move function takes a direction as a parameter. We are only dealing with left and right arrow keys now so it is as simple as it gets: if the direction is RIGHT, then the character’s position is incremented by 5 pixels (DISPLACEMENT=5). As a result, the location of the boundingBox is updated.
Now let’s talk about frame switching, better known as animation. The last function you see above is called setFrameNumber() and, even if it looks pretty bad, it works pretty nicely to animate our little friend. To explain it let’s first make a step behind. Every time the move() function is called, the character moves and a moveCounter is incremented by one. The moveCounter variable is what makes the frame switching possible because every 5 increments of the moveCounter, we change frame. Why every 5 increments? because making the frame switch at every increment would make the protagonist move like a wierdo, animating way way way too fast. So a MOVE_COUNTER_THRESH of 5 is a good trade off. Here’s the six frames I used in the game:

frameSheet

Aaaaaaand that would be all for today’s diary. Oh hey, remember that this is not a proper tutorial, but just a “how I make things” kind of thing. So if you have suggestions or you don’t understand what I say, please comment below or contact me on twitter. I’m also on tumblr, drawing stuff.

Chronicles of a videogame in Java – 2. How to make the character move + simple animation