0
votes

I'm creating a 2d game in HTML5 canvas. It's an isometric world, so actually it's also 3d. You always see that isometric games use tiles, and I think the reason is just for the depth logic. My goal is to create the game without using a tile system. Each item can be placed by the user, so item locations like walls, trees, etc., have variable positions. The positions are isometric x, y, z coordinates. If the game was just tiled, you could determine a fixed tile area for each item. (I mean: a one-tile item, or a wall of 10 tiles long). But in my game I use an areaX and areaY for the space an item uses on the ground. And I use a height to store an item's height, which is the z value. (z axiz in my world, is y axis on screen).

The problem is hard to explain. It's about depth sorting. See the following image:

enter image description here

The brown bar on top of the other bar should be after the gray pole. I'm now using the simplest form of a painter's algorithm, that only compares the x, y, z coords of each item. I know this incorrect rendering is a famous problem of the painter's algorithm. If this was a tiled game, the bars could be divided into 2 tiles next to each other. Then the tiles could be drawn in the order of their depth.

But since I'm trying to create it without tiles, I am looking for a really challenging logic.

The items should be rendered as if they were 3D objects. I would even like to have the following behavior: If multiple items would intersect, then the visible pixels of each item should be drawn, like in this image:

enter image description here

The main problem is that there is no information to determine what parts of an image should be visible, and how they must be cut. I could create a depth mask for each image, like:

enter image description here It works a little bit like a z-buffer.

But this is not possible due to the performance of a canvas, because you have to iterate literally over each pixel of each image in the map. And the second big disadvantage is that you have to load twice as much resources from the server...

Another solution might be cutting all images into vertical strips of 1 pixel wide. Then handle each strip as if it's a tile of 1x1 pixel. Then I'm still creating a tiled game, buy the tiles would be so small that I still reach my goal. But also this solution has the disadvantage performance... Since each image would be split in hundreds of strips, which are new seperate images.

So I'm looking for a challenging solution. Who can help me finding a way to define the depths (or depth areas) for images in a way that correct rendering is possible for the performance of canvas?

1
tree using THREE.js or WebGLmike510a
I would have to agree. Try threex.colliders. Example: jeromeetienne.github.io/threex.colliders/examples/basic.htmlrassar
You can get reasonable performance from the 2D canvas for true 3D isometric, but you are stuck with the depth sort, which can be a pain. The javascript standard array sort can do a reasonable sort if you are cleaver in how you arrange the objects (sort groups of sorted polygons). To solve the overlapping polygons you need to slice the polygons where they intercept. This test can be slow but again, grouping regions will help. You will get realtime if your polys are axis aligned. As soon as you go off axis its slows right down. I gave in in favour of webGL that is what it is for 3DBlindman67
But if I use Three.js / webGL, it means that my items are no longer single images, because then I have to create (textured) 3d objects of them?user2190492
You don't have to work in 3D when you use webGL. WebGL draws polygons and is very quick at drawing 2D images as 4 verts making a small fan of triangles. You can still use the zbuffer and set corners (verts) to the z distance. Most of the 2D game libraries use webGL to render 2D and fallback to canvas if webGL is not there. There is also a webGL implementation of the canvas API on github that you could modify to meet your needs.Blindman67

1 Answers

0
votes

This question was effectively asked again and answered over here

The short answer is you can use depth sprites with WebGL