Arkcann

Hello, I'm not sure if this will make sense but hopefully it will.

Essentially I working on a 2D platformer as a way to develop a small 2D engine I'm working on that will hopefully help me when creating games in the future with XNA. The game is much like Mario, and like in Mario I need the view to follow the main character while moving non-player characters/enemies off the screen. I was wondering if anyone has developed a view-handling class or other code that would allow for a view to follow my main character on the X axis atleast while moving other objects off the screen while still allowing them to move relative their location. So while my character is running to the right of the screen, all objects are being pushed to the left until they are off the screen, however they are still able to move around while this is happening (they walk on a cycle). I've looked at the XNA documentation and I haven't seen any easy way off doing this, but if there is then please point it out.

All help is appreciated, thankyou for your time.



Re: XNA Game Studio Express Moving the view in 2D games

Jim Perry

There's a Mario clone you can read about here.




Re: XNA Game Studio Express Moving the view in 2D games

Arkcann

Sadly I'm not at a computer with XNA installed right now, but I remember looking at that page before, and although I didn't download the program I thought I read that it doesn't have a following view. As the developer says that you must increased the size of the screen to have a larger playing area, and that's not quite what I would like. Correct me if I'm wrong though, as I said I haven't viewed the program yet.



Re: XNA Game Studio Express Moving the view in 2D games

waheyluggage

Hi
This is just a rough idea, and let's presume your are drawing a screen width and height of 1280x720, the first thing you want to do is set up a camera position (this is the top left corner of the camera)...
cameraWorldPosition = new Vector2( 0, 0 );
Now each items (player, enemy, effects, tiles etc) in your game work off a world position. For example your world might be 12800x1440 units wide. At 1280x720 that would be 10 screens across by 2 high. A character placed at 6400 units in the X would be halfway across your world.
Now when you render you need to take into account the camera position to work out where to draw your characters on screen.
screenPosition.X = itemWorldPosition.X - cameraWorldPosition.X;
screenPosition.Y = itemWorldPosition.Y - cameraWorldPosition.Y;
This converts the world position of the item to a screen position. (You might want to stick this into a function and call it ConvertWorldPositionToScreenPosition or something as all your items will want to use it)
Now we need to check to make sure the item we're trying to draw is on screen so.
if ((screenPosition.X >= 0) && (screenPosition.X < 1280))
{
if ((screenPosition.Y >= 0) && (screenPosition.Y < 720))
{
// draw the player as he's on screen...
}
}
Now if you move the cameraWorldPosition around everything will appear to scroll. But we want to look at the player don't we
All we do then is position the camera up and to the left of the player. For that we do...
cameraWorldPosition.X = playerWorldPosition.X - (1280/2);
cameraWorldPosition.Y = playerWorldPosition.Y - (720/2);

Remember we're drawing a screen size of 1280x720. So what we've done is move left of the player by the half the width and up by half the height. This will put the player right in the middle of the camera. Again you might want to put this into a function and call it CameraLookAt( targetX, targetY ) or something.
As the player moves we need to update the camera to keep the player in the middle.

And that will get you a game that scrolls around. There's plenty to do to make it neat and tidy though for example...
* have the camera look at any position and damp it so it kind of catches up with the player and looks smoother.
* add an offset to that position so you can do things like look at the player and then if he ducks move that offset down so the camera will look down.
* when checking to see if the item is on screen for drawing you want to take into account the sprite width and height.
* use something similar to the above for working out the ai of the other items. You don't want every sprite in your game internally running backwards and forwards only the ones within a certain distance of the player.
Hope that helps. Any questions just let me know.
Scott




Re: XNA Game Studio Express Moving the view in 2D games

OrpheusTheBard

Awesome reply Scott! :) I use the same approach in the Tiled RPG I've been making for fun, using  a Camera class to draw the view, and having a CameraLookAt(Object/Position) function to set where it should start drawing from. I just call CameraLookAt(MainCharacter) everytime I update my character's position, and don't have to worry about it more.

There's something that I've always wondered about these plataform games like the old Super Mario's. How are the usually maps saved Are they one huge contiguous horizontal picture, or they're made with tiles following a map array of some sort, like old RPG's And how do they define for each part of the map, where the bottom floor is located; if the level is all slopy going up and down: is this information stored somewhere, or is it done in real time with collision detection between each sprite and the floor layer

David





Re: XNA Game Studio Express Moving the view in 2D games

waheyluggage

Thanks!
Regarding the older games they would indeed have used a set of tiles and an array for their world. The simplest example would just have 2 tiles, a solid one and an empty one. The array would have something like...
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,1,0,0,0,0,0,0,0,0,0,0,0,0
1,1,1,1,0,0,0,0,0,1,1,1,0,0
1,1,1,1,1,1,1,1,1,1,1,1,1,1
0 would be empty space and a 1 would be a square tile. You'd convert your items world position into array position by dividing the world X position by the tile width and Y position by tile height. You'd then look this value up in the array and see what tile was under them. It didn't really matter where the floor was so long as there were solid tiles along the bottom to stop the player falling off.
It had the advantage of being tiny in size as the machines didn't have much memory. In the above example you'd have 1 graphic tile (as the other is empty it's just 'don't draw anything') and an array for the map. With just those two tiles you could make huge worlds if you wanted.
For slopes there was a couple of ways they could do it (doing it in real time was probably a bit much for the machines of the time)...
1) Make a tile a math function. The easiest would be a square tile like / (slops upwards at 45 degrees). If you were on this tile you can work out how far into the tile you are then you'd move the player up by how far into it you are. eg. If you're 1 pixel in you'd move them up in the y by 1. 10 pixels in, up in the y by 10. Basically for that tile it's math function is yOffset = x. If you wanted a gentle slope you could use yOffset = x/2 but this would only move you up half a tile so you'd need another tile to go from being half a tile up to a full tile up. This one would be yOffset = (x/2)+halfTileHeight.
2) Precalculate the heights inside the tile. Instead of working out where in the tile the top edge is you could precalculate it for each tile once and just read into it like yOffset = tiles[tilePlayerIsOn][ x ]. Then add yOffset onto the players position. Bit costly memory wise though.
You could have maps with multiple layers, not all visible as well. For example one layer might be one in the background that wraps around to give an impression of depth. Another layer would be the visual world. Another layer would be the collision tiles (eg. value 0 on the collision layer is an empty space, value 1 is a solid square, value 2 is a 45 degree slope up, value 3 is a 45 degree slope down). Another layer could be character placements (value 0 is nothing, value 1 is player start position, value 2 is player goal, value 3 is enemy type A, value 4 is enemy type B, etc). You'd flesh this out with lots of different things like the pipes in mario would be a green thing on the visual layer (probably made up of a group of blocks), a solid block on the collision layer in the same place. Then the tile above it (the space on which you stand) would have a special ID on the character placements layer that says "if you press down while standing here go to this X,Y".
With the character layer, when you're about to get to a new column of tiles as you scroll across while playing the game you can check your character placements and see what you should generate. The same kind of system works with a lot of game types as well. Sometimes what doesn't look like is worked out with tiles actually is.
Phew rambled on a bit there sorry.




Re: XNA Game Studio Express Moving the view in 2D games

Arkcann

Thankyou Scott, that's a perfect idea with a great explanation aswell. Now that the view portion of my game is complete, I'm onto collision detection! This may be a little off topic but would you happen to know if the built in bounding box using the intersects() method would be faster than using rectangles with a custom made method that does pretty much the same thing (checks for an intersection between two bounding boxes). Perhaps this is worth another topic. Anyways, thanks for all your help, have a good night!



Re: XNA Game Studio Express Moving the view in 2D games

SneakerXZ

Scott: Nice. Do you have a sample with code



Re: XNA Game Studio Express Moving the view in 2D games

Jeff Weber

This should get you started: click