A Question about 2D scrolling

KrunkSplein

New member
Joined
Oct 4, 2004
Messages
4
Working on a tile engine, and I was trying to implement scrolling. Im going to have a 600x600 (arbitrary decision, may be changed) section of window devoted to displaying a map (the rest is for interface). My question is how would you implement scrolling in case the map went beyond 600 by 600? I was tinkering around and tried:

mapDev.Transform.View = Matrix.Transform(offsetx, offsety,0)

but that crashed my program. Ive already implemented the code so that it doesnt render off-screen tiles, now I just need to be able to move the camera so that we can GET to the off-screen tiles.

Also, Im looking for a means to center the view if the map is smaller than 600 by 600, so that instead of being bunched up in the top left, it could look better. Though I have a suspicion that my two problems have one solution.

Thanks in advance,
Krunk
 
Ok - Scrolling eh? First of all, visit my Matrices and Transformations tutorial in the Tutors Corner - youll learn how to move stuff there.

Heres how youd scroll... in order to move the character left, you move the map right and keep the character ceneterd on the screen..etc. So basically you move the character in the opposite direction of the map.

D3DDev.transform.world = Matrix.Identity Dont move the character
char.Render
D3DDev.Transform.wrold = Matrix.Translation(x,y,0)
map.Render

youd set x and y like this in form1_keydown
if e.keycode = keys.right then
x -= 1 move the map LEFT to move the char right
end if

do this for all the directions..

Btw - this only applies if the center of your screen is 0,0,0. If youve used my tutorials, I generally choose topleft of my screen to be 0,0,0. So since youre only viewing 600x600 of your map, translate the world to 300,300,0 before rendering the char.

Now - hers how you make it only display 600x600 of the map:
D3Ddev.Transform.View = Matrix.OrthoOffCenterLH(0, 600, 600, 0, 1, 10)
0 - Left side of the view
600 - Right side of the view. In our case, its 800
600 - Bottom side of the view. In our case, its 600.
0 - Top side of the view
1 - Specifies the ZNear plane: The closest our object can be before its cut-off from the view
10 - Specifies the ZFar plane: The farthest our object can be before its cut-off from the view

THat makes the topleft of the screen 0,0,0 and the topright of the screen 600,600,0.


If you wanted the center of the screen to be 0,0,0 (which means that the topleft of the screen would be -300,-300,0 and the topright of the scren to be 300,300,0) - you can use the OrthoLH matrix - its the same thing as the OrthoOffCenterLH except the OrthoLH focuses on 0,0,0.

-The Pentium Guy
 
I didnt really mean scrolling as in the map moves around the character, I mean it in the WarCraft 2 sense, where youd move the mouse to the edge of the map or press a key and the view would scroll to whichever direction. Basically, relative to the map, the sprites stay still. Relative to the viewpoint, everything is moving.
 
KrunkSplein said:
I didnt really mean scrolling as in the map moves around the character, I mean it in the WarCraft 2 sense, where youd move the mouse to the edge of the map or press a key and the view would scroll to whichever direction. Basically, relative to the map, the sprites stay still. Relative to the viewpoint, everything is moving.
I suggest you move the camera, not the actual stuff. Just move the camera and have a drawing system that only draws stuff that the camera can see.

Code:
D3DDev.Transform.View = mCamera.LookAtLH( _
New Vector3(mCameraX, mCameraY, mCameraZ), _ [COLOR=Green]Where is the camera located?[/COLOR]
New Vector3(mCameraX, mCameraY, 0), _ [COLOR=Green]Where is the camera looking?[/COLOR]
New Vector3(0, 1, 0)) [COLOR=Green]Which direction is up? Positive Y coordinates are up in this case[/COLOR]

(Where mCamera is a matrix, D3DDev is the direct3d device)
(mCameraX,mCameraY,mCameraZ are simply Single datatypes that define the camera position)

This is how you transform the view sir... ;)

NOTE: Make sure you initialize the camera before you do this however...

Code:
D3DDev.Transform.Projection = Matrix.PerspectiveFovLH( _
90 * (Math.PI / 180), _ [COLOR=Green]Viewspan in RADIANS[/COLOR]
 4 / 3, _ [COLOR=Green]Aspect ratio[/COLOR]
 1, _ [COLOR=Green]The nearest Z coordinate that is shown[/COLOR]
 50) [COLOR=Green]The farthest Z coordinate that is shown[/COLOR]
 
Last edited by a moderator:
I beleive hes doing 2d - so he doesnt need Projection and LookAtLH.

KrunkSplein - this is easy :). All you have to do is change the coordinates of the View matrix.. for example, this is what you had:
D3Ddev.Transform.View = Matrix.OrthoOffCenterLH(0, 600, 600, 0, 1, 10)

If you pushed right, the "LEFT" argument would increase by 1, and the "RIGHT" argument will also incrase by 1.. same with if you pushed left, down and up. So basically, do something lik ethis

D3Ddev.Transform.View = Matrix.OrthoOffCenterLH(0 + OffsetX , 600 + offsetX , 600 + OffsetY, 0 +OffsetY, 1, 10)

(The first 4 args represent Left, Right, Bottom and Top).

Where offset is increased or decreased when you press a key.

Btw, theres numerious ways of doing this - you could even translate the entire world if you wanted. I think this is the simplest method IMHO.

-The Pentium Guy
 
KrunkSplein said:
When I try to do the Projection Transform, I get errors with your PerspectiveFovLH above. says the closest version of PerspectiveFovLH(float, float, float, float) has some invalid arguments. Whatd I do wrong?

[edit in response to PentiumGuy]

the only time I transform with OrthoOffCenterLH is at the instantiation of my gameclass. Where would I put it in the code? In the standard Render() function before I render anything?

Also, I have to make sure that anything outside of the 600 by 600 window isnt rendered, since I am going to put interface stuff on those left 200 pixels. Plus, why waste memory on map you cant go to?

And the more I think about it, wont changing the view also affect the interface panel on the left?

Man, I wish I could have just had two seperate devices, one for the main window, another for the interface. Oh well.
PerspectiveFovLH(float, float, float, float)

That makes sense, all of those should be floats.

Viewspan in RADIANS
Aspect ratio
The nearest Z coordinate that is shown
The farthest Z coordinate that is shown

Another problem might be that MDX is pulling another error on you. They overload too many functions with that build. C# also might be different than VB.NET.

@PentiumGuy: I use camera transformations simply because I like to control what the user can see. I dont use the sprite class though. ;)
 
Hey Krunksplein, could you tell us what you did with the Projection matrix? the arguments seem right :p.. I have no idea why you got the error. Im just curious as to why that happened.

I think its beacuse you need an f (aka Convert.ToSingle) at the end of the arguments.
-The Pentium Guy
 
Back
Top