Advanced isometric engine

Started by
5 comments, last by menyo 12 years, 2 months ago
Hi,

I discovered some games, like diablo 2, that use a isometric engine fake the depth even more by drawing the tiles at the bottom of the screen larger then the top ones. And i was wondering not only how to accomplish this effect but also how proper tile picking and movement on a map would work.

Since there needs to be tile picking i don't think angling a camera on a 2D plane where the flat map could be drawn upon would not very well. There needs to be some sort of skew on the complete map from the center of the screen. I already did some research on skewing sprites with the library i'm working with (XNA) and since this involves matrices this might be still out of my league since i know nothing about them and reading about matrices gives me a headache biggrin.png.

If someone has any clue on how to approach this technique i would be very happy to hear it.

Heres a image to describe what i mean, i overlayed that screenshot part within the blue lines which was taken from the bottom of the screen.
isoperspective.jpg
Advertisement
You realize that they only did that trick to fake a 3D perspective, right? And you know that their work on D2 resulted directly in them deciding to stop doing pure 2D games? IMO, just use a general 3D engine, map your isometric sprites onto geometry (axis-aligned billboards, etc..), set up a perspective camera with a fairly narrow FOV, and call it good. Trying to do a bunch of sprite scaling hacks is just making unnecessary work for yourself.
That has crossed my mind. But not being able to write shaders, and not that good with modeling might bring me more work then such a scaling "hack".

I already thought of doing it in 3D but for what i need it's overkill. Ok when i go for 3D i might just as well put some Z action in there. Doing things 3D also means i need to model everything and animate it, but then again, i might model (or hire someone to model) to make still shots in a isometric perspective.

The thing is, i'm comfortable using sprite and isometric views and i know how to complete my game doing it with sprites. Just afraid my map will look too flat even with high quality spriting. While i doodled a bit with 3D programming i'm not feeling comfortable at all using it. The last time i tried a project in 3D failed because of shader and collision techniques.

So, i'm still in doubt? Is it that much work to setup some matrix that makes a trapezoid from the tiles that need to render on screen and adjusting the tilepicker to pick correctly? My math is way below par for this but i feel like it should not be that much work since i think i just need to alter the matrix for my 2D camera and adjust the tilepicking. If this really is that hard then what? switch to 3D and see my project fail again or keep with a orthogonal isometric view that might look a little flat.
I think you misunderstood me. You don't need to go full-on 3D, with skeletally animated characters, etc... You can use the exact same pre-rendered isometric sprites, no shaders, etc... The chief difference is that instead of using scaling hacks to fake a 3D perspective within a 2D engine, you actually use a 3D perspective and engine. You map the isometric sprites to axis-oriented billboards, set up a camera that has just a slight bit of perspective to it, and the 3D engine does the rest, automatically skewing the billboards to give a similar 3D effect to what the sprite hacks in D2 accomplilshed. Only you get it for "free", without having to write a bunch of weird code. If you're worried about the project failing, I suspect you would have a larger chance of failure by trying to perfect a hacky system than you would by using established 3D engine code.
Hmmm ok i have to take a look at this then, Is it possible to detect mouse picking on these billboards and getting the exact position where the player clicked on these billboards?

-edit-
I should read some more about it but the intellisense description of a Matrix.CreateBillboard seems to be a sphere that rotates around an object. Is this really what i'm looking for? Shouldn't i have my tiles be flat quad planes, and draw the specific texture on that?

I could use some pointers for this, a pointer on how to create a flat map for this would be great.

-another edit-
Well i'm getting somewhere but i'm clueless as what billboards have to do with this. I just drawn a quad on screen with a texture applied to it. I think this could work perfectly.

So should i use ray casting for tilepicking here? What are my other options for this? I want the entities to be free from the tiles itself but use them for pathfinding and drawing the map.

A couple of problems arises, since i will be using a isometric system my walls textures will be much higher. some might be 4 times the floors. Since with normal 2D drawing i would just keep using my square grid and just push a texture which is larger up by it's texture height - regular tile height. Here the quad itself needs to be stretched and since it's not walkable the player can't stand behind walls which feels cheap.

Since everything is drawn on the same "height" (the basic tile, the object, the player, the enemies, etc will be all inside eachother) this is bound to bring up issues.

Any other issues i might run into? Or advantages that can be taken from this technique?

Anyway, i will be looking into this for a couple of days.
Billboard is a somewhat overused term, given that it can have multiple meanings. There are screen-aligned billboards that always face the screen, there are axis-aligned billboards that orient to face the screen but stay fixed along one axis (usually vertical); these might be used to, for example, in populating a distant forest with tree impostors. I probably should have not used the term billboard, since what I meant is simply a quad that is aligned along the the grid cells of a tile-based world.

Imagine a standard 2D isometric engine. You have a sprite for the floor, a sprite for the left wall and a sprite for the right wall. In a 2D engine, these are just drawn as sprites. However, in a 3D engine, these would be mapped to quads aligned along the boundaries of the cell in 3D space. Thus, they have depth in the world and can easily be picked with the mouse. Picking in this sort of setup is trivial, and actual even easier than picking in a 2D setup, in my opinion.

And yes, a ray-cast would probably be a good option, using the depth value read from the frame buffer. Or, conversely, you could just generate a ray and test intersections with game objects yourself, for example if you want to prioritize picking of, say, enemies over items, even if the item occludes the enemy in the depth buffer.

As far as mobile objects, that are not tied to the grid world as world tiles are, you would probably use a vertical axis-aligned billboard with the sprite texture mapped onto it, that always faces the camera.
Great thanks, this seems to work, at least for a normal top down tile map. But since isometric tile sprites overlap eachother i get this problem, Z fighting and sorting will not solve this issue since a tile in the middle gets overlapped by 4 other tiles. Neither does making the invisible parts of the tiles transparent or painting them 255,0,255 (which xna recognices as invisible for normal sprites.). So i guess i need some alpha mapping technique.
<edit>
Sorry, figured this out pretty quickly with the blendstate on the graphics device. But what if i want to draw a object like a chest or a tree on the map? Should i just shift that 0.0001f above these quads or something?
</edit>

But now i come back for the tilepicking system. Since i can't use this formula anymore:

int topMidX = firstX + 32; //FirstX and firstY are the first tile to draw or the top most tile.
int topMidY = firstY;
selectedTileX = ((int)mousePosition.X + (2 * (int)mousePosition.Y) - topMidX - (2 * topMidY)) / 64;
selectedTileY = ((int)mousePosition.X - (2 * (int)mousePosition.Y) - topMidX + (2 * topMidY)) / (-64);


And every spot i could possibly click contains 2 tiles so how am i able to tackle the tilepicking?

sorting.png

This topic is closed to new replies.

Advertisement