GFX with SDL: Lesson 5: Clickomania

Author: Marius Andra. Link to original: http://cone3d.gamedev.net/cgi-bin/index.pl?page=tutorials/gfxsdl/tut5 (Ukrainian).
Tags: SDL Submitted by eReS 22.03.2010. Public material.

Translations of this material:

into Ukrainian: Робота з графікою в SDL: Урок №5: Clickomania. Translated in draft, editing and proof-reading required.
Submitted for translation by eReS 22.03.2010

Text

GFX with SDL: Lesson 5: Clickomania

Hi all! In this tutorial we will build a simple game in SDL called Clickomania. Clickomania is actually a really simple game to build. Our version of the game will consist of a 10x14 grid of balls. When you click (with the mouse) on a ball, that's connected to 2 or more balls, all the connected balls of the same color as the ball you clicked dissapear. And the balls that were above the dissapeared balls will simply fall down. If you manage to clear a row of balls, then the other rows move in to the left from the right. These 4 images illustrate the basic aspects of the game:

After clicking one of the purple balls in the yellow region, all of them disappear and the balls that were above them fall down.

When we get rid of the balls in the yellow region the rest move from right to left. Note that the rows of balls move from right to left, not the individual balls themselves. Now let's get to coding the game.

We first have some #includes and some #defines.

#include <stdio.h>

#include <stdlib.h>

#include <stdarg.h>

#include <string.h>

#include <time.h>

#include <SDL/SDL.h>

Since we'll also use the SDL Font routines (tutorial 4), we'll have to include font.h

#include "font.h"

Now come some variables. The first two contain the dimensions of the playfield. They will be set to some values later.

int rows;

int cols;

screen should be obvious. balls contain the images of the 10 possible ball types. font1 and font2 shouldn't be too much to grasp as well.

SDL_Surface *screen; // The screen surface

SDL_Surface *balls[10];// The ball images

SDLFont *font1; // 2 fonts

SDLFont *font2;

playf contains the grid of all the balls. We will initalize it later.

char *playf; // The playfield itself

scrwidth and scrheight contain the default width and height of the screen. Later we'll "parse" the command line arguments checking, if the user wants to run this program at some other screen resolution. Depending on the screen resolution, the grid of balls might and might not fully cover the screen when drawn from the screen coordinates o,o. centx and centy tell us from where to start drawing the array of balls. They will be calculated later.

// The default width and height of the screen

int scrwidth=640, scrheight=480;

// Used to center the grid nicely onto the screen

int centx=0,centy=0;

The next variable, bls, tells us how many differently colored balls are there on the screen. bla is used with the mouse. More specifically it's used to see whether a mouse button has been clicked. score should be obvious.

int bls=4; // Number of differently colored balls

int bla=0; // Used with the mouse...

int score=0; // The current score

The function DrawIMG should be clear to all of you by now.

// This function draws a surface onto the screen

void DrawIMG(SDL_Surface *img, int x, int y)

{

SDL_Rect dest;

dest.x = x;

dest.y = y;

SDL_BlitSurface(img, NULL, screen, &dest);

}

Now the function swap takes references to 2 char variables (the playfield is an array of type char, btw). It then simply swaps them.

// This swaps two type char variables

void swap(char &r1, char &r2)

{

char temp=r1;

r1=r2;

r2=temp;

}

The function grid takes the coordinates of the playfield as parameters and returns the value (color of the ball) that's on that specific coordinate. It's used almost everywhere in the rest of the program. The function returns a reference to the char (instead of an instance of the char like we usually do) at the coordinate so that we could manipulate it (swap it with some other, assign a value to it, etc) outside the function.

// Returns the color of a ball in the playfield.

inline char &grid(int a, int b)

{

return playf[a*cols+b];

}

The next function, collapse, makes the level collapse. It's called right after we remove a bunch of balls from the grid.

// This function makes balls fall down and rows move left.

void collapse()

{

First we check if we can make any balls fall down. For that we loop through all the columns in the grid. With each column we loop through all the rows. If we find some ball with the value -1, then we remember it's row and move the others onto it. After we move one ball onto the previously marked spot, we decrease the location of the marked spot so that the next ball we move goes onto the top of the spot where we moved our previous ball. After we do this all the balls will be fallen down.

// Make balls fall down

int to=-1;

for(int j=0;j<cols;j++)

{

to=-1;

for(int i=rows-1;i>=0;i--)

{

if(to==-1 && grid(i,j)==-1) {to=i;}

else if(to!=-1 && grid(i,j)!=-1)

{swap(grid(i,j),grid(to,j)); to--;}

}

}

Now we want to move the balls from right to left. For that we loop through all the columns. If one of those columns should have the bottom cell in the row empty (-1), then we know that the entire column is empty. And if it is empty, we mark the location and move all the other columns onto it. After we move one column, we increase the marked location counter and move our columns there.

// Move rows to the left

to=-1;

{

for(int j=0;j<cols;j++)

{

if(to==-1 && grid(rows-1,j)==-1)

{

to=j;

} else if(to!=-1 && grid(rows-1,j)!=-1) {

for(int i=0;i<rows;i++)

{

grid(i,to) = grid(i,j);

}

to++;

}

}

After we have done all that we blank out all the leftover columns.

{

if(to!=-1)

{

for(int j=to;j<cols;j++)

{

for(int i=0;i<rows;i++)

{

grid(i,j)=-1;

}

}

Pages: ← previous Ctrl next
1 2 3 4