News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Desperate for help with scrolling

Started by kanifox, November 18, 2007, 04:46:49 PM

Previous topic - Next topic

kanifox

I've been messing around on and off for a couple of years now with game languages.  I started with DarkBasic, and I learned a lot, but then when I went to try and make a serious game, I found that the language wasn't good for what I wanted to do: 2D scrolling games.  I figured out how to do it, but it always came out choppy and slow.  Even in demos from more advanced programmers, DarkBasic didn't seem to be able to handle it well.

So I went and tested out a bunch more languages, and eventually settled on PlayBasic.  The games made with it run silky smooth, and it just seems overall like a very clean and efficient system.

I did what few tutorials I could find, but most of the stuff they teach, I already learned from DB.  I already know variables, arrays, UDTs, loops, and if statements.  I know how to manipulate sprites, give player control, and do some basic collision.  The one thing that I just can not figure out no matter how hard I try is the scrolling system that PB uses.  I have looked at source code, searched the forums, banged my head against the help files.. For some reason I just can't wrap my head around it.  I feel like this is the one thing holding me back from making "real" games, rather than just practicing and making demos.

I don't like to ask for help because I always feel like maybe I'm just not trying hard enough on my own, but I don't know what to do anymore.  Would someone would please have mercy on me and explain these things from the ground up, like you would to a child.  I'm dumb as a brick concerning them, but I'm determined to learn:

1.  Scenes and scene buffers.
2.  Worlds and world buffers.
3.  Cameras.
4.  Maps (mainly their relation to these other things, since I have a moderately good grasp of what they are).

And anything else you think I might need to know for scrolling.

kevin

#1
   Rather than trying to learn everything in one go,  just focus on Cameras/Scene with maps.  

  In a nut shell,

  * The SceneBuffer holds captured GFX items.    We capture items by telling PB to change from draw immediate mode to capture mode (ie CaptureToScene / CaptureToWorld).  When an item is captured, it's not actually drawn, rather it's position (in world space) and type are recorded for later use in the camera  drawing process.  

  * Cameras lets us draw whatever was has been captured (to the scene buffer) from any view point in world space.  So it translates a portion of the world to the screen.


   I.e.

PlayBASIC Code: [Select]
; =================================================
; Part #1 - CREATE A MAP Manually
; =================================================

; Make a map with space with 5 levels
MyMap=NewMap(5)


; Create some block gfx..
BlockWidth =32
BlockHeight =32
BlockCount =10

; Create Block Gfx in out map. These will be blank by default
CreateMapGfx MyMap,BlockWidth,BlockHeight,BlockCount,rgb(0,0,0)


; Draw an array of random blocks and copy them into the maps private block image
For lp=1 to BlockCount

; Draw a randomly colours box to the screen
boxc 0,0,BlockWidth,Blockheight,true,rndrgb()

; draw a character to the box
CenterText BlockWidth/2,Blockheight*0.4,chr$(32+rnd(64))

; grab the upper corner of the screen as a block
GetMapBlk MyMap,lp,0,0
next



; Create Level #1 and attach it to MyMap (100=width in tiles, 200 Height in tiles)
CreateLevel MyMap, 1, 100,200


; Fill our level with random block indexes. So it'll be a bit of a mess :)
For ylp=0 to GetLevelHeight(myMap,1)-1
For xlp=0 to GetLevelWidth(myMap,1)-1

; Poke (set) the block index at this x/y position in the level.
PokeLevelTile MyMap,1, Xlp,Ylp, Rnd(BlockCount)

next
next





; =================================================
; Part #2 - CREATE A CAMERA
; =================================================

; create a new camera. This camera's render output with be attached to the screen by default
MyCamera=NewCamera()




; =================================================
; Part #3 - Main Loop
; =================================================


Do

; Clear the scene buffer of any previous information
ClsScene

; Tell PB to capture all coming drawing commands to the scenebuffer
CaptureToScene



; Tell PB to give following captured (drawn) items a Z depth of 50. This will make the circles draw in front of the map
CaptureDepth 50

; Draw a ring of circles in world space, these will be assigned a scene depth of 50 when PB captures them into the scene buffer
MaxCircles=10
For lp=0 to MaxCircles-1
Angle#=(lp*(360.0/MaxCircles))
Xpos#=1000+CosRadius(Angle#,600)
Ypos#=1000+SinRadius(Angle#,600)
Circle Xpos#,Ypos#,100,true
next



; Tell PB to assign the next captured (drawn) items a Z depth of 100
CaptureDepth 100

; Draw the Map at position 0x , 0y in world space. Since we're in capture mode
; this drawing request is captured to the scene buffer list. So this object (map/level in this case)
; is positioned at 0,0 in world space. With a Z depth of 100
DrawMap MyMap,1,0,0




; DRaw the camera. This converts the objects held in the scenebuffer from world space to screen space
; Allowing us to position the camera anywhere we like (in world space) and render whatever objects are visible
; in that section of the world, and that are currently held in the scenebuffer (captured to the scene).

DrawCamera MyCamera



; Use arrows to Move the Camera through world space.
If Leftkey() then MoveCamera Mycamera,-1,0
If rightkey() then MoveCamera Mycamera,1,0
If upkey() then MoveCamera Mycamera,0,-1
If downkey() then MoveCamera Mycamera,0,1



; Call sync to refresh the physical display (swaps the hidden screen image with the visible one, so we can see it!)
sync


; Loop (jump) back to the DO statement to keep this program running in a LOOP
loop





kanifox

Thanks for your help, I studied your post until I was able to make my own program basically like yours

Wow, you have to clear and redraw the entire scene buffer every run through.  But it's not slow because it doesn't actually draw the entire thing.. it only draws what's in front of the camera(s) I'm using?

Still though, why can't you just draw everything to the scene buffer once and then move your camera around it?  Why do we have to re-tell the program what's at tile 100,100 every loop if the player might not ever even go there?

Another thing.. is the DrawCamera drawing to the screen or the scene buffer or what?  It's confusing because it's a "draw" command, and we're in capturetoscene mode, but my guess is that it doesn't capture this?

Also, why does capturetoscene have to be inside the loop?  I thought it was like a switch you flipped on and off.  Does it reset every iteration (I think that's the fancy programming term for it)?

One more thing.. I thought I remembered reading somewhere that, when you use cameras, you don't have to use sync.  Is there any truth to that?

kevin

#3
QuoteWow, you have to clear and redraw the entire scene buffer every run through.  But it's not slow because it doesn't actually draw the entire thing.. it only draws what's in front of the camera(s) I'm using?

     Clearing the scene resets the Scene object count to zero.  It doesn't actually physically clear anything.  Unlike say a CLS would clear the current surface.


QuoteStill though, why can't you just draw everything to the scene buffer once and then move your camera around it?   Why do we have to re-tell the program what's at tile 100,100 every loop if the player might not ever even go there?

      ??? -  You're not.  When a map or any complex drawing operation is captured,  all that occurs is drawing request is placed on the scene buffer list.   The request holds information passed to it from the draw commands such as the Map, level Indexs and what position to give this object in space.  

     When a scene is built and ready to be drawn.   The draw camera command sorts/clips the previously captured draw requests into render order.  
 

QuoteAnother thing.. is the DrawCamera drawing to the screen or the scene buffer or what?  It's confusing because it's a "draw" command, and we're in capturetoscene mode, but my guess is that it doesn't capture this?

 Drawing a camera - Stops capture mode and then sorts, clips, renders whatever is front of it,  to the cameras output surface (to which it will automatically attach itself upon creation).  Which in most cases will be the screen.   But in also be attached to an image.

QuoteAlso, why does capturetoscene have to be inside the loop?  I thought it was like a switch you flipped on and off.  Does it reset every iteration (I think that's the fancy programming term for it)?

 Enabling Capture Modes
     

QuoteOne more thing.. I thought I remembered reading somewhere that, when you use cameras, you don't have to use sync.  Is there any truth to that?

  Nope.

kanifox

So the scene buffer is just a line of text, and when a camera comes up, it looks in the scene buffer to see what's at its location, and works out how to draw, clip and sort it?

But this text is cleared and re-entered every iteration?