viernes, 7 de junio de 2013

Fundamentals of Scrolling

Hi all!

After the last two posts on integration, I think that we can take a breath before finishing the hard physics stuff. So in this post I will talk about something that it is not that difficult to implement and is basic for any platform game (and many other games too): scrolling.

Most games, from the very beginning, have had some sort of scrolling. Scrolling consists of moving the scenario in such a way that your character is always visible, and usually, by the center of the screen. If this movement is on the horizontal axis, it is called 'horizontal scrolling', and if it takes place on the vertical axis, we would have 'vertical scrolling'. Most games use both of them.

Technically, however, it is more accurate to say that what we really move is the view along the level. That is, the idea is that we create a very big level (let's say 3000 x 3000 pixels) and then we set a view to our screen resolution, such as 1280 x 800 pixels. Then, we basically move this view (which you can think of as a rectangle) along the level in two dimensions, as depicted in Figure 1.

Figure 1.- View vs Screen Images. For scrolling, you move the view rectangle along the level rectangle

The way to achieve this in your game will obviously depend on the library or framework you are using. As I told you in this post, I will be using the SFML library, so the code explanations will be shown in C++ and using this library. However, the concept itself is the most important thing you should understand, and not any concrete technical implementation.

void LevelScreen::update(sf::Time elapsedTime) {

//We update all the objects in the screen
std::vector<Entity *>::iterator iter;
for(iter = gameObjects.begin(); iter != gameObjects.end(); iter++) {
        Entity *e = *iter;
        e->update(elapsedTime);


//Now we update the view
//Horizontal scrolling
if (player->getPosition().getX() > SCREEN_WIDTH / 2) {
         view.move(player->getVelocity().getX() * elapsedTime.asSeconds(), 0);
}

//Vertical scrolling
if (player->getPosition().getY > SCREEN_HEIGHT / 2) {
        view.move(0, player->getVelocity().getY() * elapsedTime.asSeconds());

}

Here, we basically update all the objects in the screen in the update method of the level (I'll give more details on the overall engine architecture in a following post). Then, we update the velocity of the view using the velocity of the player (the player variable holds a pointer to the player object). The update of the view will take place only if the player is located beyond the half of the screen in any dimension. Finally, in the draw method, we should set the view and draw the objects onto this view, as shown next:

void LevelScreen::draw(sf::RenderWindow &window) {

//Set the view to be used on the window (the window is where we draw the objects)
window.setView(view); 


//Draw the objects
std::vector<Entity *>::iterator iter;
for(iter = gameObjects.begin(); iter != gameObjects.end(); iter++) {
     Entity *e = *iter;
     e->draw(window);
}
}

This is the basic background you need in order to implement more advanced scrolling features, such as parallax scrolling. This technique will provide a higher feeling of realism with relatively little effort. I will explain how to implement it in the following post.

EDIT: you can go to the next post on parallax scrolling directly here

See you!

2 comentarios: