Main file in project:
Code:
namespace paulfnicholls.game.platformation;

interface
uses
  org.lwjgl,
  org.lwjgl.input,
  org.lwjgl.opengl,
  org.lwjgl.util.glu;

type
  //
  // GameApplication class
  //
  GameApplication = public class
  private
    const cScreenWidth  = 800;
    const cScreenHeight = 600;
    const cTileWidth    = 32;
    const cTileHeight   = 32;
    var
    FScreenWidth  : Integer;
    FScreenHeight : Integer;
    FLevel        : GameLevel;

    method InitGame;
    method CleanupGame;
    method InitGL;

    method RenderTile_Ground(aTile: GameTile; aX,aY: Single);
    method RenderFrame;
  public
    method Run();
    class method main(argv: array of String);
  end;

implementation

  //
  // GameApplication class
  //
method GameApplication.InitGame;
begin
  FScreenWidth  := cScreenWidth;
  FScreenHeight := cScreenHeight;

  FLevel := new GameLevel;
  FLevel.SetBounds(10,10,cTileWidth,cTileHeight);

  FLevel.RegisterRenderTileRoutine(GameTile.cTileTheme_Earth ,@RenderTile_Ground);
  FLevel.RegisterRenderTileRoutine(GameTile.cTileTheme_Air   ,@RenderTile_Ground);
  FLevel.RegisterRenderTileRoutine(GameTile.cTileTheme_Fire  ,@RenderTile_Ground);
  FLevel.RegisterRenderTileRoutine(GameTile.cTileTheme_Water ,@RenderTile_Ground);
end;

method GameApplication.CleanupGame;
begin
  FLevel := nil;
end;

method GameApplication.InitGL;
begin
  GL11.glViewport(0, 0, FScreenWidth, FScreenHeight);

  GL11.glMatrixMode(GL11.GL_PROJECTION);
  GL11.glLoadIdentity();
  GLU.gluOrtho2D(0, FScreenWidth, FScreenHeight, 0);
  GL11.glMatrixMode(GL11.GL_MODELVIEW);

  GL11.glEnable(GL11.GL_DEPTH_TEST);

  GL11.glClearColor (0, 0, 0, 0);
end;

method GameApplication.RenderTile_Ground(aTile: GameTile; aX,aY: Single);
var
  x1,y1,x2,y2 : Single;
  w,h         : Single;
begin
  GL11.glColor3f(0.5,0.5,1.0);
    
  w  := cTileWidth;
  h  := cTileHeight;
  x1 := aX;
  y1 := aY;
  x2 := aX + w;
  y2 := aY + h;

  // draw tile quad
  GL11.glBegin(GL11.GL_QUADS);
    GL11.glVertex2f(x1,y1);
    GL11.glVertex2f(x2,y1);
    GL11.glVertex2f(x2,y2);
    GL11.glVertex2f(x1,y2);
  GL11.glEnd();

  GL11.glColor3f(1,0,0);
  GL11.glBegin(GL11.GL_LINE_LOOP);
    GL11.glVertex2f(x1,y1);
    GL11.glVertex2f(x2,y1);
    GL11.glVertex2f(x2,y2);
    GL11.glVertex2f(x1,y2);
  GL11.glEnd();
end;

method GameApplication.RenderFrame;
begin
//  FLevel.Render;
{  // set the color of the quad (R,G,B,A)
  GL11.glColor3f(0.5,0.5,1.0);
            
  // draw quad
  GL11.glBegin(GL11.GL_QUADS);
  GL11.glVertex2f(100,100);
  GL11.glVertex2f(100+200,100);
  GL11.glVertex2f(100+200,100+200);
  GL11.glVertex2f(100,100+200);
  GL11.glEnd();}
end;

method GameApplication.Run();
begin
  InitGame;
  try
    try
      Display.setDisplayMode(new DisplayMode(FScreenWidth, FScreenHeight));
      Display.create();
    except
      on e: LWJGLException do
      begin
        e.printStackTrace();
        System.exit(0)
      end; 
    end;

    //  init OpenGL here
    InitGL;

    Display.Title := 'Platformation';

    while not Display.isCloseRequested() do 
    begin
      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT or GL11.GL_DEPTH_BUFFER_BIT);
      GL11.glLoadIdentity;

      RenderFrame;

      Display.update();
      Display.sync(60);

      if Keyboard.isKeyDown(Keyboard.KEY_ESCAPE) then Break;
    end;
  finally
    CleanupGame;
  end;

  Display.destroy()
end;

class method GameApplication.main(argv: array of String);
begin
  var App: GameApplication := new GameApplication();
  App.Run()
end;

end.
classes 'unit':
Code:
namespace paulfnicholls.game.platformation;

interface

type
  //
  // GameTile class
  //
  GameTile = public class
  public
    const cTileType_Space  = 0;
    const cTileType_Ground = 1;
    const cNumTileTypes    = 2;

    const cTileTheme_Earth = 0;
    const cTileTheme_Air   = 1;
    const cTileTheme_Fire  = 2;
    const cTileTheme_Water = 3;
    const cNumTileThemes   = 4;

    var
    Id      : Integer;
    Theme   : Integer;
    IsSolid : Boolean;

    constructor(aId,aTheme: Integer; aIsSolid: Boolean);
  end;

  //
  // GameLevel class
  //
  RenderTileRoutine = delegate(aTile: GameTile; aX,aY: Single);

  LevelRow   = array of GameTile;
  LevelLayer = array of LevelRow;

  GameLevel = public class
  private
    FLevelWidth  : Integer;
    FLevelHeight : Integer;
    FTileWidth   : Integer;
    FTileHeight  : Integer;
    FLevel       : LevelLayer;
    FRenderTile  : array of RenderTileRoutine;
  public
    constructor;

    method SetBounds(aLevelWidth,aLevelHeight,aTileWidth,aTileHeight: Integer);
    method RegisterRenderTileRoutine(aTileType: Integer; aRenderTileRoutine: RenderTileRoutine);
    method Render;

    method GetTileX(aX: Single): Integer;
    method GetTileY(aY: Single): Integer;
  end;

implementation

  //
  // GameTile class
  //
constructor GameTile(aId,aTheme: Integer; aIsSolid: Boolean);
begin
  inherited Constructor;

  Id      := aId;
  Theme   := aTheme;
  IsSolid := aIsSolid;
end;

  //
  // GameLevel class
  //
constructor GameLevel;
var
  i: Integer;
begin
  inherited Constructor;

  SetBounds(10,10,32,32);

  FRenderTile := new RenderTileRoutine[GameTile.cNumTileTypes]; 
  for i := 0 to length(FRenderTile) - 1 do FRenderTile[i] := nil;
end;

method GameLevel.SetBounds(aLevelWidth,aLevelHeight,aTileWidth,aTileHeight: Integer); 
var
  x,y: Integer;
begin
  FLevelWidth  := aLevelWidth;
  FLevelHeight := aLevelHeight;
  FTileWidth   := aTileWidth;
  FTileHeight  := aTileHeight;

  FLevel := new LevelLayer(FLevelHeight);
  for y := 0 to FLevelHeight - 1 do
  begin
    FLevel[y] := new LevelRow(FLevelWidth);

    for x := 0 to FLevelWidth - 1 do
    begin
      if (x = 0) or (x = FLevelWidth - 1) or (y = 0) or (y = FLevelHeight - 1) then
        FLevel[y,x] := new GameTile(GameTile.cTileType_Ground,GameTile.cTileTheme_Earth,True)
      else
        FLevel[y,x] := new GameTile(GameTile.cTileType_Space,GameTile.cTileTheme_Earth,False);
    end;
  end;
end;

method GameLevel.RegisterRenderTileRoutine(aTileType: Integer; aRenderTileRoutine: RenderTileRoutine);
begin
  FRenderTile[aTileType] := aRenderTileRoutine;
end;

method GameLevel.Render;
var
  x,y : Integer;
  t   : GameTile;
begin
  for y := 0 to FLevelHeight - 1 do
    for x := 0 to FLevelWidth - 1 do
    begin
      t := FLevel[y,x];

      if (t.Id <> GameTile.cTileType_Space) and assigned(FRenderTile[t.Id]) then
      begin
        FRenderTile[t.Id](t,x * FTileWidth,y * FTileHeight);
      end;
    end;
end;

method GameLevel.GetTileX(aX: Single): Integer;
begin
  Result := Integer(Math.floor(aX / FTileWidth));
end;

method GameLevel.GetTileY(aY: Single): Integer;
begin
  Result := Integer(Math.floor(aY / FTileHeight));
end;

end.
I can't see what the issue is with the 'multi dimensional array complaint' and GameLevel.SetBounds()...

Any idea Oxygene experts?