Collision and Global Variables

T

Tom_SavePointsGames

Guest
So I have a set of enemies with an inheritance tree and a set of bullets with an inheritance tree.

I want different bullets to deal to different enemies based on the type of bullet and that enemies particular weaknesses.

so I know to use collision checking using place meeting but that's pretty much it. I feel like whenever I run into a problem my solution is just to add global variables but I don't know if there is a down side to having like 100 global variables.

I can easily give each child bullet a damage value and type and then when the collision even checks for the parent bullet then the enemy itself could run a check against the global variables set for the bullet type and damage.

If I keep doing this for each solution the global variables will get out of hand. Is that a bad thing? and is there a better solution?

Thanks!
 
C

Ctl-F

Guest
So, if I understand this correctly you have different enemies with weaknesses, and different bullets, and you want each bullet to deal differently based on it's type.
As a stereotypical example you have a fire based enemy and it gets shot with a water based bullet, you want the bullet to do more damage then if a plant based enemy got shot with a water based bullet.
Yes?

If so look into the spoiler, if not, please correct me.
Okay, so you made it clear you knew about inheritance, so what I'd recommend is that you create a parent bullet, and it gets used as a template for the other bullets
Code:
//////////////////////////////////// obj_bullet_parent
/// create_event

damage = 10;
type = "normal";

//////////////////////////////////// obj_enemy_parent
/// create_event
hp = 20;
type = "normal";

/// Collision with obj_bullet_parent
var modifier = 1;
if(type == "water" && other.type == "grass"){
    modifier = 2;
}
else if(type == "fire" && other.type == "water"){
    modifier = 2;
}
else if(type == "grass" && other.type == "fire"){
    modifier = 2;
}
else if(type == other.type){
    modifier = 0.75;
}
else {check strengths...}


hp -= other.damage * modifier;
Then the great thing with that template is that the child objects overwrite the parent variables

Code:
//////////////////////////////////// obj_bullet_fire -> obj_bullet_parent
/// create_event
damage = 15;
type = "fire"

//////////////////////////////////// obj_bullet_water -> obj_bullet_parent
/// create_event
damage = 13;
type = "water";

//////////////////////////////////// obj_bullet_grass -> obj_bullet_parent
/// create_event
damage = 11;
type = "grass";
Am I making sense?
 
T

Tom_SavePointsGames

Guest
ok so yeah that makes perfect sense but the part I am confused about is the other.type. I was under the impression that using place_meeting doesn't return the colliding object instance id.

So is there another form of collision I should be using?

Also while your example seems to work perfectly fine it doesn't seem like less code than just using a global variable. is there an advantage to avoiding global variables?

Thanks again for your help.
 
C

Ctl-F

Guest
Okay, that was coded in the context of a collision event.
If you want to do it outside of a collision event, it's pretty easy:
instead of place_meeting, which returns boolean
use instance_place, which returns an id
Code:
// instead of
if(place_meeting(x, y, object))

// use
var o = instance_place(x, y, bullet);
if(o != noone){
   hp -= o.damage; //etc
}
The problem with global variables is that they are always in memory. instance variables are only in memory as long as the instance exists, and temporary variables are only in memory as long as the block.

If you have tons of global variables, your game may become a bit of a memory hog.
 

FrostyCat

Redemption Seeker
What you could have done is using macros to keep track of each type and the number of types. Say TYPE_FIRE for 0, TYPE_WATER for 1, etc. and TYPE_COUNT is the total number of types. Then use a global 2D array to denote the effectiveness coefficient between attacker and defender types:

Code:
//Default effectiveness is 1
for (var i = 0; i < TYPE_COUNT; i++) {
  for (var j = 0; j < TYPE_COUNT; j++) {
    global.effectiveness[i, j] = 1;
  }
}

//Exceptions go here
global.effectiveness[TYPE_WATER, TYPE_FIRE] = 2;
Now if you do as Ctl-F said and make type an instance variable of bullets and enemies, all you need to do is check global.effectiveness[type, other.type] in the bullet's collision event with the enemy and that would give you the effectiveness coefficient.
 

Yal

šŸ§ *penguin noises*
GMC Elder
Numerical variables in GM are doubles, so they use two words of memory each. (8 byte on a 32-bit system). Not a big deal, and you need huge amounts of data for it to rival your graphics and audio resources that are in the megabytes (literally thousands). Bushido Panda has an array of 'flags' (on/off variables) that is size 1000, and it still impacts the RAM usage less than loading the shortest song in the game. :p

What you SHOULD worry about if you keep adding global variables, though, are how easy they are to manage (I strongly advocate using arrays whenever possible, especially for stuff you'd save in a savefile, since you can loop through them and do other batch-processing stuff), and making sure there's no race/conflict conditions where you use the same variable name for different things without realizing, resulting in unrelated objects messing each other up.
 
T

Tom_SavePointsGames

Guest
Thanks everyone for the help. I think i have a handle on what I need to do. Also sorry for the confusion. I am so used to coding everything because I use state machines for enemies and the player that I didn't realize you guys were talking about collision events themselves. I also didn't realize that collision events in an object returned instance IDs which is good to know.

Thanks!
 
Top