As in the **basic tutorial** I'll show you the whole code first and discuss each part later. So let's have a look at the new **Draw** function:

Public Sub Draw() Dim X as Long Dim Y as Long Dim Index as Long Dim TileIndex as Long Dim TempX as Single Dim TempY as Single With Map 'Get map position TempX = ( Camera.X / TileSize ) TempY = ( Camera.Y / TileSize ) 'Calculate index of this positon Index = Int( TempY ) * .w + Int( TempX ) 'Calculate smooth scrolling TempX = TempX - Int( TempX ) TempY = TempY - Int( TempY ) 'Draw the map For Y = 0 To Camera.TilesY For X = 0 To Camera.TilesX 'Check index If Index > ( Map.w * Map.h ) Then: Exit Sub 'Get tile index TileIndex = .Data( Index ) 'Draw tile BitBlt Camera.FrontDC, _ ( X - TempX ) * TileSize, ( Y - TempY ) * TileSize, _ TileSize, TileSize, _ Bitmap( Tile( TileIndex ).Bitmap ).Picture.DC, _ Tile( TileIndex ).ActFrame * TileSize, 0, _ vbSrcCopy 'Next tile Index = Index + 1 Next 'Get next line start Index = Index + .w - Camera.TilesX - 1 Next End With End Sub

You can see lots of **math** now and the function has grown a little. Well you know, don't be scared it's just **code**.

Public Sub Draw() Dim X as Long Dim Y as Long Dim Index as Long Dim TileIndex as Long Dim TempX as Single Dim TempY as Single

The newly declared values **TempX** and **TempY** will be used to get the **tile-based** position first and later they will represent the **pixel-offset** the camera has (to the next exact tile position). We'll get right to this.

With Map 'Get map position TempX = ( Camera.X / TileSize ) TempY = ( Camera.Y / TileSize )

Since the camera position is in **pixels** now we have to divide it by the TileSize to get the **tile-based** position. Note that this returns **floating-point** numbers, we'll need this in the next line:

'Calculate index of this positon Index = Int( TempY ) * .w + Int( TempX )

By **rounding** the position we get the tile-based position in the map. Example: The camera position is (34, 20) in pixel, this is near (32, 16) where the next **exact tile coordinates** are. TempX would be 2.125 and TileY would be 1.25. Now take the integer values and you get (2, 1) which is exactly the next valid map position. The result we transform from 2D coordinates to the 1D **index position** and that's where we have to start drawing from.

'Calculate offset TempX = TempX - Int( TempX ) TempY = TempY - Int( TempY )

Now that we have the index position we don't care about the map position anymore so we subtract it from the original TempX and TempY. The remaining part is everything after the point, so 0.125 and 0.25 in our example. Note that these are still tile-based positions and we have to multiplicate them by the TileSize to get back the offset in pixels!

'Draw the map For Y = 0 To Camera.TilesY For X = 0 To Camera.TilesX 'Check index If Index > ( Map.w * Map.h ) Then: Exit Sub 'Get tile index TileIndex = .Data( Index )

Until here everything stayed as it was before. **Nope**. The loops now go from 0 to Camera.TilesX and Camera.TilesY, before they went from 0 to (Camera.TilesX - 1) and (Camera.TilesY - 1). So why did that change? Imagine moving the whole display **8 pixel** (half a tile) to the left. The last draw function **exactly** filled up the screen, so there would be 8 untouched pixels at the very right of the screen. Therefore we have to draw **1 extra line** in both directions, X and Y, to still fill the whole screen. This is also where the **index check** comes handy, without it we'd produce a **overflow** whenever the camera reaches the very bottom of the map (because of the non-existing position where both extra lines are crossing).

'Draw tile BitBlt Camera.FrontDC, _TileSize, TileSize, _ Bitmap( Tile( TileIndex ).Bitmap ).Picture.DC, _ Tile( TileIndex ).ActFrame * TileSize, 0, _ vbSrcCopy( X - TempX ) * TileSize, ( Y - TempY ) * TileSize, _

This is already the last part that changes, as usual I marked the changed line for you. What we do here is subtracting the offset from the current (**tile-based**) position and multiplicate the result by the **TileSize** to get this position **in pixels**. Hope you're getting familiar with these transformations.

'Next tile Index = Index + 1 Next 'Get next line start Index = Index + .w - Camera.TilesX - 1 Next End With End Sub

Well that's it, the function now handles pixel-based camera positions! Feel free to extend the other tutorials with smooth scrolling if you like, shouldn't bee too hard now. As always you can download the sample project here:

- Download Showing the code in action

- Previous step Camera movement

- Back Overview