18th Maggio 2007

Programmare la GP2X - parte 1

posted in programmazione, c++, sdl, gp2x |

La GP2X è una splendida console portatile basata su standard aperti, in particolare GNU/Linux. Su gp2xdev.net è iniziata un’ottima serie di articoli sulla programmazione della GP2X in C con le librerie SDL. Nella lezione 1 vengono introdotti i rudimenti della programmazione SDL, corredati da un esempio volutamente semplice con la classica pallina che rimbalza ai quattro lati dello schermo. Raccogliendo l’invito degli autori a modificare i sorgenti e a sperimentare, ho voluto aggiungere un po’ di struttura individuando ed implementando alcune classi. Ho sfruttato così l’occasione anche per studiare un po’ di C++, provenendo io dal Java. Ovviamente una struttura del genere è superflua per un esercizio così semplice, ma diventa indispensabile con progetti appena più ambiziosi, o anche soltanto per estendere un po’ le funzionalità previste inizialmente dalla simulazione. Per quanto concerne l’installazione degli strumenti di sviluppo rimando alla lezione 0 della serie.

Nell’esempio originale tutta la logica risiede nel metodo main(), che si occupa di inizializzare l’ambiente SDL e far muovere lo sprite della pallina. In prima approssimazione ho ritenuto utile individuare e separare il concetto di corpo che si muove in uno spazio. Tale spazio è l’ambiente con cui il corpo interagisce e alle cui regole deve sottostare, per esempio quando ne raggiunge i confini. Di qui le classi Corpo e Ambiente.

La classe Corpo possiede alcune proprietà, come la posizione, la velocità e la direzione di spostamento. In base a queste caratteristiche il corpo si muove, cioè cambia la sua posizione.

class Corpo {
public:
	Corpo();
	
	SDL_Rect posizione() const { return m_posizione; }
	SDL_Rect velocita() const { return m_velocita; }
	SDL_Surface* surface() const { return m_surface; }
	
	void setDirezione(SDL_Rect direzione) { m_direzione = direzione; }
	void move();

private:
	SDL_Surface* m_surface;
	// struttura delle sdl che conterra’ le coordinate dello sprite
	SDL_Rect m_posizione;
	// vettore per la velocita’ del corpo
	SDL_Rect m_velocita;
	// vettore per la direzione di movimento del corpo
	SDL_Rect m_direzione;
};

La classe Ambiente incapsula l’ambiente SDL e detta le leggi fisiche alle quali obbedisce il corpo, ad esempio come varia la sua velocità nel tempo e cosa succede quando raggiunge i bordi.

class Ambiente {
public:
	Ambiente();
	void addCorpo(Corpo* corpo) { m_corpo = corpo; }
	void loop();
	
private:
	SDL_Surface* m_schermo;
	SDL_Surface* m_sfondo;
	Corpo* m_corpo;
	int m_esci;
};

Il metodo addCorpo() permette di inserire il corpo nell’ambiente, che attraverso il metodo loop() darà il via all’interazione.

Diamo uno sguardo alle implementazioni, iniziando dalla classe Corpo. Nel costruttore vengono semplicemente inizializzate le proprietà, fra le quali la superficie SDL che rappresenta il corpo. L’unico vero metodo è move(), responsabile di far muovere l’oggetto.

void Corpo::move() {
	m_posizione.x += m_velocita.x * m_direzione.x;
	m_posizione.y += m_velocita.y * m_direzione.y;
}

Il metodo non fa altro che variare la posizione del corpo in base al proprio stato interno, sommando semplicemente al vettore che individua la posizione corrente il vettore con la velocità, tenendo conto della direzione di spostamento.

Per quanto riguarda Ambiente, il costruttore si occupa fra le altre cose delle inizializzazioni SDL. Il metodo dove risiede tutta la logica di interazione con il corpo è loop(), che in un ciclo while fa muovere il corpo modificandone la direzione quando raggiunge gli estremi dello schermo e occupandosi delle operazioni SDL necessarie a visualizzare la scena.

void Ambiente::loop() {
	SDL_Rect direzione;
	direzione.x = 1;
	direzione.y = 1;
	
	//loop principale
	while(!m_esci) {
		/*
		per prima cosa disegnamo lo sfondo sullo schermo, l’operazione
		che copia il nostro sprite sullo schermo si chiama “blit”
		*/
		SDL_BlitSurface(m_sfondo,NULL,m_schermo,NULL);

		// movimento del corpo
		SDL_Rect posizione = m_corpo->posizione();
		if (posizione.x < 0) direzione.x = 1; //lato sinistro
		if (posizione.x + 25 > 320) direzione.x = -1; //lato destro
		if (posizione.y < 0) direzione.y = 1; //lato superiore
		if (posizione.y + 25 > 240) direzione.y = -1; //lato inferiore
		
		m_corpo->setDirezione(direzione);
		m_corpo->move();

		//disegnamo il corpo alle coordinate calcolate
		SDL_BlitSurface(m_corpo->surface(), NULL, m_schermo, &(m_corpo->posizione()));
		//infine facciamo apparire il frame creato sullo schermo
		SDL_Flip(m_schermo);
	}
	SDL_Quit();
}

A questo punto il main diventa molto semplice:

int main(int argc, char *argv[]) {
	Ambiente ambiente;
	Corpo corpo;

	ambiente.addCorpo(&corpo);
	ambiente.loop();
	exit(0);
}

Si istanziano ambiente e corpo, si inserisce il corpo nell’ambiente e si dà il via al loop d’interazione.

Nell’archivio sono contenuti i sorgenti. Rispetto al pacchetto originale ho creato due makefile: uno di sviluppo che compila per la macchina GNU/Linux su cui programmo (Kubuntu Feisty) lanciando make; l’altro per creare l’eseguibile per la GP2X con make -f Makefile.gp2x (cambiare i path della toolchain come richiesto dal proprio ambiente).

Nelle prossime puntate vedremo come questa semplice ristrutturazione ci permetta di rendere la simulazione della pallina un po’ più elaborata.

There are currently 4 responses to “Programmare la GP2X - parte 1”

Why not let us know what you think by adding your own comment! Your opinion is as valid as anyone elses, so come on... let us know what you think.

  1. 1 On Maggio 18th, 2007, SMX said:

    Grande :D spero tu riesca a far andare Open2X con KDevelop!

  2. 2 On Maggio 20th, 2007, leonardo said:

    Ce l’ho fatta. Non era poi così difficile. Ti aggiorno su gp2xdev.net ;)

  3. 3 On Maggio 25th, 2007, Hangman said:

    Ottimo tutorial! Continua così :)

  4. 4 On Giugno 2nd, 2008, Federico said:

    Grande :)
    Non sapevo che esistesse una console del genere. Peccato per il prezzo, 165 euro sono un pò tantini tenendo conto che non ha neanche la connessione WiFi. Se costasse meno forse potrebbe dare del filo dal torcere al Nintendo DS e alla Play portatile, anche perchè lo sviluppo sarebbe completamente gratuito. Comunque un buon strumento per sperimentare.

Leave a Reply