Allegro.cc - Online Community

Allegro.cc Forums » Game Design & Concepts » GAME MENU

This thread is locked; no one can reply to it. rss feed Print
 1   2 
GAME MENU
GOORE YANNIS
Member #17,073
April 2019

Hi everybody, I have to do a menu for a space battle game and i'm a little bit lost because i don't know how to make different levels, or how to put up the menu options.

piccolo
Member #3,163
January 2003
avatar

look into game states. menus input cant seen as a state. levels can all so be seen as a state

wow
-------------------------------
i am who you are not am i

GOORE YANNIS
Member #17,073
April 2019

do you have a tutorial or something like that because i don't understand how to do that I have to do 3 levels with a menu can you explain your thinking ?

Edgar Reynaldo
Member #8,592
May 2007
avatar

The menu is a state, and so is each level. Look into state machines.

A menu is a set of buttons. A button is a rectangle or other shape that monitors mouse clicks and gives visual feedback to the user.

GOORE YANNIS
Member #17,073
April 2019

Okay , I see do you have an example of that in C language ?

piccolo
Member #3,163
January 2003
avatar

https://www.allegro.cc/depot/Thegame/

keep in mind menus are usually constructed using object oriented programing.

wow
-------------------------------
i am who you are not am i

Edgar Reynaldo
Member #8,592
May 2007
avatar

Read carefully, this will affect your entire coding career :

Whenever you approach a coding problem, you need to identify the basic components that you need to create. In a program, there are two and only two things you need to worry about. 1) Data - these are the raw bits that make up your program, the values your variables hold, etc...., and 2) Instructions - what to do with all that dang data...

Now, you have to approach your programming problem with the fundamental approach of turning your problem into Data, and Instructions.

Identify the basic building blocks of your program. What values do you need to store in order to represent the parameters of your problem? And secondly, what kind of logic do you need to process that data and turn it into the correct output of the program?

So, in your case, you need a game with multiple 'screens' which can be represented by states. In C you can do this with predefined constants and a variable to hold the current state. Then your logic code and your drawing code can react to the value stored in the 'state' variable and act accordingly.

Your first screen is a menu. A menu is simply an array of buttons. A button is a shape, which can be defined mathematically using variables. The most typical example is a pure rectangle, aligned with the screen axes.

A rectangle is a position, and dimensions. xy position, and width/height.

A button is an 'object' or 'widget' that monitors mouse clicks and compares the value of the mouse position at the time of the mouse click with a stored area such as a rectangle.

So what does that mean for you? How do we reduce that all to data and instructions?

First the data ;

#SelectExpand
1/// Game states 2const int STATE_QUIT = -1; 3const int STATE_MENU = 0; 4const int STATE_GAME = 1; 5 6/// sub states for each level 7const int STATE_GAME_LEVEL1 = 0; 8const int STATE_GAME_LEVEL2 = 1; 9const int STATE_GAME_LEVEL3 = 2; 10 11/// We need to store our hit area for our buttons 12typedef struct RECTANGLE { 13 int x,y,w,h; 14}; 15 16/// Initial states 17int gamestate = STATE_MENU; 18int gamelevel = STATE_GAME_LEVEL1; 19 20/// Our button 21RECTANGLE button_play = {200,100,200,50};

That about covers it for our data. Now we need to present that data to our users with some instructions. This is where the logic handling and display handling come in.

First, we need a way to test if our button is pressed :

bool button_pressed(ALLEGRO_EVENT ev , RECTANGLE* b) {
   if (ev.type != ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) {return false;}
   return (ev.mouse.x >= b->x && ev.mouse.y >= b->y && ev.mouse.x < b->x + b->w && ev.mouse.y < b->y + b->h);
}

Second, we need to change our output depending on the game state :

#SelectExpand
1 2while (state != STATE_QUIT) { 3 if (redraw) { 4 Redraw(); 5 redraw = false; 6 } 7 do { 8 ALLEGRO_EVENT ev; 9 al_wait_for_event(queue , &ev); 10 switch (gamestate) { 11 case STATE_MENU : 12 if (button_pressed(ev , &button_play)) { 13 gamestate = STATE_GAME; 14 } 15 break; 16 case STATE_GAME : 17 /// etc... 18 break; 19 } 20 } while (!al_is_event_queue_empty(queue)); 21 22}

GOORE YANNIS
Member #17,073
April 2019

thank you verry much all of you can i send u what i have done for the moment ?

Edgar Reynaldo
Member #8,592
May 2007
avatar

You can post a zip file of your source code just attach it to the Post.

GOORE YANNIS
Member #17,073
April 2019

it's in french i come from france but there is a problem my menu don't want to appear i don't know why everything seems okay , but when i try to run it i have a black screen and i have to shutdown my Macbook.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Doctor Cop
Member #16,833
April 2018
avatar

Edgar, your explanation was splendid, the way you stored the coordinates and Height, width of the rectangle later to be used to make up for x1, y1/ x2, y2 was something I never thought before, it just makes it so much easy to create buttons!

Edgar Reynaldo
Member #8,592
May 2007
avatar

Well, I've been writing a GUI for 10 years now, if there's one thing I can do, it's buttons... :o

;)

NiteHackr
Member #2,229
April 2002

In my own game, I just created a series of images for each button. Each button has three states, a normal one you see all the time, one when t he mouse is hovering over it, and one when it is actually clicked.

I then created a struct (I code in C) to hold my button data, the image, the current state etc. I check the mouse position and compare it to each button's position then update that button's state if needed. The draw routine then draws the approriate graphic based on the state. If you click the button, I then jump to the appropriate function to play the game, switch to an options menu etc.

It's fairly simple to implement to be honest.

--
Deluxe Pacman 1 & 2 (free) with source code available
https://nitehackr.github.io/games_index.html

Doctor Cop
Member #16,833
April 2018
avatar

NiteHackr, that's the only way I see it. Do you have any other way to do it?
I would like to know.

NiteHackr
Member #2,229
April 2002

There are libraries that provide functionality for buttons and the like, but I never liked the look of them and preferred to roll my own.

In my Deluxe Pacman 2 game I wrote my own button functions for creating a button etc... (see dp2_gui.c/.h in my source). For creating a button I have the following function which takes a pointer to the new button struct, whether it is a simple toggle switch (used in my level editor mostly), it takes the filename for the file with the three images which will make up the different button states as well as the position of it on screen.

#SelectExpand
1// new_button: 2// Creates a new button, loading in the file indicated. 3// The graphics provided MUST contain three images, lined up vertically. 4// The top image is the normal button that is displayed when it isn't being used. 5// The second image down is the button to display when the mouse is over it (but not clicked) 6// The third image is the button to display when the mouse is clicked on it. 7// This function assumes a new uninitialized BUTTON variable sent to it. 8bool new_button(BUTTON *b, bool is_switch, const char *file, int x, int y) 9{ 10 b->x = x; 11 b->y = y; 12 b->state = 0; 13 b->old_state = 0; 14 b->is_switch = is_switch; 15 b->bmp = NULL; 16 b->bmp = al_load_bitmap(file); 17 if(!b->bmp) return false; 18 b->w = al_get_bitmap_width(b->bmp); 19 b->h = al_get_bitmap_height(b->bmp) / 3; 20 b->up = NULL; 21 b->up = al_create_sub_bitmap(b->bmp, 0, 0, b->w, b->h); 22 b->over = NULL; 23 b->over = al_create_sub_bitmap(b->bmp, 0, b->h, b->w, b->h); 24 b->down = NULL; 25 b->down = al_create_sub_bitmap(b->bmp, 0, b->h * 2, b->w, b->h); 26 27 return true; 28}

Then there's the function to check if the mouse is over the button, fairly simple and straight forward...

#SelectExpand
1// check_button: 2// Checks to see if the mouse is over or is clicking on a button 3// Returns true if an area was clicked in. 4bool check_button(BUTTON *b, ALLEGRO_MOUSE_STATE *mouse) 5{ 6 bool is_over = true; 7 // Convert mouse position to proper position on scaled screen. 8 int mouse_x = (mouse->x - offset_x) / scale_x; 9 int mouse_y = (mouse->y - offset_y) / scale_y; 10 11 // Calculate the right side. 12 int ex = b->x + b->w - 1; 13 14 // Calculate the bottom side. 15 int ey = b->y + b->h - 1; 16 17 // save the last state 18 b->old_state = b->state; 19 20 // set new state to up 21 if(b->is_switch && b->state == 2) b->state = b->old_state; 22 else b->state = 0; 23 24 // If the mouse is outside of the area in question, return false. 25 if(mouse_x < b->x || mouse_y < b->y || mouse_x > ex || mouse_y > ey) is_over = false; 26 27 if(is_over) { 28 if(!b->is_switch) b->state = 1; // mouse is over 29 else if(b->is_switch && b->state == 0) b->state = 1; 30 if(mouse->buttons & 1) { 31 if(b->is_switch && b->state == 2) b->state = 0; 32 else b->state = 2; // left button down? 33 } 34 } 35 // if the state hasn't changed, return false 36 if(b->state == b->old_state && !is_over) return false; 37 38 // the state has changed, return true 39 return true; 40}

And I have a function for drawing them and destroying them. I could have probably went further in this and added more to it all, but this was all I really needed and it looked and operated good enough for me in game.

My button graphics are all organized the same way, the top one is normal, then a red one for mouse over and the bottom one for left clicked.

{"name":"612007","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/3\/5338bd184b07884d1243644476908c9c.png","w":256,"h":159,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/5\/3\/5338bd184b07884d1243644476908c9c"}612007

There really is nothing to it and honest, I recommend doing it yourself so you have full control over what happens and you can customize it to your needs.

You could, for example, have your code draw t he buttons yourself, select a font and have it so your functions can have any text you wish on them rather than premade graphics like my own. That would be pretty simple to do... and something I thought about doing, given the common look to all my buttons.

I just happen to enjoy doing it myself.

--
Deluxe Pacman 1 & 2 (free) with source code available
https://nitehackr.github.io/games_index.html

Doctor Cop
Member #16,833
April 2018
avatar

I agree with you, however the reason I make my own GUI is that what I need is a modern look in GUI and all the GUI systems which I came across were not that much dynamic. I am trying to make GUI similar to what Web Designers are making, I want it to be up to the mark.

like you said that I could make some changes to your code and display the desirable font I need but I don't need just the font, I need to make it so that I may not need even any image and I will change it so that when I am not passing an image it will display a rectangle and that's when i think polymorphism really shines, OOPs.

I want to be able to do it in C too, but that would be very heavy lifting.

jmasterx
Member #11,410
October 2009

and all the GUI systems which I came across were not that much dynamic

Honestly, I spent several years on Agui to build and stabilize it, it is fully skinnable and very flexible. It is tried and tested in a commercial game selling over 1.5 million copies.

There are also a bunch of high quality alternatives like EAGLE; also fully skinnable.

Even if some how these libraries are not 'dynamic' enough for you, there is no good reason not to fork and modify one to your needs.

Gui threads have become the new Monday thread. It's silly.

If you need something for tools use QT.

If you need a complex render engine, fork chromium.

But writing a new gui because the ones out there that took years to develop are missing a little something you need is silly IMO.

Don't make a gui api in C just for the fun of it. Not all things lend well to OOP, but GUIs really lend well to OOP!

GOORE YANNIS
Member #17,073
April 2019

Thanks all of you, i will try what you taught me , but i have a another problem if i want to do checkpoints like in videogames, how allegro can help me to do that ?

Rodolfo Lam
Member #16,045
August 2015

You have to understand that the main focus of Allegro is the rendering of your program state, whatever that program is. Usually the programs are games.

Depending on your type of game, your "checkpoint" system could be something as simple as a single file containing your score and current level progress. It can also involve having a fully fledged database, holding entries for inventory items, skill tree development, past interactions with NPCs, and the like.

That is (at least partially, read below) outside the scope for Allegro, you need to bring your own code for that or find something you can use for the task at hand. Using C or C++ you could look into File I/O facilities to get the basics. If you feel like it (and have a good grasp of the basics), you can then venture into something such as JSON, XML, Protocol Buffers, and many other serialization libraries that can be adapted to store whatever program state you want to save.

ALLEGRO BASED OPTION:

Allegro 5 has support for reading and writting simple configuration files in the Windows *.INI format. IT is usually used to load whatever default configuration and flags you want without hardcoding it into the executable. You can look more into this here. Good luck!

Doctor Cop
Member #16,833
April 2018
avatar

Jmasterx: I'm using the help of WidgetZ library. Of course making a complete new GUI library won't be possible without spending months of time on it but what I'm doing is that I'm trying to learn how to make one.

This whole Messing with GUI systems thing for me is to learn how to make software. Making a complete GUI system will teach me how states work and how should I plan my software. If you suggest me otherwise then I'll be happy to hear your views.

Here's what I'm trying to achieve in buttons for now.

{"name":"612009","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/1\/d17f1819a3c817ff5601ba47be1318a4.jpg","w":1080,"h":1080,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/d\/1\/d17f1819a3c817ff5601ba47be1318a4"}612009

NiteHackr
Member #2,229
April 2002

I have used Allegro in the past to actually draw the buttons from scratch, I just didn't bother in my own game at the time. I kind of wish I had from the get go, but hindsight and all that.

It wouldn't be difficult, you take the size you wish, a style etc... you could pick a colour to shade from-to, top to bottom I would make a primary style say, if you wanted it to be blue, go from light blue at the top, to dark at the bottom, perhaps with a rounded corner rectangle (like an oval almost) near the top to give it a shine, like a glass look. You could easily change the colour for mouse over to red, same shading, then left clicked could be red shaded, only dark on top to light red on button to give the depressed look. Ad a custom font to the mix... it wouldn't be difficult to make it very flexible.

I agree, that such a system would definitely benefit from C++ classes, but I can't see any reason why it can't be done just about as nicely in C with a little effort. Personally I love the challenge of doing it in C, but that's just me. ;)

Allegro has some very nice graphic commands for drawing primitives with which would do the trick nicely and look very good and not so plain and hum drum.

There was a nice example of Allegro code used to draw a Pong style paddle someone posted, I forget who. But this reminds me a lot of the button style I like. Take this code, add in some truetype font style to it and make it more flexible for whatever you wish... and it would be pretty kewl. :)

Of course, I am always thinking in terms of Allegro 5 + games.

void draw_paddle(float x, float y)
{
  // fill
  al_draw_filled_rounded_rectangle(x, y,
    x+paddle_width, y+paddle_height, 6, 6, al_color_html("729fcf"));
  // outline
  al_draw_rounded_rectangle(x, y,
    x+paddle_width, y+paddle_height, 6, 6, al_color_html("b5edff"), 1.0);
  // shine
  al_draw_filled_rounded_rectangle(x, y,
    x+paddle_width/2, y+paddle_height-10, 6, 6, al_color_html("8abbef"));
}

--
Deluxe Pacman 1 & 2 (free) with source code available
https://nitehackr.github.io/games_index.html

jmasterx
Member #11,410
October 2009

I can tell you that Agui supports all of those button states out of the box.

Here you will find a subclass of the Agui button that supports all those states
https://github.com/jmasterx/StemwaterSpades/blob/master/Spades%20Game/Game/UI/Button.cpp

Agui draws buttons as ninepatch images so the size can be dynamic

This codebase has everything you need to have a fully skinned dynamic responsive css-worthy client-ready user experience

https://github.com/jmasterx/StemwaterSpades/tree/master/Spades%20Game/Game/UI

Doctor Cop
Member #16,833
April 2018
avatar

Thanks, Jmasterx and Neil for the direction, I'll be on it ones my exams are completed. And yes now I admit that there is no reason for me to not look at some other GUI libs made in Allegro5 and just to be clear I was using Eagle 5 for my previous project, I just decided to make one of my own because I had problems understanding States and I thought it would be cool and experience rich if I try to make my own GUI system and it did teach me alot about states that I didn't knew before.

Edgar Reynaldo
Member #8,592
May 2007
avatar

Doctor Cop, could I get some feedback on Eagle? It supports spring and toggle buttons as well as hover, focus, and disabled if you customize it. Ninepatch support is mostly done. Have you tried building eagle with cmake yet? Or just the code blocks projects?

If you have any feature requests I would probably do them for you.

 1   2 


Go to: