GML [SOLVED] Alarms, Delay and Decay.

Hey everyone,
I have run into a problem due to lack of knowledge.
I am trying to make a little prototype to test an idea I have for a proficiency system (Irrelevant info)

The Main functionality is that you start with 0XP, you click a button and you get +1XP, a small timer prevents you from spamming button. That is straight-forward enough, it is just the same code you use for a shoot mechanic, but this is where it gets tricky.

I want to have, after a certain amount of time, if the button has not been pressed the total XP starts to decay by -1xp, but if the button is pressed again the timer is reset.
obj_commander
Code:
///Create Event
global.XP = 0;
global.decay_timer = room_speed*2;
global.decay_start = 0;
global.button_pressed = 0;

///Step Event
while (!global.decay_start = 1)
{
    alarm[0] = global.decay_timer;
}
if (global.button_pressed = 1)
{
    alarm[1] = global.decay_timer;
    global.decay_start = 1;
    alarm_set(0,-1);
}
if (global.XP < 0) global.XP = 0;

///Alarm[0]
global.XP -= 1;
global.decay_start = 0;

///Alarm[1]
global.button_pressed = 0;
global.decay_start = 0;
Here is the Relevant code from the obj_button
Code:
///Step Event
if (mouse_check_button_pressed(mb_left)) && (can_click = 1)
{
    global.XP += 1;
    global.decay_start = 1;
    global.button_pressed = 1;
    can_click = 0;
    alarm[0] = 30;
}

So far the code mostly works, but the decay timer keeps happening, I want to turn it off when the button has been clicked and when the delay timer has finished I want the decay timer to start on a repeated loop until the button is pressed again or XP reaches 0.

Hopefully that makes sense, and thank you in advance for any help.
 

Roderick

Member
Code:
/// Create code
decay = 0;

/// Step code
decay--;

if (device_mouse_check_button_pressed(0, mb_left) && (point_meeting(mouse_x, mouse_y, o_button)) && (decay < 1)
{
 decay = room_speed;
 xp += 1;
}

if (decay < -room_speed)
{
 xp = max(0, xp - 1);
 decay = 0;
}
With this code, the button can be pressed at most once per second. Once the one second timer runs out, you lose 1 XP per second, to a minimum of 0. All in one nice little consolidated bit of code.
 
Code:
/// Create code
decay = 0;

/// Step code
decay--;

if (device_mouse_check_button_pressed(0, mb_left) && (point_meeting(mouse_x, mouse_y, o_button)) && (decay < 1)
{
 decay = room_speed;
 xp += 1;
}

if (decay < -room_speed)
{
 xp = max(0, xp - 1);
 decay = 0;
}
With this code, the button can be pressed at most once per second. Once the one second timer runs out, you lose 1 XP per second, to a minimum of 0. All in one nice little consolidated bit of code.
Thanks for the quick reply, by the way.
I will try this out!
I should be able to extend the timers and change the input with this right?
 

Roderick

Member
Yup. room_speed is the number of steps taken in the current room in one second. So if you want the lockout to be a half second, change it to decay = room_speed * 0.5 when you set decay. If you want the loss to happen every five seconds, check (decay < -room_speed * 5), and so on.

And if I used any commands you aren't familiar with, make sure to look them up in the manual! Don't just plug someone else's code into your project and trust it to work, or if anything goes wrong, you'll have no idea what, or why! ;D
 
I understand the code but it has entered me into an infinite loop, attempting to troubleshoot.

EDIT:
Resolved that, human failure issue there, but the problem now is that it does not register the clicking on the button. so no XP increase.
 

Roderick

Member
That code shouldn't even run. point_meeting isn't a real command. I meant place_meeting

Edit: That's still wrong, and will only work if it's being called from an instance with a collision mask. What I really meant was position_meeting

I'm really bad at remembering which collision commands are which; I often have dozens of bugs that take me forever to find because I get those backwards. Sorry. >_<
 
I figured that one out, but thanks for pointing it out either way. I removed that whole perimeter and opted for a keyboard press instead, the code works perfectly without that place_meeting function, but I would still like to get the function working.
Thank you very much by the way, the only part of the code I didn't understand is a VAR at the beginning of STEP, decay--;

EDIT:
I will try position_meeting
 
Last edited:
Thank you for clarifying that.
I put in the fixes and adjusted the code to suit my style and it works perfectly, even have the draw event showing the timer (30 to -30) and my total XP, thank you for helping me here. I didn't even think of setting a manual timer (failed knowledge(GML) roll).

I should be able to adapt this code to suite my needs and make it more complicated :)
 
Top