voilà je programme une classe c++ appelée class Perso avec SDL pour pouvoir créer des jeux plus facilement, pour le moment elle comprend une importation de ressources de type RMXP, et crée des animations a partir de là, ces animations apparaissent celon la direction de l´objet et si le booléen En_mouvement est vrai; ensuite elle est divisée en plusieurs comportement : Joueur : c´est vous qui controlez le perso, exactement comme dans RMXP; Suivre_Hero : l´element va suivre l´element hero; mon probléme se trouve au niveau de ce comportement, j´ai créé une fonction qui teste la proximité de tous les autres objet de la classe Perso, et elle marche( c´est à dire que si il y a un autre perso a coté , tu vas pas le depasser, mais être bloqué)et elle renvoie P_COLLISION(prés collision) quand il ya un objet pas depassable, mais lorsque un objet de ce type entre en collision avec un element, ben il reste bloqué jusqu´à ce que le Hero se deplace ailleurs; a part ça la classe est pas mal : on peut decider si l´éléement apparait ou pas avec un booléen, on peut decider de sa fréquence de déplacement et de sa vitesse(nombre de pixel par frame), il existe aussi une compatibilité avec les ressources RM2000, mais les collisions ne snt pas encore mises dedans^^ j´ai ajouté des element difficiles a expliqué donc vous verrez dans le code source :
// je met aussi les enumération que j´ai mis dans un autre fichier //elles permettent de mieux voir :p
SDL_Surface * ecran;
int dernier_objet = 0; // variable globale disant le nombre //d´objet de type Perso existant
enum direc{HAUT=3,BAS =0,GAUCHE=1,DROITE=2};
enum {IMMOBILE,EN_MOUVEMENT,EN_COURS,FIN};
enum type{RM2000=3,RMXP=4};
enum comportement{ SUIVRE_HERO,JOUEUR,AUCUN };
enum Collision{P_COLLISION,COLLISION,PAS_COLLISION};
class Perso
{
public:
Perso();
Timing cycle;
int fin_cycle;
Perso(char *nomImg, int type,int framex,int framey);
~Perso();
SDL_Rect position;
SDL_Rect position2;
bool En_mouvement;
bool affichage;
int frequence;
int vitesse;
int nb_framex;
int nb_framey;
SDL_Rect Trames[4][4]; // premier pour la direction second pour le mouvement en cours
int element_actuel;
int direction;
int diffusion;
int nb_diffusion;
SDL_Surface * image;
int fin_mouvement;
int bliting();
int reblit();
int comportement_actuel;
int mouvement_en_cours;
int evenement_hero(int controlej,bool mouvement);
void comportement();
int collision();
int collisionEvent(Perso *Event);
};
Perso * Objets[100]= {NULL};/* Pointeurs vers chaque Objets de la classe Perso, particuliérement utile pour les collsions etc..^^*/
Perso::~Perso()
{
SDL_FreeSurface(image);
}
Perso::Perso()
{
affichage = true;
comportement_actuel = JOUEUR;
fin_mouvement = 0;
mouvement_en_cours = 0;
vitesse = COTE;
frequence = 200;
element_actuel = dernier_objet;
Objets[dernier_objet]= this;// ajoute l´adresse de l´objet dans le //tableau de pointeur Objets
dernier_objet += 1;
char * nomImg = "charset1.png";
fin_cycle = 0;
En_mouvement = true;
diffusion = 0;
direction = BAS;
position.x = 0;
position.y = 0;
image = IMG_Load(nomImg);
for(int i =0; i< 4; i++)
{
for(int y =0; y< 4; y++)
{
Trames[i][y].x = y*image->w/4;
Trames[i][y].y = i*image->h/4;
Trames[i][y].w = image->w/4;
Trames[i][y].h = image->h/4;
}
}
nomImg = NULL;
}
Perso::Perso(char * nomImg,int type = RMXP,int framex = 0,int framey = 0)
{
comportement_actuel = JOUEUR;
affichage = true;
fin_mouvement = 0;
mouvement_en_cours = 0;
nb_diffusion = type;
if(type == RMXP)
{
nb_framex = 1;
nb_framey = 1;
enum Perso{HAUT=3,BAS =0,GAUCHE=1,DROITE=2};
}
if (type == RM2000)
{
nb_framex = 4;
nb_framey = 2;
enum Perso{HAUT=0,BAS =2,GAUCHE=3,DROITE=1};
}
vitesse = COTE;
frequence = 200;
element_actuel = dernier_objet;
Objets[dernier_objet]= this;
dernier_objet += 1;
fin_cycle = 0;
En_mouvement = true;
diffusion = 0;
direction = BAS;
position.x = 0;
position.y = 0;
image = IMG_Load(nomImg);
for(int dir =0; dir< 4; dir++)
{
for(int dif =0; dif< nb_diffusion; dif++)
{
Trames[dir][dif].w = (image->w/nb_diffusion)/nb_framex;
Trames[dir][dif].h = (image->h/4)/nb_framey;
Trames[dir][dif].x = Trames[dir][dif].w * nb_diffusion*framex + dif * Trames[dir][dif].w;
Trames[dir][dif].y = Trames[dir][dif].h * 4 *framey + dir * Trames[dir][dif].h;
}
}
}
int Perso::reblit()
{
if (affichage == true)
{
if (nb_diffusion == RM2000)
{
int temp;
switch (direction)
{
case HAUT : temp = 0;
break;
case BAS : temp = 2;
break;
case DROITE : temp = 1;
break;
case GAUCHE : temp = 3;
break;
}
SDL_BlitSurface(image, &Trames[temp][diffusion], ecran, &position);
}
else
{
int temp;
switch (direction){
case HAUT : temp = 3;
break;
case BAS : temp = 0;
break;
case DROITE : temp = 2;
break;
case GAUCHE : temp = 1;
break;
}
SDL_BlitSurface(image, &Trames[temp][diffusion], ecran, &position);
}
}
}
int Perso::bliting()
{
if (affichage == true)
{
if (cycle.cycle(frequence)== FIN)
{
diffusion+=1;
cycle.remise_a_zero();
if (En_mouvement == true && collision() != P_COLLISION)
{
switch(direction)
{
case DROITE:
if ( collision() != P_COLLISION)
position.x += vitesse;
break;
case GAUCHE:
if ( collision() != P_COLLISION)
position.x -= vitesse;
break;
case BAS:
if ( collision() != P_COLLISION)
position.y += vitesse;
break;
case HAUT:
if ( collision() != P_COLLISION)
position.y -= vitesse;
break;
}
}
}
if (diffusion > nb_diffusion-1)
diffusion = 0;
if(En_mouvement == false && nb_diffusion == RMXP)
diffusion = 0;
if(En_mouvement == false && nb_diffusion == RM2000)
diffusion = 1;
if (nb_diffusion == RM2000)
{
int temp;
switch (direction){
case HAUT : temp = 0;
break;
case BAS : temp = 2;
break;
case DROITE : temp = 1;
break;
case GAUCHE : temp = 3;
break;
}
SDL_BlitSurface(image, &Trames[temp][diffusion], ecran, &position);
}
else
{
int temp;
switch (direction){
case HAUT : temp = 3;
break;
case BAS : temp = 0;
break;
case DROITE : temp = 2;
break;
case GAUCHE : temp = 1;
break;
}
SDL_BlitSurface(image, &Trames[temp][diffusion], ecran, &position);
}
}
}
int Perso::evenement_hero(int controlej = true, bool mouvement = true)
{
En_mouvement = mouvement;
if ( controlej == true)
{
switch(event.type)
{
case SDL_KEYDOWN: //Si appui d´une touche
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
direction = DROITE;
En_mouvement = true;
break;
case SDLK_LEFT:
direction = GAUCHE;
En_mouvement = true;
break;
case SDLK_DOWN:
direction = BAS;
En_mouvement = true;
break;
case SDLK_UP:
direction = HAUT;
En_mouvement = true;
break;
}
break;
default:
En_mouvement = false;
break;
}
}
bliting();
}
void Perso::comportement()
{
En_mouvement = true;
if(comportement_actuel == SUIVRE_HERO)
{
if(((Objets[0]->position.x + Objets[0]->image->w/4 > position.x) && (Objets[0]->position.x < position.x + image->w/4)) &&((Objets[0]->position.y + Objets[0]->image->h/4 > position.y) && (Objets[0]->position.y < position.y + image->h/4)))
{
evenement_hero(false,false);
}
else
{
if (Objets[0]->position.x < position.x)
direction = GAUCHE;
if (Objets[0]->position.x > position.x)
direction = DROITE;
if (Objets[0]->position.y < position.y)
direction = HAUT;
if (Objets[0]->position.y > position.y)
direction = BAS;
evenement_hero(false);
}
}
if (comportement_actuel == JOUEUR)
{
evenement_hero();
}
if (comportement_actuel == AUCUN)
evenement_hero(false,false);
}
int Perso::collision()
{
for (int i =0;i<=dernier_objet;i++)
{ //debut boucle
if (i != element_actuel && Objets[i] != NULL && Objets[i]->nb_diffusion == RMXP){ //début condition
if(((Objets[i]->position.x + Objets[i]->image->w/4 > position.x) && (Objets[i]->position.x < position.x + image->w/4)) &&((Objets[i]->position.y + Objets[i]->image->h/4 > position.y) && (Objets[0]->position.y < position.y + image->h/4)));
if ((Objets[i]->position.x + Objets[i]->image->w/4 > position.x) && (Objets[i]->position.x < position.x + image->w/4))
{
if (direction == BAS)
if ((Objets[i]->position.y + Objets[i]->image->h/4 > position.y + vitesse) && (Objets[i]->position.y < position.y + image->h/4 + vitesse))
return P_COLLISION;
if (direction == HAUT)
if ((Objets[i]->position.y + Objets[i]->image->h/4 > position.y - vitesse) && (Objets[i]->position.y < position.y + image->h/4 - vitesse))
return P_COLLISION;
}
if ((Objets[i]->position.y + Objets[i]->image->h/4 > position.y ) && (Objets[i]->position.y < position.y + image->h/4))
{
if (direction == DROITE)
if ((Objets[i]->position.x + Objets[i]->image->w/4 > position.x + vitesse) && (Objets[i]->position.x < position.x + image->w/4 + vitesse))
return P_COLLISION;
if (direction == GAUCHE)
if ((Objets[i]->position.x + Objets[i]->image->w/4 > position.x - vitesse) && (Objets[i]->position.x < position.x + image->w/4 - vitesse))
return P_COLLISION;
}
} //fin condition
} //fin boucle
}//fin fonction
int Perso::collisionEvent(Perso *Event)
{
if (Event != NULL){ //début condition
if(((Event->position.x + Event->image->w/4 > position.x) && (Event->position.x < position.x + image->w/4)) &&((Event->position.y + Event->image->h/4 > position.y) && (Event->position.y < position.y + image->h/4)));
if ((Event->position.x + Event->image->w/4 > position.x) && (Event->position.x < position.x + image->w/4))
{
if (direction == BAS)
if ((Event->position.y + Event->image->h/4 > position.y + vitesse) && (Event->position.y < position.y + image->h/4 + vitesse))
return P_COLLISION;
if (direction == HAUT)
if ((Event->position.y + Event->image->h/4 > position.y - vitesse) && (Event->position.y < position.y + image->h/4 - vitesse))
return P_COLLISION;
}
if ((Event->position.y + Event->image->h/4 > position.y ) && (Event->position.y < position.y + image->h/4))
{
if (direction == DROITE)
if ((Event->position.x + Event->image->w/4 > position.x + vitesse) && (Event->position.x < position.x + image->w/4 + vitesse))
return P_COLLISION;
if (direction == GAUCHE)
if ((Event->position.x + Event->image->w/4 > position.x - vitesse) && (Event->position.x < position.x + image->w/4 - vitesse))
return P_COLLISION;
}
} // fin condition
}
Perso Nulos("charset2.bmp"); // pour un element de type RMXP
Perso ogre("charset_rm2000.png",RM2000,2,1);// Pour un element de type RM2000, il prend en compte l´image(charset2.bmp) , son type, (RM2000), et enfin sa position dans la trame x( 0 pour le premier et 1 pour le deuxieme etc... /* si vous depassez 3 il y aura pas ´image visible attention */) et dans la trame y ( pareil sauf qu´il faut pas depasser 1)
/*PS: vous verrez surement des variables inutiliser dans la classe, c´est que j´ai pas encore eu le temps de les utiliser. La classe est aussi faite pour être modifié pour le type de jeu utilisé, le tout avec les objet que vous utilisez c´est de faire bien attention de ne pas les iniatliser dans la boucle principale, mais juste avant */
/*PPS : si vous avez des idées pour l´amélioré n´hésitez pas^^!*/