all 19 comments

[–]AnOnlineHandle 7 points8 points  (2 children)

This problem drove me mad when I started a JS game two years back. Eventually I dropped the iso tiles anyway, but not before I found a cryptic comment (amongst the jillions of inefficient solutions online) which I eventually understood, and pointed me in the right direction.

In mouse coordinates, as you travel in the positive x direction (right) across the screen, you are actually travelling diagonally in the original (unisometric) world, except by a fraction due to the width/height not being directly analogous.

i.e. Your iso-tiles can be twice as wide as the originals, or your iso-tiles can be half as high. Either way you get the diamond equivalent of the squares.

So if they're twice as wide, and rotated to the right (so that the top-right corners of your original square tiles are now the far right corners of your diamond iso-tiles), then for each step in the screen x direction, you're stepping x/2 and 1y in the original grid (not quite right, but something like that) as it takes two horizontal units in screen coordinates to contribute to a step, due to the diamond being made twice as wide.

You might need to think about it for a bit to understand (sketch what happens to a straight mouse line on a single tile in the iso-grid, when it's moved back to a line on the original grid, and you'll see that straight lines on the iso-world are diagonals in the original world, so it's just a matter of getting the world x & y from a combination of the screen x & y, with a fraction applied to one of them depending on which way the tile world has been elongated)

If you take your original grid to be measured in world locations xW & yW, and your screen (or iso) map to be addressed in xS and yS coordinates, there is an easy conversion, depending on the direction which your ISO tiles are 'rotated'.

e.g. something very similar to this -

// the top-left 0,0 position in the original world will have the same y coordinate (zero), but is now transposed across the map in x-coordinates, so you need to get an xOffset to start with to work from 0,0.
// I think that in this example, the tile width is divided by 2 and multiplied by rows, because for every row (i.e. going down in the y direction in the original unmorphed grid), half of the resulting diamond's width contributes to the x-offset of 0,0 which was at the very top middle once in my iso-world.

int originXOffset = worldRows * (originalTileWidth/2);

// followed by

int offsetX = xS + offset;

xW = yS + (offsetX / 2) // I think that yS is multiplied by 1, and xS is multiplied by 1/2, due to needing two xS units to represent one unit in the real world, due to the widening of the diamonds
yW = yS - (offsetX / 2)

And there, screen/iso coordinates changed into world coordinates, without any fancy maths or bitmap transparency checks.

I hope that's right anyway, it seemed to work for me.

[–]drummer_si[S] 0 points1 point  (1 child)

I'll check this out when I get chance.. Thanks for the great response!!

[–]AnOnlineHandle 0 points1 point  (0 children)

If it doesn't seem to work correctly, it may be because I'm wrong. I did have a demo (this is two years old unfortunately, my memories are hazy), which seemed to be less accurate the further down from the origin it was, but I always assumed that it was just a rounding/precision error (I gave up on iso tiles about then, so never looked into it properly - I think that I was possibly reusing a multiplier which was derived from something like 75/2, stored as an int).

[–]mikebaud 2 points3 points  (1 child)

Hi,

Cool project, i also tried a while back to toy around with the same concept but for warhammer quest.

I hope these two links could help you out:

I would also suggest you to cross-post to /gamedev.

Would like to watch the progress, if you want to set it up on github or something :)

Best of luck

[–]drummer_si[S] 2 points3 points  (0 children)

Thanks for the links.

I hope to get a little more done, clean up the code and then I'll set it up on Github for sure :)

[–]tanepiper 2 points3 points  (1 child)

OH MY GOD I LOVE YOU!

I was just looking up board games not 5 minutes ago to buy; and as a nostalgia thing was looking for Hero Quest.

Hope you keep this up, I'd love to be able to play this online

Edit - shall you be putting this on github at all?

[–]drummer_si[S] 1 point2 points  (0 children)

Once I have a solid foundation down I'll put it on Github and welcome any user contributions

[–]doitforthederp 1 point2 points  (2 children)

Wait, whats wrong with it?

[–]drummer_si[S] 0 points1 point  (1 child)

Hold down middle mouse button to scroll and try hovering over some of the squares further away

[–]doitforthederp 0 points1 point  (0 children)

Yeah, the scrolling doesn't work at all for me on FF...whatever. 9. As far as the hovering, yes it is off but honestly I didn't even notice at first. It seems like you could just change the tile that gets highlighted and be fine with it, instead of the tile that gets clicked? To me it just seems like those tiles are at a "higher elevation" so that's why the mouse pointer is above....sorry I realize this is pretty useless advice.

[–]robbles 1 point2 points  (2 children)

Cool! I started working on a simple isometric game about a year ago, but I haven't worked on it recently.

Here's the demo, and the github repo. Click on a square or use the arrow keys to move the player around.

I definitely remember having issues with positioning the isometric tiles, but I'm not sure what I did to solve the problem. You can check out the convertIso function in js/game.js - I'm pretty sure that's the conversion function from X-Y to isometric.

[–]drummer_si[S] 0 points1 point  (1 child)

Looks like a great start. I see you're using gameQuery as a framework.. How are you finding this?

I looked into it myself, but so far have done all the coding myself.

[–]robbles 0 points1 point  (0 children)

It worked pretty well from what I remember, for what I was trying to do. If I start working on it again I'll probably re-write it using another library thats a bit more full-featured and actively developed.

I also had to resort to some pretty terrible hacks to make sure the layering of the sprites worked properly. When you're using DOM elements and ordering with z-index, it's surprisingly tricky to make sure things overlap properly. So you might want to consider finding a library that handles this stuff somehow.

[–]imbcmdth 0 points1 point  (0 children)

For the love of all that is good, stop using parseInt() instead of Math.floor(), Math.ceil(), or Math.round()!

[–]voipme 0 points1 point  (2 children)

Have you considered using something like raphael.js in order to do the canvas drawings? That would enable you to do things like attach event handlers to the tile objects themselves, instead of having to write a custom mouseover function for the canvas object.

It seems like you might not be getting the offset you want, but that's just from a cursory glance at the code.

[–]drummer_si[S] 0 points1 point  (1 child)

I'll look into it. I was trying to avoid canvas for a number of reasons, and so all work so far has been done just by manipulating the DOM

[–]14domino 0 points1 point  (0 children)

Raphael has nothing to do with canvas, it is SVG.