2D Isometric-Diamond: Several question into one thread

Hello everyone, I’m new here :slight_smile:

So I am currently working on a 2D Isometric-diamond Zombie survival game.

I have followed this guide for having a solid base: http://www.java-gaming.org/topics/basic-game/21919/view.html

My first problem is when I move my character my game renders white lines between the tiles like small render lags.

First problem kinda solved: I tried to increase increase the mapXOffset by deltaTime * 0.2 in each update and it removed all the white lines.
Though somehow I still think I’m doing it wrong by moving the mapXOffset instead of the player and now I have to somehow when I press the arrows keys they have to go to the update method hmm.

My plan is to keep the player in the center of the screen all the time, currently the player is the small black rectangle

The tiles graphic is both within a tilesheet.png

My tilemap array


	//Tile map
	int[][] tileMap_array = new int[][] {
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},		
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1},		
		{0,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1,0,1,1,0,0,1,1}		
	};

Rendering the map and player


		for (int i=0; i<tileMap_array.length; i++)
		{
			for (int j=(tileMap_array[i].length-1); j>=0; j--)
			{
				if (tileMap_array[i][j] == 1)
				{
					//Getting subimage of tilesheet					
					g.drawImage(tileMap_img.getSubimage(0, 32, 62, 32), ((j*tileMap_img.getSubimage(0, 32, 62, 32).getWidth()) / 2)+((i*tileMap_img.getSubimage(0, 32, 62, 32).getWidth()) / 2) - mapXOffset, ((i*tileMap_img.getSubimage(0, 32, 62, 32).getHeight()) / 2)-((j*tileMap_img.getSubimage(0, 32, 62, 32).getHeight()) / 2) + mapYOffset, null);
				}
				else
				{
					g.drawImage(tileMap_img.getSubimage(0, 0, 62, 32), ((j*tileMap_img.getSubimage(0, 32, 62, 32).getWidth()) / 2)+((i*tileMap_img.getSubimage(0, 32, 62, 32).getWidth())/2) - mapXOffset, ((i*tileMap_img.getSubimage(0, 32, 62, 32).getHeight()) / 2)-((j*tileMap_img.getSubimage(0, 32, 62, 32).getHeight()) / 2) + mapYOffset, null);
				}					
			}
		}
		
		g.setColor(Color.black);
		g.fillRect(player.x, player.y, 10, 10);

When the player clicks an arrow key its not the player moving but the world around him.


	int mapXOffset;
	int mapYOffset;

So when the player clicks an arrow key I change the value of one of the map offsets


			@Override
			public void keyPressed(KeyEvent e) {
				// TODO Auto-generated method stub
				if (e.getKeyCode() == 37)
				{
					//Left arrow
					mapXOffset -= 5;
				}				
				else if (e.getKeyCode() == 38)
				{
					//Up arrow
					mapYOffset += 5;
				}
				else if (e.getKeyCode() == 39)
				{
					//Right arrow
					mapXOffset += 5;
				}
				else if (e.getKeyCode() == 40)
				{
					//Down arrow
					mapYOffset -= 5;
				}				
			}

I have two guesses, either its doing the small white lines because I has to re-render the whole world each time or its because I’m doing the variable changing within the code above and not using the the deltatime within my update method


	protected void update(int deltaTime)
	{
	}

My second question is: How could I go about making collisions? I plan to put in objects, even interactive objects like doors and so on.

My third question is: When the player is close to a staircase how could I simulate he is walking up on the staircase to the next floor inside a building?

And ofcourse if there is any tip/advice where I could do something better, please say so.

Thanks in advance.

This Thread might be of interest to you: http://www.java-gaming.org/topics/drawing-isometric-tiles-inside-a-screen/24922/msg/212780/view.html

Thanks there is alot of good information :slight_smile:

Could you tell me, is moving the offset of the map right or should I move the player instead?

There is not right or wrong in game programming :wink:

Either is possible, I usually prefer to move the player and then offset the map based on the player. Although it sounds like more work, It makes moving the camera slightly for cutscenes or the like much easier, I feel.

Whichever seems easier and most suitable to your game is the one you should use, I know that both techniques are used.

It only depends on what effect you want to achieve.

If you move only the map, the player will always be on the center. So if you move to the edges of the map there will be a big empty space (its not attractive and makes you lose part of the map vision)
If you move both the player and the map, you can make that the map no longer moves when you get on the edge, just the player

It’s best to move the player and then set mapX/YOffset to center the player again.

The player X and Y is the X and Y of the screen so if I change those the player would not be centered anymore, and the mapX and Y offset is just so the map is centeret on the screen.

Then simply have the screen center around the player :slight_smile:


screen.x = player.x - screen.width/2;
screen.y = player.y - screen.height/2;

Then don’t make the player’s location as the screen location. Separate logic and render. All your data should be in world coordinates. When rendering, you convert to screen coordinates.

No, to find the offsets, you do:


offsetX = -(player.getX()+player.getWidth()/2) + screen.getWidth()/2;
offsetY = -(player.getY()+player.getHeight()/2) + screen.getHeight()/2;

Depends how you implement it… A screen object is much more intuitive and flexible imo. Ie instead of centering the map around the player, center the screen around the player and the map around the screen.

Thanks for the great answers.

We’ve made a choice to move to jMonkeyEngine 3 where I am currently studying theire SDK and documentation and my friend is learning how to use Blender.

Against, thanks for the help.

Move the player on the map, then scroll the map to center the player.
(so you can use the player like other NPCs)
If you notice jerky movement, cheat by not rendering the player based on the calculated position, but the fixed position
in the screens center. The playerchar is the most important object in the game, and should keep as steady as possible.