Bienvenue, Invité. Veuillez vous connecter ou vous inscrire.
Avez-vous perdu votre courriel d'activation?
Devsgen.com - Forums « Généralités « Codes en vrac « [SDL] Vague sur chaîne de caractères
Pages: [1]   Bas de page
  Imprimer  
Auteur Fil de discussion: [SDL] Vague sur chaîne de caractères  (Lu 149 fois)
0 Membres et 1 Invité sur ce fil de discussion.
pyroesp
Débutant
*
Hors ligne Hors ligne

Messages: 622


The Spanish Pyro


Voir le profil Courriel
« le: Juillet 30, 2010, 01:38:31 »

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 :

Code:
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.

Code:
//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 ( Clin d'oeil ) 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.
Code:
    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.

Code:
        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.

Code:
        _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.

Code:
        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.

Code:
        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.

Code:
        _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 Clin d'oeil.

Voila, un sample à compiler. Utilisez les touches UP et DOWN (sur PC) pour augmenter ou diminuer l'amplitude.

Code:
#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 Clin d'oeil,

A++
« Dernière édition: Juillet 30, 2010, 03:42:54 par pyroesp » Journalisée

There are only 10 types of people in this world:
  • Those who understand binary.
  • And those who don't.
seb
Pro
Débutant
***
Hors ligne Hors ligne

Messages: 368


Coding for fun


Voir le profil WWW
« Répondre #1 le: Juillet 30, 2010, 20:26:18 »

C'est un bon début ! Si tu veux t'amuser, ajoute un zoom sur chaque lettre et applique une sinusoide sur le facteur de zoom, et voilà (vers 4 min.):

http://www.youtube.com/watch?v=owEfNOvpaU8&feature=related
C'est le retour des 80s, j'approuve Grima&ccedil;ant
Journalisée
seb
Pro
Débutant
***
Hors ligne Hors ligne

Messages: 368


Coding for fun


Voir le profil WWW
« Répondre #2 le: Juillet 30, 2010, 21:05:42 »

Ah et puis zut...

u2.c
Code:
#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,
    init,
    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 _begin, SDL_Color _end)
{
    SDL_Rect pos = {_x, _y};
    int i = 0, textsize = strlen(_text);

    int dr =  (_end.r - _begin.r)/(textsize-1);
    int dg = (_end.g - _begin.g)/(textsize-1);
    int db = (_end.b - _begin.b)/(textsize-1);

    _sinus->degree = _sinus->init;

    for (i = 0; i < textsize; i++)
    {
        char help[2] = {0};
        help[0] = _text[i];

        SDL_Color new_c = {i * dr + _begin.r, i * dg + _begin.g, i * db + _begin.b};
        SDL_Rect final_pos;

        pos.y += sinf(_sinus->degree * M_PI / 180.0) * _sinus->amplitude;

        SDL_Surface *text = NULL;
        text = TTF_RenderText_Blended(_font, help, new_c);

        SDL_Surface *final = rotozoomSurface (text, 1.0, sinf(_sinus->degree * M_PI / 180.0) * 0.5 + 2.0, 0);
       
        final_pos.x = pos.x - final->w / 2;
        final_pos.y = pos.y - final->w / 2;

        SDL_BlitSurface(final, NULL, _source, &pos);

        _sinus->degree += _sinus->freq;
        _sinus->degree = _sinus->degree >= 360 ? _sinus->degree - 360 : _sinus->degree;
        pos.x += text->w * 2;
        pos.y = _y;

        SDL_FreeSurface(final);
        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 begin = {0xFF, 0, 0};
    SDL_Color end = {0, 0, 0xFF};
    SDL_Event event;

    int x = 30, y = 272/2, done = 0, start = 1, delay = 20, A = 0, P = 0;

    Sinus sinus = {10.0, 0.0, 0.0, 10.0};
    char *texte = "Arial Wave Effect SDL Hello";

    while (!done)
    {
        EventControl(&done, &event, &sinus);

        A = SDL_GetTicks();

        if (A - P > delay)
        {
            sinus.init += 5;
            sinus.init = sinus.init >= 360 ? sinus.init - 360 : sinus.init;
            SDL_FillRect(screen, NULL, 0);
            WaveText(x, y, &sinus, texte, screen, police, begin, end);
            SDL_Flip(screen);

            P = A;
        }
        else
            SDL_Delay(delay - (A - P));
    }

    SDL_FreeSurface(screen);
    SDL_Quit();

    return 0;
}

compile:
Code:
gcc u2.c -l SDL -l SDL_ttf -l SDL_gfx

SEB RULEZZZZ
Journalisée
pyroesp
Débutant
*
Hors ligne Hors ligne

Messages: 622


The Spanish Pyro


Voir le profil Courriel
« Répondre #3 le: Juillet 30, 2010, 21:57:18 »

Haha seb Souriant

merci pour le code Clin d'oeil
Journalisée

There are only 10 types of people in this world:
  • Those who understand binary.
  • And those who don't.
Geecko
Débutant
*
Hors ligne Hors ligne

Messages: 477



Voir le profil Courriel
« Répondre #4 le: Juillet 30, 2010, 23:27:04 »

J'vais essayer de mettre de l'intraFont là-dessus, en utilisant la rotation Sourire
Journalisée
pyroesp
Débutant
*
Hors ligne Hors ligne

Messages: 622


The Spanish Pyro


Voir le profil Courriel
« Répondre #5 le: Juillet 31, 2010, 03:32:52 »

Seb, j'ai vu un pti bug dans ton code:
Code:
        final_pos.x = pos.x - final->w / 2;
        final_pos.y = pos.y - final->w / 2;
devrait être :
Code:
        final_pos.x = pos.x - final->w / 2;
        final_pos.y = pos.y - final->h / 2;
...non ?


Et puis j'ai fait une fonction qui applique le sinus horizontalement, j'ai pas vraiment le temps de faire un mini tuto donc je balance juste un lien et un screen :

Lien vers code : http://pastebin.com/jMYs73Hh
 - Note : fleche haut et bas pour modifier l'amplitude et gauche et droite pour la fréquence.

Screen :


PS: Amusez-vous Clin d'oeil
Journalisée

There are only 10 types of people in this world:
  • Those who understand binary.
  • And those who don't.
Yonaba
Modérateur
Modérateur
Débutant
****
Hors ligne Hors ligne

Messages: 1432

Feel Alright

seanpaul223@live.fr
Voir le profil WWW
« Répondre #6 le: Juillet 31, 2010, 15:27:33 »

 Choqu&eacute; Choqu&eacute;

Beau travail...
Journalisée

Programming is binary.You're either 1 or 0
seb
Pro
Débutant
***
Hors ligne Hors ligne

Messages: 368


Coding for fun


Voir le profil WWW
« Répondre #7 le: Juillet 31, 2010, 17:43:25 »

...non ?

Si.

Il y'a aussi quelques bugs de ton coté  Clin d'oeil

- d'abord, faut que tu fasses l'eventcontrol systématiquement dans le boucle, sinon le programme est moins  réactif en fonction du délai.
- il te faut dé-corréler le début et la fin de ta sinusoide. Là t'as de la chance que ça tombe pas trop mal mais dès que t'essayes de changer le nombre de lettre ou de corriger textsize (voir ci dessous), c'est moche. 
- et enfin pour la version "horizontale", il te faut faire textsize = text->h, pas strlen (_text).

Bon, y'a plus qu'à combiner tout ça en un seul effet non ?  Clin d'oeil

edit:

http://www.box.net/shared/in1c1px64c
« Dernière édition: Juillet 31, 2010, 22:39:04 par seb » Journalisée
jiiceii
Invité
« Répondre #8 le: Août 04, 2010, 20:02:39 »

Està muy perfecto !  Souriant
Journalisée
pyroesp
Débutant
*
Hors ligne Hors ligne

Messages: 622


The Spanish Pyro


Voir le profil Courriel
« Répondre #9 le: Août 13, 2010, 20:34:52 »

Yop,

De retour de vacances en Espagne ( Bisou ), je commencerais par dire que le code horizontale a été fait à la va-vite xD, mais comme il marchait, je ne me suis pas trop cassé la tête.

Sinon, merci de m'avoir indiquer mes erreurs Seb Clin d'oeil
Journalisée

There are only 10 types of people in this world:
  • Those who understand binary.
  • And those who don't.
Geecko
Débutant
*
Hors ligne Hors ligne

Messages: 477



Voir le profil Courriel
« Répondre #10 le: Août 18, 2010, 00:55:05 »



Sample
intraFont-G

Edit: Seb, j'ai testé ton sample, c'est super Sourire
« Dernière édition: Août 18, 2010, 11:26:56 par Geecko » Journalisée
ac-portugal
Débutant
*
Hors ligne Hors ligne

Messages: 298



Voir le profil WWW Courriel
« Répondre #11 le: Août 18, 2010, 00:56:16 »

Wooow  Choqu&eacute;

Super Geecko  Souriant
Journalisée

Pages: [1]   Haut de page
  Imprimer  
 
Aller à: