Ethoel
26-01-2010, 11:41
Salve a tutti, mi sono da poco appassionato all'uso delle SDL dopo aver attraversato il periodo Allegro, stò seguendo i tutorial di Lazy Foo:
http://lazyfoo.net/SDL_tutorials/index.php
Solo che ora sono bloccato allo scrolling dello sfondo della semplice applicazione e non riesco a trovare soluzione al problema, chiedo a voi guru un piccolo aiuto.
:mc:
Ecco i vari codici:
MyEngine.h
#include "SDL.h"
#include <string>
SDL_Surface *load_image(std::string filename);
bool init();
bool load_files();
void eventsKeys(SDL_Event event);
void fillScreen();
void update_screen();
void clean_up();
void delay();
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip);
class Player
{
private:
//The X and Y offsets of the dot
int x, y;
//The velocity of the dot
int xVel, yVel;
public:
//Initializes the variables
Player();
//Takes key presses and adjusts the dot's velocity
void handle_input(SDL_Event event);
//Moves the dot
void move();
//Shows the dot on the screen
void show();
//Sets the camera over the dot
void set_camera();
};
MyEngine.cpp
#include "SDL.h"
#include "MyEngine.h"
const int screen_X = 640;
const int screen_Y = 480;
const int profondScreen = 16;
SDL_Surface *sfondo = NULL;
SDL_Surface *screen;
SDL_Rect camera = { 0, 0, screen_X, screen_Y };
const int PLAYER_WIDTH = 20;
const int PLAYER_HEIGHT = 20;
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;
SDL_Event event;
SDL_Surface *dot = NULL;
SDL_Surface *load_image( std::string filename )
{
//Memorizzazione temporanea per il caricamento dell'immagine
SDL_Surface* loadedImage = NULL;
//L'immagine ottimizzata che verrà usata
SDL_Surface* optimizedImage = NULL;
//Carica l'immagine
loadedImage = SDL_LoadBMP(filename.c_str());
//Se nulla và storto...
if( loadedImage != NULL )
{
//Crea un'immagine ottimizzata
optimizedImage = SDL_DisplayFormat( loadedImage );
//Libera la vecchia immagine
SDL_FreeSurface( loadedImage );
//Se l'immagine è stata ottimizzata bene
if( optimizedImage != NULL )
{
//Mappa il colorkey
Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 255, 0, 255);
//Setta il colore trasparente
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
}
}
//Ritorna l'immagine ottimizzata
return optimizedImage;
}
bool init()
{
//Inizializza tutti i sottosistemi SDL
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Setta lo schermo
screen = SDL_SetVideoMode( screen_X, screen_Y, profondScreen, SDL_SWSURFACE );
//Se c'è un errore nel settaggio dello schermo
if( screen == NULL )
{
return false;
}
//Setta il titolo della finestra
SDL_WM_SetCaption( "Event test", NULL );
//Se tutto è inizializzato bene
return true;
}
bool load_files()
{
//Load the image
dot = load_image("dot.bmp");
sfondo = load_image("sfondo.bmp");
//Se c'è un'errore nel caricamento dell'immagine
/*if( image == NULL )
{
return false;
}*/
//If everything loaded fine
return true;
}
void eventsKeys(SDL_Event event)
{
//Se un tasto viene premuto
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: SDL_WM_SetCaption( "Sopra", NULL ); break;
case SDLK_DOWN: SDL_WM_SetCaption( "Sotto", NULL ); break;
case SDLK_LEFT: SDL_WM_SetCaption( "Sinistra", NULL ); break;
case SDLK_RIGHT: SDL_WM_SetCaption( "Destra", NULL ); break;
}
}
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//Crea un rettangolo temporaneo per catturare l'immagine
SDL_Rect offset;
//Dà gli offesets al rettangolo
offset.x = x;
offset.y = y;
//Blinda il surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
void fillScreen()
{
apply_surface(0,0,sfondo,screen,&camera);
}
void update_screen()
{
SDL_Flip(screen);
}
void clean_up()
{
//Libera le immagini
SDL_FreeSurface(dot);
SDL_FreeSurface(sfondo);
//Quit SDL
SDL_Quit();
}
void delay()
{
SDL_Delay(2000);
}
Player::Player()
{
//Initialize the offsets
x = 0;
y = 0;
//Initialize the velocity
xVel = 0;
yVel = 0;
}
void Player::handle_input(SDL_Event event)
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= PLAYER_HEIGHT / 2; break;
case SDLK_DOWN: yVel += PLAYER_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= PLAYER_WIDTH / 2; break;
case SDLK_RIGHT: xVel += PLAYER_WIDTH / 2; break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += PLAYER_HEIGHT / 2; break;
case SDLK_DOWN: yVel -= PLAYER_HEIGHT / 2; break;
case SDLK_LEFT: xVel += PLAYER_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= PLAYER_WIDTH / 2; break;
}
}
}
void Player::move()
{
//Move the dot left or right
x += xVel;
//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + PLAYER_WIDTH > LEVEL_WIDTH ) )
{
//move back
x -= xVel;
}
//Move the dot up or down
y += yVel;
//If the dot went too far up or down
if( ( y < 0 ) || ( y + PLAYER_HEIGHT > LEVEL_HEIGHT ) )
{
//move back
y -= yVel;
}
}
void Player::set_camera()
{
//Center the camera over the dot
camera.x = ( x + PLAYER_WIDTH / 2 ) - screen_X / 2;
camera.y = ( y + PLAYER_HEIGHT / 2 ) - screen_Y / 2;
//Keep the camera in bounds.
if( camera.x < 0 )
{
camera.x = 0;
}
if( camera.y < 0 )
{
camera.y = 0;
}
if( camera.x > LEVEL_WIDTH - camera.w )
{
camera.x = LEVEL_WIDTH - camera.w;
}
if( camera.y > LEVEL_HEIGHT - camera.h )
{
camera.y = LEVEL_HEIGHT - camera.h;
}
}
void Player::show()
{
//Show the dot
apply_surface( x - camera.x, y - camera.y, dot, screen );
}
Main.cpp
#include "SDL.h"
#include "MyEngine.h"
#include "Timer.h"
//SDL_Event event;
int main( int argc, char* args[] )
{
SDL_Event event;
Player myPlayer;
bool uscita = false;
//inizializzazione
if( init() == false )
{
return 1;
}
//caricamento file
if( load_files() == false )
{
return 1;
}
//While che termina quando quit = true
while( uscita == false )
{
//While c'è un evento
while( SDL_PollEvent( &event ) )
{
myPlayer.handle_input(event);
eventsKeys(event);
//Se l'utente ha premuto la X
if( event.type == SDL_QUIT )
{
//Esci dal programma
uscita = true;
}
}
myPlayer.move();
//Set the camera
myPlayer.set_camera();
fillScreen();
myPlayer.show();
//Aggiorna lo schermo
update_screen();
}
//pulisce tutto
clean_up();
//Esce sdl
SDL_Quit();
return 0;
}
Scusate la lunghezza dei codici ma almeno è tutto chiaro, non fate caso a #include "Timer.h" ma nel caso in questione non serve a niente e nel main non c'è nessuna chiamata alle funzioni di Timer...
Grazie per l'aiuto, io non so più che pesci pigliare :sofico:
http://lazyfoo.net/SDL_tutorials/index.php
Solo che ora sono bloccato allo scrolling dello sfondo della semplice applicazione e non riesco a trovare soluzione al problema, chiedo a voi guru un piccolo aiuto.
:mc:
Ecco i vari codici:
MyEngine.h
#include "SDL.h"
#include <string>
SDL_Surface *load_image(std::string filename);
bool init();
bool load_files();
void eventsKeys(SDL_Event event);
void fillScreen();
void update_screen();
void clean_up();
void delay();
void apply_surface(int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip);
class Player
{
private:
//The X and Y offsets of the dot
int x, y;
//The velocity of the dot
int xVel, yVel;
public:
//Initializes the variables
Player();
//Takes key presses and adjusts the dot's velocity
void handle_input(SDL_Event event);
//Moves the dot
void move();
//Shows the dot on the screen
void show();
//Sets the camera over the dot
void set_camera();
};
MyEngine.cpp
#include "SDL.h"
#include "MyEngine.h"
const int screen_X = 640;
const int screen_Y = 480;
const int profondScreen = 16;
SDL_Surface *sfondo = NULL;
SDL_Surface *screen;
SDL_Rect camera = { 0, 0, screen_X, screen_Y };
const int PLAYER_WIDTH = 20;
const int PLAYER_HEIGHT = 20;
const int LEVEL_WIDTH = 1280;
const int LEVEL_HEIGHT = 960;
SDL_Event event;
SDL_Surface *dot = NULL;
SDL_Surface *load_image( std::string filename )
{
//Memorizzazione temporanea per il caricamento dell'immagine
SDL_Surface* loadedImage = NULL;
//L'immagine ottimizzata che verrà usata
SDL_Surface* optimizedImage = NULL;
//Carica l'immagine
loadedImage = SDL_LoadBMP(filename.c_str());
//Se nulla và storto...
if( loadedImage != NULL )
{
//Crea un'immagine ottimizzata
optimizedImage = SDL_DisplayFormat( loadedImage );
//Libera la vecchia immagine
SDL_FreeSurface( loadedImage );
//Se l'immagine è stata ottimizzata bene
if( optimizedImage != NULL )
{
//Mappa il colorkey
Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 255, 0, 255);
//Setta il colore trasparente
SDL_SetColorKey( optimizedImage, SDL_SRCCOLORKEY, colorkey );
}
}
//Ritorna l'immagine ottimizzata
return optimizedImage;
}
bool init()
{
//Inizializza tutti i sottosistemi SDL
if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
{
return false;
}
//Setta lo schermo
screen = SDL_SetVideoMode( screen_X, screen_Y, profondScreen, SDL_SWSURFACE );
//Se c'è un errore nel settaggio dello schermo
if( screen == NULL )
{
return false;
}
//Setta il titolo della finestra
SDL_WM_SetCaption( "Event test", NULL );
//Se tutto è inizializzato bene
return true;
}
bool load_files()
{
//Load the image
dot = load_image("dot.bmp");
sfondo = load_image("sfondo.bmp");
//Se c'è un'errore nel caricamento dell'immagine
/*if( image == NULL )
{
return false;
}*/
//If everything loaded fine
return true;
}
void eventsKeys(SDL_Event event)
{
//Se un tasto viene premuto
if( event.type == SDL_KEYDOWN )
{
switch( event.key.keysym.sym )
{
case SDLK_UP: SDL_WM_SetCaption( "Sopra", NULL ); break;
case SDLK_DOWN: SDL_WM_SetCaption( "Sotto", NULL ); break;
case SDLK_LEFT: SDL_WM_SetCaption( "Sinistra", NULL ); break;
case SDLK_RIGHT: SDL_WM_SetCaption( "Destra", NULL ); break;
}
}
}
void apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL)
{
//Crea un rettangolo temporaneo per catturare l'immagine
SDL_Rect offset;
//Dà gli offesets al rettangolo
offset.x = x;
offset.y = y;
//Blinda il surface
SDL_BlitSurface( source, NULL, destination, &offset );
}
void fillScreen()
{
apply_surface(0,0,sfondo,screen,&camera);
}
void update_screen()
{
SDL_Flip(screen);
}
void clean_up()
{
//Libera le immagini
SDL_FreeSurface(dot);
SDL_FreeSurface(sfondo);
//Quit SDL
SDL_Quit();
}
void delay()
{
SDL_Delay(2000);
}
Player::Player()
{
//Initialize the offsets
x = 0;
y = 0;
//Initialize the velocity
xVel = 0;
yVel = 0;
}
void Player::handle_input(SDL_Event event)
{
//If a key was pressed
if( event.type == SDL_KEYDOWN )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel -= PLAYER_HEIGHT / 2; break;
case SDLK_DOWN: yVel += PLAYER_HEIGHT / 2; break;
case SDLK_LEFT: xVel -= PLAYER_WIDTH / 2; break;
case SDLK_RIGHT: xVel += PLAYER_WIDTH / 2; break;
}
}
//If a key was released
else if( event.type == SDL_KEYUP )
{
//Adjust the velocity
switch( event.key.keysym.sym )
{
case SDLK_UP: yVel += PLAYER_HEIGHT / 2; break;
case SDLK_DOWN: yVel -= PLAYER_HEIGHT / 2; break;
case SDLK_LEFT: xVel += PLAYER_WIDTH / 2; break;
case SDLK_RIGHT: xVel -= PLAYER_WIDTH / 2; break;
}
}
}
void Player::move()
{
//Move the dot left or right
x += xVel;
//If the dot went too far to the left or right
if( ( x < 0 ) || ( x + PLAYER_WIDTH > LEVEL_WIDTH ) )
{
//move back
x -= xVel;
}
//Move the dot up or down
y += yVel;
//If the dot went too far up or down
if( ( y < 0 ) || ( y + PLAYER_HEIGHT > LEVEL_HEIGHT ) )
{
//move back
y -= yVel;
}
}
void Player::set_camera()
{
//Center the camera over the dot
camera.x = ( x + PLAYER_WIDTH / 2 ) - screen_X / 2;
camera.y = ( y + PLAYER_HEIGHT / 2 ) - screen_Y / 2;
//Keep the camera in bounds.
if( camera.x < 0 )
{
camera.x = 0;
}
if( camera.y < 0 )
{
camera.y = 0;
}
if( camera.x > LEVEL_WIDTH - camera.w )
{
camera.x = LEVEL_WIDTH - camera.w;
}
if( camera.y > LEVEL_HEIGHT - camera.h )
{
camera.y = LEVEL_HEIGHT - camera.h;
}
}
void Player::show()
{
//Show the dot
apply_surface( x - camera.x, y - camera.y, dot, screen );
}
Main.cpp
#include "SDL.h"
#include "MyEngine.h"
#include "Timer.h"
//SDL_Event event;
int main( int argc, char* args[] )
{
SDL_Event event;
Player myPlayer;
bool uscita = false;
//inizializzazione
if( init() == false )
{
return 1;
}
//caricamento file
if( load_files() == false )
{
return 1;
}
//While che termina quando quit = true
while( uscita == false )
{
//While c'è un evento
while( SDL_PollEvent( &event ) )
{
myPlayer.handle_input(event);
eventsKeys(event);
//Se l'utente ha premuto la X
if( event.type == SDL_QUIT )
{
//Esci dal programma
uscita = true;
}
}
myPlayer.move();
//Set the camera
myPlayer.set_camera();
fillScreen();
myPlayer.show();
//Aggiorna lo schermo
update_screen();
}
//pulisce tutto
clean_up();
//Esce sdl
SDL_Quit();
return 0;
}
Scusate la lunghezza dei codici ma almeno è tutto chiaro, non fate caso a #include "Timer.h" ma nel caso in questione non serve a niente e nel main non c'è nessuna chiamata alle funzioni di Timer...
Grazie per l'aiuto, io non so più che pesci pigliare :sofico: