Jump to content


Photo

Keeping track of enemy health


  • Please log in to reply
13 replies to this topic

#1 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 07:20 PM

Designing a system to keep track of all the health values of every instance of an enemy has always given me headaches.
I could create an initialise all the variables or an array at game start...
But that would require that I knew exactly how many enemies will be in each level. What if I have a spawn point which creates new enemies until it is destroyed?
Global and local variables in Game Maker can be a real ***** - variables that only one object needs (but needs to access it from different triggers) still need to be global.

What I want to know is what do you usually do under these circumstances?
How do you keep track of the health value of every in room enemy?

EDIT:
This topic is classed as SOLVED.
There is working code available should you need it.

Edited by _174413, 20 April 2012 - 10:04 PM.

  • 0

#2 Ysmor

Ysmor

    GMC Member

  • New Member
  • 84 posts
  • Version:GM8

Posted 20 April 2012 - 07:27 PM

My enemies store their health within themself - so I use local variables for them.
Why do you need /want to keep track of all your enemies’ health?

- Ysmor
  • 0

#3 IsmAvatar

IsmAvatar

    Good Samaritan

  • GMC Member
  • 2411 posts
  • Version:GM8

Posted 20 April 2012 - 07:29 PM

variables that only one object needs (but needs to access it from different triggers) still need to be global.

I believe this statement is in err.

The solution is local variables. If you can't figure out how to access a specific instance's local variable, that doesn't mean it can't be done. That just means you need to learn how. Using "dot access" (a.B), the "with" construct (with (a) { }), and special variable "other" (other.B), what you desire can be achieved without the need of introducing a global variable.
  • 0

#4 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 07:38 PM

variables that only one object needs (but needs to access it from different triggers) still need to be global.

I believe this statement is in err.

The solution is local variables. If you can't figure out how to access a specific instance's local variable, that doesn't mean it can't be done. That just means you need to learn how. Using "dot access" (a.B), the "with" construct (with (a) { }), and special variable "other" (other.B), what you desire can be achieved without the need of introducing a global variable.


Of course! I hadn't thought of that...

In the same way I can access obj_ball.x
I can also get obj_ball.myVariable

Is that right?

And the with thing. Yes. Ok, I know what to do now.
Thank you ever so much!

My enemies store their health within themself - so I use local variables for them.
Why do you need /want to keep track of all your enemies' health?

- Ysmor


Yeah, so what I meant is that if I declare a variable in the Create event, I find that I cannot access it in another event - even if it's from the same object.

In answer to your question:
I want to keep track of every enemy's health variable so I know when to destroy their instances.

Edited by _174413, 20 April 2012 - 07:35 PM.

  • 0

#5 IsmAvatar

IsmAvatar

    Good Samaritan

  • GMC Member
  • 2411 posts
  • Version:GM8

Posted 20 April 2012 - 07:46 PM

Yeah, so what I meant is that if I declare a variable in the Create event, I find that I cannot access it in another event - even if it's from the same object.

You wouldn't happen to be declaring the health variables with "var", would you?

Edited by IsmAvatar, 20 April 2012 - 07:47 PM.

  • 0

#6 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 07:49 PM

Yeah, so what I meant is that if I declare a variable in the Create event, I find that I cannot access it in another event - even if it's from the same object.

You wouldn't happen to be declaring the health variables with "var", would you?


Heh, yes I am.
Until now I wasn't aware there were any other ways of declaring them... Other than globalvar
  • 0

#7 IsmAvatar

IsmAvatar

    Good Samaritan

  • GMC Member
  • 2411 posts
  • Version:GM8

Posted 20 April 2012 - 08:04 PM

Simply assigning a value to a variable will declare it as local.
If you declare a variable with "var", it is a temporary variable that disappears once the script/event finishes.
  • 0

#8 D1g1talAli3n

D1g1talAli3n

    BoyGenius

  • New Member
  • 963 posts
  • Version:GM8

Posted 20 April 2012 - 08:06 PM


Yeah, so what I meant is that if I declare a variable in the Create event, I find that I cannot access it in another event - even if it's from the same object.

You wouldn't happen to be declaring the health variables with "var", would you?


Heh, yes I am.
Until now I wasn't aware there were any other ways of declaring them... Other than globalvar

You don't declare variables in GM. They are created once you assign a value to them.
The statement var a,b,c,d,...; is used to create temporary variables that are destroyed at the end of a script. They are used for storing temporary data that you don't want to waste memory on, or if you don't want any variable name conflict.
The statement globalvar a,b,c,d,...; is used to declare variables as global so that you don't have to keep using "global." before them. This is permanent and stays throughout the game.

I suggest you take a good long look at the GML section in the help file (press F1 in GM) to familiarize yourself with GML. Don't worry, it's a very simple language, you'll learn it in a few days if not hours.
  • 0

#9 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 08:09 PM

Right.
It all makes sense to me now.
Being a .NET developer, it sort of annoys me that variables are declared in a way that I'm used to... But hey.

Thanks for the help, DigitalAlien. But can you believe I've been using GML since 2007?
Yes, it was the first language I started to learn before I moved to C# and XNA.
I know where the documentation is and use it often, but sometimes it doesn't explain things very well.

Thanks to all your help on the subject.
  • 0

#10 D1g1talAli3n

D1g1talAli3n

    BoyGenius

  • New Member
  • 963 posts
  • Version:GM8

Posted 20 April 2012 - 08:15 PM

Right.
It all makes sense to me now.
Being a .NET developer, it sort of annoys me that variables are declared in a way that I'm used to... But hey.

Thanks for the help, DigitalAlien. But can you believe I've been using GML since 2007?
Yes, it was the first language I started to learn before I moved to C# and XNA.
I know where the documentation is and use it often, but sometimes it doesn't explain things very well.

Thanks to all your help on the subject.

Haha, I see. Getting a little rusty.
And no problem :thumbsup:
  • 0

#11 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 09:16 PM

Ok.
Things are going well.... Ish.
I had set up two objects { a player and an enemy }
and given each their own set of variables to track statistics like { hit points, attack power, defence, accuracy and so on }


Then I wanted to see what would happen if I had two instances of the enemy in play.
It appears that each instance track their own set of variables - which is perfect: exactly what I needed and why I started this topic.

However, two issues arose from my short test.
1. When the enemy fires a bullet, every one of the bullets always set their direction to the same image_angle as the enemy instance with the lowest id.
This is because of the code I use in the bullets, which I will show later.
2. I have another object which is used to draw the enemy HP just above them, but it only does it for the enemy instance with the lowest id.
This is also because of code used in this particular object.

So the problem must arise from how I am choosing to access these variables.
The method I am currently using is as thus:

obj_bullet Create Event:

image_angle = obj_enemy.image_angle;
direction = image_angle;

obj_drawEnemyHealth Draw Event:

if (instance_exists(obj_enemy))
{
draw_text(obj_enemy.x,obj_enemy.y-16,string(obj_enemy.NRG));
}

(btw, NRG is used for hit points. Say it slowly... En... Ar... Gee... Energy!)

Both problems arise from the same method of data access, but I have a feeling that they will require two separate solutions.
So what do you guys make of this?
If this was your project, what would you do?

Edited by _174413, 20 April 2012 - 09:17 PM.

  • 0

#12 Lemon Pie

Lemon Pie

    GMC Member

  • GMC Member
  • 194 posts

Posted 20 April 2012 - 09:46 PM

1. When the enemy fires a bullet, every one of the bullets always set their direction to the same image_angle

direction = instance_nearest(x,y,obj_enemy).direction;
image_angle = direction;

2. I have another object which is used to draw the enemy HP just above them, but it only does it for the enemy instance with the lowest id.

if you are using a single obj to draw it above all the instances of obj_enemy you can use this:
with obj_enemy
{
     draw_text(x,y-16,NRG)
}

  • 0

#13 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 09:50 PM

OH!
Hang on a second....
Looking through the user manual, I find the chapter titled: "Addressing variables in other instances"
Now, I've read this a million times, but another time can't hurt, right?

And then I notice the quote: "When you create an instance in the program, the call returns the id"
So... Theoretically I should be able to set the direction of the bullet using the method described here.

As for the second problem...
Well, I guess I'll have to look up the instance id.

Which is all well and good if I'm looking up the ids for instances I've placed in the designer...
But what if I have a spawn point that makes new instances?
What then? Should I use mathematics to work out what the id of an instance would be before it's even created?

If I make a variable in the spawn point called numberOfTimesSpawned,
I should be able to just add that number to the id of the last instance I placed in the designer and all should work out fine....
Right?


1. When the enemy fires a bullet, every one of the bullets always set their direction to the same image_angle

direction = instance_nearest(x,y,obj_enemy).direction;
image_angle = direction;

2. I have another object which is used to draw the enemy HP just above them, but it only does it for the enemy instance with the lowest id.

if you are using a single obj to draw it above all the instances of obj_enemy you can use this:
with obj_enemy
{
 	draw_text(x,y-16,NRG)
}


You clever little squirrel, you.
Thank you very much for your help!
I just made a new post in this forum with some of my recent thoughts, so please take a look at that too

EDIT:
Damn, the coding in this forum is smart.
So, actually that new post is now this one.

Edited by _174413, 20 April 2012 - 09:52 PM.

  • 0

#14 _174413

_174413

    GMC Member

  • New Member
  • 22 posts
  • Version:GM8

Posted 20 April 2012 - 10:03 PM

Alright. Seriously. I mean it this time.
Probably.

I'm done here. All my code works flawlessly.
Let's set this topic as SOLVED, baby!
  • 0




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users