draw_set_color not changing colour in drawGUI event for a radar

Adro

Member
Hi there,

I'm making an asteroids clone to teach myself GM. I'm still pretty new to this whole thing, so I bet there's something simple I'm missing! :rolleyes:

I have a radar in the top right cover, and it works, but the asteroids are showing up with the wrong colours and sizes. Weirdly the radar shows the right colour for the player (green) but only the last colour referred to when looking for asteroids in the play area and placing them on the radar/mini-map.

I've included the code below. Any suggestions would be a great help! Thanks in advance!

Code:
var asteroidCount_ss;
asteroidCount_ss = instance_number(obj_asteroid_ss);
draw_set_color(c_red);

for (k=0; k<asteroidCount_ss; k+=1) {
    asteroidId_ss = instance_find(obj_asteroid_ss, k);
    var wherex = xp + asteroidId_ss.x*(xscale);
    var wherey = yp + asteroidId_ss.y*(yscale);
    draw_circle(wherex, wherey,2,false);
}

var asteroidCount_s;
asteroidCount_s = instance_number(obj_asteroid_s);
draw_set_color(c_blue);

for (w=0; w<asteroidCount_s; w+=1) {
    asteroidId_s = instance_find(obj_asteroid_s, w);
    var wherex = xp + asteroidId_s.x*(xscale);
    var wherey = yp + asteroidId_s.y*(yscale);
    draw_circle(wherex, wherey,3,false);
}

var asteroidCount;
asteroidCount = instance_number(obj_asteroid);
draw_set_color(c_yellow);

for (r=0; r<asteroidCount; r+=1) {
    asteroidId = instance_find(obj_asteroid, r);
    var wherex = xp + asteroidId.x*(xscale);
    var wherey = yp + asteroidId.y*(yscale);
    draw_circle(wherex, wherey,4,false);
}

// draw player
if (instance_exists(obj_player)) {
    var wherex = xp + obj_player.x*(xscale);
    var wherey = yp + obj_player.y*(yscale);
    draw_set_color(c_green);
    draw_circle(wherex, wherey,2, false)
}
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Are the asteroids parents/children of other asteroids? for example, is "obj_asteroid" the parent for "obj_asteroid_s" and "obj_asteroid_ss"?
 

Adro

Member
Hi Nocturne :)

Yes they are, I probably should have mentioned that. obj_asteroid is the parent to obj_asteroid_s, which is the parent to obj_asteroid_ss.

Do I need to make them completely separate objects?
 

Simon Gust

Member
Hi Nocturne :)

Yes they are, I probably should have mentioned that. obj_asteroid is the parent to obj_asteroid_s, which is the parent to obj_asteroid_ss.

Do I need to make them completely separate objects?
The problem that arises is that if you put a parent in a with loop (or your loop), all children are also included. There are blue and green asteroids, they are just overdrawn by themselves as a yellow version. If you have 3 different asteroids, make 3 different objects, and create a single parent for those 3.
Code:
draw_set_color();
with (asteroid_A)
{
   // draw
}
draw_set_color();
with (asteroid_B)
{
   // draw
}
draw_set_color();
with (asteroid_C)
{
   // draw
}
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
The problem that arises is that if you put a parent in a with loop (or your loop), all children are also included.
That was exactly what I suspected he was doing which is why I asked... In this case the easiest solution is to actually use a single "with" loop on the parent and then use draw_circle_colour depending on the actual object_index value. Something like this:

Code:
var _xs = xscale;
var _ys = yscale;
var _xp = xp;
var _yp = yp;
with (obj_Asteroid)
{
switch(object_index)
    {
    case obj_Asteroid_ss: var _c = c_red; break;
    case obj_Asteroid_s: var _c = c_blue; break;
    default: var _c = c_yellow; break;
    }
var wherex = _xp + x*(_xs);
var wherey = _yp + y*(_ys);
draw_circle_colour(wherex, wherey, 4, _c, _c, false);
}
 

Adro

Member
Hey Simon,

Cool. That makes a lot of sense, and would also explain why the sizes are all coming out larger, and why it works for the player, which is a different object.

Though as I'm new to this, won't having a parent for the three different objects still create this problem? Or is this parent object never created in the room? But rather exists to transfer code to the various child objects? (if that makes any sense? :confused:)
 

Adro

Member
Wow Nocturne, that code makes a lot of sense! Thanks!

Any reason for the underscore to in front of the variable names?
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Any reason for the underscore to in front of the variable names?
Yes! That's just how I make local variables easier to identify in my code. Since I didn't know the scope of the xscale/yscale or xp/yp variables, I wanted them in local scope so that they can be used in the "with" loop without having to resort to using "other". If that makes sense, then great! but if not then let me know and I'll explain in a bit more depth.... :)
 

Adro

Member
xscale and yscale are created in the 'create' event for the radar and create a percentage for the position of the object in the room.

By other do you mean when I use code like obj_asteroid.x?

Thanks again for your help! Very much appreciated :)
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Okay, what I mean is that variables can be local, instance or global in scope. In this case the xscale/yscale variables are instance scope, which means they are available to the instance running the code in ALL events and scripts that the instance calls. Now, the code above would be like this if we stick to instance variables:

Code:
with (obj_Asteroid)
{
switch(object_index)
   {
   case obj_Asteroid_ss: var _c = c_red; break;
   case obj_Asteroid_s: var _c = c_blue; break;
   default: var _c = c_yellow; break;
   }
var wherex = other.xp + x*(other.xscale);
var wherey = other.yp + y*(other.yscale);
draw_circle_colour(wherex, wherey, 4, _c, _c, false);
}
See how we've used "other" here? That's because when you use "with" the code within the {} is actually being run from the instance that the "with" is working on. So, instance variables for the FIRST instance are out of scope for the "with" instance, which means we have to preface them with "other" (it's the "other" instance in the code block that has the variables). This is fine and will work, but it's slightly slower as the engine has to go back and forth between the two instances to get values, and (imho) it's also less clear what's going on.

So, this is where we use local variables. A local variable is declared using "var" and is ONLY scoped to the current code block or script. This means that regardless of the instance running the code, the local variables will be accessible. It also reduces the lookups for values and makes the code c leaner and easier to read.

For more information see the manual sections on Parents, Addressing Variables in other instances and Variable Scope (if you haven't already!).

:)
 
Top