Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » How keep text on the screen?

This thread is locked; no one can reply to it. rss feed Print
How keep text on the screen?
Gustavo Boni
Member #7,653
August 2006

Hi all, sorry for the double post, but i'm new with Allegro and the doubts just come pop upping.

I'm using an First State Machine in my game, and i have some states for the character like eating, sleeping, etc. When the character enter in the state sleeping for example, i need to write an text on the screen:

textout(buffer,font,"I'm very tired, i need to sleep",0,0,makecol(255,255,255));

The problem is the text is not showing on the screen like i want, it's blinking on the screen.

How can i fix this? :-/

Thanks.

GameCreator
Member #2,541
July 2002
avatar

Care to share that portion of your code? I suspect that you're not using double-buffering and are clearing the screen at an inappropriate time.

Gustavo Boni
Member #7,653
August 2006

1void timer(void)
2{
3 countSpeed++;
4}
5END_OF_FUNCTION(timer);
6 
7int main()
8{
9 start(); //inicialize the allegro things
10 
11 while(!key[KEY_ESC])
12 {
13 while (countSpeed > 0)
14 {
15 warrior->start(); //Start the Character (the state machine)
16 
17 double_buffering();
18 
19 countSpeed--;
20 }
21 }
22}
23 
24void double_buffering()
25{
26 /*Coloca o buufer na tela*/
27 blit(buffer,screen,0,0,0,0,640,480);
28 
29 /*Linmpa o buffer*/
30 clear(buffer);
31}

That's it.

Thanks

ReyBrujo
Moderator
January 2001
avatar

You are cleaning the buffer every loop. Are you also writting the text every loop?

--
RB
光子「あたしただ…奪う側に回ろうと思っただけよ」
Mitsuko's last words, Battle Royale

Michael Faerber
Member #4,800
July 2004
avatar

Should be something like this:

1int main()
2{
3 start(); //inicialize the allegro things
4 
5 while(!key[KEY_ESC])
6 {
7 while (countSpeed > 0)
8 {
9 warrior->start(); //Start the Character (the state machine)
10 
11 countSpeed--;
12 }
13 
14 double_buffering();
15 }
16}

[EDIT]
The main change is moving the drawing code outside the logic loop.

--
"The basic of informatics is Microsoft Office." - An informatics teacher in our school
"Do you know Linux?" "Linux? Isn't that something for visually impaired people?"

Gustavo Boni
Member #7,653
August 2006

ReyBrujo said:

You are cleaning the buffer every loop. Are you also writting the text every loop?

No, when i enter in a state, a text must be written on the screen and keep there. So, i just write this in that moment, not every loop.

Michael Faerber said:

Should be something like this:

int main()
{
start(); //inicialize the allegro things

while(!key[KEY_ESC])
{
while (countSpeed > 0)
{
warrior->start(); //Start the Character (the state machine)

countSpeed--;
}

double_buffering();
}
}

The main change is moving the drawing code outside the logic loop.

Now it's better, the text still flicking but i can see this for more time. Maybe the problem is i'm not wrtting the text every loop like ReyBrujo asked.

GameCreator
Member #2,541
July 2002
avatar

Do you do a clear anywhere in your warrior->start()?

KnightWhoSaysNi
Member #7,339
June 2006
avatar

/*Coloca o buufer na tela*/
blit(buffer,screen,0,0,0,0,640,480);

/*Linmpa o buffer*/
clear(buffer);

Switch these two things so it clears the buffer first and then blits.

Michael Faerber
Member #4,800
July 2004
avatar

Quote:

Switch these two things so it clears the buffer first and then blits.

Erm ... you are sure you know what you just suggested? That way it would always blit an empty (black) buffer to the screen!

Quote:

Do you do a clear anywhere in your warrior->start()?

Generally, do you do anything graphics related (blitting, clearing, drawing) in that function?
The best would be if you could post that function here. ;)

--
"The basic of informatics is Microsoft Office." - An informatics teacher in our school
"Do you know Linux?" "Linux? Isn't that something for visually impaired people?"

Gustavo Boni
Member #7,653
August 2006

GameCreator said:

Do you do a clear anywhere in your warrior->start()?

No, the only thing is the call textoutput inside.

Michael Faerber said:

Generally, do you do anything graphics related (blitting, clearing, drawing) in that function?
The best would be if you could post that function here. ;)

Ok, here it goes:

1void Sleeping::entry()
2{
3 //cout << "**************** DORMINDO *******************" << endl;
4 line(buffer,0,30,800,30,makecol(58,49,242));
5 pPersonagem->setFadiga(100);
6 textout(buffer,font,"Estou com sono. Vou dormir sem tomar banho e sem tirar as botas",0,0,makecol(255,255,255));
7 textout(buffer,font,"Zzzzzzzzzzzzzzzzzz. Pizza! Hmmm...",0,text_height(font)+5,makecol(255,255,255));
8 //cout << "Estou com sono. Vou dormir sem tomar banho e sem tirar as botas" << endl;
9 //cout << "Zzzzzzzzzzzzzzzzzz. Pizza! Hmmm..." << endl;
10 tempoSono = time(NULL);
11}
12 
13void Sleeping::exit()
14{
15 textout(buffer,font,"Jah!? Que saco! Tenho que levantar.",0,text_height(font)+10,makecol(255,255,255));
16 //cout << "**************** SAINDO DE 'DORMIR' *******************" << endl;
17}
18 
19int Sleeping::execute()
20{
21 if ((time(NULL) - tempoSono) >= totalSono)
22 {
23 return TRANSICAO_DORMIR_COMER;
24 }
25
26 return TRANSICAO_NAO_MUDA;
27}

When i call the warrior->start(); the start() function calls the Sleeping::entry().
Following it calls the execute() and later the exit(), so it goes to the next state. Each state is like this code. :)

[EDIT] Sorry guys, the name of some functions are in my language (Portuguese).

GameCreator
Member #2,541
July 2002
avatar

Since it should do the exact same thing, can you replace
warrior->start(); //Start the Character (the state machine)
with
textout(buffer,font,"Jah!? Que saco! Tenho que levantar.",0,text_height(font)+10,makecol(255,255,255));
and let us know if it still flickers?

BAF
Member #2,981
December 2002
avatar

He should do ALL the drawing at once, and not do any in the logic loop.

KnightWhoSaysNi
Member #7,339
June 2006
avatar

I meant:

clear(buffer);

drawstuffonbuffer()

blit(buffer,screen,0,0,0,0,640,480);

-Doft-
Member #7,309
June 2006

Have you tried writing the text every time? Something like:

void double_buffering()
{
        ...
        if (player->state == SLEEPING)
            textout(buffer,font,"I'm very tired, i need to sleep",0,0,makecol(255,255,255));
  blit(buffer,screen,0,0,0,0,640,480);
  clear(buffer);
        ...
}

Gustavo Boni
Member #7,653
August 2006

GameCreator said:

Since it should do the exact same thing, can you replace
warrior->start(); //Start the Character (the state machine)
with
textout(buffer,font,"Jah!? Que saco! Tenho que levantar.",0,text_height(font)+10,makecol(255,255,255));
and let us know if it still flickers?

Yes, it still flickers! :'(

[quote-Doft-]Have you tried writing the text every time?
</quote>

I can't because i will need to change all my code.

BAF
Member #2,981
December 2002
avatar

That's how you have to do it. You (in most cases) cannot draw in your logic loop like that without flickering.

[edit]
If you lock drawing AND logic to the timer you could but there's no point in doing that.

Gustavo Boni
Member #7,653
August 2006

BAF said:

That's how you have to do it. You (in most cases) cannot draw in your logic loop like that without flickering.

[edit]
If you lock drawing AND logic to the timer you could but there's no point in doing that.

Hm... :-/

Maybe i should change my project structure.

It would be better if there was in Allegro a function like cout << "Hello" << endl; i just need to show the message. :'(

BAF
Member #2,981
December 2002
avatar

Make a message system like that then... you set the message up and then have a manager which draws them when its time to draw.

Steve Terry
Member #1,989
March 2002
avatar

If it's not too complex to make the change make a text object part of your main character. If a string value is present then print that to the buffer, or alternatively set a flag but checking for NIL is just as easy. That way when the character needs to speak you set your text, and on drawing of the screen the text is printed, no need for a state for each text.

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Tobias Dammers
Member #2,604
August 2002
avatar

Quote:

checking for NIL is just as easy

C tends to call it NULL.

Anyway: Separate logic from drawing!
Put all the logic into a logic_update() function, and the drawing into another function. Call the appropriate one in the main loop. The drawing procedure is:
1. Clear back buffer
2. Draw scene (background first, then objects, then overlays)
3. Flip buffers, or blit back buffer to screen

The logic function must never touch any graphics routines, and must not call any function that does. Ideally, the logic function has no idea where to draw to (which is why the back buffer should not be a global var, but rather be maintained by the main loop or a dedicated module, and only passed to the drawing code).

The drawing function must not change any state of the game logic. In C++, an object's draw() function should be const. Regard the game logic as read-only in the drawing function.

---
Me make music: Triofobie
---
"We need Tobias and his awesome trombone, too." - Johan Halmén

Steve Terry
Member #1,989
March 2002
avatar

NULL is 0, same as NIL but NIL is represented by a character, namely '\0'... which is also 0 :P

___________________________________
[ Facebook ]
Microsoft is not the Borg collective. The Borg collective has got proper networking. - planetspace.de
Bill Gates is in fact Shawn Hargreaves' ßî+çh. - Gideon Weems

Go to: