Here is some code that might help, except for the matrix rotation issue. I'll let someone smarter than I help there.
Camera mod:
Rem
Copyright (c) 2007 David J. Hayes
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
End Rem
SuperStrict
Rem
bbdoc: altitude.camera
End Rem
Rem
Module altitude.camera
ModuleInfo "Version: 1.00"
ModuleInfo "License: MIT"
ModuleInfo "Copyright: 2007 David J. Hayes"
ModuleInfo "Modserver: N/A"
ModuleInfo "History: 1.00"
ModuleInfo "History: First release."
End Rem
Import brl.Max2D
Import brl.LinkedList
Import brl.Random
Rem
bbdoc: The main 2D camera type.
about: Allows for easy creation of game worlds larger than the screens resolution,
simple render queing, split screens, camera effects, etc.
End Rem
Type TCamera
Global List:TList
Field RenderList:TList
Field WorldX:Float
Field WorldY:Float
Field TargetX:Float
Field TargetY:Float
Field X:Float
Field Y:Float
Field Width:Float
Field Height:Float
Field Zoom:Float
Field ClsColor:Int[3]
Field _VPX:Int, _VPY:Int, _VPW:Int, _VPH:Int, _SX:Float, _SY:Float, _OX:Float, _OY:Float, _A:Float, _B:Int, _R:Float, _C:Int[3]
Rem
bbdoc: Creates a new camera
End Rem
Function Create:TCamera (_WorldX:Float, _WorldY:Float,_X:Float, _Y:Float, _Width:Float, _Height:Float)
Local Camera:TCamera = New TCamera
Camera.WorldX = _WorldX
Camera.WorldY = _WorldY
Camera.Set(_X, _Y, _Width, _Height)
Camera.Zoom = 1.0
Return Camera
End Function
Method New()
If List = Null List = CreateList()
List.AddLast Self
RenderList = CreateList()
End Method
Rem
bbdoc: Resets render settings to default.
about: Call before calling a render objects Render() function.
End Rem
Method StartRender()
GetViewport _VPX,_VPY,_VPW,_VPH
GetScale _SX,_SY
GetOrigin _OX,_OY
_A = GetAlpha()
_B = GetBlend()
_R = GetRotation()
GetColor _C[0],_C[1],_C[2]
SetViewport X,Y,Width,Height
SetOrigin 0,0
SetColor ClsColor[0],ClsColor[1],ClsColor[2]
DrawRect X, Y,Width,Height
SetScale Zoom, Zoom
SetRotation 0
SetBlend ALPHABLEND
SetAlpha 1
SetColor 255,255,255
End Method
Rem
bbdoc: Returns to previous render settings.
about: Call after calling a render objects Render() function.
End Rem
Method EndRender()
SetViewport _VPX,_VPY,_VPW,_VPH
SetScale _SX, _SY
SetOrigin _OX,_OY
SetAlpha _A
SetBlend _B
SetRotation _R
SetColor _C[0],_C[1],_C[2]
End Method
Rem
bbdoc: Calls all Render() functions for TRenderObjects in RenderList.
End Rem
Method RenderAll()
StartRender
For Local Obj:TRenderObject = EachIn RenderList
If TRenderObject(obj) obj.Render(Self)
Next
EndRender
End Method
Rem
bbdoc: Calls all Render() functions for TRenderObjects in given list.
End Rem
Method RenderFromList(_List:TList)
StartRender
For Local Obj:TRenderObject = EachIn _List
If TRenderObject(obj) obj.Render(Self)
Next
EndRender
End Method
Rem
bbdoc: Sets the position and size of the camera.
End Rem
Method Set(_X:Float, _Y:Float, _Width:Float, _Height:Float)
X = _X
Y = _Y
Width = _Width
Height = _Height
End Method
Rem
bbdoc: Helper function for converting world to screen coordinates.
End Rem
Method ScreenX:Float (_WorldX:Float)
Return (_WorldX * Zoom) + WorldX
End Method
Rem
bbdoc: Helper function for converting world to screen coordinates.
End Rem
Method ScreenY:Float (_WorldY:Float)
Return (_WorldY * Zoom) + WorldY
End Method
Rem
bbdoc: Centers camera onto specified world position.
End Rem
Method CenterOnPosition(_X:Int, _Y:Int)
WorldX = -_X * Zoom + (X + (Width / 2))
WorldY = -_Y * Zoom + (Y + (Height / 2))
End Method
Rem
bbdoc: Centers camera onto specified world position smoothly using easing.
End Rem
Method CenterOnPositionSmooth(_X:Float, _Y:Float, _Speed:Double = 1.0)
_X = Int(_X);_Y = Int(_Y)
TargetX = -_X * Zoom + (X + (Width / 2))
TargetY = -_Y * Zoom + (Y + (Height / 2))
WorldX :+ (TargetX - WorldX) * (_Speed * Zoom)
WorldY :+ (TargetY - WorldY) * (_Speed * Zoom)
End Method
Rem
bbdoc: Zooms camera to specified world position and zoom level.
End Rem
Method ZoomTo(_X:Float, _Y:Float, _Level:Float)
Zoom = _Level
TargetX = -_X * Zoom + (X + (Width / 2))
TargetY = -_X * Zoom + (Y + (Height / 2))
WorldX = TargetX
WorldY = TargetY
End Method
Rem
bbdoc: Offsets camera position randomly by a given strength.
End Rem
Method Shake(_Strength:Float)
WorldX :+ Rnd(-_Strength,_Strength) * Zoom
WorldY :+ Rnd(-_Strength,_Strength) * Zoom
End Method
End Type
Rem
bbdoc: An abstract class for renderable game objects to extend.
End Rem
Type TRenderObject Abstract
Method Render(_Camera:TCamera)
End Method
End Type
Quick example:
SuperStrict
Import altitude.camera
Graphics 640, 480
Const STATICFRICTION:Float =.02
Type TEntity Extends TRenderObject
Field List:TList
Field X:Float, Y:Float, VX:Float, VY:Float
Field Radius:Float, Color:Int[]
Function Create:TEntity (X:Float, Y:Float, Radius:Float, Color:Int[])
Local Entity:TEntity = New TEntity
Entity.X = X
Entity.Y = Y
Entity.Radius = Radius
Entity.Color = Color
Return Entity
End Function
Method New()
If List = Null List = CreateList()
List.AddLast Self
End Method
Method Update()
VX:*(1 - STATICFRICTION)
VY:*(1 - STATICFRICTION)
X:+VX
Y:+VY
End Method
Method Render(Cam:TCamera)
Local SX:Float = Cam.ScreenX(X - radius)
Local SY:Float = Cam.ScreenY(Y - radius)
SetColor Color[0], Color[1], Color[2]
DrawOval SX, SY, (Radius * 2) * Cam.Zoom, (Radius * 2) * Cam.Zoom
End Method
End Type
Local cam:TCamera = TCamera.Create(0, 0, 0, 0, 640, 480)
Local cam2:TCamera = TCamera.Create(0, 0, 540, 380, 100, 100)
cam2.Zoom =.25
cam2.ClsColor =[0, 128, 0]
For Local i:Int = 1 To 100
Cam.RenderList.AddLast(TEntity.Create(Rnd(- 1000, 1000), Rnd(- 1000, 1000), 25, [Int(Rnd(0, 255)), Int(Rnd(0, 255)), Int(Rnd(0, 255))]))
Next
Local e:TEntity = TEntity.Create(100, 100, 50, [255, 255, 0])
Cam.RenderList.AddLast(e)
While not KeyHit(KEY_ESCAPE)
e.VX:+(KeyDown(KEY_RIGHT) - KeyDown(KEY_LEFT)) *.5
e.VY:+(KeyDown(KEY_DOWN) - KeyDown(KEY_UP)) *.5
e.Update()
Cam.Zoom:+(KeyDown(KEY_A) - KeyDown(KEY_Z)) *.005
Cam.CenterOnPositionSmooth(e.X, e.Y, .5)
Cam.RenderAll()
Cam2.CenterOnPosition(e.X, e.Y)
Cam2.RenderFromList(Cam.RenderList)
DrawText "Zoom: " + Cam.Zoom, 0, 0
Flip;Cls
Wend
End