GameMaker: Studio

GameMaker: Studio

Not enough ratings
ADEDB - Advanced Drag Enabled Dialog Boxes
By Shalle
Hello, fellow yoyo community. In this tutorial I will explain you how to make a dialog box for your GM:S application. The dialog box can be interacted with, moved and you can even press the buttons ("yes", "no" in this case). Plus, I'll show you how to make a new colour (c_rainbow), so that we can use it for a retro feel of our dialog and even the buttons of it. It is advised that you own the full version of GM:S, because the requirements might go past the limitations of demo version.
   
Award
Favorite
Favorited
Unfavorite
Startup, prerequisites

Requirements

Today we'll be making these dialog boxes above, but before we do, we need some things.
  • GM:S full version (PC module) is advised
  • Font that we'll be using for this tutorial
  • Average knowledge of Game Maker is advised for further custom uses

Everything else, including the buttons and box, will be drawn on the screen using a single instance with Draw functions and seperate scripts.
Let's start with scripts first
Script to spawn the dialog box

So, as far as many different popup boxes usually appear in middle of the screen, I won't define where to spawn the dialog, because it will center itself later... BUT if you really want to, you could add 2 more arguments to the script and replace the 0;0 coordinates with these arguments, aswell remove the x and y variables from the instance creation code, so that it doesn't replace your values.

So, basically, with this script you will define what information you want the dialog box to store (description, title of the 1st button, title of the 2nd button). You can call the script whatever you wish, but for simplicity I'd advise you to keep it all as it is, for now.

dialog_new_dynamic(question, answer_a, answer_b)
///dialog_new_dynamic(question, answer_a, answer_b) // Only 1 dialog per instance if (instance_exists(oDialog_dynamic)) exit; // -------------------------- with (instance_create(0, 0, oDialog_dynamic)) { txt = argument0; txta = argument1; txtb = argument2; }

Don't worry about the unexistient instance "oDialog_dynamic", we'll make it later.

Let's make rainbows (optional)

I wanted to make the dialog box a little bit more lively and retro, so I also made my own script for this glichy sort of rainbow effect, but it's just purely visual and you could even skip this part, if you wish, or you can make your own rainbow script if you don't like this one

make_colour_rainbow()
///make_colour_rainbow() switch(c_rainbow_h) { case 0: c_rainbow_h = 100; break; case 55: c_rainbow_h = 150; break; case 105: c_rainbow_h = 200; break; case 155: c_rainbow_h = 250; break; case 205: c_rainbow_h = 50; break; default: c_rainbow_h-=5; break; } return make_colour_hsv(c_rainbow_h, 255, 255);

We'll make that "c_rainbow_h" outside the script so that it doesn't reset. If we were using c++, we could of course just define it gazillion times it without replacing, but it's a little bit different in gml.

Right now it doesn't make much sense and scripts won't work on themselves, so let's go the the next part of our tutorial!
Controller Instance
We need a controller instance that will actually spawn the dialog box and which could actually store our font (if you're using a custom font), aswell as destroy it, and probably store/use the dialog return value. We'll name our controller oControl (but it doesn't really matter what it's called).

So, in the create event, we'll spawn our dialog.

#oControl_Create_1
dialog_new_dynamic("EST-CE QUE TU AS SOIF?", "OUI", "NON");

I also made a "Game Start" event (my controler would spawn in the first room of the game and remain with persistence ticked to true) where I created a new sprite based font, but it really depends on if you want to use a custom sprite based font:

#oControl_Game Start_1
global.F_SMALL = font_add_sprite(sSmallFont, ord('!'), 1, 0);

I also made a code that will prevent the screen from going nuts if we have ticked "Allow user to resize the game window", which I put in the step even of the game, and yes, we'll be using VIEWS for this tutorial, but it also depends on of you want to allow such a feature.

#oControl_Step_1
// THIS CODE IS OPTIONAL AND PROBABLY UNOPTIMIZED // Maintains same pixel size in case of window resizing var w, h; w = round(window_get_width()); h = round(window_get_height()); if ((view_wview != w) || (view_hview != h)) { window_set_size(w, h); view_wport = w; view_hport = h; view_wview = w; view_hview = h; surface_resize(application_surface,w,h); }
Hardest part
First of all,
  • I'm using views for this tutorial, but you could later rewrite it if you really need to.
  • I made macros (COL_BTN etc.) for storing a few colors that I needed, but you can really just use c_gray or c_dkgray if you wish.
  • c_rainbow IS LOCALY SAVED (I did it, so that only when the dialog appears the script would run, rather than waste the pc resources all the time)

Create event for oDialog_dynamic

Some variables aren't defined in "Create Event", because they get defined when spawning the dialog using the previously written script "dialog_new_dynamic(...)".

There's allot of code here, so it might be a little hard to understand, and I used allot of round functions, so that our objects don't draw in between pixels making it all blurred out. I also tried to explain as much as possible, so here's the code from create event of "oDialog_dynamic":

#oDialog_dynamic_Create_1
// You can modify the info of the dialog box here w = 300; // width in pixels of the dialog box h = 200; // height in pixels of the dialog box wbut = 96; // width of a single button in pixels hbut = 32; // height of a single button in pixels // ------------------------------------------------ hover_a = 0; // Is the first button hovered hover_b = 0; press_a = 0; // Is it pressed press_b = 0; but_col_a = COL_BTN; // Colors in stored in macros but_col_b = COL_BTN; hover_window = 0; // Did we hover over the top of dialog box (for dragging the dialog) press_window = 0; // Are we trying to drag the box xpt = 0; ypt = 0; // These you can remove if you don't want the dialog to center itself x = view_xview[0] + round((view_wview[0] / 2) - (w / 2)); y = view_yview[0] + round((view_hview[0] / 2) - (h / 2)); // ------------------------------------------------------------------ // Mostly for drawing the box itself xx = x+w; yy = y+h; x_mid = round(x + (w / 2)); y_mid = round(y + (h / 2)); y_label = round(y_mid - (h / 4)); y_buttons = round(y_mid + (h / 4)); // Mostly for calculating where to draw buttons and how big x_but_a = x_mid - round((wbut / 2) + (w / 4)); y_but_ab = y_buttons - round(hbut / 2); x_but_b = x_mid + round((w / 4) - (wbut / 2)); xx_but_a = x_but_a+wbut; yy_but_ab = y_but_ab+hbut; xx_but_b = x_but_b+wbut; x_but_mid_a = x_mid - round(w / 4); x_but_mid_b = x_mid + round(w / 4); // These variables are saved in case you want to use c_rainbow with colour c_rainbow = c_red; c_rainbow_h = 49;

The Step Event

The stuff is more or less explained here, but basically, this is the step event of "oDialog_dynamic", which makes the dialog work in depth

#oDialog_dynamic_Step_1
// Code so that the box updates if it's being moved xx = x+w; yy = y+h; x_mid = round(x + (w / 2)); y_mid = round(y + (h / 2)); y_label = round(y_mid - (h / 4)); y_buttons = round(y_mid + (h / 4)); x_but_a = x_mid - round((wbut / 2) + (w / 4)); y_but_ab = y_buttons - round(hbut / 2); x_but_b = x_mid + round((w / 4) - (wbut / 2)); xx_but_a = x_but_a+wbut; yy_but_ab = y_but_ab+hbut; xx_but_b = x_but_b+wbut; x_but_mid_a = x_mid - round(w / 4); x_but_mid_b = x_mid + round(w / 4); // Move the box around (MAKES IT DRAGABLE, YAAY) if (point_in_rectangle(mouse_x, mouse_y, x, y, xx, y+20)) { hover_window = 1; if mouse_check_button_pressed(mb_left) { press_window = 1; xpt = mouse_x - x; ypt = mouse_y - y; } if (mouse_check_button_released(mb_left)) { press_window = 0; } } else { hover_window = 0; if (mouse_check_button_released(mb_left) || !mouse_check_button(mb_left)) { press_window = 0; } } if (press_window = 1) { x = mouse_x - xpt; y = mouse_y - ypt; } // ------------------------------------------ // First Button interaction if (point_in_rectangle(mouse_x, mouse_y, x_but_a, y_but_ab, xx_but_a, yy_but_ab)) { hover_a = 1; if mouse_check_button_pressed(mb_left) { press_a = 1; } else if (mouse_check_button_released(mb_left) && press_a) { press_a = 0; // Action here global.dialog_answer = 0; // This I put here so that I could later use it in oControl instance instance_destroy(); } } else { hover_a = 0; if (mouse_check_button_released(mb_left) || !mouse_check_button(mb_left)) { press_a = 0; } } // ------------------------- // Second Button interaction if (point_in_rectangle(mouse_x, mouse_y, x_but_b, y_but_ab, xx_but_b, yy_but_ab)) { hover_b = 1; if mouse_check_button_pressed(mb_left) { press_b = 1; } else if (mouse_check_button_released(mb_left) && press_b) { press_b = 0; // Action here global.dialog_answer = 1; // This I put here so that I could later use it in oControl instance instance_destroy(); } } else { hover_b = 0; if (mouse_check_button_released(mb_left) || !mouse_check_button(mb_left)) { press_b = 0; } } // ------------------------- // makes the local variable c_rainbow into a never ending random color from a script c_rainbow = make_colour_rainbow(); // This is for drawing the buttons so that they animate if (press_a) {but_col_a = c_rainbow;} else if (hover_a) {but_col_a = COL_HOVER;} else {but_col_a = COL_BTN;}; if (press_b) {but_col_b = c_rainbow;} else if (hover_b) {but_col_b = COL_HOVER;} else {but_col_b = COL_BTN;};

The draw event where all the magic appears

The finale of our dialog box, remember to change the "COL_BTN" and "COL_HOVER" with c_dkgray and c_gray or somilar colors if you're not using Macros

#oDialog_dynamic_Draw_1
draw_set_halign(fa_middle); draw_set_valign(fa_center); // Draw the dialog box draw_set_alpha(0.7); draw_set_colour(make_colour_rgb(50, 50, 50)); draw_rectangle(x, y, xx, yy, false); // Draws the shiny dragable top of the dialog if hovered over if (hover_window) { draw_set_colour(COL_BTN); // Again the macro is here draw_rectangle(x, y, xx, y+20, false); } // Draws a rainbowy outline of the dialog draw_set_alpha(1); draw_set_colour(c_rainbow); // Our rainbow colour in action draw_rectangle(x-1, y-1, xx+1, yy+1, true); draw_triangle(x, y+8, x, y, x+8, y, false); // Draws the buttons draw_set_alpha(0.7); draw_set_colour(but_col_a); // sets to colour previously defined in step event (when hovered) draw_rectangle(x_but_a, y_but_ab, xx_but_a, yy_but_ab, false); draw_set_colour(but_col_b); draw_rectangle(x_but_b, y_but_ab, xx_but_b, yy_but_ab, false); // Draws the text on dialog draw_set_alpha(1); draw_set_colour(c_white); draw_set_font(global.F_SMALL); draw_text_ext(x_mid, y_label+16, txt, 20, 300); draw_text_ext(x_but_mid_a, y_but_ab + round(hbut/4), txta, 3, 280); draw_text_ext(x_but_mid_b, y_but_ab + round(hbut/4), txtb, 3, 280);

Just place the controller in the room and you're set. Of course when pressed it won't launch a nuke or aything, but that can be defined later as you wish...
Conclusions
Source code
I decided to put up a source code, plus it has a few other things in it aswell, an example, the font that I made.

Dropbox (rar file)
1 Comments
Shalle  [author] Jul 17, 2016 @ 9:12am 
Unfortunitely steam keeps deleting the source code. adf(dot)ly/1601970/gmsdialogsrc