2
\$\begingroup\$

Following up on this question, I have created a snakelike enemy which consists of a head followed by segments. I get the segments to follow the head by constraining each segment's position relative to the segment in front of it. I get the difference between the actual distances between the segments and the desired distance, and correct that error 30% per frame.

The GDScript code looks like this:

for segment in [segment1, segment2, segment3, segment4, segment5, segment6]:
    # get actual distance between segment and its target
    var distance = segment.global_position.distance_to(segment.target.global_position)
    # find difference with desired distance
    var error = distance - desired_distance
    # move segment a percentage of the error toward its target segment
    var vector_to_target = (segment.target.global_position - segment.global_position).normalized()
    segment.global_position += vector_to_target * error * 0.30

I am happy with the result.

Now I want to create a similar enemy also composed of segments, but whose final segment is a kind of base, rooted to one position. Similar to the Chain Chomp from Mario.

enter image description here

I then want to code movement of the head, but for everything to be constrained. I'm guessing all intermediate segments would be doubly constrained by both of their neighbor segments, and the head itself would also have to be constrained by its neighbor segment, even though I'd be coding movement for it.

I'm not sure how to set up constraints like these which have to look in both directions, and would appreciate any advice?

Although I work in Godot, an engine-neutral explanation of the technique would suffice.

\$\endgroup\$
  • 1
    \$\begingroup\$ Would constraining the last segment to fix value and the head to fixed distance to last segment not achieve what you want to do? So, e.g. saying segment6.global_position = (x,y) and if ((head.postion - segment6.global_position).lenght() <= range) move(); \$\endgroup\$ – Anonymous Anonymous Sep 28 '18 at 17:27
  • \$\begingroup\$ It might, I'll give it a shot! It would be nice for a general technique, though, that would allow me to specify the springiness of the entire segment chain. \$\endgroup\$ – GoldenGremlin Sep 28 '18 at 17:39
  • \$\begingroup\$ The technique you suggest doesn't work. While it keeps the head within a radius of the base, it does not guarantee that the intermediate segments rearrange themselves to form a chain between the head and the base. \$\endgroup\$ – GoldenGremlin Sep 28 '18 at 20:44
1
\$\begingroup\$

Assuming you are interested in having an enemy that behaves roughly like the Chain Chomp from Mario, rather than one that respects real-world rope physics, I can think of an approach that might work for you. To start with, consider the two possible cases:

1) The head of the snake is at the maximum distance, D, from the rooted point. That is, the chain is extended out as far as it can go.

2) The head of the snake is not at the maximum distance from the rooted point.

The first is the simple case, because when the chain/rope is fully extended, we can use linear interpolation to place each body segment. For example, if you have three body segments, you might do something like:

FirstSegment.X = (Base.X - Head.X) * 0.25
SecondSegment.X = (Base.X - Head.X) * 0.50
ThirdSegment.X = (Base.X - Head.X) * 0.75

This will space them out evenly, stretching them from the base, to the head. Just be mindful that this assumes Base.X is greater than Head.X. You will have to switch the order of the subtraction if this is not true.

The second case is the more interesting one. You can start by defining a distance, r, that constrains how far each segment can be from the one in front of it. That is, the first body segment must be within distance r from the head. The second body segment must be within distance r from the first segment, etc.

Then, each frame, starting at the first segment and proceeding backwards, you check whether that constraint is being met. If it's not met, that body segment should move towards. Consider how this will play out as the head of the snake moves:

enter image description here

From your post, I believe this is the effect you desire. For completion, in the Mario games, I believe gravity is applied to the body segments of the chain chomp any time it is not at maximum distance from its post. That is, the segments are either on the ground, or they are stretched out towards the chomp. I don't believe they ever "dangle" loosely in the air (unlike how a rope would behave in real life.) If I am mis-remembering, I apologize.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.