Tom's Guide > Forum > Programmation > Cherche aide pour "animation" de Sprites en C, avec SDL

Cherche aide pour "animation" de Sprites en C, avec SDL

Forum Programmation : Cherche aide pour "animation" de Sprites en C, avec SDL

TomsGuide.com : 800 000 inscrits répondent à toutes vos questions high-tech et informatique. Pour obtenir de l'aide, inscrivez-vous gratuitement !
Mot :    Pseudo :           
 

Salut salut ^^, svp j'aimerai savoir comment avoir l'effet d'un personnage qui marche (le verbe lol) lorsqu'on appui sur une touche spécifique, j'utilise la librairie SDL, voici un bout de mon code,( dsl je sais pas comment lui mettre que c'est un code en C pr laffichage, vous pourrez copier le texte sur votre IDE ) merci ;-)

#include <stdlib.h>
#include <stdio.h>
#include <SDL/SDL.h>
#include <fmod.h>
#include <SDL/SDL_ttf.h>
#include "mouvements.h"
#include "jeu.h"



void mouvements(SDL_Surface* ecran)
{
int continuer = 1;

SDL_Event event;
SDL_EnableKeyRepeat(100, 100);
SDL_Surface *yuri1 = NULL, *yuri2 = NULL, *yuri3 = NULL, *yuri4 = NULL, *Fond = NULL;

SDL_Rect positionyuri;

positionyuri.x = 50;
positionyuri.y = 404;

SDL_Rect positionFond;

positionFond.x = 0;
positionFond.y = 0;


Fond = SDL_LoadBMP("maptest.bmp" );
yuri4 = SDL_LoadBMP("yuri4.bmp" );
yuri3 = SDL_LoadBMP("yuri3.bmp" );
yuri2 = SDL_LoadBMP("yuri2.bmp" );
yuri1 = SDL_LoadBMP("yuri1.bmp" );

SDL_SetColorKey(yuri1, SDL_SRCCOLORKEY, SDL_MapRGB(yuri1->format, 255, 255, 255));
SDL_BlitSurface(yuri1, NULL, ecran, &positionyuri);


while (continuer)
{
SDL_PollEvent(&event);
switch(event.type)
{
case SDL_QUIT:
continuer = 0;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_ESCAPE: /* Appui sur la touche Echap, on arrête le programme */
continuer = 0;
break;
}
switch (event.key.keysym.sym)
{
//Déplacements du persos
case SDLK_UP: // Flèche haut
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri1, NULL, ecran, &positionyuri);
SDL_Flip(ecran);
break;

case SDLK_RIGHT: // Flèche droite
//************C'est ici ou j'ai besoin d'aide, je veux que mon perso ai un effet de marcher ou courir
//quand j'appui sur la fleche droite, oui j'ai plusieurs sprites de ce dernier avec une distance entre les pieds qui vari
//mais le probleme et que je n'arrive pas a lui donner cet effet de "courir" en les chargeant et affichant:
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_SetColorKey(yuri4, SDL_SRCCOLORKEY, SDL_MapRGB(yuri4->format, 255, 255, 255));
SDL_BlitSurface(yuri4, NULL, ecran, &positionyuri);
positionyuri.x+=2;
SDL_Flip(ecran);
break;

case SDLK_LEFT: // Flèche gauche
positionyuri.x-=2;
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri1, NULL, ecran, &positionyuri);
SDL_Flip(ecran);
break;
}
break;



case SDL_KEYUP :
switch (event.key.keysym.sym)
{
case SDLK_RIGHT:
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_SetColorKey(yuri1, SDL_SRCCOLORKEY, SDL_MapRGB(yuri1->format, 255, 255, 255));
SDL_BlitSurface(yuri1, NULL, ecran, &positionyuri);
SDL_Flip(ecran);
break;

}
break;


SDL_FillRect(ecran, NULL, SDL_MapRGB(ecran->format, 255, 255, 255));
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri1, NULL, ecran, &positionyuri);
SDL_BlitSurface(yuri3, NULL, ecran, &positionyuri);
SDL_BlitSurface(yuri4, NULL, ecran, &positionyuri);


SDL_Flip(ecran);
SDL_FreeSurface(yuri3);
SDL_FreeSurface(yuri4);
SDL_FreeSurface(yuri1);
SDL_FreeSurface(Fond);
}
}
}

Merci bcp pour votre aide ;)

Liens sponsorisés
Inscrivez-vous ou connectez-vous pour masquer ceci.

Déjà, une petite remarque : c'est pas très très joli de définir 4 surfaces séparément pour Yuri séparément... Tu ne pourrais pas faire un tableau ? Du style :

---------------------------------------
SDL_Surface* Yuri[4];
---------------------------------------

Ensuite, pour faire avancer ton perso, tu peux utiliser ceci :

---------------------------------------
for( char i = 0 ; i < 4 ; i++ )
{
SDL_BlitSurface(yuri[i], NULL, ecran, &positionyuri);
SDL_Flip(ecran);
}
---------------------------------------

Essaye alors le résultat.

Répondre à Sethpolma

A merci bcp pour ta reponse ;) c'est vrai je n'avais pas encore atteint les cours sur les tableaux, mais maintenant je trouve que c'est plus pratique ^^ ; j'essaye et vs tient au courant, encore merci.

Répondre à othmanes007

Sinon je peux aussi faire for ( i = 0 ....
a la place de for ( char i = 0... ?

Répondre à othmanes007

Bah la, la variable est juste déclarée dans la boucle (en C89, les variables doivent etre declarees en debut de bloc)

int main(void)
{
int i;
.....

for (i = 0; i < 9; i++)
{
....
}
return 0;
}

Répondre à tebonb

Merci, sinon meme apres avoir changé mon code, j'ai toujours le meme probleme, le perso n'est pas animé; ou plutot, il est animé a une vitesse tres tres haute, resultat, il clignotte !

Répondre à othmanes007

Ca yé j'ai reussi, JAI REUSSI !!!!!!!!!!!!!!!!!!!!!!
je fais quelques modif et vs donne le code ;)

Répondre à othmanes007

Tu peux mettre en place un timer (fonction SDL_getTicks() il me semble... le SDL est bien loin maintenant).

Répondre à Sethpolma

oui justement je lai fait avec des timers et SDL_GetTicks();
sinon svp jai un autre ptit probleme, je voudrai afficher une image progressivement, j'ai pensé a utiliser le setalpha, mais puisque c un peu chiant d'ecrire la fonction 255 fois, j'ai fait ça :

int i;

for( i = 0 ; i <= 255 ; i+=1 )
{

SDL_Delay(30);

SDL_SetAlpha(createdby, SDL_SRCALPHA, i);
SDL_BlitSurface(imageDeFond, NULL, ecran, &positionFond);
SDL_BlitSurface(createdby, NULL, ecran, &positionCreatedby);
SDL_Flip(ecran);

}

l'effet d'apparition progressive du texte est tres convainctant, mais le probleme :s, c'est la boucle infinie... je peux plus fermer mon programme qu'avec ctrl+alt+supr, que faire pour remedier à cela svp ?

Répondre à othmanes007

La boucle infinie ? Quelle boucle infinie ? Tout à l'air correct ici pourtant... Ta variable est incrémentée à chaque parcours de la boucle, et on passe bien à la valeur 255. Tu es sûr que c'est d'ici que vient le problème ? Essayes de commenter cette partie du code pour voir si cela résoud le problème ou non.

Répondre à Sethpolma

Excusez moi je suis vraiment dsl , c'est pas exactement ds ce code parceque quand je le teste seul jarrive a quitter, mais quand je teste ds tout mon programme j'y arrive pas, est-ce parceque apres cette fonction je fais appel a un autre fichier ? (jouer(ecran);) et que dans ce fichier jai encore la boucle for pour avoir le meme effet ?

En tout cas en testant tout le programme, jarrive pas a quitter une fois que je suis dans "jouer" :p.

Répondre à othmanes007

Il ne faut pas faire de boucle dans ta fonction jouer() car ces boucles ne gèrent pas la gestion SDL clavier et autres.
Pour tout ce qui est boucles, tu dois utiliser une astuce avec la boucle des messages SDL. Cette boucle est la boucle prncipale de ton programme.

Répondre à CRicky

:o Desolé j'ai trouvé d'ou provenait le probleme ... ma boucle while qui gerait les evenements :p merci bcp pr votre aide ;) sinon un autre tite question :D quelle est la meilleure façon de faire sauter un perso , j'ai fait ça :

case SDLK_UP:

positionyuri.y-=8;

SDL_SetColorKey(yuri[INITIAL], SDL_SRCCOLORKEY, SDL_MapRGB(yuri[INITIAL]->format, 255, 255, 255));
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri[INITIAL], NULL, ecran, &positionyuri);
SDL_Flip(ecran);
SDL_Delay(20);

mais le perso va jusqu'à l'extremité de l'ecran(y), alors que j'aimerai qu'il sarrete apres quelques pixels ( et pourquoi pas qu'il revienne a sa position.y initial pour avoir l'effet d'un saut ), j'ai essayé avec tout ce que je connais sans y arriver ;-) Je suis encore débutant merci bcp pr votre aide ;-)
(la resolution de l'ecran que j'ai choisi est 800*600)

Répondre à othmanes007

Bon j'en ai fait quelques uns alors je te donnes quelques pistes ;-)
La gravité ça donne quelque chose de parabolique.
Donc, pour ton jeu:
- soit tu fais le petit calcul de y au cours du temps
- soit tu ne fait pas vraiment une parabole mais un truc qui y ressemble.

Pour le 2ème point (le plus simple je pense), je te suggère ceci:
1. Sur l'appui d'une touchen mémoriser le fait que l'on effectue un saut:
int saut; mis à 0 si on ne saute pas et mis à 1 si l'on saute:

Code :
  1. // init: on saute pas
  2. int saut = 0;
  3. ...
  4. case SDLK_UP:
  5.   if( !saut )
  6.   {
  7.       // Si on n'est pas en train de faire un saut précédent
  8.       // On fait un nouveau saut, alors on saute
  9.       saut = 1;
  10.   }



Ensuite pour faire un saut joli, au lieu de faire un décalage de 8 pixels, on commence par 8 et on diminue jusqu'à -8. Comme ça, ça monte jusqu'à atteindre 0, puis ça redescend jusqu'à -8.
Pour cela, tu peut utiliser une variable (par exemple int decalage;) pour faire la variation du saut.

Dans ce cas, à chaque saut, tu dois tu doit remettre le compteur décalage à sa valeur initial (c'est-à-dire remettre dealage à 8 à chaque nouveau saut):

Code :
  1. // init: on saute pas
  2. int saut = 0;
  3. int decalage = 8;
  4. ...
  5. case SDLK_UP:
  6.   if( !saut )
  7.   {
  8.       // Si on n'est pas en train de faire un saut précédent
  9.       // On fait un nouveau saut, alors on saute
  10.       saut = 1;
  11.       decalage = 8;
  12.   }



plus propre:

Code :
  1. #define DECALAGE_INITIAL 8
  2. // init: on saute pas
  3. int saut = 0;
  4. int decalage = DECALAGE_INITIAL;
  5. ...
  6. case SDLK_UP:
  7.   if( !saut )
  8.   {
  9.       // Si on n'est pas en train de faire un saut précédent
  10.       // On fait un nouveau saut, alors on saute
  11.       saut = 1;
  12.       decalage = DECALAGE_INITIAL;
  13.   }



Ensuite, tu effectues le saut dans ta boucle de message, mais en dehors du traitement des messages !
En faisant cela, que l'on appuie sur une touche ou pas, le saut se termine (après tout, l'impulsion est déjà faite, et la gravité n'est pas déclenchée par l'appuie d'une touche ;-) ).
Bref, en dehors de la gestion des évènements, tu sais si le bonhomme fait un saut ou pas grace à la variable "saut". Donc, là tu fait le saut avec le décalage. Et, en même temps, tu fais baisser le décalage.

Code :
  1. // Après le switch case, mais dans la boucle
  2. // On teste si le joueur effectue un saut
  3.   if( saut )
  4.   {
  5.       // c'est le cas ici
  6.       // on fait bouger le joueur selon le décalage
  7.       positionyuri.y -= decalage;
  8.       // On teste si le joueur a retouché le sol
  9.       if (positionyuri.y >= positionSol)
  10.       {
  11.         // On repositionne le joueur sur le sol (car il se peut qu'il ait dépassé de quelques pixels)
  12.         positionyuri.y = positionSol;
  13.         // Et surtout, on arrête le saut !
  14.         saut = 0;
  15.       }
  16.       // on fait ralentir la montée, voire accélérer la descente
  17.       decalage -= 1;
  18.   }



Pour ce dernier bout de code, il faut penser à utiliser un timer (http://www.libsdl.org/intro.fr/usingtimersfr.html), car, sinon ça sera très très rapide ;-)
Ceci en utilisant SDL_GetTicks() et pas SDL_Delay().
D'ailleurs, il faut éviter au maximum d'utiliser SDL_Delay(), car s'il bloque les évènements et que tu les accumules, le programme mettra du temps à réagir au touches.

J'ai fait ce post rapidement, sans relire, alors s'il y a un truc bizarre ou mal expliqué faut dire :-D

Répondre à CRicky

Salut merci bcp pour tes reponses et d'avoir pri le temps d'écrire ce code c'est tres sympa ;-) ... mais je sais pas pourquoi le perso ne s'arrete pas de sauter meme s'il y a saut=0; bizarre ?

Répondre à othmanes007

:-D c'est bon j'ai pu le faire :

while (positionyuri.y >= 10 && (positionyuriyinitial - positionyuri.y) < 100) // quand le personnage monte
{
positionyuri.y-=2;
SDL_SetColorKey(yuri[INITIAL], SDL_SRCCOLORKEY, SDL_MapRGB(yuri[INITIAL]->format, 255, 255, 255));
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri[INITIAL], NULL, ecran, &positionyuri);
SDL_Flip(ecran);
}
while (positionyuri.y <= 403) // quand le personnage redescend
{
positionyuri.y+=3;
SDL_SetColorKey(yuri[INITIAL], SDL_SRCCOLORKEY, SDL_MapRGB(yuri[INITIAL]->format, 255, 255, 255));
SDL_BlitSurface(Fond, NULL, ecran, &positionFond);
SDL_BlitSurface(yuri[INITIAL], NULL, ecran, &positionyuri);
SDL_Flip(ecran);
}


cette fois il saute si je clique sur le fleche de haut, arrivé a une hauteur precise il redescent, et meme si pendant sa montée le joueur clique sur la fleche haute, il ne ressaute pas :) , voila vai ajouter un vecteur vitesse qui diminu en montant et augmente en descendant pour avoir un effet plus realiste ;-)
...:s difficile a faire lol, Merci.

Répondre à othmanes007

Slt , j'ai pour projet de créer un jeu style gta avec SDL comme toi!
Au debut je voulais le faire en 3D (du faux) c'est à dire que on gere un personnage 2D sur un décor 2D en perspective.

mais le manque de décor ma limité a un jeu 2D (pour le moment)

j'ai aussi un autre probleme:
j'ai chercher de sprites , j'en ai trouver un exelent mais que de TONY , dnc sa ma bloquer!

ps: pour la gestion des collision , j'ai écrit ce qui avait droit de faire:

(j'écri juste un bout de la boucle while)

case SDLK_RIGHT:

if(positionTony.x < positionVoiture.x) //tony peut à marcher vers la droite tant qu'il est avant la voiture
{


mouv++;
positionTony.x++;

if(mouv = 1)
{

Tony = SDL_LoadBMP("GtaSprites/Tony/TonyDroite1.bmp" )

}

if(mouv = 2)
{

Tony = SDL_LoadBMP("GtaSprites/Tony/TonyDroite2.bmp" )
mouv = 0;
}

}

Mon code est plus complexe car il gere plusieur objet de différent type et pour faire un mouvement il y a plus que 2 sprites


Revenons a mon probleme:
comme je ne trouve pas assez de sprites jaimerais les créer moi meme!
y a t'il un logiciel gratuis ou payant qui me permetteré de créer des perso et des décor , si possible 3D!

msn:
Axeel@skyrock.fm

Répondre à Anonyme
Tom's Guide > Forum > Programmation > Cherche aide pour "animation" de Sprites en C, avec SDL
Aller à :

Il y a 284 utilisateurs connus et inconnus. Pour voir la liste des connectés connus, cliquez ici.

Attention

Vous allez répondre sur un sujet resté inactif pendant plus de 6 mois.
Assurez-vous d'apporter des éléments nouveaux à la discussion avant de poursuivre.

Répondre Annuler
Liens