Results 1 to 6 of 6

Thread: Isometric Worlds

  1. #1

    Isometric Worlds

    Hi guys.

    So I have finished my platformer with great performance thanks to those of you who helped me! Once I finished the Super Mario lookalike, I got bored at drawing simple flat objects on the screen, so I decided to tackle Isometric worlds next. I found it to be much easier to program than my previous 2D game and I already have set up the map. Now I have two questions.

    1. How do you implement zoom in an Isometric world? Like in Age Of Empires, you can zoom in and out. I have searched the NET, but found nothing.

    2. I also created a map editor, but I need a little help with placing tiles where the user clicks. How will I determine the X and Y coordinates where the user clicked? And also how do I check if the user cliked on a tile that is inside map boundaries? I have gone through the tutorial given on DelphiGameDev, but to be honest, it lacks explanation...

    Once again a big thanks to those who helped!

    PS. I use tiles of 128x64 and my current map size is 50x50.


    ================================================== ================================================== =======

    Below is the new code. Sorry for changing, but I have found a MUCH easier way...


    Code:
    Unit LoD;
    
    Interface
    
    Uses
     Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
     Dialogs, DXDraws, DIB, DXClass, DXSprite, DXPlay, DXInput;
    
    Type
      TTile = Record
        TileImage: Integer;
      End;
    
      TTileMap = Record
        MapArray: Array[0..49, 0..49] Of TTile;
      End;
    
      TForm1 = Class( TDXForm )
        DXDraw1: TDXDraw;
        DXImageList1: TDXImageList;
        DXTimer1: TDXTimer;
        DXInput1: TDXInput;
        Procedure FormCreate( Sender: TObject );
        Function CartesianToIsometric( CartPoint: TPoint ): TPoint;
        Function IsomectricToCartesian( IsoPoint: TPoint ): TPoint;
        Procedure PlaceTile( PatternIndex: Integer );
        Procedure DXTimer1Timer( Sender: TObject; LagCount: Integer );
        Procedure FormKeyDown( Sender: TObject; var Key: Word; Shift: TShiftState );
      Private
        { Private Declarations }
      Public
        { Public Declarations }
      End;
    
    Var
     Form1: TForm1;
     Map: TTileMap;
     StartX, StartY: Integer;
    
    Implementation
    
    {$R *.dfm}
    
    Procedure TForm1.FormCreate( Sender: TObject );
    Var
     X, Y: Integer;
    Begin
      DXDraw1.Display.Width := Screen.Width;
      DXDraw1.Display.Height := Screen.Height;
    
      StartX := 0;
      StartY := 0;
    
      For X := 0 To 49 Do
       Begin
         For Y := 0 To 49 Do
          Begin
            Map.MapArray[X, Y].TileImage := 0;
          End;{ For }
       End;{ For }
    
      DXTimer1.Enabled := True;
    End;
    
    Function TForm1.CartesianToIsometric( CartPoint: TPoint ): TPoint;
    Var
     IsoPoint: TPoint;
    Begin
      Result := Point( 0, 0 );
    
      IsoPoint.X := CartPoint.X - CartPoint.Y;
      IsoPoint.Y := Round( ( CartPoint.X + CartPoint.Y ) / 2 );
    
      Result := IsoPoint;
    End;
    
    Function TForm1.IsomectricToCartesian( IsoPoint: TPoint ): TPoint;
    Var
     CartPoint: TPoint;
    Begin
      Result := Point( 0, 0 );
    
      CartPoint.X := Round( ( 2 * IsoPoint.Y + IsoPoint.X ) / 2 );
      CartPoint.Y := Round( ( 2 * IsoPoint.Y - IsoPoint.X ) / 2 );
    
      Result := CartPoint;
    End;
    
    Procedure TForm1.PlaceTile( PatternIndex: Integer );
    Var
     i, j: Integer;
     X, Y: Integer;
     TileImage: Integer;
    Begin
      If DXDraw1.CanDraw
      Then
       Begin
         For i := 0 To 49 Do { Loop through rows }
          Begin
            For j := 0 To 49 Do { Loop through columns }
             Begin
               X := J * 66; // Change to 64
               Y := i * 66; // Change to 64
               TileImage := Map.MapArray[i, j].TileImage;
               DXImageList1.Items[TileImage].Draw( DXDraw1.Surface, StartX + CartesianToIsometric( Point( X, Y ) ).X, StartY + CartesianToIsometric( Point( X, Y ) ).Y, PatternIndex );
             End;{ For }
          End;{ For }
       End
      Else Exit;
    End;
    
    Procedure TForm1.DXTimer1Timer( Sender: TObject; LagCount: Integer );
    Begin
      DXDraw1.Surface.Fill( 0 );
      PlaceTile( 0 );
      DXDraw1.Flip;
    
      DXInput1.Update;
      If IsLeft In DXInput1.States
      Then StartX := StartX + 16;
      If IsRight In DXInput1.States
      Then StartX := StartX - 16;
      If IsUp In DXInput1.States
      Then StartY := StartY + 8;
      If IsDown In DXInput1.States
      Then StartY := StartY - 8;
    End;
    
    Procedure TForm1.FormKeyDown( Sender: TObject; Var Key: Word; Shift: TShiftState );
    Begin
      If Key = VK_ESCAPE
      Then Application.Terminate;
    End;
    
    End.

    Here's the source for those who wish to compile the code.


    Game.zip
    Last edited by Proph3t; 11-10-2013 at 12:56 PM.
    IF YOU'VE FAILED TO TAKE OVER THE WORLD, CREATE A GAME WHERE YOU CAN.

  2. #2
    I'll try to ckech your code when I get home.
    But for next time please use CODE tags when inserting code samples into posts.

  3. #3
    Thank you very much.

    This is probably a stupid question, but Im new to forums. How do I add a code tag?
    IF YOU'VE FAILED TO TAKE OVER THE WORLD, CREATE A GAME WHERE YOU CAN.

  4. #4
    Click "Go Advanced" button, and you get more tools for message posting.

  5. #5
    Quote Originally Posted by User137 View Post
    Click "Go Advanced" button, and you get more tools for message posting.
    Ah okay many thanks I will use that next time.
    Last edited by Proph3t; 11-10-2013 at 12:51 PM.
    IF YOU'VE FAILED TO TAKE OVER THE WORLD, CREATE A GAME WHERE YOU CAN.

  6. #6
    Quote Originally Posted by Proph3t View Post
    1. How do you implement zoom in an Isometric world? Like in Age Of Empires, you can zoom in and out. I have searched the NET, but found nothing.
    To get the best results with zoom you should create different graphics for different zoom levels (Transport Tycoon did this) or you can just scale the tiles, in other words to zoom in 2x set the tile size to 256x128 and draw all tiles with 2X scaling.

    Quote Originally Posted by Proph3t View Post
    2. I also created a map editor, but I need a little help with placing tiles where the user clicks. How will I determine the X and Y coordinates where the user clicked? And also how do I check if the user cliked on a tile that is inside map boundaries? I have gone through the tutorial given on DelphiGameDev, but to be honest, it lacks explanation...
    Theese are my isometric screen to world and world to screen functions:

    Code:
    const
      TileWidth  = 64;
      TileHeight = 32;
    
      MapWidth  = 16;
      MapHeight = 16;
    
      MapOffsetX = 400;
      MapOffsetY = 100;
    
    function WorldToScreen(const Value: TVector2f): TVector2f;
    begin
      Result.X:= MapOffsetX + (Value.X - Value.Y) * (TileWidth  div 2);
      Result.Y:= MapOffsetY + (Value.X + Value.Y) * (TileHeight div 2);
    end;
    
    function ScreenToWorld(const Value: TVector2f): TVector2f;
    var X,Y: Single;
    begin
      X:= (Value.X - MapOffsetX) / (TileWidth  div 2);
      Y:= (Value.Y - MapOffsetY) / (TileHeight div 2);
    
      Result.X:= (X + Y) / 2;
      Result.Y:= (Y - X) / 2;
    end;
    And to check if its inside the map just check the returned X and Y coordinates:

    Code:
      Position:= ScreenToWorld(Input.Mouse.X, Input.Mouse.Y);
    
      X:= Trunc(Position.X);
      Y:= Trunc(Position.Y);
    
    
      if(X >= 0) and (X < MapWidth) and (Y>=0) and (Y < MapHeight) then
      begin
        MapData[0, Y, X]:= Tile;
      end;

    I have a working sample of this in Phoenix (Addons\01_Sprites\05_Isometric):

    http://phoenixlib.net/wiki/doku.php?id=start
    Amnoxx

    Oh, and this code appears to be an approximate replacement for return(random() & 0x01);

    Phoenix Wiki
    http://www.phoenixlib.net/

    Phoenix Forum
    http://www.pascalgamedevelopment.com/viewforum.php?f=71

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •