Ok to start you out here is a simple 2D camera system that will let you have multiple viewports each able to zoom in and out.
And here is a tile map system for you.
Let me know if you have questions.
Global CameraList:TList = CreateList() Type TCamera Field WorldX:Float Field WorldY:Float Field TargetX:Float Field TargetY:Float Field ViewX:Float Field ViewY:Float Field ViewWidth:Float Field ViewHeight:Float Field ViewZoom:Float Function Create:TCamera (_WorldX:Float, _WorldY:Float,_ViewX:Float, _ViewY:Float, _ViewWidth:Float, _ViewHeight:Float) Local Camera:TCamera = New TCamera Camera.WorldX = _WorldX Camera.WorldY = _WorldY Camera.SetView(_ViewX, _ViewY, _ViewWidth, _ViewHeight) Camera.ViewZoom = 1.0 CameraList.AddLast(Camera) If Debug.Enabled Debug.Console.Output("Camera Created",[255,255,255]) Return Camera End Function Method Cls() Local ClsColor:Int [3] GetClsColor ClsColor[0],ClsColor[1],ClsColor[2] SetColor ClsColor[0],ClsColor[1],ClsColor[2] DrawRect ViewX, ViewY,ViewWidth,ViewHeight End Method Method SetView(_ViewX:Float, _ViewY:Float, _ViewWidth:Float, _ViewHeight:Float) ViewX = _ViewX ViewY = _ViewY ViewWidth = _ViewWidth ViewHeight = _ViewHeight End Method Method CenterOnPosition(_X:Float, _Y:Float, _Speed:Float = 1.0) TargetX = -_X * ViewZoom + (ViewX + (ViewWidth / 2)) TargetY = -_Y * ViewZoom + (ViewY + (ViewHeight / 2)) WorldX :+ (TargetX - WorldX) * (_Speed * ViewZoom) WorldY :+ (TargetY - WorldY) * (_Speed * ViewZoom) End Method Method Shake(_Strength:Float) WorldX :+ Rnd(-_Strength,_Strength) * ViewZoom WorldY :+ Rnd(-_Strength,_Strength) * ViewZoom End Method End Type
And here is a tile map system for you.
Global Tiles:TImage [1] Type TTileMap Field Name:String Field TileSize:Float Field Depth:Int Field Width:Int Field Height:Int Field Data:Int [,,] Function CreateBlank:TTileMap (_Name:String, _Depth:Int, _Width:Int, _Height:Int, _TileSize:Int = 32) Local o:TTileMap = New TTileMap o.Name = _Name o.TileSize = _TileSize o.Depth = _Depth o.Width = _Width o.Height = _Height o.Data = New Int[_Depth, _Width, _Height] o.Clear() Return o End Function Function CreateFromFile:TTileMap (_File:String) Local o:TTileMap = New TTileMap o.Load(_File) Return o End Function Method LimitCameraToMapBounds(_Camera:TCamera) If _Camera.WorldX < -(Width*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewX + _Camera.ViewWidth) _Camera.WorldX = -(Width*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewX + _Camera.ViewWidth) End If If _Camera.WorldY < -(Height*(TileSize *_Camera.ViewZoom)) + (_Camera.ViewY + _Camera.ViewHeight) _Camera.WorldY = -(Height*(TileSize * _Camera.ViewZoom)) + (_Camera.ViewY + _Camera.ViewHeight) End If If _Camera.WorldX > _Camera.ViewX Then _Camera.WorldX = _Camera.ViewX If _Camera.WorldY > _Camera.ViewY Then _Camera.WorldY = _Camera.ViewY End Method Method Load (_File:String) Local In:tStream = ReadStream(_File) If Not In Return False End If Name = ReadString(In,16) TileSize = Readint(In) Depth = Readint(In) Width = Readint(In) Height = Readint(In) Data = New Int[Depth, Width, Height] For Local d:Int = 0 To Depth - 1 For Local x:Int = 0 To Width - 1 For Local y:Int = 0 To Height - 1 Data [d,x,y] = Readint(In) Next Next Next CloseStream In End Method Method Save (_File:String) Local Out:tStream = WriteStream(_File) If Not Out Return False End If WriteString (Out,Name[..16]) WriteInt (Out,TileSize) WriteInt (Out,Depth) WriteInt (Out,Width) WriteInt (Out,Height) For Local d:Int = 0 To Depth - 1 For Local x:Int = 0 To Width - 1 For Local y:Int = 0 To Height - 1 WriteInt(Out,Data [d,x,y]) Next Next Next CloseStream Out End Method Method Clear() For Local d:Int = 0 To Depth - 1 For Local x:Int = 0 To Width - 1 For Local y:Int = 0 To Height - 1 Data [d,x,y] = 0 Next Next Next End Method Method Fill(_Depth:Int, _TileIndex:Int) For Local x:Int = 0 To Width - 1 For Local y:Int = 0 To Height - 1 Data [_Depth,x,y] = _TileIndex Next Next End Method Method ScreenToMapCoords(_Camera:TCamera,_ScreenX:Float, _ScreenY:Float, _MapX:Float Var, _MapY:Float Var) If _ScreenX < _Camera.ViewX Or _ScreenX > _Camera.ViewX + _Camera.ViewWidth Or _ScreenY < _Camera.ViewY Or _ScreenY > _Camera.ViewY + _Camera.ViewHeight Then _MapX = -1 _MapY = -1 Return False EndIf If _Camera.WorldX > 0 Then _MapX = (_ScreenX - _Camera.WorldX) Else _MapX = (-_Camera.WorldX + _ScreenX) EndIf If _Camera.WorldY > 0 Then _MapY = (_ScreenY - _Camera.WorldY) Else _MapY = (-_Camera.WorldY + _ScreenY) EndIf Return True End Method Method ScreenToMapCell(_Camera:TCamera,_ScreenX:Float, _ScreenY:Float, _MapCellX:Int Var, _MapCellY:Int Var) Local _MapX:Float Local _MapY:Float ScreenToMapCoords(_Camera,_ScreenX, _ScreenY, _MapX, _MapY) If _MapX <0 Or _MapX > Width * (TileSize * _Camera.ViewZoom) Or _MapY < 0 Or _MapY > Height * (TileSize * _Camera.ViewZoom) Then _MapCellX = -1 _MapCellY = -1 Else _MapCellX = _MapX / (TileSize * _Camera.ViewZoom) _MapCellY = _MapY / (TileSize * _Camera.ViewZoom) EndIf End Method Method MapToMapCell(_Camera:TCamera,_MapX:Float, _MapY:Float, _MapCellX:Int Var, _MapCellY:Int Var) If _MapX < 0 Or _MapX > Width * (TileSize * _Camera.ViewZoom) Or _MapY < 0 Or _MapY > Height * (TileSize * _Camera.ViewZoom) Then _MapCellX = -1 _MapCellY = -1 Else _MapCellX = _MapX / (TileSize * _Camera.ViewZoom) _MapCellY = _MapY / (TileSize * _Camera.ViewZoom) EndIf End Method Method MapCellToScreenCoords(_Camera:TCamera,_MapX:Float, _MapY:Float, _ScreenX:Float Var, _ScreenY:Float Var) _ScreenX = _Camera.WorldX + (TileSize * _Camera.ViewZoom) * _MapX _ScreenY = _Camera.WorldY + (TileSize * _Camera.ViewZoom) * _MapY End Method Method MapToScreenCoords(_Camera:TCamera,_MapX:Float, _MapY:Float, _ScreenX:Float Var, _ScreenY:Float Var) _ScreenX = (_MapX * _Camera.ViewZoom) + _Camera.WorldX _ScreenY = (_MapY * _Camera.ViewZoom) + _Camera.WorldY End Method Method Render(_Camera:TCamera,_Depth:Int = 0) Local ScreenX:Float Local ScreenY:Float For Local MapX = 0 To Width - 1 ScreenX = MapX * (TileSize * _Camera.ViewZoom) + _Camera.WorldX If ScreenX + (TileSize * _Camera.ViewZoom) >= _Camera.ViewX And ScreenX <= _Camera.ViewX + _Camera.ViewWidth Then For Local MapY = 0 To Height - 1 ScreenY = MapY * (TileSize * _Camera.ViewZoom) + _Camera.WorldY If ScreenY + (TileSize * _Camera.ViewZoom) >= _Camera.ViewY And ScreenY <= _Camera.ViewY + _Camera.ViewHeight Then Local TileIndex:Int = Data[_Depth, MapX, MapY] If TileIndex < 0 TileIndex = 0 If TileIndex > Tiles.Length - 1 TileIndex = 0 If Tiles[TileIndex] = Null If TileIndex <> 0 Print "Error: Tile does not exist: #"+TileIndex Continue End If SetScale _Camera.ViewZoom,_Camera.ViewZoom DrawImage Tiles[TileIndex],ScreenX, ScreenY SetScale 1,1 EndIf Next EndIf Next End Method Method RenderGrid(CurrentCamera:TCamera) Local _Size:Float = TileSize * CurrentCamera.ViewZoom For Local _X:Float = 0 To Width DrawLine _X*_Size+CurrentCamera.WorldX,CurrentCamera.WorldY,_X*_Size+CurrentCamera.WorldX,CurrentCamera.WorldY+(Height*_Size) Next For Local _Y:Float = 0 To Height DrawLine CurrentCamera.WorldX,_Y*_Size+CurrentCamera.WorldY,CurrentCamera.WorldX+(Width*_Size), _Y*_Size+CurrentCamera.WorldY Next End Method End Type
Let me know if you have questions.