Isometric problem


(Capro) #1

I’m making an isometric game (like Ultima VI), and I have some problems with layers. When the player approaches a wall from the right and the bottom he should be shown over the wall. Instead, he is not rendered over it until he stops. While the player is moving he always appears under the wall, but if he stops he is correctly rendered over it when he is on the bottom and on the right.

The wall has a 48x48 sprite and its base is 32x32, the player has 32x32 sprite and its base is 16x16.

This is the player:

public class Player extends Entity
{
	[Embed(source="../lib/Player.png")]
	private const MAN:Class;
	
	private var spriteMap:Spritemap = new Spritemap(MAN, 32, 32);
	
	private const unit:int = 32;
	
	public var v:Point=new Point;
	
	public function Player() 
	{
		graphic = spriteMap;
		graphic.x = graphic.y = -16;
		spriteMap.add("Idle", [0]);
		
		mask = new Hitbox(16,16,0,0);
		type = "player";
		
		spriteMap.play("Idle");
	}
	
	override public function update():void
	{
		upMovement();
		upCollision();
		
		layer = 16 - (x + y);
		trace(layer);
	}
	
	public function upMovement():void
	{
		var move:Point = new Point;
		
		if (Input.check(Key.RIGHT)) move.x++;
		if (Input.check(Key.LEFT)) move.x--;
		if (Input.check(Key.DOWN)) move.y++;
		if (Input.check(Key.UP)) move.y--;
		
		v.x = 150 * FP.elapsed * move.x;
		v.y = 150 * FP.elapsed * move.y;
	}
	
	public function upCollision():void
	{
		x += v.x;
		
		if (collide("wall", x, y))
		{
			if (FP.sign(v.x) > 0)
			{
				v.x = 0;
				x = Math.floor(x / 32) * 32 + 16;
			}
			else
			{
				v.x = 0;
				x = Math.floor(x / 32) * 32 + 32;
			}
		}
		
		y += v.y;
		
		if (collide("wall", x, y))
		{
			if (FP.sign(v.y) > 0)
			{
				v.y = 0;
				y = Math.floor(y / 32) * 32 + 16;
			}
			else
			{
				v.y = 0;
				y = Math.floor(y / 32) * 32 + 32;
			}
		}
	}
}

And this is the world:

	public class Tav1 extends World
{
	[Embed(source="../lib/Wall.png")]
	private const WALL:Class;
	
	private const unit:int = 32;
	
	private var wall:Image = new Image(WALL);
	
	private var player:Player = new Player();
	
	public function Tav1() 
	{	
		add(new Wall);
		spawnwall(wall, 5, 5);
		spawnwall(wall, 5, 6);
		spawnwall(wall, 6, 5);
		spawnwall(wall, 6, 6);
		
		add(player);
	}
	
	public function spawnwall(img:Image, wx:int, wy:int):void
	{
		addGraphic(img, -(wx+wy) * unit, wx * unit-16, wy * unit-16);
	}
}

I tried a lot of different things but nothing works. At this point the problem should probably be in the way I move the player or in flashpunk itself. I’m blocked, help me.


(JP Mortiboys) #2

Have a read of this : http://bannalia.blogspot.com.es/2008/02/filmation-math.html


(Capro) #3

I don’t understand, it doesn’t seem related to my problem. I’m using a completely different isometric style…


(rostok) #4

my solution for isometric projection in FP is to move each entity`s graphics so that it’s centered on the ground. so for example sprite

should its graphics repositioned like this

graphic = sprite;
graphic.x = -sprite.width / 2;
graphic.y = -sprite.width * 0.85;

after that layer should be set to:

layer = -this.y;	

this applies both to moving and static entities. however in my game everything is flat (no stairs or ladders).


How to determine what is in front or not in a 2D world?
(Bartłomiej Kalemba) #5

Sorry for re-archive this topic, but:

  • I have similar problem with isometric and: I draw my map using… gimp and then just add Entity with graphic, then cut some areas and I have mask for my map.

My problem: still have problem with some really small places, where I don’t know how to solve it:

I mark corners where player could be befor and after this areas. I use advice about player hitbox near his foot. I cut of this orange areas and set then to be always covering player (just check it in any iso game) But this corners still remaining unrosolved.

Somone could help? Maybe there is another way: just using flashPunk for iso game is waste of time?


(rostok) #6

Iso in FP is doable yet requires some effort. I would recommend using Tiled editor to break walls into smaller entities (player size would be most convenient). Take a look at this iso tileset: http://opengameart.org/content/cave-tileset. Author (Clint Bellanger) also provides automatic rules for Tiled that adjust the tiles based on the surroundings.

I think that there is also possibility to use your map the way it is. Assuming that walls #006a16 are always back (bottom most layer) and #ffcd9d ale always on top all you need to do is a little hack. Just cut out those marked corners (white triangles) and make separate entities of them. place their layer to -this.y and make the origin to point at lower pixel.


(Ultima2876) #7

Feel free to ignore me if you think this is insane, but have you considered pretending your collisions are on a regular 2D grid? If you imagine having a minimap in your game that’s just 2D top-down, and internally handle all the collisions as if that’s the case. Then you just have to represent your game isometric-style; the logic is all just top-down.

… does that make any sense?


(Jacob Albano) #8

I did exactly this sort of thing in a raycasting FPS I was working on a while ago. All the entities’ movement and collisions were simulated in 2d, and I just ran through them all each frame and did rendering in a completely separate system.

It takes a bit of getting used to, but it really helps.


(Bartłomiej Kalemba) #9

Ok, so You motivated me to work on it! Thanks :smiley:

Sorry for a little off topic, but now I resolve this problem. I’ll try to describe how I solve this, but first of all I have to finish my project. After I finished, I’ll try to write here some main points about solving this problem :smile: