Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by ansimuz

Hi,

What would be the logic or best way to create a entity followed by other entities to create a snake made of linked entities.

For example a head entity that will be followed by other entities that form the body of the snake.

/><br />
<br />
here's an animated example <br />
<img src=

1 decade ago by stillen

I have a bouncy laser entity that works similar to a snake. You could do something similar.

When the head spawns, in the init, it spawns the body pieces at the appropriate distance from the head. Then in the body entity update, it can move based on the head entity position.

Put all the move login in the head entity and then the bodies just follow with a position offset that you set depending on how far away it is.

This won't work if you have the snake "breakable" ie, if the head is gone, the bodies won't work.

1 decade ago by ansimuz

@stillen

Great do you have a code example of the body logic?

1 decade ago by stillen

This should give you the idea. I pulled the extra stuff out, so this will need to be cleaned up and expanded, but this should give you the idea.


// example head init 
ig.game.spawnEntity(EntitySnakeBody, this.pos.x, this.pos.y,{scrollOffest:0});
ig.game.spawnEntity(EntitySnakeBody, this.pos.x, this.pos.y{scrollOffest:100});
ig.game.spawnEntity(EntitySnakeBody, this.pos.x, this.pos.y,{scrollOffest:200});



// head example update
update:function(){
	if(this.lifeTime.delta() > 1.5){
		this.kill();
	}
	if(this.flip){
		this.vel.x = this.maxVel.x;
	}else{
		this.vel.x = - this.maxVel.x;
	}
	if(this.pos.y > this.maxHeight && this.movingUp){
		this.pos.y = this.pos.y -3;
	}else{
		this.pos.y = this.pos.y +3;
		this.movingUp = false;
	}
	if(this.pos.y > this.minHeight && !this.movingUp){
		this.movingUp = true;
	}
	this.parent();
}


// body update
var head = ig.game.getEntitiesByType( EntitySnakeHead)[0];
this.flip ? this.scrollOffest; -this.scrollOffest;; 
this.pos.x = head.pos.x +this.scrollOffest;
this.pos.y = head.pos.y;

Basically the body follows the head with the scroll offset being the distance between each item. The head can move up and down in a small curve. It only moved across the x axis in my case, since its a laser.

This should give you an idea to get started.

1 decade ago by y0ungb0b

Use the same movement data for the head (start pos, velocity or a tween etc) for each body part, but spawn each body part after a incremental delay. The length of the delay will determine the space between each body part, so you will need to tweak/calculate each body parts delay depending on the speed of the head if you want the body parts to look 'joined' together.

Spawn head.
spawn body part 1 (after 0.5 second delay)
spawn body part 2 (after 1 second delay)
spawn body part 3 (after 1.5 second delay)
etc
.
.
.

1 decade ago by ansimuz

Thanks everybody.

@Y0ungB0b

Your solution worked better for my problem.

This is what i did i spawned the body parts with a delay each part follow the same path so it looks like they are linked even thought they are just one after another following the same path. Like cars in a road.


Thanks for everybody for your help.

9 years ago by Rungo73

Hi @ansimuz

Are you able to share how you ended up achievng this? Also in the .gif above it appears you have the snake entities moving on a predetermined path? how did you achieve that?

Many thanks in advance.

9 years ago by drhayes

Watch out, long post.

I did this in my game. Spoilers! ( ;

Here's how:

I defined an entity called EntityArea. It has no gravity and is _wmScalable. I placed a bunch of these over the "holes" in the background of the map. These are the entrance and exit holes. I name each one, e.g. spawn1, spawn2, etc.

I created an entity called EntityWyrmSpawner. In Weltmester I set a bunch of target properties, like target.0 is spawn1, target.1 is spawn2, etc. You might be able to see where this is going.

The ready function for the spawner looks like this:

    ready: function() {
      this.parent();
      this.spawnPoints = Object.keys(this.target).map(function(i) {
        return ig.game.getEntityByName(this.target[i]);
      }.bind(this));
    },

Now my spawner has a property named spawnPoints that contains the entities for all the areas I've defined in the map. It has an event chain that spawns a new EntityWyrmHead and EntityWyrmBody:

      this.spawnChain = EventChain(this)
      .wait(2)
      .then(this.pickSpawnPoints)
      .then(this.spawnWyrm)
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody())
      .wait(.1)
      .then(this.spawnBody(true))
      .wait(15)
      .orUntil(function() {
        return this.wyrmGone;
      })
      .wait(1)
      .repeat();

Each head and body entity knows what the two spawn points were so it can get their positions and sizes. That last spawnBody(true) call says "this is the tail, use a different animation".

I then wrote a bezier path library which I'll put on GitHub soonish. You give it the start value, the end value, the control points, then a time between 0 and 1, and it'll spit out what the number should be. In this case, those numbers are the x and y positions of the wyrm segments.

The wyrm head and body entities take care of some other stuff, like fading in when spawned, fading out when killed, shooting stuff, all that. The final tail segment tracks when it has faded out (wyrmGone, above). But that's the gist.

I'd be interested in hearing what other people are doing.

Here's the bezier module, it's pretty short:

ig.module(
  'game.util.bezier'
)
.defines(function() {
  'use strict';

  // With the help of: http://www.moshplant.com/direct-or/bezier/math.html
  // Code totally stolen from processing.js.

  // 0 <= t <= 1
  window.bezierPoint = function bezierPoint(a,b,c,d,t) {
    return (1-t)*(1-t)*(1-t)*a+3*(1-t)*(1-t)*t*b+3*(1-t)*t*t*c+t*t*t*d;
  }

  window.bezierTangent = function bezierTangent(a,b,c,d,t) {
    return (3*t*t*(-a+3*b-3*c+d)+6*t*(a-2*b+c)+3*(-a+b));
  }
});

9 years ago by Apiheld

Very neat, looks pretty good :)
Page 1 of 1
« first « previous next › last »