Update movement
pixelschaos

Hello,

 

It might be a stupid question but I want a scenceobject to follow another.

For example,

When SceneObject duck is moving I want the SceneObject text to follow it aswel.
Which event is capable of doing so? I've tried onUpdate without success but also read that you can assign events from wade's functions for example the isMoving function can also have an event which you can create by using wade.addEventListener(myobject, 'isMoving') & then myobject.isMoving = function(eventdata) { //do something with them }.

 

All this might be my fault but I'd like a clear, verified answer on this since such events will be my main concern when writing games.

 

P.S Thank you again for this GREAT piece of software!

 

Kind regards,

Chris

All 5 Comments
foxcode

Hello pixelschaos

 

If one of these objects is simple enough to be a sprite, your text for example, you could do the following.

duck.addSprite(text, {x:0. y:0});

This would add a sprite to the duck object, that would be a specified offset from the objects center, in this case, 0, 0.

 

If however you do want objects to follow one another, I do not think there is a function to do that currently, however I can see it being a reasonably common case so we might look into the possibility of adding it.

 

The way I have done this in the past is the way you have done it using onUpdate, here is a simple example, that I have not tested :p but should work.

var duckSprite = new Sprite("rubberDuck.png");var duck = new SceneObject(duckSprite);wade.addSceneObject(duck)var text = new TextSprite("I am the batman", "32px Arial", "red", "center");var textObj = new SceneObject(text);textObj.parentObj = duck;textObj.onUpdate = function(){	this.setPosition(this.parentObj.getPosition().x, this.parentObj.getPosition().y);};wade.addSceneObject(textObj, true);

* Notice the true in addSceneObject, this is very important, it tells the object to listen for events, these event functions must be declared before adding to the scene, else you will need to use the wade.addEventListener function.

 

In the above example, using addSprite for the text would be better than having 2 scene objects, but when you do have 2 scene objects, the above example should work.

 

You could alter the on update function to add an offset so that the text was not directly on the ducks position eg

 

var offset = {x:10, y:30};

this.setPosition(this.parentObj.getPosition().x + offset.x, this.parentObj.getPosition().y + offset.y);

 

You could also make the text object move gradually towards the duck, by finding the vector between them, and only modifying the texts position by a fraction of that each frame.

 

 

I hope this answers your question, if you have any problems, please reply to this thread, good luck :)

Gio

Oh well, foxcode just beat me to it - I was writing an elaborate answer to your question :) I'll post it anyway:

 

It's funny you should mention that - I am currently in the process of preparing some video tutorials for WADE 2.0 and one of them is exactly a "Follow" behavior.

To be honest I think that onUpdate would be a good candidate to do it. You can listen for events, that's true, but only some events are fired automatically by WADE. isMoving is not one of them. But you can fire your own custom events using wade.processEvent(). So if you do
 

wade.processEvent('myOwnEvent');

all the SceneObjects that are listening for 'myOwnEvent' will run their 'myOwnEvent' functions. If these objects have behaviors that have 'myOwnEvent' functions, those functions (for the behaviors) will be executed too.
Objects can listen for events (custom events or pre-defined events) in a few different ways - the easiest is probably:

myObject.listenFor('myOwnEvent');

Anyway, let's look at your specific 'Follow' case. I'd just do it in the onUpdate function of your object. In fact, it may be a good idea to create a Follow behavior, and do this in the 'onUpdate' function of your behavior.

Following can be done in a couple of ways: the simpler way is to just look at the target object's position and move towards it. The harder way is to 'remember' the previous positions of the target object, and try to move to all the positions that your target object has visited.

I don't know which one you need, so I'm just going with the simple approach here - but if you need the other one, just let me know and I'll post some more code. So your 'Follow' behavior might look a bit like this:
 

Follow = function(){    this.name = 'Follow';   // the name of the behavior - not essential, but it's good practice to store it this way    this.targetName = '';   // the name of the object to follow    this.speed = 100;       // our movement speed        this.onUpdate = function()    {        if (this.targetName)        {            var targetObject = wade.getSceneObject(this.targetName);            if (targetObject)            {                var targetPosition = targetObject.getPosition();                this.owner.moveTo(targetPosition.x, targetPosition.y, this.speed);            }        }    };};

And the code that creates your objects might look like this:
 

var myDuck = new SceneObject(....);   // create it however you likemyDuck.setName('duck');               // give it a name so our behavior code can find it easilyvar text = new SceneObject(mySprite, Follow);text.getBehavior().targetName = 'duck';wade.addSceneObject(text, true);    // 'true' is important - it means the object will receive onUpdate events automatically

This is just a way of doing it - not sure if this is what you want. You don't need a behavior for this, but if you make a behavior, then it's easy to get any objects to use this Follow behavior without having to duplicate any code.

Note that if you just wanted two objects to move at the same time, keeping their distance constant, a much easier way would be to create a SceneObject that contains multiple sprites (each one with its own offset). This way, when the scene object moves, all the sprites in the scene object move accordingly. In this scenario, you could just do:
 

var myComplexSceneObject = new SceneObject([duckSprite, textSprite]);  // note we use an array of spritesmyComplexSceneObject.setSpriteOffset(1, {x: 100, y: 123});             // set and offset for the text sprite (sprite number 1 in the array)
pixelschaos

Thanks a lot for your detail answer sir!

Using onUpdate seemed logical for me but I was hoping to get a list of properties when I binded that event on a SceneObject for example "eventType === "move" etc so I'd know what info onUpdate provides.
Too bad I didn't.

 

I'll try your suggestion soon.

Shri

PixelsChaos,

 

If you look at the code I posted here -  http://www.clockworkchilli.com/forum/index.php?/topic/154-pt-raid-new-wade-game/

for a game I made called PT raid, there are a couple of files which might help you out.

The one file is called Steering.js - it implements some steering nehavior routines.

Then look at one of the 'enemy' files (i.e. enemyCruiser.js, enemyPT.js...).

These are scene objects which use a steering manager to implement their steering behavior.

In the main ptRad.js file, each enemy runs its ai throigh the runAI function.

I chose not to use onUpdate, because running the AI at the same rate as the game made the enemies react too quickly.

Lastly, check out this tut http://gamedevelopment.tutsplus.com/series/understanding-steering-behaviors--gamedev-12732

on steering behavior, the whole series is an excellent read.

 

There are other ways to approach this problem than the way I did, probably using behaviors as Gio suggested.

This might be overkill for what you want to do; but it gives you another look at how you can put together a solution in wade.

 

cheers,

Shri

pixelschaos

Thanks a lot Shri!

Post a reply
Add Attachment
Submit Reply
Login to Reply