Page 1 of 1

Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 9:59 pm
by energiez
I'm very new to both GE and C. I'm currently working on an RPG in the vein of LoZ: Link to the Past (although i'm still working on the base mechanics) and games like that. I have some questions, to which I haven't yet found good answers or resources.

As far as combat goes, is it best to use collision rather than distance to determine whether damage should be dealt? If it helps, I do want solid (not being able to be walked through by the player) enemies.

In the case of collision, i tried using collisionfree and an if/else statement to reduce the hp of the Collision Actor if there was a collision, but I couldn't get this work.

Currently, I have my code set to check for distance between the player and a specific other actor (the enemy) and then reduce its hp if it is close enough. Of course, this set up isn't very useful, as it can only work for one actor without having to change variables in order to check for distance/ reduce the hp of a different actor.

Generally, I am just looking for tips, etc. for developing a good combat system.

Thanks for any assistance!

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 10:46 pm
by skydereign
I would go with collisions, but instead of using player colliding with the enemy, I would use another invisible actor (or visible if you make it the sword). Essentially when you want to attack you create this invisible hitbox that if it is colliding with the enemy reduces hp, but ultimately destroys itself when the attack should stop. Also I'm not sure if you are already doing this, or the game isn't supposed to be 2.5d, but if you want the 2.5d effect I would recommend using collision bases at the feet of the characters. That way you can be in front or behind of other actors based off of the base actor's y coordinates.

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:00 pm
by energiez
All right thanks!
But how do I get it to harm the target that is being collided with? I still can't figure out how to make it so the player can attack any actor being collided with. Is there a way I can get the name of the actor in the collision, in order to implement it in a DestroyActor when it's hp reaches zero?

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:06 pm
by skydereign
Okay, so you can have a collision event with any actor. In the collision event gE provides a special actor type. If you are using functions that gE provides, such as DestroyActor, you can use this code to destroy the specific actor you are colliding with.
Code: Select all
DestroyActor("Collide Actor");


Now if you want to access any of the other actor's variables you can use collide.var. So in your case you wanted to access the colliding actor's name, which you would do by having collide.name(though actually using "Collide Actor" is better since you were asking about DestroyActor). Now I assume you have an actor variable hp, so you can do this.
Code: Select all
collide.hp--;
if(collide.hp<=0)
{
    DestroyActor("Collide Actor");
}

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:11 pm
by energiez
Awesome! Thanks a ton. I've seen you on a ton of threads here, you're doing great things for people!

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:26 pm
by energiez
Dang it, just realized I am missing something very important:
How/where do i define actor variables? I assume i need an enemy.hp (assuming the enemy actor is just named "enemy") or something for the collide.hp to reference, right?
I have just been using global variables this whole time, i think.

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:31 pm
by skydereign
Well how have you been declaring global variables? If you are using gE's built in system opposed to global code then all you need to do is go to the variable and where it says global specify actor instead. If you are using global code, you'll have to learn how to use the other way. When in the script editor click [Variables], then [Add]. From here type a name and switch the [Global] to be [Actor variable]. Then click add and you have an actor variable.

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:34 pm
by energiez
Oh wow, thats a duh moment for me, thanks.

Re: Melee combat questions from a GE newbie

PostPosted: Fri Feb 10, 2012 11:57 pm
by energiez
So I set the collision event to be with any actor, in order to not have to make a new event for every different enemy. In this case, how can I prevent other actors, like walls, from being killed?
Additionally, how could I check for a key press (e.g. the attack animation button) during the collision? Would i use getLastKey, or something different?

Re: Melee combat questions from a GE newbie

PostPosted: Sat Feb 11, 2012 12:05 am
by skydereign
Why do you need to know what the last key was? Are you implementing different attacks? If so I recommend having a variable instead of relying on a key press. But to answer your question getLastKey could work, that or you could use getKeyState (this allows you to see what keys are pressed). The way I suggested is when you attack, you should be able to tell you are attacking either via a state variable or just using one that tells the game you are attacking.

As for the collision event, what I usually do is for my enemy actors, I have a variable that holds what type of enemy. In their create actor events I set their actor variable type to some unique identifier (the key being they are set to a nonzero value). That way you can do this in the collision event to single out only the enemy actors.
Code: Select all
if(collide.type!=0)
{
    // colliding with an enemy
}

Re: Melee combat questions from a GE newbie

PostPosted: Sat Feb 11, 2012 12:13 am
by energiez
For now, i just wanted the player to have to press a key to swing, instead of just having to run into the enemy.
Ok, that "type" actor variable makes a lot of sense. So then the inanimate objects can just be type 0. Thanks!

Re: Melee combat questions from a GE newbie

PostPosted: Sat Feb 11, 2012 12:18 am
by skydereign
Ok, well the collision actor should destroy itself after a certain amount of time. So when you press attack it creates it in front of the player, and it destroys itself when the attack ends (you could have the animation finish of the player destroy it as well). But generally I use a variable that holds what the player is doing at all times, and use that to determine if things should happen. It's been coined the state method, there's several things on the forums about it, as well as I wrote this tutorial for another user if you're interested. http://game-editor.com/State_Method
It's a good way of controlling how your things interact with your player.

Re: Melee combat questions from a GE newbie

PostPosted: Sat Feb 11, 2012 1:30 am
by energiez
I checked that tutorial out, thanks, that will be very helpful.
I'm having a problem with types:

The hitbox is still interacting with the player, although i declare it's type and provide the if statement for collision.
Code: Select all
Player.hp = 50;
Player.type = 0;

I declare that when starting the game.

Then
Code: Select all
if(collide.type!=0)
{
   collide.hp = collide.hp - playerdmg;
}
if(collide.hp<=0)
{
    DestroyActor("Collide Actor");
    playerxp = playerxp + collide.xp;
}

in the collision event

Re: Melee combat questions from a GE newbie

PostPosted: Sat Feb 11, 2012 4:34 am
by skydereign
As for every problem you have I suggest dissecting the code that surrounds it. In your case I'll comment in what is happening.
Code: Select all
if(collide.type!=0) // if colliding with an enemy (only enemy actors have a type of 1
{
   // lower the enemy's hp
   collide.hp = collide.hp - playerdmg;
}


// notice this large gap



if(collide.hp<=0) // if the colliding actor's hp is less than or equal to 0
{
    // destroy the colliding actor
    DestroyActor("Collide Actor");

    // increase the hp
    playerxp = playerxp + collide.xp;
}

So you have two independent if statements. Notice how the second if just checks if the hp is less than or equal to 0, which is the case for any actor without hp.