Merge SpriteAnimation into xSprite and interface improvements
- remove dead code - a sprite with no clip uses the default surface dimensions to draw - a sprite with a single clip uses it - a sprite with multiple clips (i.e. frames) has the first as a default but when orchestrated iterates over clips in order
This commit is contained in:
parent
12871d93dc
commit
44de8cb3ea
|
@ -6,6 +6,5 @@
|
||||||
#include "../xSDL/xController.h"
|
#include "../xSDL/xController.h"
|
||||||
#include "../xSDL/xElement.h"
|
#include "../xSDL/xElement.h"
|
||||||
#include "../xSDL/xSprite.h"
|
#include "../xSDL/xSprite.h"
|
||||||
#include "../xSDL/xSpriteAnimation.h"
|
|
||||||
|
|
||||||
#endif
|
#endif
|
176
xSDL/xSprite.cpp
176
xSDL/xSprite.cpp
|
@ -7,28 +7,19 @@ xSprite::~xSprite(){
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** empty sprite */
|
|
||||||
xSprite::xSprite(){
|
|
||||||
_type = "basic";
|
|
||||||
}
|
|
||||||
|
|
||||||
/** color sprite */
|
/** color sprite */
|
||||||
xSprite::xSprite(const int rgba[]){
|
xSprite::xSprite(const int rgba[]){
|
||||||
_type = "basic";
|
|
||||||
this->setSurface(rgba);
|
this->setSurface(rgba);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** image sprite */
|
/** image sprite */
|
||||||
xSprite::xSprite(const char *url){
|
xSprite::xSprite(const char *url){
|
||||||
_type = "basic";
|
|
||||||
|
|
||||||
this->setSurface(url);
|
this->setSurface(url);
|
||||||
}
|
}
|
||||||
|
/** image sprite with clip */
|
||||||
/** texture copy sprite */
|
xSprite::xSprite(const char *url, SDL_Rect clip){
|
||||||
xSprite::xSprite(SDL_Surface *s){
|
this->setSurface(url);
|
||||||
_type = "basic";
|
this->setClip(clip);
|
||||||
this->setSurface(s);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** update sprite to rhb color */
|
/** update sprite to rhb color */
|
||||||
|
@ -41,8 +32,6 @@ void xSprite::setSurface(const int rgba[]){
|
||||||
|
|
||||||
_surface = SDL_CreateRGBSurface(0, 0, 0, 32, rgba[0], rgba[1], rgba[2], rgba[3]);
|
_surface = SDL_CreateRGBSurface(0, 0, 0, 32, rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||||
|
|
||||||
// On cree la texture a partir de la surface
|
|
||||||
// _surface = SDL_CreateTextureFromSurface(_manager->renderer(), surf);
|
|
||||||
if( _surface == NULL ) {
|
if( _surface == NULL ) {
|
||||||
throw runtime_error("[xSprite] setSurface(rgba) -> NULL surface");
|
throw runtime_error("[xSprite] setSurface(rgba) -> NULL surface");
|
||||||
}
|
}
|
||||||
|
@ -67,8 +56,7 @@ void xSprite::setSurface(const char *url){
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [SETTEXTURE] Modification de la texture texture
|
/** copies an existing surface */
|
||||||
=========================================================*/
|
|
||||||
void xSprite::setSurface(SDL_Surface *s){
|
void xSprite::setSurface(SDL_Surface *s){
|
||||||
_mutex.try_lock();
|
_mutex.try_lock();
|
||||||
if( _surface != NULL ){
|
if( _surface != NULL ){
|
||||||
|
@ -85,128 +73,72 @@ void xSprite::setSurface(SDL_Surface *s){
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** move sprite with a (x,y) velocity
|
/** add new animation frame with new clip */
|
||||||
* - int[0]: new
|
void xSprite::addFrame(SDL_Rect clip){
|
||||||
* - int[1]: can move on y
|
|
||||||
*/
|
|
||||||
// bool* xSprite::move(double xSpeed, double ySpeed){
|
|
||||||
// _mutex.try_lock();
|
|
||||||
|
|
||||||
// bool result[2] = {false, false};
|
|
||||||
|
|
||||||
// /* logic variables */
|
|
||||||
// int incrx = x;
|
|
||||||
// int incry = y;
|
|
||||||
// bool moveFasterOnY = abs(x) <= abs(y);
|
|
||||||
|
|
||||||
// int signofx = (x==0) ? 0 : x / abs(x);
|
|
||||||
// int signofy = (y==0) ? 0 : y / abs(y);
|
|
||||||
|
|
||||||
// // while velocity not null
|
|
||||||
// while( incrx != 0 || incry != 0 ){
|
|
||||||
|
|
||||||
// result[0] = incrx;
|
|
||||||
// result[1] = incry;
|
|
||||||
|
|
||||||
// /* (3) Si on peut aller a la destination */
|
|
||||||
// // if( !_manager->hit(this, incrx, incry) ){
|
|
||||||
// // _dst.x += incrx;
|
|
||||||
// // _dst.y += incry;
|
|
||||||
|
|
||||||
// // // cerr << ">>> not locked <<<" << endl;
|
|
||||||
|
|
||||||
// // result[0] = incrx;
|
|
||||||
// // result[1] = incry;
|
|
||||||
|
|
||||||
// // _mutex.unlock();
|
|
||||||
// // return result;
|
|
||||||
// // }
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// /* (4) Sinon, on decremente les deplacements 'alternativement' */
|
|
||||||
// if( moveFasterOnY ){ // Si on a plus de mouvement horizontal
|
|
||||||
// if( signofx != 0 && incrx != 0 ) // si la vel. sur x n'est pas nulle
|
|
||||||
// incrx -= signofx; // on diminue la vel. sur x
|
|
||||||
// else if( signofy != 0 && incry != 0 ) // sinon si vel. sur y n'est pas nulle
|
|
||||||
// incry -= signofy; // on diminue la vel. sur y
|
|
||||||
// else // sinon, velocite nulle
|
|
||||||
// return result; // On arrete de chercher
|
|
||||||
|
|
||||||
// }else{ // Si on a plus de mouvement vertical
|
|
||||||
// if( signofy != 0 && incry != 0 ) // si la vel. sur y n'est pas nulle
|
|
||||||
// incry -= signofy; // on diminue la vel. sur y
|
|
||||||
// else if( signofx != 0 && incrx != 0 ) // sinon si vel. sur x n'est pas nulle
|
|
||||||
// incrx -= signofx; // on diminue la vel. sur x
|
|
||||||
// else // sinon, velocite nulle
|
|
||||||
// return result; // On arrete de chercher
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // if( !_manager->hit(this, 0, 1) ){
|
|
||||||
// // cerr << "locked from (" << _dst.x << ", " << _dst.y << ") to (" << incrx << ", " << incry << ")" << endl;
|
|
||||||
// // }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // retour
|
|
||||||
// _mutex.unlock();
|
|
||||||
// return result;
|
|
||||||
// }
|
|
||||||
|
|
||||||
/** get/set sprite type */
|
|
||||||
string xSprite::getType(){ return _type; }
|
|
||||||
void xSprite::setType(string newtype){ _type = newtype; }
|
|
||||||
|
|
||||||
/** set default dimensions */
|
|
||||||
void xSprite::dimensions(){
|
|
||||||
_mutex.try_lock();
|
_mutex.try_lock();
|
||||||
/* extract surface lengths*/
|
_frames.push_back(clip);
|
||||||
int w = _surface->w;
|
|
||||||
int h = _surface->h;
|
|
||||||
|
|
||||||
_dst = (SDL_Rect){0, 0, w, h};
|
|
||||||
_src = (SDL_Rect){0, 0, w, h};
|
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set surface dimensions */
|
/** clear every animation frames */
|
||||||
void xSprite::dimensions(SDL_Rect r){
|
void xSprite::clearFrames(){
|
||||||
_mutex.try_lock();
|
_mutex.try_lock();
|
||||||
/* extract surface lengths */
|
_frames.clear();
|
||||||
int w = _surface->w;
|
_mutex.unlock();
|
||||||
int h = _surface->h;
|
}
|
||||||
_src = (SDL_Rect){0, 0, w, h};
|
/** set sprite clip and clears animation frames */
|
||||||
|
void xSprite::setClip(SDL_Rect clip){
|
||||||
/* store destination dimensions */
|
_mutex.try_lock();
|
||||||
_dst = (SDL_Rect){r.x, r.y, r.w, r.h};
|
_frames.clear();
|
||||||
|
_frames.push_back(clip);
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** set surface dimensions + clip */
|
/** set sprite projection */
|
||||||
void xSprite::dimensions(SDL_Rect r, SDL_Rect clip){
|
void xSprite::project(SDL_Rect dest){
|
||||||
_mutex.try_lock();
|
_mutex.try_lock();
|
||||||
_src = (SDL_Rect){clip.x, clip.y, clip.w, clip.h};
|
_projection = dest;
|
||||||
_dst = (SDL_Rect){r.x, r.y, r.w, r.h};
|
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** returns the surface */
|
|
||||||
SDL_Surface *xSprite::surface(){ return _surface; }
|
|
||||||
|
|
||||||
/** return destination dimensions */
|
|
||||||
SDL_Rect *xSprite::dst(){ return &_dst; }
|
|
||||||
|
|
||||||
/** return source dimensions */
|
|
||||||
SDL_Rect *xSprite::src(){ return &_src; }
|
|
||||||
|
|
||||||
|
|
||||||
/** draws to renderer */
|
/** draws to renderer */
|
||||||
void xSprite::draw(SDL_Renderer* renderer){
|
void xSprite::draw(SDL_Renderer* renderer){
|
||||||
_mutex.try_lock();
|
_mutex.try_lock();
|
||||||
|
|
||||||
|
// no clip -> use surface dimensions
|
||||||
|
if( _frames.size() <= 0 ){
|
||||||
|
setClip( (SDL_Rect){0, 0, _surface->w, _surface->h} );
|
||||||
|
}
|
||||||
|
|
||||||
|
// only 1 clip -> use it
|
||||||
|
if( _frames.size() == 1 ){
|
||||||
|
_active_clip = 0;
|
||||||
|
}
|
||||||
|
|
||||||
SDL_RenderCopy(
|
SDL_RenderCopy(
|
||||||
renderer,
|
renderer,
|
||||||
SDL_CreateTextureFromSurface(renderer, this->surface()),
|
SDL_CreateTextureFromSurface(renderer, _surface),
|
||||||
this->src(),
|
&_frames.at(_active_clip),
|
||||||
this->dst()
|
&_projection
|
||||||
);
|
);
|
||||||
_mutex.unlock();
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** animation process */
|
||||||
|
void xSprite::tick(const uint32_t ticks){
|
||||||
|
_mutex.try_lock();
|
||||||
|
uint32_t time_index = ticks / _animation_interval;
|
||||||
|
_active_clip = time_index % _frames.size();
|
||||||
|
_mutex.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** orchestrate the animation */
|
||||||
|
void xSprite::animate(uint32_t interval){
|
||||||
|
_animation_interval = interval;
|
||||||
|
xApplication::get()->addOrchestrable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** stops orchestrating the animation */
|
||||||
|
void xSprite::freeze(){
|
||||||
|
xApplication::get()->removeOrchestrable(this);
|
||||||
|
}
|
|
@ -7,51 +7,60 @@
|
||||||
#include "SDL.h"
|
#include "SDL.h"
|
||||||
#include "SDL_image.h"
|
#include "SDL_image.h"
|
||||||
#include "xElement.h"
|
#include "xElement.h"
|
||||||
|
#include "xOrchestrable.h"
|
||||||
|
#include "xApplication.h"
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
class xSprite : public xElement {
|
class xSprite : public xElement, public xOrchestrable {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
xSprite(); // empty
|
// color sprite
|
||||||
xSprite(const int rgba[]); // color sprite
|
xSprite(const int rgba[]);
|
||||||
xSprite(const char *url); // image sprite
|
// image sprite
|
||||||
xSprite(SDL_Surface *s); // copy sprite
|
xSprite(const char *url);
|
||||||
~xSprite();
|
// image with default clip
|
||||||
|
xSprite(const char *url, SDL_Rect clip);
|
||||||
|
virtual ~xSprite();
|
||||||
|
|
||||||
// replace surface
|
// replace surface
|
||||||
void setSurface(const int rgba[]); // color sprite
|
void setSurface(const int rgba[]); // color sprite
|
||||||
void setSurface(const char *url); // image sprite
|
void setSurface(const char *url); // image sprite
|
||||||
void setSurface(SDL_Surface *t); // copy surface
|
void setSurface(SDL_Surface *t); // copy surface
|
||||||
|
|
||||||
// move the sprite
|
// animation
|
||||||
// const bool* move(double xSpeed, double ySpeed);
|
void addFrame(SDL_Rect clip);
|
||||||
|
void clearFrames();
|
||||||
|
|
||||||
// action to apply on collision
|
// sets the sprite clip
|
||||||
// virtual void onCollide(vector<bool> from, xSprite* by);
|
// + clears animation frames
|
||||||
|
void setClip(SDL_Rect clip);
|
||||||
|
|
||||||
// get/set sprite type
|
// set projection into scene
|
||||||
string getType();
|
void project(SDL_Rect dest);
|
||||||
void setType(string newtype);
|
|
||||||
|
|
||||||
// set dimensions
|
|
||||||
void dimensions(); // defauts
|
|
||||||
void dimensions(SDL_Rect r);
|
|
||||||
void dimensions(SDL_Rect r, SDL_Rect clip); // w/ clip
|
|
||||||
|
|
||||||
// getters
|
|
||||||
SDL_Surface *surface();
|
|
||||||
SDL_Rect *dst();
|
|
||||||
SDL_Rect *src();
|
|
||||||
|
|
||||||
// implement xElement
|
// implement xElement
|
||||||
virtual void draw(SDL_Renderer* renderer) override;
|
virtual void draw(SDL_Renderer* renderer) override;
|
||||||
|
|
||||||
protected:
|
// orchestrable process
|
||||||
string _type;
|
void tick(const uint32_t ticks);
|
||||||
|
|
||||||
|
// animation handles
|
||||||
|
void animate(uint32_t interval);
|
||||||
|
void freeze();
|
||||||
|
|
||||||
|
protected:
|
||||||
SDL_Surface* _surface = NULL;
|
SDL_Surface* _surface = NULL;
|
||||||
SDL_Rect _dst;
|
SDL_Rect _projection;
|
||||||
SDL_Rect _src;
|
|
||||||
|
// surface clips
|
||||||
|
// [0] : no clip, use default surface dimensions
|
||||||
|
// [1] : global clip, use it every time
|
||||||
|
// [2+]: clips are used for animation
|
||||||
|
vector<SDL_Rect> _frames;
|
||||||
|
|
||||||
|
// active clip for animation ; equal to 0 if not an animated sprite
|
||||||
|
size_t _active_clip = 0;
|
||||||
|
uint32_t _animation_interval;
|
||||||
|
|
||||||
mutex _mutex;
|
mutex _mutex;
|
||||||
|
|
||||||
|
|
|
@ -1,76 +0,0 @@
|
||||||
#include "xSpriteAnimation.h"
|
|
||||||
|
|
||||||
/** clean SDL objects and frames */
|
|
||||||
xSpriteAnimation::~xSpriteAnimation(){
|
|
||||||
_mutex.try_lock();
|
|
||||||
SDL_FreeSurface( _surface );
|
|
||||||
_frames.erase( _frames.begin(), _frames.end() );
|
|
||||||
_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** builds an animation */
|
|
||||||
xSpriteAnimation::xSpriteAnimation(const char *url, SDL_Rect dest)
|
|
||||||
: xSprite( url ){
|
|
||||||
this->dimensions(dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** builds an animation from an existing surface */
|
|
||||||
xSpriteAnimation::xSpriteAnimation(SDL_Surface *s, SDL_Rect dest)
|
|
||||||
: xSprite(s) {
|
|
||||||
this->dimensions(dest);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** adds an animation frame */
|
|
||||||
void xSpriteAnimation::addFrame(SDL_Rect clip){
|
|
||||||
_mutex_frames.try_lock();
|
|
||||||
_frames.push_back( (SDL_Rect){
|
|
||||||
clip.x,
|
|
||||||
clip.y,
|
|
||||||
clip.w,
|
|
||||||
clip.h
|
|
||||||
} );
|
|
||||||
_mutex_frames.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** clears all frames */
|
|
||||||
void xSpriteAnimation::clearFrames(){
|
|
||||||
_mutex_frames.try_lock();
|
|
||||||
_frames.erase(_frames.begin(), _frames.end());
|
|
||||||
_mutex_frames.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** draw to scene */
|
|
||||||
void xSpriteAnimation::draw(SDL_Renderer* renderer){
|
|
||||||
_mutex.try_lock();
|
|
||||||
SDL_RenderCopy(
|
|
||||||
renderer,
|
|
||||||
SDL_CreateTextureFromSurface(renderer, this->surface()),
|
|
||||||
this->src(),
|
|
||||||
this->dst()
|
|
||||||
);
|
|
||||||
_mutex.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** animation process */
|
|
||||||
void xSpriteAnimation::tick(const uint32_t ticks){
|
|
||||||
_mutex_frames.try_lock();
|
|
||||||
uint32_t time_index = ticks / _interval;
|
|
||||||
size_t frame_index = time_index % _frames.size();
|
|
||||||
|
|
||||||
// update current frame clip
|
|
||||||
_src = _frames.at(frame_index);
|
|
||||||
_mutex_frames.unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** adds the animation to the render */
|
|
||||||
void xSpriteAnimation::start(uint32_t interval){
|
|
||||||
_interval = interval;
|
|
||||||
xApplication::get()->addOrchestrable(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** stops the animation */
|
|
||||||
void xSpriteAnimation::stop(){
|
|
||||||
xApplication::get()->removeOrchestrable(this);
|
|
||||||
}
|
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef DEF_XSPRITEANIMATION_H
|
|
||||||
#define DEF_XSPRITEANIMATION_H
|
|
||||||
|
|
||||||
#include "SDL.h"
|
|
||||||
#include <vector>
|
|
||||||
#include "xSprite.h"
|
|
||||||
#include "xApplication.h"
|
|
||||||
#include "xElement.h"
|
|
||||||
#include "xOrchestrable.h"
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
class xSpriteAnimation : public xSprite, public xOrchestrable {
|
|
||||||
|
|
||||||
public:
|
|
||||||
// spritesheet with sprite size
|
|
||||||
xSpriteAnimation(const char *url, SDL_Rect dest);
|
|
||||||
xSpriteAnimation(SDL_Surface *s, SDL_Rect dest);
|
|
||||||
~xSpriteAnimation();
|
|
||||||
|
|
||||||
void addFrame(SDL_Rect clip);
|
|
||||||
void clearFrames();
|
|
||||||
|
|
||||||
// animation control handles
|
|
||||||
void start(uint32_t delay);
|
|
||||||
void stop();
|
|
||||||
|
|
||||||
// implement xElement
|
|
||||||
void draw(SDL_Renderer* renderer) override;
|
|
||||||
|
|
||||||
// implement xOrchestrable
|
|
||||||
void tick(const uint32_t ticks);
|
|
||||||
protected:
|
|
||||||
vector<SDL_Rect> _frames;
|
|
||||||
mutex _mutex_frames;
|
|
||||||
|
|
||||||
// animation
|
|
||||||
uint32_t _interval;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in New Issue