Adding range to dynamite character (SOLVED)

Started by R4L, Sat 24/02/2007 23:01:35

Previous topic - Next topic

R4L

Hello! Im working on a small side project (I'm taking time off of HH) and I have a character who can drop dynamite anywhere, and it blows up as planned. This works great, but I want the character to be affected by the blast, so he loses health.

Problem is, I don't know how to script it. I've searched for adding a "range" or dynamic collision to the dynamite character (cDummy) so that there is no collision until it explodes, then it goes away after, but to no avail.

Help is much appreciated! :)

R4L

EDIT: Also, how would I be able to make it so my character can walk into objects to pick them up?

Thanks!

Scorpiorus

QuoteI have a character who can drop dynamite anywhere, and it blows up as planned. This works great, but I want the character to be affected by the blast, so he loses health.

For example, you can check how far the player is from cDummy (dynamite) and apply damage based on that:

repeatedly execute:

Code: ags

if ( cDummy.Animating ) // it's blowing up
{
Ã,  Ã,  if (player.Room == cDummy.Room)
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  float dX = IntToFloat( player.x - cDummy.x );
Ã,  Ã,  Ã,  Ã,  float dY = IntToFloat( player.y - cDummy.y );
Ã,  Ã,  
Ã,  Ã,  Ã,  Ã,  float distance = Maths.Sqrt( dX*dX + dY*dY * (1.0) );
Ã, Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  if (distance == 0.0) distance = 0.001; // just to avoid division by zero
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  int damage = FloatToInt( 10000.0 / distance ); // calculate damage (you can try other formulas here)
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  playerHealth = playerHealth - damage; // decrease health
Ã,  Ã,  
Ã,  Ã,  }
}


You may probably need to tweak the values to correspond to the player health magnitude.

Also note the factor 1.0 in the distance formula -- you may want to increase it so that the player could walk behind/infront of the dynamite and would not get hurt too much.





Quote from: R4L on Sat 24/02/2007 23:01:35Also, how would I be able to make it so my character can walk into objects to pick them up?

You can use the player.IsCollidingWithObject() function in room's repeatedly execute to determine which objects are near the player, iterating through all objects in this room:

room's (or global) repeatedly execute:

Code: ags

int i = 0;
while (i < Room.ObjectCount)
{
Ã,  Ã,  if ( player.IsCollidingWithObject( object[i] ) )
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  // pick it up
Ã,  Ã,  }

Ã,  Ã,  i++;
}

R4L

WOW! Thanks a lot Scorpious! I have two problems though.

1. The code I put in repeatedly_execute doesn't work?  :'(

Im not sure whats wrong.

2. Im not sure what to put here:

Code: ags

    {
        // pick it up
    }


Sorry if I seem to demand. Its just that it's been a long time simce I coded for a long while. It starts to mess with me. :D

Scorpiorus

Quote from: R4L on Sun 25/02/2007 01:59:50The code I put in repeatedly_execute doesn't work?

Which one? The dynamite code won't compile as I used undeclared playerHealth variable. I assume you should change it to yours which stores character health.

Quote2. Im not sure what to put here:
{
Ã,  Ã,  // pick it up
}

Standart object is being picked up routine: :)

Code: ags

// pick it up
object[i].Visible = false;
player.AddInventory( inventory[i] );


R4L

Quote from: Scorpiorus on Sun 25/02/2007 02:23:48
Quote from: R4L on Sun 25/02/2007 01:59:50The code I put in repeatedly_execute doesn't work?

Which one? The dynamite code won't compile as I used undeclared playerHealth variable. I assume you should change it to yours which stores character health.

I did that but it won't work. Here is my code:

Code: ags

#sectionstart repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE
function repeatedly_execute() {
  // put anything you want to happen every game cycle here
   
  
  if (IsTimerExpired(2) == true){
    
   RawDrawImage(cDummy.x-14, cDummy.y-18, 62);
    return;
  }
  
    int dynamite = GetGlobalInt(1);
  String temp = String.Format("%d", dynamite);
  GInt.Text = temp;
   
   int health = 100;
  String teemp = String.Format("%d", health);
  GHeal.Text = teemp; 
  
if(cDummy.Animating == true){
        if (cEgo.Room == cDummy.Room)
    {
        cDummy.FollowCharacter(null);
        float dX = IntToFloat( player.x - cDummy.x );
        float dY = IntToFloat( player.y - cDummy.y );
   
        float distance = Maths.Sqrt( dX*dX + dY*dY * (200.0) );
                          
        if (distance == 0.0) distance = 0.001; // just to avoid division by zero
                         
        int damage = FloatToInt( 10000.0 / distance ); // calculate damage (you can try other formulas here)
                         
        health = health - damage; // decrease health
   
    }
}

  else{
    cDummy.Transparency = 100;
  cDummy.FollowCharacter(cEgo, FOLLOW_EXACTLY, 0);
}
}
#sectionend repeatedly_execute  // DO NOT EDIT OR REMOVE THIS LINE


Quote
Quote2. Im not sure what to put here:
{
    // pick it up
}

Standart object is being picked up routine: :)

Code: ags

// pick it up
object[i].Visible = false;
player.AddInventory( inventory[i] );



See thats the thing, its not really an item. It just adds to health, or dynamite depending on what item you pick up. So I think I need to change this to change the dynamite int (GLOBAL INT 1) and health int (int = health) but I'm not sure where to start.

Scorpiorus

I see the code obviously won't work but I can't quite get what are you trying to do, can you elaborate a little bit more?

For instance, what is cDummy.FollowCharacter(cEgo, FOLLOW_EXACTLY, 0) for?


Quote from: R4L on Sun 25/02/2007 02:30:21See thats the thing, its not really an item. It just adds to health, or dynamite depending on what item you pick up. So I think I need to change this to change the dynamite int (GLOBAL INT 1) and health int (int = health) but I'm not sure where to start.

Sure, you don't necesserely have to add an item, you can as well increase a global variable or something, depends on what you are after:

Code: ags

object[i].Visible = false;

if ( i == 0 ) // object #0 some health potion
{
Ã,  Ã,  health = health + 1;
}
else if ( i == 1 ) // object #1 ammo or whatever
{
Ã,  Ã,  ammo = ammo + 3;
}

R4L

#6
Oh, now I see.  As for cDummy, hes my invisible lightning fast character who follows the main character around. When you hit D on the keyboard, he stops following and turns into a piece of dynamite. I have this working fine, but would like to add a range to him, so he does damage to others. Sorry for not explaining as much Scorpious.

EDIT: The code that lets me pick up objects works! It works really good too! Couldn't I use the pixel perfect collision detection module to work out damages?

EDIT: The range code is working now too. I just had to export my health int. I forget to do stuff sometimes.  :D

So it's working, but it always takes health off, which is bad right now. Seeing how int distance is a float, can I use int distance to make a check to see if cEgo is far enough, THEN take off health?

Scorpiorus

Quote from: R4L on Sun 25/02/2007 17:25:59So it's working, but it always takes health off, which is bad right now. Seeing how int distance is a float, can I use int distance to make a check to see if cEgo is far enough, THEN take off health?

I think you just need to tweak up the logic:

repeatedly executed routine:

if ( dynamite is exploding... )
{
Ã,  Ã,  if ( character is in the dynamite's room )
Ã,  Ã,  {
Ã,  Ã, Ã,  Ã,  Ã, calculate distance between the dynamite and the player;
Ã,  Ã,  Ã,  Ã,  calculate damage based on distance;
Ã,  Ã, Ã,  Ã,  Ã, take off health;
Ã,  Ã,  }

Ã,  Ã,  finally, stop dynamite's exploding so that it won't take health off constantly;
}


dynamite is exploding...

it can be an if ( cDummy.Animating ) or if ( IsTimerExpired(...) ) or if ( cDummy.Frame == LAST_FRAME ) or etc check, depending on how you have actually implemented it.


As for distance check, the script I posted before applies damage amount depending on how far the character is from the dynamite, but of course you can set up a threshold and don't take off health if the character is beyond that:

if ( dynamite is exploding... )
{
Ã,  Ã,  if ( character is in the dynamite's room )
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  calculate distance between the dynamite and the player;
Ã,  Ã,  Ã,  Ã,  if ( distance < 100.0 )
Ã,  Ã,  Ã,  Ã,  {

Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  calculate damage based on distance;
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  take off health;
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  }

Ã,  Ã,  finally, stop dynamite's exploding so that it won't take health off constantly;
}


R4L

#8
I get the logic, and i've implemented that into the script, but it's still taking health off
as soon as I lay the dynamite down. As soon as I drop it, it starts taking health. Would I have to get a certain frame of the animation, then run the code?

EDIT: Thanks you so much Scorpious! I had to add this to get it working:

Code: ags

if(cDummy.Animating == true)
{
Ã,  Ã,  if (cEgo.Room == cDummy.Room) 
Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  cDummy.FollowCharacter(null);

Ã,  Ã,  Ã,  Ã,  if (cDummy.Frame > 6)
Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã, Ã,  Ã,  Ã, float dX = IntToFloat( player.x - cDummy.x );
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  float dY = IntToFloat( player.y - cDummy.y );
Ã,  Ã, 
Ã,  Ã, Ã,  Ã,  Ã, Ã,  Ã,  float distance = Maths.Sqrt( dX*dX + dY*dY * (1.0) );
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  
Ã, Ã,  Ã,  Ã, Ã,  Ã,  Ã,  if (distance < 100.0 )
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  {
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  int damage = FloatToInt( 10.0 / distance ); // calculate damage (you can try other formulas here)
Ã,  Ã,  Ã,  Ã,  Ã, 
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  health = health - damage; // decrease health
Ã,  Ã,  Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  Ã,  Ã,  }
Ã,  Ã,  }
}


Once again, thank you so much for helping me. It was really bothering me and I wasn't sure of what angle I should look at it from.

EDIT: Also, if you don't mind me asking, how does the distance calculation formula work? Im only in 10th grade (halfway to 11th) and haven't learned any trigonometry yet, so I have no clue how to calculate floats.

edit by scorpiorus to fix code indentation

Scorpiorus

You are welcome, I'm glad you got it working!

As for the distance, I just used the Pythagorean Theorem. This is a common way to calculate a distance between two points.

:)

R4L

Ah, a2 + b2 = c2...

Looks way different in code!  :D

SMF spam blocked by CleanTalk