3
\$\begingroup\$

I'm writing an IsoMetric renderer for my html5 isometric game. The isometric renderer should be able to render objects with floating point coordinates.

SOURCE: https://github.com/ilmattodel93/EaselJs-Isometric-with-Heightmaps

As now, the renderer works pretty well, but I have some questions and a problem to fix. Note that little square is the anchor point, and lines are AABB (not correctly drawn I think).

THE PROBLEM

If you have a look at the demo, you should note that when the dragon is behind the tree on a higher level, it will be rendered over the tree instead of behind, as expected.

isometric dragon problem

As you can see in js/mmo/renderer/IsoEntity.js#L91 and js/mmo/renderer/IsoLayer.js#L65, i have a "rough" implementation, and maybe it is'nt good. I've googoled around and find something called "topological sort", i've attempted to implement it, but it does'nt seems to solve.

For each tile I have information about minX, minY, minZ, maxX, maxY, maxZ. An AABB as you can notice.

THE QUESTION

My question is, how can I solve this problem? Is it better (and will be faster) to maybe implement a depth-buffer? And how can I implement it? Will it ensure high performance? Maybe will a correct anchor point (represented with little square) solve the problem?

Thanks for any help! :D

\$\endgroup\$
4
\$\begingroup\$

enter image description here

Basically if you number X and Y iso-coordinates their sum is the number of the diagonal, you sort tiles by diagonal, and then draw first tiles with lower Z. This is indipendent of screen coordinates. (of course assuming the camera is in the bottom left corner of the image)

\$\endgroup\$
  • \$\begingroup\$ This only works for static objects, if one of them is moving and some of your sprites are bigger that 1*1 then you will have a problem,because the sprite that for example has a 2 by 2 tiles size (like an asphalt block) will have the same zPosition through all of its tiles and if a one by one tile character wants to move to one of the sprite tiles at its behind, the sprite will covers the character wrongly, the character needs to be bringed to front because if you can break the 2*2 block into one by one blocks and you can assign a Z for each it will solve the problem but you can’t break…. \$\endgroup\$ – Iman Sep 13 '15 at 13:19
  • \$\begingroup\$ Why I can't break? as far as I know if each sprite is a textured quad, no one fordibs breaking 2 triangles into 8 triangels, and for the moving characters you can still sort everything every frame (pretty quick with ad hoc radix sort) \$\endgroup\$ – GameDeveloper Sep 14 '15 at 21:29
  • \$\begingroup\$ of course you may break big sprites into 1*1 tiles but you have to write a lot of new code to handle such a big sprite while panning, rotation will be a nightmare, selecting it for example, if you loop fade in/out you must handle the latency, they will blink asynchronous for sure, or just imagine how physics should be handled, joining tiles in physics and many many other codes that I haven't mentioned here, why? I know a better solution! \$\endgroup\$ – Iman Sep 14 '15 at 22:02
  • \$\begingroup\$ Which is, do your method to sort all sprites and give them a zPosition(Swift accept a zPosition and will sort the sprites) however it will work for static objects only, for moving objects you should create an update() method and check if your moving object or the sprites on the same position with your moving object should be on top, while sorting big sprites just set its nearest tile to camera to its zPosition. Thats all, no breaking! \$\endgroup\$ – Iman Sep 14 '15 at 22:10
  • \$\begingroup\$ I think you are complicating it too much by overdesigning every possible feature. First of all physics should be decoupled from visualization so the physics will just see single tiles, coupling physics with visualization like you mention would be the mother of all debuggin nightmares. Also if I would need rotation (wich can still be done by breaking a tile with few lines of code) or other advanced features I fear is more easy using 3D rendering and a Zbuffer to fake isometric.Also you are assuming someone would be using Swift ^^.I know your way would work, but I prefer a different architecture \$\endgroup\$ – GameDeveloper Sep 15 '15 at 7:25
1
\$\begingroup\$

I wanted to write this as a comment because I have not the time to dig that deep into your code at the moment but I don't have enough reputation nevertheless I wanted to maybe help you so I have to write an answer (maybe someone could correct/improve it):

It seems you sort the order of the sprites by a value you get by adding and subtracting the x,y,z values. This is also the way I did it in my isometric engine. Every object gets a "depth" value describing the distance from the camera and every object is put in a list which is sorted by this depth-value. Then everything is rendered in the order of the list.

You have to take into account that you are using isometric view so that the axis are shortened. Try multiplying or dividing by sqrt(2) (or maybe factor of 2). The exact factor and axis depends on your architecture of your map and the use of the axis, which I did not fully understand by now.

As far as I know you can not use min/max values but must use only one single point for sorting (because otherwise you should have to render a part in front and another part behind)

EDIT: Also try browsing some related questions. There are some more detailed answers already.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.