SDL#3 Animations gerees (mais pb de <vector> avec thread donc 1 seule a la fois pour l'instant) + Gestion de la redimension + animation avec changement de SDL_Rect uniquement a faire

This commit is contained in:
xdrm-brackets 2016-03-12 00:10:38 +01:00
parent dfe178e140
commit b0e5c93a23
8 changed files with 224 additions and 224 deletions

View File

@ -1,89 +1,130 @@
/* [DESTRUCTOR] Destruction de la surface
=========================================================*/
Sprite::~Sprite(){
SDL_FreeSurface( _surface );
SDL_DestroyTexture( _texture );
_manager = NULL;
}
/* [CONSTRUCTOR] Construction de la surface vide
=========================================================*/
Sprite::Sprite(SDL_Rect r){
_surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, 0);
// On definit les dimensions
_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
_origin = (SDL_Rect){0, 0, r.w, r.h};
// On applique les offset
SDL_SetClipRect( _surface, &_rect );
Sprite::Sprite(sdltl *m){
_manager = m;
_texture = NULL;
}
/* [CONSTRUCTOR] Construction de la surface avec couleur
=========================================================*/
Sprite::Sprite(const int rgb[], SDL_Rect r){
cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl;
_surface = SDL_CreateRGBSurface(0, r.w, r.h, 32, 0, 0, 0, rgb[3]);
// On recupere la couleur
Uint32 color = SDL_MapRGBA( _surface->format, rgb[0], rgb[1], rgb[2], rgb[3]);
// On remplit avec la couleur
SDL_FillRect( _surface, NULL, color );
// On definit les dimensions
_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
_origin = (SDL_Rect){0, 0, r.w, r.h};
Sprite::Sprite(sdltl *m, const int rgb[]){
_manager = m;
_texture = NULL;
// On applique les offset
SDL_SetClipRect( _surface, &_rect );
cout << "a: [" << (sizeof(rgb)/sizeof(*rgb)) << "]" << endl;
SDL_Surface *surf = SDL_CreateRGBSurface(0, 0, 0, 32, 0, 0, 0, rgb[3]);
// On recupere la couleur
Uint32 color = SDL_MapRGBA( surf->format, rgb[0], rgb[1], rgb[2], rgb[3]);
// On cree la texture a partir de la surface
_texture = SDL_CreateTextureFromSurface(_manager->renderer(), surf);
// On libere la surface inutile maintenant
SDL_FreeSurface( surf );
surf = NULL;
}
/* [CONSTRUCTOR] Construction de la surface avec image
=========================================================*/
Sprite::Sprite(const char url[], SDL_Rect r, SDL_Rect clip){
Sprite::Sprite(sdltl *m, const char *url){
_manager = m;
_texture = NULL;
/* (1) On cree la surface (avec image) */
_surface = IMG_Load( url );
_texture = IMG_LoadTexture(_manager->renderer(), url);
// Gestion erreur
if( _surface == NULL )
if( _texture == NULL )
return;
// On definit les dimensions
_rect = (SDL_Rect){r.x, r.y, r.w, r.h};
_origin = (SDL_Rect){clip.x, clip.y, r.w, r.h};
// On applique le clip
SDL_SetClipRect( _surface, &clip );
}
/* [APPENDTO] Ajoute le Sprite au rendu
/* [DIMENSIONS] Definition des dimensions par defaut
=========================================================*/
void Sprite::appendTo(sdltl *mgr){
_texture = SDL_CreateTextureFromSurface(mgr->renderer(), _surface);
void Sprite::dimensions(){
cout <<"A"<<endl;
mgr->add(_texture, &_origin, &_rect);
/* (1) On recupere les informations de la texture */
int w, h;
SDL_QueryTexture(_texture, NULL, NULL, &w, &h);
/* (2) On definit les dimensions par defaut */
_dst = (SDL_Rect){0, 0, w, h};
_src = (SDL_Rect){0, 0, w, h};
}
/* [REMOVEFROM] Retire une sprite du rendu
/* [DIMENSIONS] Definition des dimensions de la texture
=========================================================*/
void Sprite::removeFrom(sdltl *mgr){
mgr->remove( _texture );
void Sprite::dimensions(SDL_Rect r){
cout <<"B"<<endl;
/* (1) On recupere les informations de la texture */
int w, h;
SDL_QueryTexture(_texture, NULL, NULL, &w, &h);
/* (2) On definit les dimensions */
_dst = (SDL_Rect){r.x, r.y, r.w, r.h};
_src = (SDL_Rect){0, 0, w, h};
}
/* [SURFACE] Retourne la surface
/* [DIMENSIONS] Definition des dimensions de la texture+clip
=========================================================*/
SDL_Surface *Sprite::surface(){ return _surface; }
void Sprite::dimensions(SDL_Rect r, SDL_Rect clip){
cout <<"C"<<endl;
/* (1) On definit les dimensions */
_dst = (SDL_Rect){r.x, r.y, r.w, r.h};
_src = (SDL_Rect){clip.x, clip.y, clip.w, clip.h};
}
/* [PUSH] Ajoute le Sprite au rendu
=========================================================*/
void Sprite::push(){
_manager->push(_texture, &_src, &_dst);
}
/* [PULL] Retire une sprite du rendu
=========================================================*/
void Sprite::pull(){
_manager->pull( _texture );
}
/* [UPDATE] Mise a jour du rendu
=========================================================*/
void Sprite::update(){
_manager->update();
}
/* [TEXTURE] Retourne la texture
=========================================================*/
SDL_Texture *Sprite::texture(){ return _texture; }
/* [MANAGER] Retourne le manager
=========================================================*/
sdltl *Sprite::manager(){ return _manager; }
@ -132,18 +173,27 @@ void SpriteGroup::remove(Sprite *s){
}
/* [APPENDTO] Ajoute tous les Sprite du groupe a une surface parente
/* [PUSH] Ajoute tous les Sprite du groupe a une surface parente
=========================================================*/
void SpriteGroup::appendTo(sdltl *mgr){
void SpriteGroup::push(){
for( int i = 0 ; i < _sprites.size() ; i++ )
_sprites[i]->appendTo( mgr );
_sprites[i]->push();
}
/* [REMOVEFROM] Retire une sprite de la surface parents
/* [PULL] Retire une sprite de la surface parents
=========================================================*/
void SpriteGroup::removeFrom(sdltl *mgr){
void SpriteGroup::pull(){
for( int i = 0 ; i < _sprites.size() ; i++ )
_sprites[i]->removeFrom( mgr );
_sprites[i]->pull();
}
/* [UPDATE] Mise a jour du rendu
=========================================================*/
void SpriteGroup::update(){
if( _sprites.size() > 0 )
_sprites[0]->update();
}
@ -158,7 +208,7 @@ Sprite* SpriteGroup::get(int i){
/* [TRHEAD] Process de l'animation
=========================================================*/
void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){
void SpriteGroupAnimation(SpriteGroup *sg, int t, int flags){
int length = sg->_sprites.size();
int timer = 0;
int step = 1;
@ -175,13 +225,13 @@ void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){
// On retire le sprite precedent
if( lastindex > -1 )
sg->_sprites[lastindex]->removeFrom( mgr );
sg->get(lastindex)->pull();
// On ajoute le sprite
sg->_sprites[i]->appendTo( mgr );
sg->get(i)->push();
// On met a jour le rendu
// mgr->update();
// sg->get(i)->update();
if( SDL_GetTicks()-timer < t )
@ -212,8 +262,8 @@ void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags){
/* [ANIMATE] Modifie le Sprite dans l'ordre du SpriteGroup
=========================================================*/
thread* SpriteGroup::animate(sdltl *mgr, int t, int flags){
_animation = new thread(SpriteGroupAnimation, mgr, this, t, flags);
thread* SpriteGroup::animate(int t, int flags){
_animation = new thread(SpriteGroupAnimation, this, t, flags);
// On attends pas le thread
_animation->detach();

View File

@ -24,25 +24,31 @@
class Sprite{
public:
Sprite(SDL_Rect r);
Sprite(const int rgb[], SDL_Rect r);
Sprite(const char url[], SDL_Rect r, SDL_Rect clip);
Sprite(sdltl *m); // Sprite vide
Sprite(sdltl *m, const int rgb[]); // Sprite couleur
Sprite(sdltl *m, const char *url); // Sprite image
~Sprite();
void setImage(const char url[], int ox=0, int oy=0);
void dimensions(); // Dimensions par defaut
void dimensions(SDL_Rect r); // Dimensions sortie
void dimensions(SDL_Rect r, SDL_Rect clip); // Dimensions in/out
void appendTo(sdltl *mgr);
void removeFrom(sdltl *mgr);
void push(); // Ajoute a l'affichage
void pull(); // Retire de l'affichage
void update(); // Fait renmonter la mise a jour du manager
// GETTERS
SDL_Surface *surface();
SDL_Texture *texture();
sdltl *manager();
private:
SDL_Surface *_surface;
sdltl *_manager;
SDL_Texture *_texture;
SDL_Rect _rect;
SDL_Rect _origin;
SDL_Rect _dst;
SDL_Rect _src;
};
@ -55,18 +61,20 @@
void add(Sprite *s);
void remove(Sprite *s);
Sprite* get(int i);
void appendTo(sdltl *mgr);
void removeFrom(sdltl *mgr);
thread *animate(sdltl *mgr, int t, int flags=0);
void push(); // Ajoute les sprites a l'affichage
void pull(); // Retire les sprites de l'affichage
void update(); // Fait renmonter la mise a jour du manager
thread *animate(int t, int flags=0);
private:
SDL_Renderer *_renderer;
vector<Sprite*> _sprites;
thread *_animation;
vector<Sprite*> _sprites;
thread *_animation;
friend void SpriteGroupAnimation(sdltl *mgr, SpriteGroup *sg, int t, int flags=SPRITE_ANIM_ONCE );
friend void SpriteGroupAnimation(SpriteGroup *sg, int t, int flags=SPRITE_ANIM_ONCE );
};

BIN
SDL#3/exe

Binary file not shown.

View File

@ -9,143 +9,115 @@ static bool running = true;
int main(int argc, char* argv[]) {
srand(time(0));
/* [0] Initialisation de SDL
/* [0] Initialisation du manager + Creation de la fenetre
=========================================================*/
mgr = new sdltl("Ma fenetre SDL", WIN_WIDTH, WIN_HEIGHT);
/* [1] Creation de la fenetre
=========================================================*/
if( !mgr->status() ) cout << "Erreur: " << SDL_GetError() << endl;
// Gestion erreur
if( !mgr->status() ){
cout << "[INIT] -> " << SDL_GetError() << endl;
return -1;
}
/* [3] On definit le background color
/* [2] On definit le background color
=========================================================*/
bool bgLoaded = mgr->setBackground(255, 255, 255);
cout << "BG: " << bgLoaded << endl;
// bool imageLoaded = mgr->setImage( "src/1.bmp" );
mgr->setBackground(255, 0, 255, 150);
// mgr->setImage( "src/1.bmp" );
/* [4] On ajoute Une animation
=========================================================*/
/* (1) On cree les fonds pour couvrir les frames en arriere plan */
int white[] = {255, 255, 255};
Sprite *mb_background = new Sprite(
white,
(SDL_Rect){0, 0, 20, 20}
);
Sprite *gs_background = new Sprite(
white,
(SDL_Rect){100, 0, 20, 20}
);
Sprite *rs_background = new Sprite(
white,
(SDL_Rect){150, 0, 20, 20}
);
// int white[] = {255, 255, 255};
// Sprite *mb_background = new Sprite(mgr, white );
// mb_background->dimensions((SDL_Rect){0, 0, 20, 20});
/* (2) On enregistre les frames de l'animation du bloc mystere */
// Sprite *gs_background = new Sprite(mgr, white);
// gs_background->dimensions((SDL_Rect){100, 0, 20, 20});
// Sprite *rs_background = new Sprite(mgr, white);
// rs_background->dimensions((SDL_Rect){150, 0, 20, 20});
// /* (2) On enregistre les frames de l'animation du bloc mystere */
SpriteGroup animated_mystery_bloc;
for( int i = 0 ; i < 4 ; i++ ){
animated_mystery_bloc.add( new Sprite(
"src/mario_crop.png",
(SDL_Rect){0, 0, 20, 20},
animated_mystery_bloc.add( new Sprite(mgr, "src/mario_crop.png") );
animated_mystery_bloc.get(i)->dimensions(
(SDL_Rect){0, 0, 100, 100},
(SDL_Rect){4*19+19*i, 2*20, 20, 20}
) );
);
}
/* (3) On enregistre les frames de l'animation d'une carapace verte */
// (3) On enregistre les frames de l'animation d'une carapace verte
SpriteGroup animated_green_shell;
for( int i = 0 ; i < 4 ; i++ ){
animated_green_shell.add( new Sprite(
"src/mario_crop.png",
animated_green_shell.add( new Sprite(mgr, "src/mario_crop.png") );
animated_green_shell.get(i)->dimensions(
(SDL_Rect){100, 0, 20, 20},
(SDL_Rect){4*19+19*i, 11*19, 20, 20}
) );
);
}
/* (4) On enregistre les frames de l'animation d'une carapace rouge */
// /* (4) On enregistre les frames de l'animation d'une carapace rouge */
SpriteGroup animated_red_shell;
for( int i = 0 ; i < 4 ; i++ ){
animated_red_shell.add( new Sprite(
"src/mario_crop.png",
(SDL_Rect){150, 0, 20, 20},
animated_red_shell.add( new Sprite(mgr, "src/mario_crop.png") );
animated_red_shell.get(i)->dimensions(
(SDL_Rect){150, 0, 50, 50},
(SDL_Rect){2+19*i, 11*19, 20, 20}
) );
);
}
// TEST
int red[] = {255, 0, 0};
int pink[] = {255, 0, 255};
SpriteGroup testgroup;
testgroup.add( new Sprite(
"src/mario_crop.png",
(SDL_Rect){150, 0, 20, 20},
(SDL_Rect){2+19*1, 11*19, 20, 20}
) );
testgroup.add( new Sprite(
pink,
(SDL_Rect){100, 0, 100, 100}
) );
// testgroup.appendTo(mgr);
testgroup.get(0)->appendTo(mgr);
/* [5] On lance les animation en parallele
=========================================================*/
// /* [5] On lance les animation en parallele
// =========================================================*/
vector<thread*> animations(0);
animations.push_back( animated_mystery_bloc.animate(
mgr, // rendu a mettre a jour
200, // delai entre-frames
SPRITE_ANIM_INFINITE // FLAGS
) );
delete animations[0]; // On le supprime ensuite
// animations.push_back( animated_mystery_bloc.animate(
// 200, // delai entre-frames
// SPRITE_ANIM_INFINITE // FLAGS
// ) );
// delete animations[0]; // On le supprime ensuite
animations.push_back( animated_green_shell.animate(
mgr, // rendu a mettre a jour
100, // delai entre-frames
SPRITE_ANIM_INFINITE // FLAGS
) );
delete animations[1]; // On le supprime ensuite
// animations.push_back( animated_green_shell.animate(
// 100, // delai entre-frames
// SPRITE_ANIM_INFINITE // FLAGS
// ) );
// delete animations[1]; // On le supprime ensuite
animations.push_back( animated_red_shell.animate(
mgr, // rendu a mettre a jour
100, // delai entre-frames
SPRITE_ANIM_INFINITE // FLAGS
) );
delete animations[2]; // On le supprime ensuite
delete animations[0]; // On le supprime ensuite
/* [n-1] Boucle infinie
=========================================================*/
mgr->update();
mgr->manageFps(FPS);
running = true;
while(running){
mgr->waitEvent(SDL_QUIT, &quitEventHandler);
// cout << "Main loop" << endl;

View File

@ -19,8 +19,8 @@
/* [CONST] Constantes et enumerations
=========================================================*/
#define WIN_WIDTH 600
#define WIN_HEIGHT 400
#define WIN_WIDTH 1200
#define WIN_HEIGHT 800
#define FPS 60

Binary file not shown.

View File

@ -32,7 +32,7 @@ sdltl::sdltl(const char *t, int w, int h){
_renderer = SDL_CreateRenderer(
_window,
-1,
SDL_RENDERER_ACCELERATED
SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC
);
}
@ -65,38 +65,9 @@ SDL_Renderer* sdltl::renderer(){ return _renderer; }
/* [SETBACKGROUND] Modifie la couleur de fond
=========================================================*/
bool sdltl::setBackground(int r, int g, int b){
/*// On cree la surface
SDL_Surface *surf = NULL;
int win[2];
SDL_GetWindowSize(_window, &win[0], &win[1]);
bool sdltl::setBackground(Uint8 r, Uint8 g, Uint8 b, Uint8 a){
// On cree la surface
surf = SDL_CreateRGBSurface(0, win[0], win[1], 32, 0, 0, 0, 0);
if( surf == NULL )
return false;
// On cree la couleur
Uint32 color = SDL_MapRGB(surf->format, r, g, b);
// On colore la surface
SDL_FillRect(surf, NULL, color);
// On applique a la texture
_texture = SDL_CreateTextureFromSurface(_renderer, surf);
if( _texture == NULL )
return false;
// On libere la memoire
SDL_FreeSurface(surf);
surf = NULL;
*/
SDL_SetRenderDrawColor( _renderer, 0xFF, 0xFF, 0xFF, 0x00 );
SDL_SetRenderDrawColor( _renderer, r, g, b, a );
return true;
}
@ -105,39 +76,25 @@ bool sdltl::setBackground(int r, int g, int b){
=========================================================*/
bool sdltl::setImage(const char *url){
SDL_Surface *image = NULL;
image = SDL_LoadBMP( url );
// Si erreur de chargement image
if( image == NULL )
return false;
// On cree la texture associee
_texture = SDL_CreateTextureFromSurface(
_renderer,
image
);
_texture = IMG_LoadTexture( _renderer, url );
// On libere la surface pour l'image
SDL_FreeSurface(image);
delete image;
return true;
return _texture != NULL;
}
/* [ADD] Ajoute une texture au rendu principal
/* [PUSH] Ajoute une texture au rendu principal
=========================================================*/
void sdltl::add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest){
_sprites.push_back( t );
_origins.push_back( origin );
_dests.push_back( dest );
void sdltl::push(SDL_Texture *t, SDL_Rect *src, SDL_Rect *dst){
_sprites.push_back( t );
_src.push_back( src );
_dst.push_back( dst );
}
/* [REMOVE] Retire une texture du rendu principal
/* [PULL] Retire une texture du rendu principal
=========================================================*/
void sdltl::remove(SDL_Texture *t){
void sdltl::pull(SDL_Texture *t){
// On cherche l'indice de la texture
int index = -1;
@ -150,8 +107,8 @@ void sdltl::remove(SDL_Texture *t){
// On supprime la texture et ses dimensions
_sprites.erase( _sprites.begin() + index );
_origins.erase( _origins.begin() + index );
_dests.erase( _dests.begin() + index );
_src.erase( _src.begin() + index );
_dst.erase( _dst.begin() + index );
}
@ -159,21 +116,32 @@ void sdltl::remove(SDL_Texture *t){
/* [UPDATE] Mise a jour du rendu
=========================================================*/
void sdltl::update(){
// On efface l'ecran
/* (1) On efface le rendu */
SDL_RenderClear(_renderer);
// On ajoute le rendu principal au rendu
/* (2) On applique la couleur de fond */
SDL_Rect dRect; // On recupere les dimensions de la fenetre
SDL_GetWindowSize(_window, &dRect.w, &dRect.h);
SDL_RenderDrawRect(_renderer, &dRect);
/* (3) On ajoute le rendu principal (si existe) */
if( _texture != NULL)
SDL_RenderCopy(_renderer, _texture, NULL, NULL);
// On ajoute toutes les textures ajoutees
cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl;
// for( int i = _sprites.size()-1 ; i >= 0 ; i-- )
for( int i = 0 ; i < _sprites.size() ; i++ )
SDL_RenderCopy(_renderer, _sprites[i], _origins[i], _dests[i]);
// On affiche le resultat
/* (4) On ajoute toutes les textures pushees */
cout << "Update MAIN SPRITE +" << _sprites.size() << " added sprites.." << endl;
for( int i = 0 ; i < _sprites.size() ; i++ )
SDL_RenderCopy(_renderer, _sprites[i], _src[i], _dst[i]);
/* (n) On affiche le resultat */
SDL_RenderPresent(_renderer);
}
/* [WAITEVENT] Attends un evenement pour executer

View File

@ -5,6 +5,7 @@
/* [LIBS] Internes
=========================================================*/
#include "SDL.h"
#include "SDL_image.h"
#include <vector>
/* [LIBS] Externes
@ -24,12 +25,13 @@
SDL_Window *window();
SDL_Renderer *renderer();
bool status();
bool setBackground(int r=255, int g=255, int b=255);
bool setBackground(Uint8 r=0xff, Uint8 g=0xff, Uint8 b=0xff, Uint8 a=0xff);
bool setImage(const char *url);
void waitEvent(SDL_EventType t, void(*handler)(SDL_Event*) );
void add(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest);
void remove(SDL_Texture *t);
void push(SDL_Texture *t, SDL_Rect *origin, SDL_Rect *dest);
void pull(SDL_Texture *t);
void update();
void manageFps(const int fps=0);
@ -48,8 +50,8 @@
SDL_Texture *_texture;
vector<SDL_Texture*> _sprites;
vector<SDL_Rect*> _origins;
vector<SDL_Rect*> _dests;
vector<SDL_Rect*> _src;
vector<SDL_Rect*> _dst;
};