## Recommended Posts

HI guys,

Our City game is progressing well . Now I wanted to animate cars to ply on the roads which is created by the players in the game. After creating the roads i want the car to move on the same road,  The roads are created by clicking each tile by the user. The entire road length is saved in a array. I need the cars to move from starting point of my road to end point of road where the user has plotted.

can some one tell me what method i can use to achieve this, for now I am trying with https://github.com/Kibo/melonjs-cookbook/tree/master/cookbook/patrol/js  patrol method. I am having trouble with my co-ordinates because patrol is in 2d but my game is in isometric , And If I move or pan the screen car was not sticking with my game world rather its taking the browser screen.

tried using functions like .toiso(),localToWorld() . But of no luck

can some one tell me is their any other way to achieve it or solution for this.

Thank you

HAPPY GAMING...

##### Share on other sites

Hey @Hashasm, I'd suggest to start by making your own stuff to begin with, so you fully understand the concepts behind this task.

Anyway, try to complete the following tasks:

1. Make a car go straight from Road_Piece_1 to Road_Piece_2 (basically get the coordinates and orientation of each road piece, 1 by 1, and move the car on them)
2. Make a car go straight for any amount of road pieces
3. Make a car handle single turns (either left or right)
4. Make a car decide on a crossroad which part to turn
5. Make a car go from A to B and come back forever
6. Add collision detection before trying to move onto the following road piece

Congrats! You have a simple patrol algorithm which can be tweaked and improved according to your game needs

##### Share on other sites

so far i am doing good with patrol thing but i struct at giving Velocity. car is moving on the road but its not going straight , its going in zigzag way within the road but i want it to go straight along with the road this is the code which i am using to give velocity

var dx = this._target.x - this.pos.x;
var dy = this._target.y - this.pos.y;

var angle = Math.atan2( dy, dx  )  ;
//var angle = Math.atan2( dx, dy  )  ;
console.log( Math.cos( angle ));

this.body.vel.x = Math.cos( angle )  * this.body.accel.x * me.timer.tick;
this.body.vel.y = Math.sin( angle )  * this.body.accel.y * me.timer.tick;

//alternate way of setting velocity.......

//              this.body.vel.x = dx.clamp(-1, 1) * this.body.accel.x;
//            this.body.vel.y = dy.clamp(-1,1) * this.body.accel.y;

}

##### Share on other sites

Is that in the update function running every frame? If things run every frame then the result of the calculation changes a bit every frame and it can end up with something that looks like a sine wave.

##### Share on other sites

yes the update function running every frame and i want to have it in a straight line instead of sine wave.Is there any way to fix it

sample code can be found here https://github.com/Kibo/melonjs-cookbook/tree/master/cookbook/patrol/js   for patrol.

##### Share on other sites

As I said, if it runs every frame it will plot different paths.

I used code like yours every frame and ended up with wavy paths.

You must set the velocity only once every time it reaches a new destination.

I myself used this:

``````		if (this.body.vel.y === 0 && this.body.vel.x === 0) {
var Angle = Math.atan2(target.y - this.pos.y, target.x - this.pos.x);
var ySpeed = Math.sin(Angle) * this.speed;
var xSpeed = Math.cos(Angle) * this.speed;
this.body.vel.x = xSpeed * me.timer.tick;
this.body.vel.y = ySpeed * me.timer.tick;
}``````

It's basically the same as yours.

##### Share on other sites

hi @01271  can you tell me wether i am updating velocity in correct place or not

game.PlayerEntity = me.Entity.extend({
//    _patrol_isReverse: false,
init: function(data,rand_color) {

this.patrol_path = [];
this.patrol_isReverse = false;
this.patrol_isInfinite = true;

var settings={}
//console.log(this.gameWorldX+" "+this.clientX);
console.log(tile.row+""+tile.col); */

var vehicle_name;
//         console.log(data.frequency)
if(data.frequency=="RealTime"){
//            vehicle_name="chopper";
vehicle_name="scooter_"+rand_color;
//               vehicle_name="truck_"+rand_color;

}
else if(data.frequency=="Daily"){
//             vehicle_name="van_"+rand_color;
//             vehicle_name="mini_truck_"+rand_color;
//              vehicle_name="HORSE_CARRIAGE_"+rand_color;
vehicle_name="chopper_"+rand_color;
//              vehicle_name="chopper_float-01";
}
else if (data.frequency=="Monthly"){
vehicle_name="car_"+rand_color;
}
else if(data.frequency=="BiWeekly"){
vehicle_name="HORSE_CARRIAGE";

}
else{

vehicle_name="scooter_"+rand_color;

}
game.texture = new me.video.renderer.Texture(
{ framewidth : 48, frameheight : 48, anchorPoint : new me.Vector2d(0.5, 0.5) },
);

var obj = game.texture.getAtlas() //make this dynamic

settings.width = 0;
settings.height =0;
var x=data.path[0].x;
var y= data.path[0].y;
console.log("x"+x+" ==y=="+y);

this._super(me.Entity, "init", [/*7324, 3702*/x,y, settings]);
this.body.setVelocity(1.8,1.8);
this.renderable = game.texture.createAnimationFromName([0, 1, 2, 3/*, 4, 5, 6, 7,*/ ]);
for(var i=0;i<data.path.length;i++){
console.log( new me.Vector2d(data.path[0].x, data.path[0].y))
}
this.renderable.addAnimation( "down", [ 2 ] );

this.afterPatrolFinished = function(){
console.log("patrol finished");
me.game.world.removeChild(this)
};
this.patrol_walk();
},
this.patrol_path.push(point);
},
patrol_walk:function(){
this._isWalking = true;
if( !this._target && this.patrol_path[ 0 ] ) {
this._target = this.patrol_path[ 0 ];
}
this._setDirection(this._target.x - this.pos.x, this._target.y - this.pos.y);
this.renderable.setCurrentAnimation( this.direction );
},
_setDirection: function( dx, dy ) {
if(dx>0&&dy<0){
this.direction = "up";
}
else if(dx<0&&dy>0){
this.direction="down";
}
else if(dx<0&&dy<0){
this.direction="left";
}else{
this.direction="right";
}

},
update: function(dt) {

if( !this._isWalking ){
return false;
}
this._calculateStep();
this.body.update(dt);
return (this._super(me.Entity, 'update', [dt]) || this.body.vel.x !== 0 || this.body.vel.y !== 0);
},

_calculateStep: function( ) {

if( this._target ) {

var dx = this._target.x - this.pos.x;
var dy = this._target.y - this.pos.y;

console.log("this.pos.x");            console.log(this.pos.x+"=="+this.pos.y);
console.log(this._target);
console.log(dx+"=="+dy);
if( Math.abs( dx ) < this.body.maxVel.x && Math.abs( dy ) < this.body.maxVel.x ) {

var idx = this.patrol_path.indexOf( this._target );
console.log(idx);
//next point index
idx++;

if( idx == ( this.patrol_path.length ) ) {
delete this._target;
if(typeof this.afterPatrolFinished === 'function'){
this.afterPatrolFinished();
}

if( this.patrol_isReverse ){
this.patrol_path.reverse( );
}

if( this.patrol_isInfinite){
this.patrol_isInfinite = false;
}

} else {
this._target = this.patrol_path[ idx ];
this._setDirection(this._target.x - this.pos.x, this._target.y - this.pos.y);
this.renderable.setCurrentAnimation( this.direction );

}

return;
}
var angle = Math.atan2( this._target.y - this.pos.y, this._target.x - this.pos.x )  ;
this.body.vel.x = Math.cos( angle )   *  this.body.accel.x+1.9 /** me.timer.tick*/;
this.body.vel.y = Math.sin( angle )  * this.body.accel.y*0.5 /** me.timer.tick*/;

} else {
this.body.vel.x = 0;
this.body.vel.y = 0;
}

},
/**
* Stop walking
*/
patrol_stop: function( ) {
this._isWalking = false;
},

/**
* Set reverse.
* When is reverse, the movement is there and back
* @param {boolean}
*/
patrol_setReverse: function( isReverse ) {
this.patrol_isReverse = isReverse;
},

/**
* Set infinite.
* When is infinite, the movement is in an endless loop
* @param {boolean}
*/
patrol_setInfinite: function( isInfinite ) {
this.patrol_isInfinite = isInfinite;
},

onCollision : function (/*response, other*/) {
return true;
}
});

##### Share on other sites

Wow, that's a whole lot of code. You know it would be easier to debug if you uploaded the project somewhere, so that it could be run in a browser. GitHub's collaboration tools are also incredibly useful for these kinds of requests, since patches can be easily submitted as pull requests, and applied at the click of a button.

Anyway, this line is curious:

On 6/12/2017 at 8:11 AM, Hashasm said:

if( Math.abs( dx ) < this.body.maxVel.x && Math.abs( dy ) < this.body.maxVel.x )

You don't seem to set the max velocity anywhere explicitly, so that means it is set implicitly by the setVelocity call in the constructor:

On 6/12/2017 at 8:11 AM, Hashasm said:

this.body.setVelocity(1.8,1.8);

Given this constraint, it appears impossible to satisfy that first condition; the distance between the source and destination positions are very unlikely to be less than 1.8 pixels.

##### Share on other sites

hi  all,

@Parasyte i found the solution , but i dint change my code , what i did is passing the co-ordinates by converting row and col values .. but before i was passing the coordinates by using event.gameWorld ..

but i am curious to understand in depth about setting velocity and acceleration . if you have any resource for the same please share with me

thank you

##### Share on other sites

Just the source code/documentation:

And how maxVel is used for clamping the total velocity: