Platformer Revisited
The 2D platform game demo that comes with PlayBasic V1.63, dates back probably 3 or 4 years ago, maybe more. It's one of those demo's that I'd love to really vamp up, given infinite time and media.. but..
Anyway, while working on the camera routines for PLayBasic V1.64I, I needed something to test the camera functionality so choose to set up a batch rectangle operation,using the camera for the clipping and rendering. What i wanted to do was add 'something' behind the backdrop layers of the old game, just to pretty the scene up a bit. Hence, so I just slapped a some picture and some clouds in the backdrop.
Rather than just use the blit everything approach, the code scans the foreground map layers for 'transparent' runs of tiles. In other words we only bother drawing backdrop stuff, when it's potentially visible. When a run of transparent tiles are discovered, we draw this portion of the screen using the camera (the backdrop pictures are pre-captured to the scene). While this makes the drawing the scene a multi pass affair, we end up giving the the demo somewhere between a 15->25fps boost. Which of course means we can drop more effects in for free.
So since i'm using PlayBasic V1.64 (since it;s the current version of PlayBasic), I threw in Tinted Anti aliased sprites, and some gouraud quads with blending in backdrop, then slapped an alpha shaped in the foreground. The savings in the backdrop mean the extras are pretty much free.
This is really important when we have games where we move through scrolling land scapes. In particular when the foreground(s) have sections, are fully or partially covering the backdrop. Anyway the moral of the story is design !, you know how you're game works, your graphics engine doesn't. .
Here's the viewport creation code.
Function Calc_Map_Mask(VP().SceneView, ThisCamera,Thismap,MaskLevel)
CamX=GetCameraX(ThisCamera)
CamY=GetCameraY(ThisCamera)
BlockWidth =GetMapBlockWidth(ThisMap)
BlockHeight =GetMapBlockHeight(ThisMap)
TileX1 =CamX/BlockWidth
TileY1 =CamY/BlockHeight
TileX2 =(CamX+GetCameraWidth(ThisCamera))/BlockWidth
TileY2 =(CamY+GetCameraHeight(ThisCamera))/BlockHeight
inc TileX2
LevelWidth =GetLevelWidth(ThisMap,MaskLevel)
LevelHeight =GetLevelHeight(ThisMap,MaskLevel)
TileX1=ClipRange(TileX1,0,LevelWidth)
TileX2=ClipRange(TileX2,0,LevelWidth)
TileY1=ClipRange(TileY1,0,LevelHeight)
TileY2=ClipRange(TileY2,0,LevelHeight)
for ylp=tiley1 to tiley2
Ypos1 =ylp*BlockHeight
Ypos2 =Ypos1+BlockHeight
RunStart =false
RunLength =TileX1
RunXpos =TileX1*BlockWidth+10
for Xlp=TileX1 to TileX2
Transparent=PeekLevelTile(ThisMap,MaskLevel,Xlp,ylp)
if Transparent
if RunStart
VP(Count).x1=RunXpos
VP(Count).y1=Ypos1
VP(Count).x2=RunXpos+(RunLength*BlockWidth)
VP(Count).y2=Ypos2
RunStart=false
inc Count
endif
else
if RunStart=false
RunStart=True
RunXpos=Xlp*BlockWidth
RunLength=0
endif
inc RunLength
endif
next
if RunStart
; boxc RunXpos,ypos1,Xlp*BlockWidth,ypos2,true,255*Ylp*RunXpos
VP(Count).x1=RunXpos
VP(Count).y1=Ypos1
VP(Count).x2=Xlp*BlockWidth
VP(Count).y2=Ypos2
inc Count
endif
next
EndFunction Count