Game Mechanics Help?

Godot Version

4.2.2

Question

Hi all,

I have a specific problem that I am hoping that one of you maybe able to help with in my 2D game.

In the game, I intend to have an “invisibility” potion, and when you get to the specific part of the stage, and you don’t have the aforementioned potion, the opening, to a small space containing an item needed to the complete the stage, will close. This will be done with a area2D trigger that can’t be missed - I’ll make sure of that. Now, if you have the potion that area will leave that opening open :grinning:.

Now, I have tried running through the options I could use, but, seeing as I don’t have actual sprites providing the opening and closing states, I cannot use either the “Animation Tree” of “Animated Sprites2D”. Now, that leaves an “AnimatableBody2D”, again, I don’t know if it possible to be able to stop half way through the states eg between the open and close state. I don’t think it is, I have used it for platforms and a type of swinging rope but stopping and starting not so sure?!?

Which leaves me with coding options and lerp/lerpf - now I have used lerp before in Unreal for opening closing door, moats and such but I can’t remember how I used it and it’s been a long time. So, I would need a tutorial or YouTube to help with that - if you think that is the way to go?

Also, are there are other coding solutions I should check out? The function move_toward() comes to mind, but, there might to more.

Any help is greatly appreciated.

  • You could use an AnimationPlayer to move an object - create an animation called Open that moves the object from the closed to the open position, and then you can play that backwards when you want to close the door.
  • You could use move_toward with code along the lines of:
var is_open = false
# Set these three variables yourself:
var open_position : Vector2
var closed_position : Vector2
var speed : float

func open_door():
  is_open = true

func close_door():
  is_open = false

func _process(delta):
  if is_open:
    position = position.move_toward(open_position, speed * delta)
  else:
    position = position.move_toward(closed_position, speed * delta)
  • And you can achieve the same with lerp, sure, but then you’ll need some way to calculate your t variable, which represents how far between point A and B you want to be (0.0 for all the way at point A, 1.0 for all the way at point B, and 0.5 for halfway in between). You can do that by keeping track of time, but move_toward seems more straightforward, since it just moves at a fixed speed and never goes past its target.
1 Like

Is all depends to your designings

you can use:

  • State machine for doors and manual control them,
  • Tween’s you can abort them any time with reference and kill()
var tween
func animate():
	if tween:
		tween.kill() # Abort the previous animation.
	tween = create_tween()

Thankyou both for your replies, they were helpful. I really wasn’t expecting a reply so soon!!!

I think I will move forward with move_toward after seeing @tayacan’s explanation, it looks like the most straightforward, in any case, I will at least be able the cause some damage :sunglasses:. And it’s fun learning something new that I will be able to use into the future.

Regards.

1 Like

I have received so much help - dare I ask for more?

I have this code:

var speed :float = 0.01;
var closed_pos	:int = 79-1;   #global pos
var open_pos	:int = 135-1;  #global pos

func _physics_process(delta):
	if(is_open):
		#close it
		rock_top.global_position.y = move_toward(open_pos, closed_pos, speed*delta);
		rock_bottom.global_position.y = move_toward(open_pos+28,closed_pos+28, speed*delta);
	if(!is_open):
		#open it
		rock_top.global_position.y =move_toward(closed_pos, open_pos, speed*delta);
		rock_bottom.global_position.y =move_toward( closed_pos+28, open_pos+28, speed*delta);
	#pass

It works in that the 2 rocks do go up and down, but, it’s instantaneous, and I can’t see the problem that will allow it to go slower. I have never used move_towards before though I did know about the command.

Any further help would be very greatly appreciated.

Regards.

Yeah, sure, I can help a bit more :slight_smile:

I’ll focus on just the movement of rock_top from the closed to the open position.

The three parameters to move_toward are:

  • current position
  • target position
  • max speed

So when you give it open_pos and closed_pos, which are fixed positions, as the first two arguments, and speed * delta (which will be very small since your speed is 0.01) as the last, then it will always return open_pos + sign(closed_pos - open_pos) * (speed * delta), which will be almost exactly open_pos. That’s why it jumps to what looks like the open position instantly.

To actually get it to move from one position to another we need to think like this: When we’re trying to open the door, then we’re moving from closed_pos toward open_pos. But actually, because we do this movement over many frames, we’re moving from whatever position we’re currently at. So it becomes:

rock_top.global_position.y = move_toward(
    # We move *from* our current position...
    rock_top.global_position.y,
    # ...toward the open position...
    open_pos,
    # ...at this speed
    speed * delta)

And then the speed probably needs to be quite a bit bigger, since we’re actually using it now! Since you’re working in 2D, think of it as pixels/second, that’s what you’ll get by multiplying it by delta.

1 Like

Oh man, I can’t believe how much I messed this up! Of course, the current position needed to be updated - D’oh!!!

In my defense it was at 6.00am and I had just found that the game had a huge problem and needed to be rectified pronto just to work correctly.

But even saying that I don’t think I would’ve seen that solution - I had forgotten how interpolation works. Thanks so much! Moving forward I think I will be able to use move_toward with much more confidence, and I can use the post as a reference if I forget.

:beers: are on me!

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.