Link to home
Start Free TrialLog in
Avatar of brainware
brainware

asked on

ISOMetric Game Maps 1000 & 500 Pts

Im looking for DELPHI SOURCE for a ISO Metric map for game use, there are 2 types i need, both have to work in Delphi 3, using DIB's, WrapX or just TCanvas.

1.(500 Points) Simple ISOMetric Map
where you have map as it is in Age of empires eg. Map drawed in a Dimond shaped format and the non-map is black, + Get what ISO-Tile was clicked on.

2.(1000 Points) Advanced ISOMetric Map
like the Simple one but with same features/example as Simcity 2/3000, Transport Tycoon, RollerCoaster Tycoon where you can Raise/Lower Land.

Both can be as a small game sample on a form just mixed to work but as a GraphicControl or such is also ok.

if you need Screenshots of what im talking about just let me know and ill kick some online.

If interested you can get Full Licence for WrapX in addition to points.
As we will use this help for developing Map Engine + Samples etc for WrapX too.
www.wrapx.suite.dk

Regards
Michael V. Andersen - BrainWare Software
brainware@cyberjunkie.dk
Avatar of TheNeil
TheNeil

Your draw routine is actually pretty easy. You just need to specify the size of your blocks in two variables, Block_Width and Block_Height, and the number of blocks tro display across and down the screen (held in no_rows, and no_columns).

Display.Canvas.Brush.Color := clBlack;
Display.Canvas.FillRect(RECT(0, 0, Display.Width, Display.Height));
FOR m := 0 TO (no_rows - 1)
DO
  FOR n := 0 TO (no_columns - 1)
  DO
    IF ODD(m)
    THEN
      Display.Canvas.Draw(Block_Width DIV 2 + Block_Width * n, m * (Block_Height DIV 2), Graphic)
    ELSE
      Display.Canvas.Draw(Block_Width * n, m * (Block_Height DIV 2), Graphic);

Just make sure that when you draw your graphics, you draw them transparently.

The selection process is a little more complex but still not too diffcult. There are a couple of ways but a good cheat (and quick) way is to create a selection mask while drawing the blocks.

Using the above code, create a second bitmap (24 bit colour) the same size as your drawing area and clear it all to black. When you draw the block onto the display, also draw a polygon onto this second bitmap. e.g.

SelectionMap.Canvas.Brush.Color := clBlack;
SelectionMap.Canvas.FillRect(RECT(0, 0, SelectionMap.Width, SelectionMap.Height));
Display.Canvas.Brush.Color := clBlack;
Display.Canvas.FillRect(RECT(0, 0, Display.Width, Display.Height));
FOR m := 0 TO (no_rows - 1)
DO
  FOR n := 0 TO (no_columns - 1)
  DO
  BEGIN
    SelectionMap.Canvas.Brush.Color := m * no_columns + n;
    SelectionMap.Canvas.Pen.Color := m * no_columns + n;

    IF ODD(m)
    THEN
    BEGIN
      Display.Canvas.Draw(Block_Width DIV 2 + Block_Width * n, m * (Block_Height DIV 2), Graphic);
      SelectionMap.Canvas.Polygon([Point(Block_Width * (n + 1), m * (Block_Height DIV 2)),
                                   Point(Block_Width * (n + 1) + Block_Width DIV 2, m * (Block_Height DIV 2) + Block_Height DIV 2),
                                   Point(Block_Width * (n + 1), m * (Block_Height DIV 2) + Block_Height),
                                   Point(Block_Width * (n + 1) - Block_Width DIV 2, m * (Block_Height DIV 2) + Block_Height DIV 2)])
    END
    ELSE
    BEGIN
      Display.Canvas.Draw(Block_Width * n, m * (Block_Height DIV 2), Graphic);
      SelectionMap.Canvas.Polygon([Point(Block_Width * (n + 1) - Block_Width DIV 2, m * (Block_Height DIV 2)),
                                   Point(Block_Width * (n + 1), m * (Block_Height DIV 2) + Block_Height DIV 2),
                                   Point(Block_Width * (n + 1) - Block_Width DIV 2, m * (Block_Height DIV 2) + Block_Height),
                                   Point(Block_Width * (n + 1) - Block_Width, m * (Block_Height DIV 2) + Block_Height DIV 2)])
    END;
  END;

When you get your mouseevent (And therefore the co-ordinates, you just pull the pixel from the SelectionMap.

e.g. Index := SelectionMap.Canvas.PIxels[X, Y] - 1;

Index now contains the index of the block in the grid.

As for doing a raised map then I'm fresh out of ideas, the drawing is a doddle (you can use the code above) but selection is tricky unless you limit yourself to selecting at 'ground' level. To get an impression of raised buildings, you really need to modify your graphics rather than any code. The above code layers everything so that the most distant objects get drawn first. Say your 'ground' is 64x32 pixels but your building can be up to 128 pixels high, you need to set the block width and height to be 64 and 32 respectively in the above code, and it'll handle the rest for you. If you want a more detailed explanation then just ask.

The Neil

   
Michael,

please visit http://www.digitalprojects.com/way-x/english.htm for the 3D TT engine and look if this is what you want. The description on the games engine list (http://cg.cs.tu-berlin.de/~ki/engines.html) states:

3D TT is a 3D game engine for a game like Transport Tycoon for Windows from Peter Dobrovka ( dobrovka@hkn.de ) and WAY-X (a group of hobby programmers).
Based on OpenGL
Multitextured landscape (without shading)
Perspective and isometric view
Large maps (1024x1024)
3D Sprites
Moving objects (esp. trains)
Integrated editor
Written in Delphi Pascal
More information, screenshots and a demo can be found on the (german) WAY-X Homepage under 3DTT (click one of the four icons in the top frame to view screenshots etc).


Ciao, Mike
Avatar of brainware

ASKER

TheNeil: checking out you idea, mostley the selecting part im wondering about..
did manage to do a Normal ISO Map once eg. Drawed as a normal Rectangular map like C&C.  

Lischke: i found Way-X months ago but have nothing to do with the Map i need, Way-X is 3D, the ISO Map used in Transport Tycoon Deluxe etc is simply 2D eg. IsoMetric / Visual Illusion.


Even if TheNeil's way work for Simple i would still be needing the Advanced one wich is a bit harder and the type where i have never found any docs nor source for.
TheNeil i just wrapper a fast code out from what you wrote, but about the selecting i was Refereing to getting the Block eg. Inside the Correct Poly,
not drawing it, all you showed i can do in a few minutes my self as i just did,
check the code i zipped up and mabye continiue on that if you want.
http://www.bw-soft.com/devtemp/

i sayd SIMPLE w. Dimond Shaped MAP,
a bad sketch :
###/\###
##/  \##
##\  /##
###\/###

drawing it as a Rectangular map is no challange..
What is the problem with the selection idea? Using the second bitmap (the selection map), you can quickly find out which block the user clicked on. Isn't that what you wanted?

The Neil
Not quite sure i understand that idea, would you please kick some sample together.
Mail it to me if you want or post url here to a file.

PS: When this is solved i will make a larger sample(s) avalible and post urls here.

About Lower/Raise im not talking about Simple Building heights, but LAND eg. you can raise land build a tunnel if you like and build on top of that, eg having a 3 Dim Array, but that's also just for Advanced type as i sayd..



I'll explain it in detail then.

When you're creating your display (actually drawing your graphics to the display), you also create a second bitmap (the selection map) where you draw polygons that happen to be the same shape as your graphics (in this case diamonds). The clever part comes in the colour that you draw the polygon in. By using a 24 bit bitmap (in memory), you create a direct mapping between the colour and the block that it represents. Therefore the first block in your grid has a colour of just 1 (very, very dark red RGB(1, 0, 0)), the second has 2 etc. When the user clicks on the display you use the mouse co-ordinates to access the pixel property of the selection map image.

e.g.

procedure TForm1.Image1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  iIndex := SelectionMap.Canvas.Pixels[x, y];
end;

iIndex now contains the index into the array of elements. Because you initially clear the selection map image to black, you'll get a value of zero returned when the user clicks outside the valid area.

It's as simple as that.

If you want the actual code sample then give me an e-mail address and I'll create a sample app.

I'll have a think on the diamond drawing algorithm.

The Neil
hmm yeah please send a sample, that way is rather weird to my ears and understanding.. mabye i have just been working other ways for way to longm who knows :)
E-MAIL Listed at top..

You get 1 Index pointing to what?
what kind of an Array are you taloking about? normaly i would use a Array[0..mapwidth,0..mapheight] of a ISOBlock

NOT to be a dificult person, but aint there some good way just to check if its inside Block?'s Polygon insted? just becuse wasting memory for somthing like this is NOT my style..

Also becuse the game will need a lot of memory already, so saving a few kb when possiple i want to do it.
Have you ever worked with Isometric maps ?
Anyhow Anyone else with some bright ideas????
Check ISO Layers here.. its C++/C++ Builder source, i just downloaded it and will take a look at it my self, but if there was anything interesting to someone else well take a look..

http://www.serpentsoftware.com/progindex.html
I did not yet work it out fully but here is some preliminary result of determining where you are in the isometric grid:

function CoordToISOCoord(x,y: Integer): TPoint;
var
  p, i: TPoint;
  dx, dy: Integer;
begin
  // determine rectange
  p.X := X div Block_Width;
  p.Y := 2 * (Y div Block_Height);
  // determine the offset within the retangle
  i.X := X mod Block_Width;
  i.Y := Y mod Block_Height;
  // determine the quadrant
  dx := -1;
  if i.X > Block_Width div 2 then begin
    i.X := -(i.X - (Block_Width div 2)) + (Block_Width div 2);
    dx := 0;
  end;
  dy := -1;
  if i.Y > Block_Height div 2 then begin
    i.Y := -(i.Y - (Block_Height div 2)) + (Block_Height div 2);
    dy := 1;
  end;
  // if external
  if (Block_Height div 2)- i.X * (Block_Height / Block_Width) > i.Y then begin
    p.X := p.X + dx;
    P.Y := p.Y + dy;
  end;
  Result := p;
end;

Regards Jacco
Jacco, ill take a look at it.

btw.. wondering if any of ya have seen
Railroad Tycoon II Gold, i just tryed it and the graphics are great.. but also the Isometric map is special, not fixed heights like sc2000 etc but a bit like Voxel generated maps.
brainware,

Can you put somewhere a snapshot of Tycoon II on a site? Perhaps I know a way.

Zif.
ASKER CERTIFIED SOLUTION
Avatar of Jacco
Jacco
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hi BrainWave,

I could add some code for creating/maintaining tunnels/bridges as well.

I did not build in the possibility of tiles with edges

  1
0   2
  1

of which one diagonal rises 2 planes in height. (It is possible but it requires even more tile-images).

You need a lot more tile-images in this advanced map. I experimented a bit, but I work on Windows NT and do not have DirectX 6 or 7...

Did you get my sample running? It is written in Delphi 5 but should compile easily in D3.

Regards Jacco
I will 1. Add Screenshot of TT2 on http://www.bw-soft.com/devtemp/ 
in a few hours, and going to try the sample shortly.. backing up data to dvd in win98 right now becuse a HDD says like a buldozer so i bet its about to drop dead..
gonna boot to w2k and code shortly.. but it all sounds very interesting..
i do however know it requires alot of Images for the advanced type..

Regards
Michael^2 xor V mod Andersen
Adjusted points to 1500
Jacco you da man :)
im very impressed, not much code and covers alot.

If you dont mind have the time any futher samples of this VERY Welcome,
mabye take a look at the Screenshots from Railroad tycoon 2 if you have any suggestions to that too. anyhow for now i would sayd 'Jacco' won the 1000 Points and the 500 as your last sample simply goes over the edge :)

However if you or ZifNab can come up with more heavy map 'engines' samples for the Railroad tycoon style where you mabye generate map out from a grayscale image and with option to set 'Face/Poly' Details/Quality well im very interested, as im hungry for good maps to be used for Building/RTS Games, Like the Total Annihilation maps wich are very great.
I don't care if its 2D or 3D as long as it works, and since DDRAW and D3D can work greatly together/mixed well 3D is very welcome as it would be possiple to do additional effects etc w. hardware.

Raising Points here to 1500 for you Jacco, and i have about 400pts left for more good maps if thats enough right now.. else i dont mind a few free once hehe.. :)

Many thanks to all of ya.
sorry TheNeil you lose ,)

Iso Regards
Michael V. Andersen
Thanks brainware :)

Never earned so many points answering a question. (1500x4 = 6000). I earned my second T-Shirt.

I suggest you post a new Q with the specifics so we can keep track of the conversation.

Regards Jacco
oki.. here it is..
https://www.experts-exchange.com/jsp/qShow.jsp?ta=delphi&qid=10296648 

Now im rather LOOOOW on points, but anyhow.. if you would have a sample laying around of a ISO Engine like in Diablo eg. ISO/Layers well feel free to post or email it :)

i am writing such my self, but ideas from others can sometimes be a good help.