Advertisement

Make a worm move ?

Started by May 11, 2018 02:21 PM
8 comments, last by the incredible smoker 6 years, 6 months ago

Hi, i have made some simple worm graphics, now i want to make it move.

 

The worm consists of 5 seperate sphere like meshes :

1 big sphere as head

3 medium spheres as center body parts

1 small tail piece

 

It is a enemy worm that moves towards you in 2D, so theres only 2 axis ( X & Y )

The worm has the desired rotation value, the head already rotates towards the player.

Now i like to make the movement go where the head is pointed, and make all bodyparts follow.

 

What would be the most efficient way to do this ?

btw : i use DX9

 

thanks in advance

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

There are many different ways to do it.

Efficiency in a worms game might be important on a computer where speed is measured in Hertz, but yours is measured in gigahertz, so even a badly performing routine will be fast.

Consider that if you have 2 GHz to run, that's 2 billion cycles, or far more than 33 million cycles per frame. Modern CPUs can process several instructions every cycle. You would have to be extremely inefficient to require thirty million cycles to move a five segment worm.

 

Do the spheres stay put, or do they move? One way of handling the pieces in a game where the items don't move is to have a circular buffer.  That is, if your worms are always 5 squares long, instead of moving where each item is at only modify where the head is.

When the head is 0, the body pieces are 1, 2, 3, and the tail is 4. When the head is 1, the body pieces are 2, 3, 4, and the tail is 0. When the head is 2, the body pieces are 3, 4, 0, and the tail is 1.

That way you can be lazy and only update a single value that tells you where the head is. You'll compensate by needing to track how far down the array each position is for the body and tail.

 

If you are growing and not always the same length, then you can copy each position one element down the row.  You'll probably want to start from the tail, make the tail's position the same as the one before it, then move up the chain.

If all the pieces need to move, you'll need to figure out how they move in your game. Are they always moving toward the piece in front of them? What distance do they move? Often that is called a "delta", which is an old math term commonly used to indicate a distance changed. You can compute your snake's delta, or compute what direction the head needs to move, and then using whatever rules make sense for how you choose to implement your game, advance each piece down the line.

 

Advertisement

Hi, thanks for the reply.

 

The spheres move, its a enemy for a side scroller, its a space game so the worms are flying.

The worm dont grow or shrink, and you can not destroy the pieces 1 by 1 ( yet ), i would be happy as it is moving.

I use atan2f to get rotation towards the enemy, then let the worm head rotate slowly towards the enemy, the worm is always moving forward.

With sin & cos the direction can be calculated, now i only need the 4 extra body pieces to follow the worms exact rotation and direction while staying in shape.

The head X position = 0, second part = 50, third part = 90 fourth part = 130 fifth part = 170.

I like to make it efficient as possible to have many worms in screen together.

 

I make the head rotate smooth so the worm wont go 180 degrees backward thru itself,

The thing i want to try myself is having each piece follow the same program,

the problem is there is no fixed framerate in windows with DX9, all frames have different timing,

so when windows goes on the background doing some things, in my method the worm pieces will not be exactly in shape no more, there might be some space between the pieces eventually in a bad case.

 

I hope you can suggest me some methods, thanks.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

On 5/11/2018 at 4:21 PM, the incredible smoker said:

What would be the most efficient way to do this ?

Inverse Kinematics, one of the most basic tutorials on IK is how to make worms/ropes. One of the nice things about a IK snake is how it uncoils it self like a chain or rope. If it was just a path it would have to complete the path before it uncoiled.

If you add some physics to the objects it will be able lo collide with it self.

attachment.php?id=42609

Here is one I made in Unity, as you can see it doesn't have self collision, I am using in a way that it isn't needed, you can see how it "acts" like it tries to avoid it self.

It is a common tutorial so here us one: 

Here is the Unity code if you want a quick peek, translating should be easy but learning yourself will be better:

Spoiler




using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class BasicIK : MonoBehaviour {

	public GameObject Head;

	Vector3 Offset;
	Vector3 RelativeOffset;

	void SolveIK(){
		RelativeOffset = Head.transform.position - this.transform.position;

		if (RelativeOffset != Vector3.zero) {
			this.transform.rotation = Quaternion.LookRotation (RelativeOffset, Vector3.up);

			RelativeOffset = RelativeOffset.normalized * Offset.magnitude;
			this.transform.position = Head.transform.position - RelativeOffset;
		}
	}

	// Use this for initialization
	void Start () {
		Offset = this.transform.position - Head.transform.position;
	}
	
	// Update is called once per frame
	void Update () {
		SolveIK ();
	}
}


 

 

34 minutes ago, the incredible smoker said:

The spheres move, its a enemy for a side scroller, its a space game so the worms are flying.

IK makes nice worms.

attachment.php?id=42608

Thank you, it looks like the exact thing i need.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

So i looked at those movies, there are not much i can find.

https://www.youtube.com/watch?v=2772HKIsf1M

 

I still dont understand really, since my worm is moving, its not a tentacle.

The movie says you snap to the target position, then move back.

Move back to what ?, the last tail piece, while the head should be moving not the last tail piece.

So where do i snap back to ?

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

Advertisement

For any framerate issues, fix your timestep, read this article:

https://gafferongames.com/post/fix_your_timestep/

The different solutions for a worm suggested above depend on what medium your worm is in. You say it is 'in space'. Is there friction in this space?

The two extreme solutions are the one that frob suggests, which is like an earthworm on soil, friction is high and each piece of the worm is anchored to the ground. The other extreme is a frictionless environment, where the worm moves purely by physics (somehow, I'm not up on space worm locomotion!). Presumably you'd have the head rotate towards the target and have a force towards the target, then have the other segments follow the head in some kind of spring system.

The IK solution is a kind of in between, in that it is normally assuming the tail is anchored somewhere (think of a arm anchored to a shoulder joint). I suspect the solution you might use might be a little mishmash between an IK version and a physics version, the IK videos shown use an almost physics like approach anyway.

Just try moving the head towards the target, moving the next segment towards the head, the next segment towards that segment, until you get to the tail, and see how that looks. No need to snap back to anything if you aren't anchored.

5 hours ago, the incredible smoker said:

Move back to what ?

Move back by the length of the segment. To find the length of a vector you can use pythagoras theorem, but most engines will allow you to ask for it.

This is what he is doing: Edit: There was a small mistake in the image, fixed it.

SnakeJoint.jpg.91da702bb537f40a66c9b8e591a5f64b.jpg

 

Then later he removes the middle step by moving the nose of the red joint to the tail of the blue. After that he subtracts the length of the joint from the rednose to find the tail location.

You need to know basic vector math to follow this. Vector math is very easy and makes a lot of sense.

 

In my above Unity example I use two things:

Spoiler

 

1.) RelativeOffset = Head.transform.position - this.transform.position; This gives me the rotation and distance vector towards the target.

2.) Offset = this.transform.position - Head.transform.position; Here I grab the length of my joints at the start as a vector.

Answer)  RelativeOffset = RelativeOffset.normalized * Offset.magnitude;  Here I normalize to only get a rotation then I make that rotation as long as the joint.

this.transform.position = Head.transform.position - RelativeOffset; Finally I subtract my new rotation vector from my position to move backwards to the point where I should be.

 

 

Hi, thanks for the reply`s.

 

For the : fix your timestep :

I have my timestep for offline games limited to a certain value.

Fixed timestep is impossible on modern computers if you ask me.

The other interpolation trick will cost more power, i only want to use more power to add enemys and bullets ( hart-attack sidescroller ).

 

@ Ninja : i dont use Unity.

I can do vector math to calculate distance and aim rotation, no problem.

I will try to make the head move and aim next parts toward the head and subtract distance.

Thing is : its needed for every body part, it wil cost some power ( im working on cheap computer ).

Now i have per frame one worm using atan2f function, so the worms can not aim all at the same frame for optimizing.

 

btw : my engine is called the "FAST ENGINE", made for fast performance & fast results, so i can make a total overdose of enemys and bullets and items running on old computers, specially made for 2D also with 3D support, with only the minimum requirements to release a simple game, its a rewrite of my previous engine, nothing special.

S T O P C R I M E !

Visual Pro 2005 C++ DX9 Cubase VST 3.70 Working on : LevelContainer class & LevelEditor

This topic is closed to new replies.

Advertisement