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.
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 TypeAnd 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.