- ABPS
- Allefant1
- Allefant2
- Allefant3
- Allefant4
- Allefant5
- Allefant7
- Antarctica
- Battery
- BlitzHack
- BloboTron
- Bob'n'Rob
- Command Code
- Donkey
- Doomed
- Dragonfly
- EggHack
- Evil
- Feud
- Forest
- FruitWorm
- Garbage
- GnomeGuard
- Hare
- Hydra
- Insanity
- JetFighters
- Kaos
- Kings
- Krampus18
- Lawn
- Lunte
- Magnetotron
- MarsFight
- Nefertem
- Owl
- Photon
- PI
- PumpkinForest
- Quest
- Red, White & You
- Shopkeeper
- SIC
- Sleigh Race
- SoF
- Squiddle
- Swarm
- Teacher
- Tom
- Troll
- 20000
- Ultimatum
- Velocity
- Wave Rider
- X
- xmas
- Yellow and Dangerous
- Zombie Master

- advent mockup
- About
- algif
- Allefant
- allegro 5 faq
- Allegro
- AllegroGL
- Articles
- Ballroom
- Chachacha
- Discofox
- EggHackGUI
- Elephant
- f4
- FudgeFont
- Galaxy
- Games
- hartlauer glasses
- HexMap
- IceJunk
- icejunk.c
- IsometricProjection
- JavaAllefant
- JavaAppletTest
- Jive
- Land
- LD48_Logs
- Lua
- LudumDare
- Mambo
- Miscellaneous
- ObjectOrientedC
- Optimization
- Options_are_Good
- Presentation
- Python
- Quickstep
- Remakes
- Rumba
- Samba
- Scratch_Book
- SpaceNomads
- SpeedHack
- SpeedHackGuide
- static linking
- Syntax
- Tango
- Templates
- TODO
- Tools
- tshirt
- Veggie Pasta
- Viennese Waltz
- VSync
- Waltz
- Wesnoth
- Why reverse polish notation is bad
- WIP
- Woosls
- Woosls2

- Krampus Hack 2018
- Resurrection Hack 2018
- TINS 2017
- Easter Hack 2017
- Krampus Hack 2016
- rm -rf wordpress
- Speedhack 2015
- Speedhack 2014
- My SantaHack entry
- my ABC of compo entries
- Kaos
- TINS 2012
- Pyweek #14
- Moosader compo 7
- FOSDEM 2012 in Brussels
- Global Game Jam 2012
- SantaHack 2011
- The Coke diet
- Speedhack 2011
- LD48 2011 (#20)
- fosdem picture
- fosdem
- Global Game Jam 2011
- Google App Engine
- Apple has no idea of user interface design
- wordpress theme updated
- TINS 2010
- Allegro 5 regression testing
- took part in ludumdare #18
- new host again
- testing new host
- wordpress 3.0
- godaddy.com
- Ludum Dare #17
- wordpress 2.9.2
- the end of END_OF_MAIN
- allefant.com
- time for an update
- wordpress upgrade
- LD48 #12
- Mini LDs
- WordPress
- New Year
- Shedskin
- Retrohack
- Pyweek and Speedhack
- PyWeek
- Worst software of the year award
- Nothing much
- TINS and pyweek entries
- moin update
- 2007
- Allegro
- 72 Hour Game Development Contest
- Got new cellphone
- Moin upgrade to 1.5.5
- Speedhack is over
- 72hrgdc results are in, Speedhack is looming
- Lots of compos going on
- Upgrade to MoinMoin 1.5.3
- LudumDare #8
- Velocity the Bee
- SHMUP Compo
- TINS 2006
- FudgeFont
- Happy new Year!
- Merry Christmas
- Wiki
- Allegro 4.2.0
- Woosls
- Scripting, Forth, Lua, Python, perl, pygame and Land
- New news posting interface
- 2005-09-01
- 2005-08-16
- 2005-08-12
- 2005-08-06
- 2005-07-27
- 2005-03-09
- 2005-03-09b
- 2004-04-16
- 2004-03-27
- 2003-10-18
- 2003-07-31
- 2003-07-10
- 2003-07-08
- 2003-06-28
- 2003-03-07
- 2002-12-31
- 2002-08-01
- 2002-04-12
- 2002-04-05
- 2002-03-31
- 2002-02-15
- 2002-02-11
- 2002-02-05
- 2002-01-01
- 2001-12-24
- 2001-12-22
- 2001-12-07
- 2001-12-01
- 2001-10-01
- 2001-09-01
- 2001-07-01
- 2001-04-01
- 2000-04-01

pixel_x = tile_x * tile_w/2 - tile_y * tile_w/2 pixel_y = tile_x * tile_h/2 + tile_y * tile_h/2This transformation can be put into a function

for each tile_x, tile_y: pixel_x, pixel_y = isometric_transform(tile_x, tile_y) picture = map.get_picture_at(tile_x, tile_y) picture.draw(pixel_x, pixel_y)In words, for each tile in our map, get the corresponding pixel position, and draw the tile there.

tile_x = (pixel_x/(tile_w/2) + pixel_y/(tile_h/2)) / 2 tile_y = (pixel_y/(tile_h/2) - pixel_x/(tile_w/2)) / 2For example, if in our example 4x4 map at the top, the mouse is clicked on pixel position 20/40 - which tile is there? The size of the tiles is 32x16. So we get:

tile_x = (20/16 + 40/8) / 2 = 3.125 tile_y = (40/8 - 20/16) / 2 = 1.875So, the tile is 3/1, and we even know that it is at (.125/.875) inside the tile. .0/.0 would mean the pixel is exactly the topmost pixel inside the tile, .99/.99 would mean it is at the bottommost pixel. Pixel -48/24 from the initial example would accordingly yield the tile position ((-48/16+24/8)/2,(24/8-(-48/16))/2) or (0.0/3.0).

- There are different possibilities now. Such units could for example use a normal, not transformed offset position inside the tile. With our sample 32x16 tiles, they could e.g. roam inside a diamond with the four corners (0/0), (16, 8), (-16, 8), (0, 16).

- Another possibility would be to make the units completely independent of the tilemap, keep their position in normal, un-transformed pixel coordinates, and use our second transform above to convert into fractional tile coordinates for drawing them.

- The first two solution both do something bad though: They mix up different coordinate system, which in a somewhat bigger game will sooner or later cause you to scream at your code. I prefer to keep the fact of an isometric display confined to the drawing code, and to things like mouse positions. An easy way for this is to keep the intra-tile positions of objects in the floating point rectangle 0/0 to 1/1, that is, in the same fractional positions we already have in the pixel-to-tile transformation. So if for example there's a tree on tile 2/2 and it is on 0.5/0 inside that tile, we know that tile is drawn at (0,32). More precisely, its topmost pixel is at (0,32). Now, the intra-tile position can be transformed with the same formula, and (0.5/0) is (8,4). So we can added that offset in pixels to draw the tree there.

- If each tile of the game stores its objects, then probably the previous method is best. But instead of using intra-tile positions, it can sometimes be better to store global coordinates for units. In this case, our tree would then be at 2.5/2. And the transformation formula still works, and returns (8,36). (At least, as long as floating point is used.)

\ / view vector \ / /.\ l/2 / \ /_________\ a l \ view plane

At the bottom, there's the tile, with length l. It is viewed from an angle a, and we want it to appear as length l/2 (the vertical direction in the pixel art). The sideways direction (horizontal in the pixel art) will continue to be l, so the result will be the desired - lines who are exactly 2:1. This means:

sin a = 1/2 -> a = asin 1/2 = 30°So, the angle to the floor should be exactly 30° (and conversely, the angle to the vertical should be 60°).

|\ h'| \h | \ | \ 60° ------

If something has a height h, what will be the projected height h'? We know h' / h = sin 60° = cos 30° = sqrt(3) / 2. So if something is h' pixels tall, it really is h = h' * 2 / sqrt(3) pixels high. And if we want something to have a height of h, we draw it as h * sqrt(3) / 2 pixels. Real height to drawn pixels is 2 to sqrt(3).

Turning everything by 45°, we get this:

/\ / \ \ / | \/s | x / 2 __x

2 * x^2 = s^2 s = x*sqrt(2)

A diamond.

To make the width x units, the side length must be x*sqrt(2);Now, what it means, is this. We have an isometric tile, which let's say fits into a 64x32 rectangle. So the 'x' in this case is 32. This means, a side really (un-projected) has a length of s = 32 * sqrt(2). And we know by the formula above that something appearing x pixels high really is 2 * x / sqrt(3). So: 32 * sqrt(2) = 2 * x / sqrt(3), or x = 16 * sqrt(2) * sqrt(3). Believe it or not, as always with math formulas, but the result would be about: 39.192 There's no need to understand any of this, just know: For an isometric tile which fits into 64x32, make something 39 pixels tall to have about the same height as a side is long. This cube also will align exactly when using in an isometric tile-map, or stack on top of others. All you need to remember is, if your tile fits into a box w * h (where w = 2 * h, e.g. 64 * 32), then (h * sqrt(6) / 2) is how many pixels high to get a perfect cube. In summary (x is horizontal, y is vertical, z is depth):

**z / x = 1 : 2****z / y = 1 : sqrt(3)**