Se connecter / S'enregistrer
Votre question

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

Tags :
  • Programmation
Dernière réponse : dans Programmation
19 Juillet 2006 03:52:09

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 ;) 

Autres pages sur : cherche aide animation sprites sdl

19 Juillet 2006 11:57:01

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, NULL, ecran, &positionyuri);
SDL_Flip(ecran);
}
---------------------------------------

Essaye alors le résultat.
19 Juillet 2006 16:03:07

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.
Contenus similaires
19 Juillet 2006 16:04:24

Sinon je peux aussi faire for ( i = 0 ....
a la place de for ( char i = 0... ?
19 Juillet 2006 16:18:08

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;
}
19 Juillet 2006 16:21:49

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 !
19 Juillet 2006 17:04:20

Ca yé j'ai reussi, JAI REUSSI !!!!!!!!!!!!!!!!!!!!!!
je fais quelques modif et vs donne le code ;) 
19 Juillet 2006 18:05:59

Tu peux mettre en place un timer (fonction SDL_getTicks() il me semble... le SDL est bien loin maintenant).
21 Juillet 2006 07:38:20

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 ?
21 Juillet 2006 07:43:04

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.
21 Juillet 2006 08:15:02

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 .
a b L Programmation
21 Juillet 2006 12:57:23

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.
21 Juillet 2006 17:52:49

: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)
a b L Programmation
21 Juillet 2006 19:36:38

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:

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


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


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
22 Juillet 2006 04:40:03

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 ?
22 Juillet 2006 06:32:30

:-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.
Anonyme
25 Janvier 2009 11:33:47

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

8 Janvier 2010 15:26:46

Alors, je ne sais pas si cela va pouvoir aider (surtout que le précédent message date un peu ^^ !
Je crée actuellement un jeu en 2D avec SDL ! Je me suis aussi poser la question si je voulais faire ce jeu en 2D simple ou en 2D isométrique !

Différence 2D simple :
http://img13.imageshack.us/img13/4302/map2d.png

2D isométrique:
http://img502.imageshack.us/img502/4157/map2diso.png


Finalement j'ai choisit la 2D isométrique, mais il me restait à créer les blocs, ce qui n'était pas très simple : je faisais plusieurs transformations avec Gimp pour avoir un bloc isométrique utilisable !

J'ai donc appris à écrire un script-fu pour Gimp et j'ai ainsi créer un script qui converti en un clic une image carré (ou rectangulaire) en un bloc isométrique de 100x50 !

Exemple:

Avant la manip, j'ai ceci:
http://img121.imageshack.us/img121/3796/testto.png

Après avoir appliqué le script avec Gimp, j'obtiens :
http://img341.imageshack.us/img341/7282/testisom.png

(les bandes blanches me servent pour mon jeu: cela fait des cases sur la map)

Enfin bref, si ce script vous intéresse, le voici : http://dl.free.fr/pochED1NB

Il est à placer (par défaut) dans C:\Documents and Settings\MonCompte\.gimp-2.6\scripts
et s'utilise donc avec la version 2.6 de Gimp (la plus récente)!

Ce script apparait dans Gimp dans la barre de fonction lorsqu'il est installé (RPG/Bloc Map isométrique) !

Après, vous pouvez partir de ce script pour le modifier un peu afin de créer vos blocs personnalisés !
Si besoin d'aide, n'hésitez pas à me demander, sinon, j'espère avoir été utile ^^!
Tom's guide dans le monde
  • Allemagne
  • Italie
  • Irlande
  • Royaume Uni
  • Etats Unis
Suivre Tom's Guide
Inscrivez-vous à la Newsletter
  • ajouter à twitter
  • ajouter à facebook
  • ajouter un flux RSS