SOLVED A more elegant way of coding my timer countdowns?

otterZ

Member
Hey guys, I will be the first to admit that I am not an elegant coder and tend to repeat lines of code that resembles spaghetti. I am trying to change this. Can anyone suggest a way to code my timer countdowns more elegantly? Here's some code as it is at the moment . . . repetitive and ugly. . . a hallmark of my coding style lol.

GML:
timer20A[1] -= 1;
timer20A[2] -= 1;
timer20A[3] -= 1;
timer20A[4] -= 1;
timer20A[5] -= 1;
timer20A[6] -= 1;
timer20A[7] -= 1;
timer20A[8] -= 1;
timer20A[9] -= 1;
timer20A[10] -= 1;
I am interested in how more experienced programmers would code this more succinctly / elegantly as I want to change my 'spaghetti/if it works who cares' type of approach as I want my code to be more readable.
 

Mr Magnus

Viking King
This just seems like a textbook case for a for loop

GML:
for(var i = 1; i <= 10; i++){ //Loop i from 1 to 10
    timer20A[i] -= 1;
}
Generally if you have many lines of code that are identical except for only subtle changes like input parameters or a number going up or down loops are probably the way to go.
 

Reprom

Member
GML:
var array = timer20A;

var i = 0;
repeat (array_length(array)) {
    array[@ i] -= 1;
    ++i;
}
This will loop through whole array and does the same thing. You can set array variable to be timer20A or some other array.
 
Last edited:
Also, you can start thinking extending this by using methods so that any timers added automatically count down and then fire a function you provide (the function won't be able to take arguments, or all the arguments need to be uniform for every alarm). To scope this properly, I would have an alarm object that is persistent (or added to the rooms you want to use the custom alarms in at least):

Alarm functions
Code:
function AlarmSet(total_time,func) {
   with (alarm_object) {
      array_push(alarm_array,[timer,func]);
   }
}
function AlarmStep() {
   var alarm_len = array_length(alarm_array);
   for (var i=0;i<alarm_len;i++) {
      if (alarm_array[i][0] > 0) {
         alarm_array[@i][@0]--;
      }
      else if (alarm_array[i][0] == 0) { // There's a very small possibility you might have to account for tiny floating point errors here, but I don't think I've run into trouble with this sort of thing
         alarm_array[@i][@0]--;
         alarm[i][1]();
      }
      else {
         array_delete(alarm_array,i,1);
      }
   }
}
Then whenever you want an alarm to do something, you simply call the AlarmSet function (from any object) and give it the method to execute when the alarm is finished:
Code:
AlarmSet(30,function() { // This function here is the method I'm talking about
   show_debug_message("Alarm fired!");
});
This'll work from any object, but you'll have to have:
Code:
AlarmStep();
In the step event of the alarm object. This is a super simplified version, and there's few pitfalls (scoping what the method acts on is one that you'll need to watch out for), but there's a lot that can be done with this sort of thing, once you start to wrap your head around it.
 

otterZ

Member
Thank you RefresherTowel, a really useful extension and a good example of how this can be built upon. That was really interesting and I will create a test project and play around with this method.
I think it is worth overhauling a spaghetti style coding / bang it out style and replacing it with a more elegant style. I will put the time into using more loops and other ways to make coding more concise. It may take some time learning new skills but will be totally worth it in the long run. I appreciate the advice.

This just seems like a textbook case for a for loop

GML:
for(var i = 1; i <= 10; i++){ //Loop i from 1 to 10
    timer20A[i] -= 1;
}
That is a nice example, I will spend the day getting familiar with loops. I must admit I never really use them much. Thank you.

Generally if you have many lines of code that are identical except for only subtle changes like input parameters or a number going up or down loops are probably the way to go.
GML:
var array = timer20A;

var i = 0;
repeat (array_length(array)) {
    array[@ i] -= 1;
    ++i;
}
This will loop through whole array and does the same thing. You can set array variable to be timer20A or some other array.
Nice, so much neater, it is interesting how much space and time can be saved with more succinct code, Thanks for that.
 
Top