|
From A4 to A5: questions (console window, key presses,timers/sprite animation) |
alex Ioan
Member #12,015
June 2010
|
Ok I managed to install and configure A5 on MSVS 2010... First question: Are these the good dll's I should be using if I want to distribute my game to other PCs ? Second question: I see A5 brings a console window with it every time I run the project, in debug and even in release. How can I remove the window in release only ? Third question: this is my A4 menu: how would this work in A5 ? I read about the events stuff but I can't seem to grasp the concept for single key presses like menu navigation. Oww and how can I get input from the user? I now use: 1string edittext;
2string::iterator iter = edittext.begin(); // string iterator
3int caret = 0; // tracking purposes yarr!
4bool insert = true;
5if (player.getname()=="")
6 {textout_ex( screen, blood, "ENTER YOUR NAME:", 100, 65, white,-1);
7 do {rest(1); while(keypressed())
8 { int newkey = readkey();
9 char ASCII = newkey & 0xff;
10 char scancode = newkey >> 8;
11
12 // a character key was pressed; add it to the string
13 if(ASCII >= 32 && ASCII <= 126)
14 { // add the new char, inserting or replacing as need be
15
16 if(insert || iter == edittext.end())
17 iter = edittext.insert(iter, ASCII);
18 else
19 edittext.replace(caret, 1, 1, ASCII);
20
21 // increment both the caret and the iterator
22 sound.playclick1();
23 caret++;
24 iter++;
25
26 }
27 // some other, "special" key was pressed; handle it here
28 else
29 switch(scancode)
30 { case KEY_DEL:
31 if(iter != edittext.end()) iter = edittext.erase(iter);
32 break;
33 case KEY_BACKSPACE:
34 if(iter != edittext.begin())
35 { sound.playclick2();
36 caret--;
37 iter--;
38 iter = edittext.erase(iter); }
39 break;
40 case KEY_RIGHT:
41 if(iter != edittext.end()) caret++, iter++;
42 break;
43 case KEY_LEFT:
44 if(iter != edittext.begin()) caret--, iter--;
45 break;
46 case KEY_INSERT:
47 if(insert) insert = 0; else insert = 1;
48 break;
49 default:
50 break; } }
51
52 clear(namebuffer);
53
54 textout(namebuffer, blood, edittext.c_str(), 100, 100, white);
55 blit(namebuffer, screen, 0, 0, 50, 90, 820, 240);
56
57 } while(!(key[KEY_ENTER]||key[KEY_ENTER_PAD]));
58 sound.playclick1();
59 player.nameset(edittext);}
This is to get the player's name and store in in a class... I really don't think it will work in A5... 4'th Question: 1void increment_speed_counter2()
2{speed_counter2++;}
3END_OF_FUNCTION(increment_speed_counter);
4
5LOCK_VARIABLE(speed_counter2);
6LOCK_FUNCTION(increment_speed_counter2);
7install_int_ex(increment_speed_counter2,BPS_TO_TIMER(100));
8
9while (speed_counter2 > 0)
10{if (key[KEY_UP]||key[KEY_W])
11 {player.move(8); } //this changes the player's X position via a class
12
13speed_counter2--; //this was the logic loop
14}
15
16if(player.Direction()==8)
17{} //drawing of sprite depending on what frame it is at.
18
19if(bla bla)
20{} //this is also where I do damage handling stuff, sounds etc
21
22if(drawingtoscreen==1)
23{draw all the different stuff on to a buffer then on to the screen.}
24}
so the question is... the same principle applies in A5 ? logic check then drawing stuff? That would be all , thanks in advance for your help
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
First off, please use consistent indentation - don't have code on the same line after an opening brace, line up code blocks, and indent every time you enter a new block. It makes it so much more pleasant to read (and help fix your problems). ALEXAROTH said: First question: Are these the good dll's I should be using if I want to distribute my game to other PCs ? If you're linking to the libraries that came with them, then yes those are the dll's you want to distribute with your program. ALEXAROTH said: Second question: I see A5 brings a console window with it every time I run the project, in debug and even in release. How can I remove the window in release only ? There should be a setting in MSVC that allows you to change whether the program is compiled as a console program or a graphical program. Look for subsystem::windowed or something like that in your settings. ALEXAROTH said:
If you want to know whether a key is up or down, there are two ways to detect this in Allegro 5. ALEXAROTH said:
Oww and how can I get input from the user? I now use: Use al_wait_for_event and check the event type for equivalence to ALLEGRO_EVENT_KEY_CHAR. It will work in A5 just fine... ALEXAROTH said:
4'th Question: Yes, in A5 you process events until there aren't any, and for each tick of the timer you process your logic and set a redraw flag. Then when you're done with all the events, you check your redraw flag and draw if necessary. ALEXAROTH said: That would be all , thanks in advance for your help
You'll probably want to look at several things from the manual : You should also take a look at the tutorials for A5 on the wiki, and the Porting guide from A4 to A5 on the wiki. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
alex Ioan
Member #12,015
June 2010
|
Thanks for the response ! I got the release version working without the console ! But I still can't figure out how to do the menu navigation... "Use al_wait_for_event and check the event type for equivalence to ALLEGRO_EVENT_KEY_CHAR." and what do to about int newkey = readkey(); ? and switch(scancode) 30 { case KEY_DEL: //....
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
1class Menu;
2
3class MenuItem {
4private :
5 int x;
6 int y;
7 int w;
8 int h;
9 string text;
10 Menu* submenu;
11public :
12 MenuItem(int xpos , int ypos , int width , int height , string textstr) :
13 x(xpos),
14 y(ypos),
15 w(width),
16 h(height),
17 text(textstr),
18 submenu(0)
19 {}
20 void SetPosition(int xpos , int ypos , int width , int height) {
21 x = xpos;
22 y = ypos;
23 w = width;
24 h = height;
25 if (submenu) {submenu->SetPosition(x + w , y);}
26 }
27}
28
29class Menu {
30private :
31 int x;
32 int y;
33 int w;
34 int h;
35 vector<MenuItem*> items;
36public :
37 Menu(int xpos , int ypos , int width , int height) :
38 x(xpos),
39 y(ypos),
40 w(width),
41 h(height),
42 items()
43 {}
44 void SetPosition(int xpos , int ypos) {
45 x = xpos;
46 y = ypos;
47 int ix = xpos;
48 int iy = ypos;
49 for (int i = 0 ; i < items.size() ; ++i) {
50 items[i]->SetPosition(ix , iy , w , h);
51 }
52 }
53}
54
55
56
57void MenuItem::SetMenu(Menu* menu) {
58 submenu = menu;
59 if (submenu) {submenu->SetPosition(x + w , y);}
60}
That should give you a basic idea of a setup for a menu. You'll have to implement hit checks and drawing yourself. ALEXAROTH said:
"Use al_wait_for_event and check the event type for equivalence to ALLEGRO_EVENT_KEY_CHAR." Yes, you can use al_is_event_queue_empty to check if there are any events in the queue. When you get a KEY_CHAR event, send the keycode and the unichar field to your input object to be processed. Check the keycode first to process things like left/right/backspace/delete and if the keycode wasn't used then check the unichar field. I'm not totally sure how unicode works, but I think you can get away with checking to see if the value is greater than or equal to 32 then I think it will be a printable character. You'll want to take a look at the ALLEGRO_USTR type. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
alex Ioan
Member #12,015
June 2010
|
1
2string edittext;
3string::iterator iter = edittext.begin();
4int caret = 0;
5bool insert = true;
6if (1)
7 {ALLEGRO_EVENT ev;
8 do { al_wait_for_event(event_queue, &ev);
9 if (ev.type == ALLEGRO_EVENT_KEY_CHAR)
10 {
11 int newkey = ev.keyboard.unichar;
12 char ASCII = newkey & 0xff;
13 char scancode = ev.keyboard.keycode;
14
15 // a character key was pressed; add it to the string
16 if(ASCII >= 32 && ASCII <= 126)
17 { // add the new char, inserting or replacing as need be
18
19 if(insert || iter == edittext.end())
20 iter = edittext.insert(iter, ASCII);
21 else
22 edittext.replace(caret, 1, 1, ASCII);
23
24 // increment both the caret and the iterator
25
26 caret++;
27 iter++;
28
29 }
30 // some other, "special" key was pressed; handle it here
31 else
32 switch(scancode)
33 { case ALLEGRO_KEY_DELETE:
34 if(iter != edittext.end()) iter = edittext.erase(iter);
35 break;
36 case ALLEGRO_KEY_BACKSPACE:
37 if(iter != edittext.begin())
38 {
39 caret--;
40 iter--;
41 iter = edittext.erase(iter); }
42 break;
43 case ALLEGRO_KEY_RIGHT:
44 if(iter != edittext.end()) caret++, iter++;
45 break;
46 case ALLEGRO_KEY_LEFT:
47 if(iter != edittext.begin()) caret--, iter--;
48 break;
49 case ALLEGRO_KEY_INSERT:
50 if(insert) insert = 0; else insert = 1;
51 break;
52 default:
53 break; } }
54
55
56
57 al_draw_text(font, al_map_rgb(255,255,255), 20,20,ALLEGRO_ALIGN_LEFT,edittext.c_str());
58
59 al_flip_display();
60 } while(1);
EDIT: Code above works quite well ! new question:
|
AMCerasoli
Member #11,955
May 2010
|
You need to send an ALLEGRO_SAMPLE_ID, not just an ALLEGRO_SAMPLE. When you play a sample using al_play_sample(ALLEGRO_SAMPLE *spl, float gain, float pan, float speed, ALLEGRO_PLAYMODE loop, ALLEGRO_SAMPLE_ID *ret_id) you need to set an ALLEGRO_SAMPLE_ID. ALLEGRO_SAMPLE_ID * id; al_play_sample(spl, 1, 0, 1, 1, id); al_stop_sample(id);
|
Matthew Leverton
Supreme Loser
January 1999
|
The reason is that you can call al_play_sample() many times on the same sample, so the id distinguishes those. Technically there's some misnomers with the function names, but I think they are easier to understand misnamed. |
alex Ioan
Member #12,015
June 2010
|
another question: why can't I draw text onto a bitmap anymore ? how could I do that ? and: how can I pass arguments ? al_draw_text( font, l_map_rgb(255,255,255), 210,-1,ALLEGRO_ALIGN_LEFT,"You are now level %d",level); } and a bonus one: is masked_blit gone ? like, the concept of it also what does al_clear_to_color clear ? the screen ? how can I make it clear a specified bitmap ? //done note that I have read the A5 tutorials but they don't provide any info on this EDIT: got the set target function.. but why complicate things ? anyway
|
Matthew Leverton
Supreme Loser
January 1999
|
See al_draw_textf(). The alpha component with the default blender automatically gives you masked_blits. So all you need to do is load a PNG file and those pixels with alpha=0 will be skipped. A convenience method is provided al_convert_mask_to_alpha() that converts the old pink style bitmaps to an alpha-ready bitmap. The al_set_target_bitmap() affects the drawing operations. |
alex Ioan
Member #12,015
June 2010
|
so if I have a bmp with pink background it will automatically see the pink as transparent ? and how exactly would I use al_convert_mask_to_alpha() ? and I still don't get key presses I would have while (!key[KEY_ESC]) {do stuff} how is that in A5 again ? don't tell me I have to use events here too
|
Matthew Leverton
Supreme Loser
January 1999
|
al_convert_mask_to_alpha(bmp, al_map_rgb(255,0,255)); If bmp was an old A4 magic-pink bitmap, it is now an A5 ready alpha bitmap. ALEXAROTH said: how is that in A5 again ? don't tell me I have to use events here too Read the manual section that talks about al_get_keyboard_state(). |
alex Ioan
Member #12,015
June 2010
|
al_get_keyboard_state(&kbdstate); if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE)) got it thanks ! Although it feels kinda complicated and seems impossible to implement as I wish without adding another loop around the original loop ...
|
Matthew Leverton
Supreme Loser
January 1999
|
Allegro 5 is not as simple for quick & dirty implementations. But it allows you to do more, so the complications are not for nothing. If you really want an old key style function, just do: bool is_key_pressed(int key) { ALLEGRO_KEYBOARD_STATE s; al_get_keyboard_state(&s); return al_key_down(&s, key); } while (!is_key_pressed(ALLEGRO_KEY_ESCAPE)) { }
|
alex Ioan
Member #12,015
June 2010
|
Yea hopefully timers will work better in A5... I'll probably have some questions for those too thanks for the help so far ! its past midnight here so might stop coding and start reading more tutorials tomorrow. PS isn't it
|
Matthew Leverton
Supreme Loser
January 1999
|
Fixed. |
alex Ioan
Member #12,015
June 2010
|
still can't find a work around for the menu... It's not the escape while in a fight type of menu , but more like a simple out of the game menu. Let's say I have several options, that can be triggered by key presses like: load, options, play, shop etc. You press let's say "4" to visit the shop (which is a separate function, with it's own .cpp file), then you have multiple sub-menus like buy/sell/back. buy has some other sub-menus and so on.
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
ALEXAROTH said: Let's say I have several options, that can be triggered by key presses like: load, options, play, shop etc. You press let's say "4" to visit the shop (which is a separate function, with it's own .cpp file), then you have multiple sub-menus like buy/sell/back. buy has some other sub-menus and so on. The first thing I came up with is a switchboard. Use a function pointer to store the current menu that you're in, and do stuff based on the return value of the current menu. For the simplest kind of menus (selecting a state), this will work perfectly. For more complicated menus that change settings interactively it should still work as long as you can change the settings inside the menu function. You can easily separate each menu into it's own file if you like, as long as you include the function's declaration in your main source file. 1int readkey(ALLEGRO_EVENT_QUEUE* eq) {
2 while (1) {
3 ALLEGRO_EVENT ev;
4 al_wait_for_event(eq , &ev);
5 if (ev.type == ALLEGRO_EVENT_KEY_CHAR) {
6 return ev.keyboard.keycode;
7 }
8 }
9 return 0;
10}
11
12
13int main_menu() {
14 clear_to_color(screen , makecol(0,0,0));
15 // draw buttons
16 al_flip_display();
17 al_flush_event_queue(event_queue);
18 while (1) {
19 int keycode = readkey(event_queue);
20 switch (keycode) {
21 case ALLEGRO_KEY_1 : return 1;
22 case ALLEGRO_KEY_ESCAPE : return 0;
23 }
24 }
25 return -1;
26}
27
28int gfx_menu() {
29 // same as main menu except with different options
30}
31
32/// In main
33
34bool in_menu = false;
35
36typedef int (*MENU_FUNC)();
37MENU_FUNC current_menu = 0;
38
39/// In logic loop
40 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
41 in_menu = true;
42 current_menu = main_menu;
43 }
44///...
45 while (in_menu) {
46 int retval = current_menu();// call active menu function
47 if (current_menu == main_menu) {// In main menu
48 switch (return) {
49 case 0 : in_menu = false;break;// user cancelled menu
50 case 1 : current_menu = gfx_menu;break;
51 }
52 }
53 else if (current_menu == gfx_menu) {// In graphics menu
54 switch (return) {
55 case 0 : current_menu = main_menu;break;// user escaped out of gfx menu
56 }
57 }
58 }
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|