Salut,
Me re-voila, avec une adaptation de
la fonction vague créé par Ac-Portugal, en C avec la SDL.
Bon, on commence par deux petit screen:

La fonction :typedef struct
{
float amplitude,
degree,
freq;
}Sinus;
Tout d'abord il va falloir ajouter cette structure Sinus.
Elle contient 3 float; amplitude, degree et freq.
//SDL.h, SDL_ttf.h ET math.h doivent être inclus
void WaveText(int _x, int _y, Sinus *_sinus, const char* _text, SDL_Surface *_source, TTF_Font *_font, SDL_Color _color)
Alors, les arguments:
- _x et _y pour la positions du texte.
- _sinus, pour ne pas avoir 3 arguments en plus (
) et pour différent calcul que nous verront plus tard. - _text contiendra le string à afficher.
- _source est la surface sur laquelle nous allons blitter le texte.
- _fond est la police que nous utiliserons pour le texte.
- _color est la couleur du texte.
SDL_Rect pos = {_x, _y};
int i = 0, textsize = strlen(_text);
for (i = 0; i < textsize; i++)
{
On déclare une variable pos de type SDL_Rect qui contient la position X et Y du texte.
Puis 2 int; i sera utilisé dans la boucle for et textsize contient la taille du texte.
Et puis on a notre boucle for.
char help[2] = {0};
help[0] = _text[i];
Un tableau de char utilisé pour la fonction TTF_RenderText_Blended. Cette fonction prend un const char* en argument et non un const char.
_sinus->degree = _sinus->degree >= 360 ? _sinus->degree - 360 : _sinus->degree;
On vérifie si l'angle n'est pas supérieur à 360. Si c'est le cas on retire 360 à degree, sinon on ne fait rien.
Ceci m'évite d'écrire un "if (_sinus->degree >= 360) blablabla", c'est bien plus simple comme ça.
pos.y += sinf(_sinus->degree * M_PI / 180.0) * _sinus->amplitude;
Maintenant on calcule la position Y ou sera affiché notre lettre.
Avec sinf on calcule le sinus et ensuite on le multiplie par _sinus->amplitude.
La position Y maximum qu'une lettre puisse avoir est pos.y + _sinus->amplitude et la position Y minimum est pos.y - amplitude.
SDL_Surface *text = NULL;
text = TTF_RenderText_Blended(_font, help, _color);
SDL_BlitSurface(text, NULL, _source, &pos);
On déclare notre surface, on l'initialise à NULL, on crée la surface qui contient la lettre et puis nous blittons cette surface sur la surface _source.
_sinus->degree += _sinus->freq;
pos.x += text->w;
pos.y = _y;
SDL_FreeSurface(text);
}
}
On incrémente la variable _sinus->degree par _sinus->freq.
Si _sinus->freq vaut 10 : screen 1
S'il vaut 20 : screen 2
Tout dépends de la taille du texte, donc a vous de voir la "freq" qui vous convient.
On ajoute la taille de la surface text à la position X comme ça on écrit pas les lettres les unes sur les autres.
Ensuite on re-initialise la position Y à _y, sinon le texte ne sera pas bien affiché.
Et on termine par libérer la surface text de la mémoire.
On ferme la boucle for et la fonction.
C'est tout

.
Voila, un sample à compiler. Utilisez les touches UP et DOWN (sur PC) pour augmenter ou diminuer l'amplitude.
#include <SDL/SDL.h>
#include <SDL/SDL_ttf.h>
#include <math.h>
#define SCR_H 272
#define SCR_W 480
#define OFFSET 2
typedef struct
{
float amplitude,
degree,
freq;
}Sinus;
void EventControl(int *_done, SDL_Event *_event, Sinus *_sinus)
{
SDL_PollEvent(_event);
switch(_event->type)
{
case SDL_QUIT:
*_done = 1;
break;
case SDL_KEYDOWN:
switch(_event->key.keysym.sym)
{
case SDLK_ESCAPE:
*_done = 1;
break;
case SDLK_SPACE:
*_done = 1;
break;
case SDLK_UP:
_sinus->amplitude += OFFSET;
_sinus->amplitude = _sinus->amplitude >= (SCR_H/2 - 15) ? (SCR_H/2 - 15) : _sinus->amplitude;
break;
case SDLK_DOWN:
_sinus->amplitude -= OFFSET;
_sinus->amplitude = _sinus->amplitude <= 0 ? 0 : _sinus->amplitude;
break;
}
break;
default:
*_done = 0;
}
}
void WaveText(int _x, int _y, Sinus *_sinus, const char* _text, SDL_Surface *_source, TTF_Font *_font, SDL_Color _color)
{
SDL_Rect pos = {_x, _y};
int i = 0, textsize = strlen(_text);
for (i = 0; i < textsize; i++)
{
char help[2] = {0};
help[0] = _text[i];
_sinus->degree = _sinus->degree >= 360 ? _sinus->degree - 360 : _sinus->degree;
pos.y += sinf(_sinus->degree * M_PI / 180.0) * _sinus->amplitude;
SDL_Surface *text = NULL;
text = TTF_RenderText_Blended(_font, help, _color);
SDL_BlitSurface(text, NULL, _source, &pos);
_sinus->degree += _sinus->freq;
pos.x += text->w;
pos.y = _y;
SDL_FreeSurface(text);
}
}
int main ( int argc, char** argv )
{
if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
{
printf( "Unable to init SDL: %s\n", SDL_GetError() );
return 1;
}
SDL_Surface* screen = SDL_SetVideoMode(480, 272, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
if (!screen)
{
printf("Unable to set 480x272 video: %s\n", SDL_GetError());
return 1;
}
TTF_Init();
TTF_Font *police = NULL;
police = TTF_OpenFont("Arial.ttf", 16);
SDL_Color color = {0xFF, 0, 0};
SDL_Event event;
int x = 100, y = 272/2, done = 0, start = 1, delay = 80, A = 0, P = 0;
Sinus sinus = {10.0, 0.0, 10.0};
char *texte = "Arial Wave Effect SDL Hello World";
while (!done)
{
A = SDL_GetTicks();
if (A - P > delay)
{
EventControl(&done, &event, &sinus);
SDL_FillRect(screen, NULL, 0);
WaveText(x, y, &sinus, texte, screen, police, color);
SDL_Flip(screen);
P = A;
}
else
SDL_Delay(delay - (A - P));
}
SDL_FreeSurface(screen);
SDL_Quit();
return 0;
}
C'est tout

,
A++