• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

How to make an item when the hero approaches it, attacks the hero every few seconds and plays animations (gms 1.4)

sensodyne

Member
It might help to see an actual screenshot of the sprites you're using. Is it actually the case that the obj_hero's bounding box is contained completely within the trap's bounding box?
I don't know what you mean, but the trap object has a set of trap animation icons which consists of a dozen images. It is assigned to an object


What is the image_index value when the animation isn't playing? The condition if image_index > 14 && image_index < 16 means that the block should only run if the image_index is 15. Is that the only place in the entire game where you reduce obj_hero.hp?

should be image_index = 0 because this is the start frame of the animation, Should there be a condition that would check the start frame of the animation? Do I understand it correctly?
I do not understand if this is the only place in the game where I reduce the player's hp
 

Nidoking

Member
the trap object has a set of trap animation icons which consists of a dozen images.
That's the number of frames in the sprite. That's not particularly helpful, although if it has twelve images, then its image_index should clearly never be greater than 14. I was asking about the dimensions of the sprite. Its width and height, and the width and height of the sprite you've assigned to the obj_hero.

should be image_index = 0 because this is the start frame of the animation, Should there be a condition that would check the start frame of the animation?
image_index = 0
Check whether the image_index is equal to zero, or better, less than one (again, due to rounding error). But I say again, as I have said before: If you want the hp subtracted when the animation begins, why can't you subtract the hp at the same time that you set the animation to begin? Is the trap supposed to animate if the condition you're trying to explain, which causes the obj_hero instance to be "trapped" in the trap, is not true? Or should the trap only animate when the obj_hero is in the correct position? You still haven't explained your actual problem very well. You will get much better answers to your question if you ask the question clearly. More screenshots/pictures might help. It would be very helpful to see an example of what is happening that you don't want to happen.
 

sensodyne

Member
That's the number of frames in the sprite. That's not particularly helpful, although if it has twelve images, then its image_index should clearly never be greater than 14. I was asking about the dimensions of the sprite. Its width and height, and the width and height of the sprite you've assigned to the obj_hero.
AAA Ok
sprite dimensions are

width 148
height 186
subimages trap has 29

height of the sprite you've assigned to the obj_hero.

width 128
height 128

I have many states of the hero's animation when the hero is standing, it has the dimensions of 128x128 as he goes, it also has the dimensions of 128x128 but when he shoots, he attacks, he has different dimensions, the same as he dies
The hero's collision mask has dimensions

width 63
height 128

orgin x31 y64


Check whether the image_index is equal to zero, or better, less than one (again, due to rounding error). But I say again, as I have said before: If you want the hp subtracted when the animation begins, why can't you subtract the hp at the same time that you set the animation to begin? Is the trap supposed to animate if the condition you're trying to explain, which causes the obj_hero instance to be "trapped" in the trap, is not true? Or should the trap only animate when the obj_hero is in the correct position? You still haven't explained your actual problem very well. You will get much better answers to your question if you ask the question clearly. More screenshots/pictures might help. It would be very helpful to see an example of what is happening that you don't want to happen.

ok i will try to draw it

trap.jpg
 
Last edited:

TailBit

Member
Ok
This is what my code looks like now.
I did so as suggested Tailbit.
In this variant, it does not take the energy trap from the player.
The player has full energy all the time

collision of the trap with the hero

GML:
if bbox_left < other.bbox_left
&& bbox_right > other.bbox_right{

if image_speed > 0 {
if obj_hero.hurtClock = 0  {
obj_hero.hp -= 1;
obj_hero.hurtClock = room_speed*2
}

  }
   }
Animation end

GML:
image_index = 0;
image_speed = 0;
alarm[0] = 3*room_speed;
Step

GML:
if !active
&& abs(x+16-obj_hero.x) < 72 {
active = 1;
image_speed = 1;
}
Alarm[0]

GML:
active = 0;
I tried this code
Oh, I tried too, and still the trap is not taking away the player energy.

GML:
if bbox_left < other.bbox_left
&& bbox_right > other.bbox_right{

if image_index = 15 {
if obj_hero.hurtClock = 0  {
obj_hero.hp -= 1;
obj_hero.hurtClock = room_speed*2
}

  }
   }
With that part, and it worked for me ..
- it starts animating as player touch it
- only damaging player on frame 15, if in bbox

1642181265298.png

I had them draw their bbox just to be sure:
GML:
draw_self();
draw_rectangle(bbox_left,bbox_top,bbox_right,bbox_bottom,1);
trap also drew:
draw_text(x,y,string(abs(x+16-obj_hero.x)) + " " + string(sprite_index) + " " + string(image_index))
You can set a manual bbox in the sprite settings if that is the problem .. but yeah, tested and it works, so I'm not sure what else it could be :/
 

Nidoking

Member
Those are excellent pictures, thank you. Now I understand what it is you want, and I think I can help you make it work the way you want. Here's what I recommend:

Create some Scripts that will help you determine the relative position of the obj_hero to the trap instance. Let's call them something like scr_HeroIsNearTrap (to tell you when the hero is close enough to activate the trap) and scr_HeroIsInTrap (to tell you when the hero is actually in range to be damaged). You'll have each script return true when the condition is met, and false when it's not. This way, you can remove the position logic from the timer and damage parts, which will make things easier. Here's an example.

GML:
// Script scr_HeroIsInTrap
if (!instance_exists(obj_hero)) return false; // Just a sanity check
return (obj_hero.bbox_left >= bbox_left && obj_hero.bbox_right <= bbox_right);
Now, when you write the logic for your trap, it'll look more like this:
Code:
if (!active) // whatever condition determines whether the trap is active
{
  if (scr_HeroIsNearTrap())
  {
    // activate the trap
    active = true;
    image_speed = 1;
    if (scr_HeroIsInTrap())
    {
      // additionally damage the hero
      obj_hero.hp -= 1;
    }
  }
}
Then, you can use either an alarm or the Animation End event to repeat triggering the trap (if the hero is close enough) or set active back to false and image_speed back to zero if not. If something doesn't work properly, you'll know which script it's in, because the logic has been split up neatly.
 

sensodyne

Member
hmmmm ... kind of confusing. I created these two scripts run the game now I don't see the trap
maybe it would have to be displayed in draw info?

step

GML:
 if !active && abs(x+16-obj_hero.x) < 72
{
  if (scr_HeroIsNearTrap() )
  {
    // activate the trap
    active = true;
    image_speed = 1;
    if (scr_HeroIsInTrap())
    {
      // additionally damage the hero
      obj_hero.hp -= 1;
    }
  }
}


collision of the trap with the hero

Code:
//there is nothing here now empty code

animation end

GML:
image_index = 0;
image_speed = 0;
alarm[0] = 3*room_speed;
alarm[0]

GML:
active = 0;

I think the most sensible solution I have outlined in this picture would be that the champion takes damage while in the middle of a trap and takes damage from frame 15 (image_index)
then the trap's fist will be centrally over the hero's head and it will give a more realistic effect.
so this code would have to be improved because you mentioned that I have to check if image_index is greater than zero right?


collision of the trap with the hero

GML:
if image_index > 14
&& image_index < 16 {
if obj_hero.hurtClock = 0  {
obj_hero.hp -= 1;
obj_hero.hurtClock = room_speed*2
}
  }
 
Last edited:

Nidoking

Member
&& abs(x+16-obj_hero.x) < 72
You don't need this. The scr_HeroIsNearTrap should be checking where the hero is, so you don't need to check it here. That's the point of having the script - it does all of the position checking for you.

I think the most sensible solution I have outlined in this picture would be that the champion takes damage while in the middle of a trap and takes damage from frame 15 (image_index)
Okay, that's not what you put in the picture. In the picture, you said "When the trap starts to play its animation, then it should take the energy of the hero". You need to describe what you want accurately. That goes extra for the computer, because a computer will never try to guess what you mean. It will just do exactly what you say, and if you said the wrong thing, it will do that.

you mentioned that I have to check if image_index is greater than zero right?
I don't believe I ever said that, and if I did, you've changed your mind at least once since about what you say you want. What you need to check is what you want to check. By now, you should have all the tools you need. You shouldn't need to come back and ask how to compare values.

if image_index > 14 && image_index < 16 { if obj_hero.hurtClock = 0 { obj_hero.hp -= 1; obj_hero.hurtClock = room_speed*2 } }
First, what is hurtClock? Is it some kind of invulnerability timer? I don't think you need that for just this. Get rid of it for now, and once you understand what you're doing here, you may be able to put it back if it does something you need. Second, why aren't you checking scr_HeroIsInTrap here? That's the whole point of having a function to check something. You say "I only want the hero to be hurt if the hero is in the trap." So... only hurt the hero if the hero is in the trap. This is where you hurt the hero, so check whether the hero is in the trap and only hurt the hero if the hero is in the trap, because that's what you said you wanted. Which part of the code you pasted was supposed to check whether the hero is in the trap? Remember, nothing that you post on a forum has any effect on your game. You need to put the things you want to be in your game in your game. This is what I meant when I said you need to think about what you're doing. If you can't describe it to me, in natural language (however auto-translated it may be), then how do you expect to describe it to a computer, which needs every detail to be exact?
 

sensodyne

Member
ok

You don't need this. The scr_HeroIsNearTrap should be checking where the hero is, so you don't need to check it here. That's the point of having the script - it does all of the position checking for you.
step

GML:
 if !active
{
  if (scr_HeroIsNearTrap() )
  {
    // activate the trap
    active = true;
    image_speed = 1;
    if (scr_HeroIsInTrap())
    {
      // additionally damage the hero
      obj_hero.hp -= 1;
    }
  }
}

I don't believe I ever said that, and if I did, you've changed your mind at least once since about what you say you want. What you need to check is what you want to check. By now, you should have all the tools you need. You shouldn't need to come back and ask how to compare values.

really? see a few posts above and here are your words

Check whether the image_index is equal to zero, or better, less than one (again, due to rounding error). But I say again, as I have said before: If you want the hp subtracted when the animation begins, why can't you subtract the hp at the same time that you set the animation to begin? Is the trap supposed to animate if the condition you're trying to explain, which causes the obj_hero instance to be "trapped" in the trap, is not true? Or should the trap only animate when the obj_hero is in the correct position? You still haven't explained your actual problem very well. You will get much better answers to your question if you ask the question clearly. More screenshots/pictures might help. It would be very helpful to see an example of what is happening that you don't want to happen.

First, what is hurtClock? Is it some kind of invulnerability timer? I don't think you need that for just this. Get rid of it for now, and once you understand what you're doing here, you may be able to put it back if it does something you need. Second, why aren't you checking scr_HeroIsInTrap here? That's the whole point of having a function to check something. You say "I only want the hero to be hurt if the hero is in the trap." So... only hurt the hero if the hero is in the trap. This is where you hurt the hero, so check whether the hero is in the trap and only hurt the hero if the hero is in the trap, because that's what you said you wanted. Which part of the code you pasted was supposed to check whether the hero is in the trap? Remember, nothing that you post on a forum has any effect on your game. You need to put the things you want to be in your game in your game. This is what I meant when I said you need to think about what you're doing. If you can't describe it to me, in natural language (however auto-translated it may be), then how do you expect to describe it to a computer, which needs every detail to be exact?
ok i did so hurtClock is a hero damage timer and enemies
I threw out all the code from

collision of the trap with the hero


the rest remained the same in the animation end event in the alarm [0] event
I don't think I need to use this script there
in the step event there is a piece of code that is responsible for dealing damage to the hero while the animation is playing
 

Nidoking

Member
see a few posts above and here are your words
Sigh. You've been going back and forth the whole thread about whether you want the damage applied at the first frame, the last frame, frame 15, or some other option. Checking if the image_index is zero gets you the first frame. At the time, that's what I thought you wanted because you hadn't explained what you wanted properly. Here is the question you asked:
Should there be a condition that would check the start frame of the animation?
I answered the question you asked. If you want an answer to a different question, ask the question you want answered. If you want a frame that isn't numbered zero, you use that number instead of zero, at the place where the zero is. You have to be able to figure that much out. That's not even computer science. That's computer entering the classroom for the first time and sitting at your desk.

Also:

you mentioned that I have to check if image_index is greater than zero right?
Check whether the image_index is equal to zero, or better, less than one
Not the same. Pretty much exact opposites, in fact. But that's splitting hairs.

in the step event there is a piece of code that is responsible for dealing damage to the hero while the animation is playing
But that piece of code is OUTSIDE the block that makes the animation start, because you don't want the damage to happen when the animation starts, you want it to happen in the middle, right? So where's the code? Show me the code, and tell me what's wrong with it.
 

TailBit

Member
GML:
 if !active
{
  if (scr_HeroIsNearTrap() )
  {
    // activate the trap
    active = true;
    image_speed = 1;
  }
}else{
    if (scr_HeroIsInTrap() && image_index == 15)
    {
      // additionally damage the hero
      obj_hero.hp -= 1;
    }
}
could alternativly add the image_index check to the script

if draw event is active in a object, then it will stop drawing itself, you can counter that with draw_self() or by removing the draw event again
 

sensodyne

Member
Thank you very much to everyone for all their help, even for Nidoking, everything works fine now.
I have one more question about this topic. The trap mechanism works as I wanted. Now how do I make the trap turn towards it when the hero approaches it? currently it is pointing to the right. I understand that image_xscale has to be used, but how to implement it correctly in this code?
 
Last edited:

TheouAegis

Member
typical way:

if obj_hero.x - x != 0 {image_xscale=sign(obj_hero.x-x);}

Put that in when you activate the trap to make it turn only at the start of the animation. Or put it in the Step event under the condition active is 0 to make it only turn when not active.
 
Top