• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

SOLVED Help with selecting objects for a minigame

hitch55

Member
Hi,

I'm trying to make a minigame within my game and am wondering how to get starting with selecting things.

Below you'll see my coffee machine. It has a milk jug, steam nob, espresso buttons, mugs etc.

coffee machine.jpg

What I'd like to do is have a box that surrounds the object that is currently selected, and have that box change size and position when the user selects the next thing (so if I currently have the jug selected, that has a large box around it, but if I press right, it highlights the steam nob, the box shrinks down and changes position to surround that object). Below is a GIF mockup showing this.

CM-example.gif

Firstly, I am not sure where to start with such an endeavor, so any pointers would be appreciated.

Secondly, any additional advice on how I would let the game know that when I press enter, I'm 'activating' that particular object would also be appreciated.

I think once I have that down I can figure out how to activate the various animations involved, and output results to other functions so the player can know if they've made the correct coffee recipe.

Thanks in advance :)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, first the selection. Personally I'd use a unique object for each item, then have a mouse click event to detect when it's been clicked on. Drawing the box around the object is easy enough as you can use a nine-slice sprite and the bbox_ variables to get the width/height of the object sprite to draw the nineslice box with (I say this because with a pixel game like this you won't get good results using draw_rectangle). If you aren't using the mouse then things are slightly more complex, so let us know a bit more about how you intend the user to interact with the game.

So, you have a selection option... but it has issues as you also need to deselect any other items at the same time you select something new. You'll first want to make a PARENT object for all selectable objects. This will greatly simplify things and permit you to add code into the parent and have all the items inherit it. So make a "obj_Selectable_Parent" and give all the parts of the coffee machine (or whatever) that object as their parent. Now, in the PARENT object, you'll need to add a couple of variables into the CREATE event: one to detect when it's selected and one to detect when it's clicked. Now, when you click on the object you use "with" to set the selected variable on all objects to false, and then set the selected on the clicked object to true.

The other thing we can do in the parent object is deal with the ENTER key event to make the object do something. What I'd do is have this key check in the parent, then in all the children (the actual items in the game) have an alarm event or a step event with the code to run. So the parent sets up all the main input events, then the children perform the required actions. This would be controlled by a variable or by using an alarm.

Put this altogether and you have a framework like this for the parent object (which will work on all the child objects):

GML:
// CREATE EVENT
selected = false;
clicked = false;


// MOUSE CLICK EVENT
if clicked == false // check to see if the object has been clicked already and only accept input if it's not
{
// Deselect all other objects
with(obj_Selectable_Parent)
    {
    selected = false;
    }
// Only select the object that has been clicked on
selected = true;
}

// ENTER KEY PRESSED EVENT
// Deal with the enter kley being pressed to activate the object
if selected == true // check the item is selected first
{
if clicked == false
    {
    clicked = true;
    // Here you would then call an alarm or set a variable or whatever is
    // required to make the object DO something
    }
}

// DRAW EVENT
// We can add the draw code into the parent object too!!
draw_self(); // draw the object sprite
if selected == true
{
draw_sprite_stretched(spr_NineSlice_Selected, 0, bbox_left, bbox_top, sprite_width, sprtite_height); // Draw the selection box using a nineslice sprite
}
 

hitch55

Member
Thanks for explaining that, makes complete sense to me now :)
Regarding input, the game is meant to mimic the old Gameboy style, so keyboard/control pad options would be what I'm after instead of mouse hover/click. How would something like that work?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, so, if there is no mouse control then things are slightly more complicated. In this case I'd make a controller object that will say which object is highlighted and which isn't. Keep the parent object for all the items in the display though, as that'll still make things simple, but now we'll need to move most of the code out of the parent and into the Controller. In this object, you'll need to keep track of which item is currently highlighted and which item has been pressed and is performing it's actions. So, you'll need to make a new object like "obj_Coffee_Control", for example. In this object we'll create an array and use THAT to decide which object is currently highlighted based on a variable....

In code then, first keep the parent object Create Event and Draw Event, ie:
GML:
// CREATE EVENT
selected = false;
clicked = false;

// DRAW EVENT
draw_self();
if selected == true
{
draw_sprite_stretched(spr_NineSlice_Selected, 0, bbox_left, bbox_top, sprite_width, sprtite_height);
}
Next we need to set things up in the controller object so let's start with the Create event:
GML:
// CREATE EVENT

pos = 0; // this will control which item is currently being selected
pos_max = 6; // The number of objects in the scene

// Now we create an array that holds the object index of each of the items in the scene
item[0] = obj_Mug;
item[1] = obj_Switch;
//etc...

// Now set the first object (or whatever one you require) to be the selected one
with (item[0])
{
selected = true;
}
Now we'll use the STEP event of the controller object. In this event we'll first check to see if the position has changed (ie: the player has pressed the up, or down or left or right buttons on the Dpad/Keyboard):
GML:
var _change = "none";
// Get input
if keyboard_check_pressed(vk_left) || keyboard_check_pressed(vk_up)
{
_change = "up";
}
else if gamepad_button_check_pressed(0, gp_padl) || gamepad_button_check_pressed(0, gp_padu)
{
_change = "up";
}
else if keyboard_check_pressed(vk_right) || keyboard_check_pressed(vk_down)
{
_change = "down";
}
else if gamepad_button_check_pressed(0, gp_padr) || gamepad_button_check_pressed(0, gp_padd)
{
_change = "down";
}
// Check input and change position
switch (_change)
{
case "up":
    pos += 1;
    if pos > pos_max pos = 0;
    break;
case "down":
    pos -= 1;
    if pos < 0 pos = pos_max - 1;
    break;
}
// If the position has changed, change the item selected
if _change != "none"
{
// Deselect everything
with (obj_PARENT) // Put the name of the item parent object here 
    {
    selected = false;
    }
// Select the new item
with (item[pos])
    {
    selected = true;
    }
}
With that done, you'll want to then check for a button or key press to "activate" the item. Again, this is done like before, only within a "with" on the controller object, after the above code:
GML:
if keyboard_check_pressed(vk_space) || gamepad_button_check_pressed(0, gp_face1)
{
with (item[pos])
    {
    if clicked == false
        {
        clicked = true;
        // Here you would then call an alarm or set a variable or whatever is
        // required to make the object DO something
        }
    }
}
That's the basics of how I'd do it. I've made the code as simple as possible to follow, which I hope is okay... Oh, and don't forget that when the item has finished performing the action it has to do, to set the "clicked" variable back to false if you want the item to be available for interaction again. :)

Hope that helps!
 

hitch55

Member
That works beautifully! One thing It freaks out on is i can go down from item 4 to item 0 and then if i keep going down it will loop back up to item 9 and keep going, but if i go the other way I reach item 9 and it gives me an error message instead of looping back to item 0. Im guessing this is something that needs to get added in the switch (_change) function?
 
Top