Game Development Community

how to move two sprites together?

by KevinYuen · in Torque 2D Beginner · 08/14/2013 (8:46 am) · 10 replies

SpriteA: player
SpriteB: bubble
How to make the bubbles with player move?

I tried to use createWeldJoint(..) to bind them, but the player's movement speed will be affected by the bubble, What should I do to achieve the desired effect?

%phiz = new Sprite()
{
    Size = GetAnimationRawScaleSize( "GameAssets:PhizAngryAnimation" );
    Animation = "GameAssets:PhizAngryAnimation";
    Position =%player.Position;
    SceneLayer = 0;
    Visible = true;
    LifeTime = 2;
    Active = true;
    BodyType = "dynamic";
};
Game.MainScene.add(  %phiz );
%jointId = Game.MainScene.createWeldJoint( %this.GameLogo, %phiz, "0 0", "0 -5" );
Game.MainScene.setWeldJointFrequency( %jointId, 100 );    
Game.MainScene.setWeldJointDampingRatio( %jointId, 0 );    

%player.MoveTo( %pos, 15);

#1
08/14/2013 (9:17 am)
Make the player a CompositeSprite and add the *bubble* as a sprite to it?
#2
08/14/2013 (9:36 am)
I second Jonathan's suggestion.
#3
08/14/2013 (11:54 am)
Yup, Jon is on fire these days!

If you connect two objects via a joint, you will have to deal with the repercussions of each objects' physical properties.

Note that by calling CompositeSprite.addSprite(%logicalposition);, the bubble and the player sprite will now be children of the CompositeSprite, meaning that you can still change their properties but you will have to do so by selecting the sprite first.

This is done by calling CompositeSprite.selectSpriteID(%spriteID); and then calling the desired function, for example CompositeSprite.setSpriteImageFrame(5);.

I suggest looking at the Sandbox's CompoundObjectsToy for a good example.
#4
08/14/2013 (5:34 pm)
Thank you for all the reply :)

I tried to use CompositeSprite, but it can't add exist sprite, such as ImageFont, behavior-sprites.

I want to known how to bind two independent sprites together?

#5
08/14/2013 (6:16 pm)
I've been working on this as well. I haven't gotten into the nitty gritty yet, but I was thinking of making an array that contains all the sprites I want to move/apply a force to, and then when the time comes to move them make a function that applies that force to everything in the array. I haven't tested it yet, but it's about the only idea I have on how to appropriately move a large object composed of sprites attached to each other.
#6
08/14/2013 (8:36 pm)
I think sprite array is not good idea, it has not logical progression.

we must like this:

spriteArray::moveTogether( %this, %pos )...

in many cases we need a sprite-leader.

I made a spriteGUI class, it can bind Sprites, ImageFont, Buttons together, but need
call SpriteGUI's methods to op them. :(
#7
08/15/2013 (7:33 am)
If using CompositeSprite, we must solve some problems:

1: how to control sub-sprite's animation loop?
I can't catch onAnimationEnd notify. ImageFrameProviderCore::onAnimationEnd() was not post event.

2: how to control sub-sprite's lifetime?

3: etc..

I think if we can support a method for sceneobject to attach another sprites, like attachGui, will solved these problems.
#8
08/15/2013 (8:22 am)
http://www.garagegames.com/community/forums/viewthread/134178

You'll encounter some inconsistencies with collisions between mounted and non-mounted objects because of box2d. One torquescript solution is running a schedule that updates positions and calls itself every 1 milisecond but such a loop can cause lag.

Torquescript solution example (deathball):
http://www.youtube.com/watch?v=vJiDSMX5to8

My sceneobject::mount() mod solution example (shield around ship):
http://www.youtube.com/watch?v=q_XHyU8FKXM
#9
08/15/2013 (8:43 am)
I create a new behavior :):

function ObjectBehaviorAttach::onBehaviorAdd( %this )
{	
	%this.Owner.AttachList = new SimSet();
}

function ObjectBehaviorAttach::onBehaviorRemove( %this )
{
	%this.Owner.AttachList.delete();
}

function ObjectBehaviorAttach::AttachObject( %this, %object, %offset )
{
	if( !isObject( %object ) )
	{
		TraceE( "ObjectBehaviorAttach.AttachObject.Failed.BadObject" );
		return false;
	}
	
	if( !%object.isMemberOfClass( "SceneObject" ) )
	{
		TraceE( "ObjectBehaviorAttach.AttachObject.Failed.NotSceneObject" );
		return false;
	}
	
	%offset = ( %offset $= "" ) ? "0 0" : %offset;
	
	%object.AttachOffset = %offset;
	%object.LinearVelocity = %this.Owner.LinearVelocity;
	%object.Position = %this.Owner.Position.x + %offset.x SPC %this.Owner.Position.y + %offset.y;
	%this.Owner.AttachList.add( %object );
	
	return true;
}

function ObjectBehaviorAttach::DetachObject( %this, %object )
{
	%this.Owner.AttachList.remove( %object );
}

function ObjectBehaviorAttach::DetachObjectAll( %this )
{
	%this.Owner.AttachList.clear();
}

function ObjectBehaviorAttach::MoveTogether( %this, %pos, %speed )
{
	%speed = ( %speed $= "" ) ? 0 : %speed;
	
    if( %speed == 0 )
    {
        %this.Owner.setPosition( %tarPos );
    }
    else
    {
        %this.Owner.moveTo( %pos, %speed );
    }
		
	for( %index = 0; %index < %this.Owner.AttachList.getCount(); %index++ )
	{
		%object = %this.Owner.AttachList.getObject( %index );
		if( !isObject( %object ) ) continue;
		
		%tarPos = %pos.x + %object.AttachOffset.x SPC %pos.y + %object.AttachOffset.y;
			
		if( %speed == 0 )
		{
			%object.setPosition( %tarPos );
		}
		else
		{
			%object.moveTo( %tarPos, %speed );
		}
	}
}

function ObjectBehaviorAttach::StopMoveTogether( %this )
{
	%this.Owner.cancelMoveTo();
	
	for( %index = 0; %index < %this.Owner.AttachList.getCount(); %index++ )
	{
		%object = %this.Owner.AttachList.getObject( %index );
		if( !isObject( %object ) ) continue;
		
		%object.LinearVelocity = "0 0";
		%object.cancelMoveTo();
	}
}
#10
08/15/2013 (8:45 am)
%player.AttachObject( %bubble, "0 5" );
%player.MoveTogether( %pos, %speed );

like attachGUI, this behavior can attach all type of sceneobject.