Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [a5] Problem with upgrade of images/text and loop

This thread is locked; no one can reply to it. rss feed Print
[a5] Problem with upgrade of images/text and loop
Jefferson Almeida
Member #12,659
March 2011

I tried to use "map_edit();" after of state2 == QUESTMODE; but did not work, appears only if I'm holding the ENTER and when I try add a new "if" or "switch", my screen stayed flashing between images and the text of map_edit().

void map_edit()
{
    bool passa = false;

    al_clear_to_color(al_map_rgb(0, 0, 0));

    font2 = al_load_ttf_font("DejaVuSans.ttf", 15, 0);
    al_draw_text(font2, al_map_rgb(255, 255, 255), 300, 300, 0, "Editor de Mapa Isometrico");
    al_draw_text(font2, al_map_rgb(255,255,255),300, 320, 0," Selecione o que deseja fazer");
    al_flip_display();
};

#SelectExpand
1bool redraw = true; 2while (!doexit) { 3 if (redraw) { 4 al_clear_to_color(al_map_rgb(0,0,0)); 5 al_draw_bitmap(remakelogo, 150, 150, 0); 6 al_draw_bitmap(credits, 120, 451, 0); 7 switch (state) { 8 case PRESSKEY : 9 myflasher.Draw(); 10 break; 11 case SHOWSTART : 12 al_clear_to_color(al_map_rgb(0,0,0)); 13 al_draw_bitmap(remakelogo, 150, 150, 0); 14 al_draw_bitmap(credits, 120, 451, 0); 15 16 al_draw_bitmap(newgame, 250, 280, 0); 17 al_draw_bitmap(continuar, 250, 296, 0); 18 al_draw_bitmap(questmode, 250, 312, 0); 19 al_draw_bitmap(quit, 250, 328, 0); 20 21 al_draw_bitmap(seta, 280, 395 + 16*menu_choice, 0 ); 22 break; 23 } 24 al_flip_display(); 25 redraw = false; 26 } 27 while (1) { 28 ALLEGRO_EVENT ev; 29 al_wait_for_event(event_queue , &ev); 30 switch (state) { 31 case PRESSKEY : 32 if (ev.type == ALLEGRO_EVENT_TIMER) { 33 myflasher.Update(1.0/FPS); 34 } else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 35 if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 36 state = SHOWSTART; 37 } 38 } 39 break; 40 case SHOWSTART : 41 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { 42 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 43 doexit = true; 44 } 45 else if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 46 if (menu_choice > 0) { 47 menu_choice--; 48 } 49 } 50 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 51 if (menu_choice < NUM_MENU_ITEMS-1) { 52 menu_choice++; 53 } 54 } 55 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { 56 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 57 } 58 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 59 } 60 else if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 61 switch (menu_choice) { 62 case 0 : 63 state2 = STARTNEWGAME; 64 case 1 : 65 state2 = LOADGAME; 66 break; 67 case 2 : 68 state2 = QUESTMODE; 69// map_edit(); 70 break; 71 case 3 : 72 doexit = true; 73 break; 74 } 75 } 76 } 77 } 78 } 79 if (ev.type == ALLEGRO_EVENT_TIMER) { 80 redraw = true; 81 } else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 82 doexit = true; 83 break; 84 } 85 if (al_is_event_queue_empty(event_queue)) {break;} 86 } 87} 88 return 0; 89} 90 91 92 93//END_OF_MAIN()

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

I tried to use "map_edit();" after of state2 == QUESTMODE; but did not work, appears only if I'm holding the ENTER and when I try add a new "if" or "switch", my screen stayed flashing between images and the text of map_edit().

Use a single state variable. In your if (redraw) {/*...*/}, check for the state there, and then call map_edit (which would be more appropriately named draw_map_editor_intro).

Use uma única variável de estado. Em sua if (redraw) {/*...*/}, para verificar o estado lá, e depois chamar map_edit (o que seria mais apropriadamente chamado draw_map_editor_intro).

Jefferson Almeida
Member #12,659
March 2011

I try something like:

if (redraw) {
   if (state2 == QUESTMODE){
   draw_map_editor_intro();
   }
...

but, did not work!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

Hi! I put everything into a single state but when they get to the part of the "menu_choice" I think happens any conflict.

enum GameState {
   PRESSKEY,
   SHOWSTART,
   STARTNEWGAME,
   LOADGAME,
   QUESTMODE
};

GameState state = PRESSKEY;

const int NUM_MENU_ITEMS = 4;
int menu_choice = 0;

I have to change the order of "case numbers" to work... but still gets all messy.
example, case 1: case: 2... etc

menu_choice code:

switch (menu_choice) {
                       case 0 :
                          state = STARTNEWGAME;
                          printf("teste...");
                       case 1 :
                          state = LOADGAME;
                       break;
                       case 2 :
                           state = QUESTMODE;
                       break;
                       case 3 :
                         doexit = true;
                       break;

ALL code!

#SelectExpand
1bool redraw = true; 2while (!doexit) { 3 if (redraw) { 4 al_clear_to_color(al_map_rgb(0,0,0)); 5 al_draw_bitmap(remakelogo, 150, 150, 0); 6 al_draw_bitmap(credits, 120, 451, 0); 7 switch (state) { 8 case PRESSKEY : 9 myflasher.Draw(); 10 break; 11 case SHOWSTART : 12 al_clear_to_color(al_map_rgb(0,0,0)); 13 al_draw_bitmap(remakelogo, 150, 150, 0); 14 al_draw_bitmap(credits, 120, 451, 0); 15 16 al_draw_bitmap(newgame, 250, 280, 0); 17 al_draw_bitmap(continuar, 250, 296, 0); 18 al_draw_bitmap(questmode, 250, 312, 0); 19 al_draw_bitmap(quit, 250, 328, 0); 20 21 al_draw_bitmap(seta, 280, 395 + 16*menu_choice, 0 ); 22 break; 23 } 24 al_flip_display(); 25 redraw = false; 26 } 27 while (1) { 28 ALLEGRO_EVENT ev; 29 al_wait_for_event(event_queue , &ev); 30 switch (state) { 31 case PRESSKEY : 32 if (ev.type == ALLEGRO_EVENT_TIMER) { 33 myflasher.Update(1.0/FPS); 34 } else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 35 if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 36 state = SHOWSTART; 37 } 38 } 39 break; 40 case SHOWSTART : 41 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { 42 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 43 doexit = true; 44 } 45 else if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 46 if (menu_choice > 0) { 47 menu_choice--; 48 } 49 } 50 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 51 if (menu_choice < NUM_MENU_ITEMS-1) { 52 menu_choice++; 53 } 54 } 55 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { 56 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 57 } 58 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 59 } 60 else if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 61 switch (menu_choice) { 62 case 0 : 63 state = STARTNEWGAME; 64 printf("teste..."); 65 case 1 : 66 state = LOADGAME; 67 break; 68 case 2 : 69 state = QUESTMODE; 70 break; 71 case 3 : 72 doexit = true; 73 break; 74 } 75 } 76 } 77 } 78 } 79 if (ev.type == ALLEGRO_EVENT_TIMER) { 80 redraw = true; 81 } else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 82 doexit = true; 83 break; 84 } 85 if (al_is_event_queue_empty(event_queue)) {break;} 86 } 87} 88 return 0; 89}

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Please start using consistent indentation in your code. It is really hard to read without it.

Por favor, começar a usar o recuo consistente em seu código. É realmente difícil de ler sem ele.

Don't check for the event type inside a block that has already checked the event type. You did this in your code, and the second if will never be executed :

Não verificar o tipo de evento dentro de um bloco que já verifiquei o tipo de evento. Você fez isso no seu código, eo segundo, se nunca vai ser executado:

if (ev.type == ALLEGRO_EVENT_KEY_CHAR) {
if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
} }

You're missing a break statement in case 0 of your switch (state) code :

Você está perdendo uma instrução break no caso de 0 a chave do código (estado):

                       case 0 :
                          state = STARTNEWGAME;
                          printf("teste...");
                          /// MISSING BREAK STATEMENT HERE!

I reformatted and fixed your code. I took out the bad if statements, added break statements where needed, and fixed all the indentation problems. If I have to reformat your code again, I will no longer help you. So, here it is :

Eu reformatado e fixa seu código. Tirei o ruim se as declarações, acrescentou quebrar declarações, quando necessário, e corrigiu todos os problemas de recuo. Se eu tiver que formatar o seu código novamente, eu não vou mais te ajudar. Então, aqui está :

#SelectExpand
1 2 3int main(int argc , char** argv) { 4 5///.................... 6 7 bool redraw = true; 8 while (!doexit) { 9 if (redraw) { 10 al_clear_to_color(al_map_rgb(0,0,0)); 11 al_draw_bitmap(remakelogo, 150, 150, 0); 12 al_draw_bitmap(credits, 120, 451, 0); 13 switch (state) { 14 case PRESSKEY : 15 myflasher.Draw(); 16 break; 17 case SHOWSTART : 18 al_clear_to_color(al_map_rgb(0,0,0)); 19 al_draw_bitmap(remakelogo, 150, 150, 0); 20 al_draw_bitmap(credits, 120, 451, 0); 21 22 al_draw_bitmap(newgame, 250, 280, 0); 23 al_draw_bitmap(continuar, 250, 296, 0); 24 al_draw_bitmap(questmode, 250, 312, 0); 25 al_draw_bitmap(quit, 250, 328, 0); 26 27 al_draw_bitmap(seta, 280, 395 + 16*menu_choice, 0 ); 28 break; 29 } 30 al_flip_display(); 31 redraw = false; 32 } 33 while (1) { 34 ALLEGRO_EVENT ev; 35 al_wait_for_event(event_queue , &ev); 36 switch (state) { 37 case PRESSKEY : 38 if (ev.type == ALLEGRO_EVENT_TIMER) { 39 myflasher.Update(1.0/FPS); 40 } else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 41 if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 42 state = SHOWSTART; 43 } 44 } 45 break; 46 case SHOWSTART : 47 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) { 48 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 49 doexit = true; 50 } 51 else if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 52 if (menu_choice > 0) { 53 menu_choice--; 54 } 55 } 56 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 57 if (menu_choice < NUM_MENU_ITEMS-1) { 58 menu_choice++; 59 } 60 } 61 else if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER) { 62 switch (menu_choice) { 63 case 0 : 64 state = STARTNEWGAME; 65 printf("teste..."); 66 break; 67 case 1 : 68 state = LOADGAME; 69 break; 70 case 2 : 71 state = QUESTMODE; 72 break; 73 case 3 : 74 doexit = true; 75 break; 76 } 77 } 78 } 79 break; 80 } 81 if (ev.type == ALLEGRO_EVENT_TIMER) { 82 redraw = true; 83 } else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 84 doexit = true; 85 } 86 if (al_is_event_queue_empty(event_queue)) {break;} 87 if (doexit) {break;} 88 } 89 } 90 return 0; 91}

Your code is getting really complex because of all the states it has to handle. I would suggest moving your code into a class. It will allow you to separate handling of different states in your code very easily :

Seu código está ficando muito complexo, porque de todos os estados tem que segurar. Eu sugiro mover o seu código em uma classe. Ele permitirá que você separe tratamento de estados diferentes no seu código muito facilmente:

#SelectExpand
1 2enum GameState { 3 PRESSKEY, 4 SHOWSTART, 5 STARTNEWGAME, 6 LOADGAME, 7 QUESTMODE 8}; 9 10class Game { 11private : 12 GameState state; 13 14 // Drawing for each state 15 void DrawPressKey(); 16 void DrawShowStart(); 17 void DrawStartNewGame(); 18 void DrawLoadGame(); 19 void DrawQuestMode(); 20 21 // input for each state 22 void CheckPressKeyInput(ALLEGRO_EVENT& ev); 23 void CheckShowStartInput(ALLEGRO_EVENT& ev); 24 void CheckStartNewGameInput(ALLEGRO_EVENT& ev); 25 void CheckLoadGameInput(ALLEGRO_EVENT& ev); 26 void CheckQuestModeInput(ALLEGRO_EVENT& ev); 27 28public : 29 bool quit; 30 bool redraw; 31 32 33 Game() : state(PRESSKEY) , quit(false) {} 34 35 void Draw() { 36 switch (state) { 37 case PRESSKEY : 38 DrawPressKey(); 39 break; 40 case SHOWSTART : 41 DrawShowStart(); 42 break; 43 case STARTNEWGAME : 44 DrawStartNewGame(); 45 break; 46 case LOADGAME : 47 DrawLoadGame(); 48 break; 49 case QUESTMODE : 50 DrawQuestMode(); 51 break; 52 } 53 } 54 55 void CheckInput(ALLEGRO_EVENT& ev) { 56 switch (state) { 57 case PRESSKEY : 58 CheckPressKeyInput(ev); 59 break; 60 case SHOWSTART : 61 CheckShowStartInput(ev); 62 break; 63 case STARTNEWGAME : 64 CheckStartNewGameInput(ev); 65 break; 66 case LOADGAME : 67 CheckLoadGameInput(ev); 68 break; 69 case QUESTMODE : 70 CheckQuestModeInput(ev); 71 break; 72 } 73 if ev.type == ALLEGRO_EVENT_TIMER) { 74 redraw = true; 75 } 76 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 77 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 78 quit = true; 79 } 80 } 81 else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 82 quit = true; 83 } 84 } 85}; 86 87int main() { 88 89 Game game; 90 91 while (!game.quit) { 92 if (game.redraw) { 93 game.Draw(); 94 } 95 while (!game.quit) { 96 ALLEGRO_EVENT ev; 97 al_wait_for_event(event_queue , &ev); 98 game.CheckInput(ev); 99 if (al_is_event_queue_empty(event_queue)) {break;} 100 } 101 } 102 103 return 0; 104}

See how much cleaner that is?

Veja como muito mais limpo que é isso?

Jefferson Almeida
Member #12,659
March 2011

Hi, thanks! sorry for not using consistent indentation... I did not know!

Really with class the code stayed much cleaner :)
I'm reading about class... My doubt is like I'll to use the DrawPressKey()...
I tryed but..

undefined reference to `Game::DrawPressKey()'|

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

Can you give me an example with one of the functions for I based me to do the rest?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

As an example :

void DrawPressKey() {
   al_clear_to_color(al_map_rgb(0,0,0));
   al_draw_bitmap(remakelogo, 150, 150, 0);
   al_draw_bitmap(credits, 120, 451, 0);
   myflasher.Draw();
   al_flip_display();
}

So now you will need to add your ALLEGRO_BITMAP*'s to your class, as well as your Flasher. That means you will need to load and free the ALLEGRO_BITMAP*'s in your class as well. You might want to load / free the ALLEGRO_BITMAP*'s based on your GameState too.

Então, agora você terá que adicionar o teu * ALLEGRO_BITMAP "para sua classe, bem como o seu pisca-pisca. Isso significa que você vai precisar carregar e livre é a * ALLEGRO_BITMAP "em sua classe também. Você pode querer carregar / grátis * ALLEGRO_BITMAP é baseado em seu estado de jogo também.

Jefferson Almeida
Member #12,659
March 2011

Thankful..., I get it to work, I just do not get the flasher, I have to put everything on class: "game" and remove the class Flasher?

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

My "myflasher.Update(1.0/FPS);" work, but my "myflasher.Draw();" makes the program crash :|

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

Yeah friend! If I put the myflasher.Draw() inside of the "void DrawPressKey() {" the program crash... if I put out of the void... do not work the flasher!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

The only reason al_draw_bitmap would fail is if you passed it NULL, or if you passed it an ALLEGRO_BITMAP* that was destroyed with al_destroy_bitmap.

Let's see (all) your code again.

O al_draw_bitmap única razão pela qual não é se você passou NULL, ou se você passou um * ALLEGRO_BITMAP que foi destruído com al_destroy_bitmap.

Vamos ver (tudo) o código novamente.

Jefferson Almeida
Member #12,659
March 2011

I had forgotten that detail, thanks! :)

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

The problem is that you define your Flasher myflasher before you load your ALLEGRO_BITMAP* that you pass to it. So you are passing an uninitialized ALLEGRO_BITMAP* to the Flasher constructor.

Solution 1 :
Don't create your myflasher object until after you initialize Allegro and load your ALLEGRO_BITMAP*. Then you would have to pass a reference to your myflasher object to your game object, and so you would have to add a Flasher* to your Game class.

Solution 2 :
Add a Flasher object to your Game class and initialize it in the Game class constructor initialization list (Don't create your game object until after Allegro is initialized and the flasher's ALLEGRO_BITMAP* is loaded).

Solution 3 :
Add a Flasher* to your Game class. Create your Flasher myflasher object after initializing Allegro and loading the necessary ALLEGRO_BITMAP. Set the Game::Flasher* to the address of your myflasher object.

O problema é que você define o seu myflasher Flasher antes de carregar o * ALLEGRO_BITMAP que você passar para ele. Então você está passando uma * ALLEGRO_BITMAP inicializada para o construtor Flasher.

Solução 1:
Não crie o seu objeto myflasher até depois de inicializar Allegro e carregar seu ALLEGRO_BITMAP *. Então você teria que passar uma referência ao seu objeto myflasher para o objeto do jogo, e assim você teria que adicionar um * pisca-pisca para a classe Game.

Solução 2:
Adicione um objeto Flasher para sua classe Game e inicializá-lo na lista de inicialização do construtor da classe Game (Não crie o seu objeto de jogo até depois Allegro é inicializado e * o pisca-pisca da ALLEGRO_BITMAP é carregado).

Solução 3:
Adicionar Flasher * a sua classe Game. Crie seu objeto myflasher Flasher Allegro após inicializar e carregar o ALLEGRO_BITMAP necessário. Defina o jogo:: Flasher * para o endereço do seu objeto myflasher.

Jefferson Almeida
Member #12,659
March 2011

I tryed the option 3 but do not work! I'll have coffee and then review the code! Thanks a lot!

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

An example of option 3 :

class Game {
private :
   Flasher* flasher;
   GameState state;
   bool redraw;
   bool quit;

public :
   Game() : flasher(0) , state(PRESSKEY) , redraw(true) , quit(false) {}

   void SetFlasher(Flasher* f) {flasher = f;}

///..... Same as before
};

And to use it :

// in main

// initialize allegro, load bitmaps

Flasher myflasher(bmp , 200 , 200 , 0.5);
Game game;
game.SetFlasher(&myflasher);

///..... Same as before

Jefferson Almeida
Member #12,659
March 2011

My code until was similar to yours, only a few details and the names
It is showing up: \ main.cpp | 98 | error: 'myflasher' was not declared in this scope |

#SelectExpand
1class Game { 2private : 3 Flasher* flasher; 4 GameState state; 5 6public : 7 bool quit; 8 bool redraw; 9 Game() : flasher(0) , state(PRESSKEY) , redraw(true) , quit(false) {} 10 11 void SetFlasher(Flasher* f) {flasher = f;} 12 13// as before 14}; 15 16// int main 17 18// allegro, load bitmaps... 19 20Flasher myflasher(bmp, 250, 320, 0.5); 21Game game; 22game.SetFlasher(&myflasher); 23 24// as before

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

It is showing up: \ main.cpp | 98 | error: 'myflasher' was not declared in this scope |

Huh? That's odd. Show all of your code again.

Actually, I bet the problem is inside the definition of your Game class methods. You need to refer to it as 'flasher' now, not 'myflasher', because the member is named 'flasher' :

   void CheckPressKeyInput(ALLEGRO_EVENT &ev) {
      if (ev.type == ALLEGRO_EVENT_TIMER) {
flasher->Update(1.0/FPS);
} else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { if (ev.keyboard.keycode == ALLEGRO_KEY_ENTER); state = SHOWSTART; } }

   void DrawPressKey() {
      al_clear_to_color(al_map_rgb(0,0,0));
      al_draw_bitmap(remakelogo, 150, 150, 0);
      al_draw_bitmap(credits, 120, 451, 0);
flasher->Draw();
al_flip_display(); }

Jefferson Almeida
Member #12,659
March 2011

oh... I changed and it worked, thanks

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

I had forgotten that detail, thanks! :)

Go to: