We already have a map but we have nothing to move around yet. What we need is a camera object that tells our engine which part of the map should be displayed on the screen. The camera basically has a position and a size which is actually the screen size. Since the camera is quite comparable to the screen we'll make the front DC a property of it. The front DC is nothing more than a reference to the canvas where we'll draw our game on. You don't have to know how it works exactly, it's just a value we'll need for the BitBlt call later. Also we want to store how many tiles fit on the screen in X and Y direction.
This is completely different from the map or tiles so add another module to the project and name it mCamera.
Public Type tCamera 'Camera position X as Long Y as Long 'Screen size w as Long 'W means width h as Long 'H means height 'Number of tiles that fit on screen TilesX as Long TilesY as Long 'Front buffer FrontDC as Long End Type Public Camera as tCamera
So this is how the camera Type looks like. Put the code into the mCamera module and go on.
Again for the camera we want some functions to modify it's data. As before we need a Reset function to set up the properties and also a function to access the data (which in this case means: setting the camera position). The reset function here is a little more complex since we need to pass the Front picture. It's called Front because when using double-buffering it would be the visible buffer, in opposite to the Back Buffer which would be hidden. Besides we can get the screen size and calculate the number of tiles that fit there:
Public Sub Reset( iFront as PictureBox ) With Camera 'Get viewport size .w = iFront.ScaleWidth .h = iFront.ScaleHeight 'Calculate number of visible tiles .TilesX = ( .w / TileSize ) .TilesY = ( .h / TileSize ) 'Get device context .FrontDC = iFront.hDC End With End Sub
The second function we need sets the camera position and checks if the focussed area is still inside the map. In case we left the map it rejects the position and clips it back to a valid position. Note that for the upper-bound check we have to get the right und bottom border position of the camera and not just it's position!
Public Sub LookAt( iX as Long, iY as Long ) 'Store position Camera.X = iX Camera.Y = iY 'Check upper boundaries If ( Camera.X + Camera.TilesX ) > Map.w Then: Camera.X = ( Map.w - Camera.TilesX ) If ( Camera.Y + Camera.TilesY ) > Map.h Then: Camera.Y = ( Map.h - Camera.TilesY ) 'Check lower boundaries If Camera.X < 0 Then: Camera.X = 0 If Camera.Y < 0 Then: Camera.Y = 0 End Sub