Game Development Community

Would this script be correct??

by Martyn · in Torque Game Builder · 01/18/2009 (4:59 pm) · 15 replies

Hello,

I am working on my own shooter which I am working from the tutorial one but change and developing.

I am trying to set it up so that when the player fires a missile at the enemy it reduces their life - once their life is at 0 they explode and a new on is respawn.

I have set the life varible on level load:

function EnemyApprentice::onLevelLoaded(%this, %scenegraph)
{
$EnemyApprentice = %this;
$EnemyApprentice.life = 50;
}

Here is what I have when they are hit by the missile (this script gets called from the missile CS file on collision

function EnemyApprentice::damage(%this)
{
if($EnemyApprentice.life == 0)
{
%this.spawn()
}

else
{
$EnemyApprentice.life == 25;
}

I am not sure if it is correct or if I am doing it completely wrong lol

Any feedback would be greatful :)

Thank You

About the author

I have been interested in game development for around 10 years, it has always remained a hobby. I am now looking to develop my skills and maybe progress it from a hobby into a 2nd income.


#1
01/18/2009 (5:15 pm)
Why are you making it global?
#2
01/18/2009 (5:22 pm)
Not sure, I assume that for the player it would want to be global so that their life continues to the next level.

Although for the enemy I would probably best using local since its not going to the next level - is that correct?
#3
01/18/2009 (5:50 pm)
Well, the EnemyApprentice is global, which is fine if you're doing a 1v1 game, but it won't scale.

function EnemyApprentice::onAdd(%this, %scenegraph)
{
%this.life = 50;
}

Since you'll be making more enemies, you probably don't want to use "onLevelLoaded" for them, that's only called when the level is loaded. Also, I would recommend putting the value for "life" in the datablock as well. Again, that's just a personal preference.

That would be sufficient, but when it dies, you'll need to spawn a new one, won't you?

In that case, you could then do something like:

function EnemyApprentice::SpawnAnother(%this)
{
     %obj = new t2dStaticSprite()
     {
     scenegraph = %this.scenegraph;
     config = YourEnemyApprentice_Datablock;
     }
}

In this case, when you call %this.scenegraph, that's referring to the object which called the function. The config should call a datablock which would have all of the relevant information, layer, class, etc. You could just pile all of that into the OnAdd(), but I find that to be tacky.

If your enemy isn't a t2dStaticSprite, just use the right thing there.

#4
01/18/2009 (5:53 pm)
Excellent Thank You :)

Would my damage function be correct??

So if my attack did 25 damage, it would take 25 of the enemies life, checks if its 0 and if so the enemy ship would explode.

My plan is then to have it respawn at specific spawn points after x amount of time which I would then uise the schedule for
#5
01/18/2009 (6:01 pm)
No, the damage function is not right.

else
{
$EnemyApprentice.life == 25;
}

That's a comparison, plus, you want to go back to using the local form of it. So...

function EnemyApprentice::damage(%this)
{
if(%this.life == 0)
{
%this.spawn()
}

else
{
%this.life = 25;
}

}

Your code will *not* change the life, it will just do a comparison and quietly return a boolean which you aren't capturing in any way. Remember "=" sets a value, "==" compares if two values are equal. It's kind of a funny thing, because the first part has the comparison properly written, but the 2nd part uses it again instead of a assigning a new value to the life member.

Strings are slightly different for comparison.
#6
01/18/2009 (6:06 pm)
oh I see thank you :) - no coding experience I think im sort of starting to get how it works hehe

Thanks again!
#7
01/18/2009 (6:13 pm)
Well, you'll figure it out. The best thing you can do is to plan your code and your program out before you write the code. If you just dive into it, you'll write poor code and then you'll keep hacking away at it until it's an unmaintainable mess.

It's good that you have a general idea of what you're hoping to accomplish. Also, it's important to think about the scalability and re-usability of what you write. In that sense, your damage(...) function should probably accept an integer of how much damage to give that enemy and then subtract that damage instead of just setting it directly.

Lastly, "damage" might seem like a good name at first for a function, but "damage" is a transitive verb. So you *damage* something, right? To me, that sounds like a bullet would have a function called "damage", but when some function damages the object which called it, you might want to consider "takeDamage" or something synonymous. Clarity is key to maintainable code.
#8
01/18/2009 (6:23 pm)
yeah that makes sense - Thanks :)
#9
01/19/2009 (6:06 am)
Hi, I have one more issue now lol

I am currently using this code:

function PlayerFireball::onCollision( %srcObj, %dstObj, %srcRef, %dstRef, %time, %normal, %contactCount, %contacts )
{
if (%dstObj.class $= "EnemyApprentice") {
%srcObj.explode();
%dstObj.ReceiveDamage();
}
}

Its job (well if it worked) was when the fireball hits an object in this case EnemyApprentice it would run the receivedamage script.

The plan is to try and add multiple classes so that if the fireball was to hit something else it would run another script.

This is the receive damage function I have;

function EnemyApprentice::ReceiveDamage(%this)
{
if(%this.life == 0)
{
%this.SpawnApprentice();
}

else
{
%this.life = 25;
}

}

Thanks :)
#10
01/19/2009 (7:34 am)
The simple thing is a case statement. Although if you are going to throw a lot of fireballs around, then I would instead of have the target actually handle the collision logic.

The reason goes something like this:

Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.
Fireball hits an object
     Checks to see if it's a cow, house, car, person, tree, airplane, peanut butter sandwhich.

The problem here is that you're checking a big list every single time and that's not very efficient. Instead, you might be better off just have the recipient process it if you have many types of recipients. Of course, if you just want to have it do something very common like damage it for 25 points, then just have every class get a function that takes damage and a value. Also, if your primary means of doing things is by a fireball, you could just give each target class a function of "hitByFireball(...)'.

{ 
%srcObj.explode(); 
%dstObj.hitByFireball(); 
}
#11
01/19/2009 (7:44 am)
Great! Thank you :)

Not long received Game Programmers guide to Torque so hopefully I can get through that :)
#12
01/19/2009 (11:27 am)
Sorry to post again! LOL

I have followed your advice and I am using the hitByFireball function.

Within this function I wish to do it so that it does actually take life from the enemy as above. This is so that I can bring in more abilities later to offer stronger attacks etc.

Within the function stated above would I do this?

%this.life - 25; = %this.life (DO not think this is right but not sure how I would do it)

if(%this.life == 0)
{
%this.spawn()
}

else
{
return;
}

Thanks
#13
01/19/2009 (11:37 am)
%this.life = %this.life - 25;
#14
01/19/2009 (11:53 am)
Cool Thanks :)
#15
01/19/2009 (1:03 pm)
Makes perfect sense I am kicking myself right now! :)