lunes, 30 de septiembre de 2013

Fundamentals of Scrolling (part II)

Hi all!

This is the follow-up of a previous post about scrolling.

In this case, we are going to talk about parallax scrolling. This technique provides greater realism as it simulates some feeling of depth. To understand it, think when you're in a car and you look out the window. Obviously the closest objects (e.g. the stripes of the the road) move far much faster than the objects in the horizon (e.g. the mountains or clouds). 

The way you can implement this is pretty straightforward. Look at Figure 1. 


Figure 1.- Parallax Scrolling: layers and objects. The closest layer (the fastest one) is the one of the palms and floor. The furthest layer (i.e. the slowest one) is the one with the moon. 

The idea is simply to create several layers or views and make the furthest layers to move slower than the closest layers. Therefore, in pseudo-code, you would have something like the following:

Level::createLevel() {
    Mountain* m = new Mountain("mountain.png");
    Cloud* farCloud = new Cloud("cloud.png");
    Cloud* closeCloud = new Cloud("cloud.png");
    Platform* p = new Platform("platform.png");

    //velocityFarLayer < velocityMidLayer < velocityCloseLayer
    Layer* farLayer = new Layer(velocityFarLayer);
    farLayer -> addObject(farCloud);
    farLayer -> addObject(m);

    Layer* midLayer = new Layer(velocityMidLayer);
    midLayer -> addObject(closeCloud);

    Layer* closeLayer = new Layer(velocityCloseLayer);
    closeLayer -> addObject(p);
}

Level::update() {
   for (Layer *l: layersInLevel) {
       l -> update();
   }
}

Layer::update() {
   for (Object *o: objectsInLayer) {
       //Each object knows how to update itself in response to physics or input
       o -> update();
   }
   //We move the layer too
   this -> move (layerVelocity);
}

Layer::move(Vector &velocity) {
  for (Object *o: objectsInLayer) {
     o -> move (velocity);
  }
}

I think that the code is more or less self-explanatory. A level is composed of layers, each of which has a different velocity. Each layer, in turn, is composed of objects. When you design a level, you first specify the number of layers and each layer velocity. Then, you associate each object to a level. When the level is updated, each layer is updated, which means that each object in the layer will be updated and moved according to the layer velocity.

Well, that's all for now. Hope you find this information useful. Don't hesitate to leave comments or suggestions or questions.

See you!

jueves, 12 de septiembre de 2013

On Game Loops

Hi all!

Today I want to talk to you about something that is a must-know in the world of game programming: the game loop.

The game loop is the sequence of actions that are run by the machine during the execution of the game and that are repeated until the game finishes. In C++-style, the game loop looks something like this:

while (!finished()) {
      finished = getInput(&input);
      update(input);
      draw();
      clearScreen(); 
}

The first thing the game does is to check the input provided by the player: keyboard presses/releases, screen touches, etc. Then, it updates, probably according to the input, the world: player, enemies, platforms, score and other variables, collisions, etc. Then, it draws (or more technically, it renders) the scene onto the screen, and then it clears out the screen to allow the rendering of the next loop execution, also known as frame

I think that (almost) any game in the world can be organized by using this structure. How explicit this structure is from the viewpoint of the developer, is, however, another story, and it depends on the level of abstraction that the developer is using. 

For example, in the game I'm developing for PC/Mac (that famous platform game I mentioned in earlier posts), I began almost from scratch. Therefore, all my class hierarchy and methods are set so as to follow the game loop structure, and the actual code for my main method matches almost perfectly the previous one.

However, I've recently started developing a small, puzzle game for iOS (more in future posts), and for this, I'm using the Cocos2D framework. When you use high-level libraries or frameworks, many of the gory details are hidden in order to abstract away unnecessary complexities and let the developer focus on the gameplay. In the case of frameworks, furthermore, it is usual the so-called inversion of control. This means that the framework takes the role of the main routine, and is the framework that is in charge of calling certain components/classes developed by the programmer, taking a leading role.

I'll give you a very simple concrete example: Cocos2D uses the notion of Node (CCNode class) and Layer (CCNode layer). Layers can contain nodes, and nodes can be rendered. Therefore you can write something like [layer addChild: node], which adds a node to a layer. Once you've added the node to a layer, the framework itself ensures that the draw method of the node is called every frame, so you cannot see the explicit call to this method because it is hidden inside the framework implementation and it's not exposed as an API (actually, you can override the draw method, but this is an advanced feature for more experienced developers). 

The moral is this: even when you don't see the game loop, you must be aware that it's there, observing each of your movements... So be aware of it! Once you really understand the game loop and concept of frame, everything becomes nicer and easier.

See you!

martes, 10 de septiembre de 2013

A tutorial on how to develop a platform game

Hi all!

I've been reading an excellent tutorial about how to make a 2d platform game and I wanted to share it with you. The tutorial is divided into three parts, and here you can access the first one (the rest is linked at the bottom of the post).

As a 2d platform game developer, I can assure that reading this tutorial is really worth it, as I've found many challenges and problems that the author discusses, even though I've dealt with some of them in different ways.

Read and above all, experiment and have fun!