Moving and scaling an object with a weld joint to another object.

Hi,

I have a spaceship (dynamic physics body from a spritesheet) and two thruster flames (dynamic physics bodies from spritesheet) on each side of it where the engines are. The flames are attached to the spaceship with a weld joint. The spaceship engines (and thereby the thruster flames) are activted by the user swiping and thereby giving it a direction with applyForce().

The longer the swipe, the more force is applied. The different force/speed is reflected in the size of the thruster flames, which are displayed at scale 1 at full speed and at lower scales for lower speeds (i.e. the width and height of the flames are a function of the speed). The spaceship can also turn along the Z axis (hence the sprite sheet), which means that the position of the thruster flames need to change relative to the spaceship during the turn (to still be where the engines are). 

Each sprite sheet frame for the flames contain both of the flames, which means that if I scale the image down, they will also move towards each other (away from the engines) as the entire image gets smaller. On the other hand, if I put the flames in separate sprite sheets I would have to move them relative to the object they are joined to during the turn so that they stay where the engines are (i.e. “manually” assign a position to a dynamic object affected by both gravity and an added force = bad idea).

How can this be done? 

Hi @Divergent Monkey,

Could you post some screenshots of what you want this to look like? Perhaps using “hybrid” draw mode to show the position of the physics bodies?

Have you considered using particle emitters for the thrusters instead of sprites? IMHO those look really nice, and you could easily control them (independently) in terms of how much flame they’re outputting.

Brent

Hello @Brent,

Even though I really like them visually, I have always avoided particle emitters for performnce reasons. Maybe I’m overly (unjustly) cautious?

Anyway, I’m going to go with your suggestion and check out Particle Designer and see if that works better. I know it’s going to look better than my “home made” thruster flame. From what I have gathered this far, I can dynamically change “size”, position and angle, which mean that they would fit my project perfectly. Thanks for the tip!

Just for the record though: is it advisable (or even possible) to move the relative x/y positions of two objects joined by a weld joint once the joint has been made?

@Brent: I have played around with the particle emitters a little but I still haven’t figured out how to dynamically change an emitter value after its creation. In my game, the spaceship can have different speeds and the emitter “size” (i.e. its lifespan) has to change accordingly to reflect that. Is there some function by which I can dynamically set the parameters and will they in that case overrride what was set at the creation of the emitter?

Hi again,

If you look at this document, you’ll see that any emitter property can be changed post-creation of the emitter. Just change the property value on the emitter object:

https://docs.coronalabs.com/api/type/EmitterObject/index.html

As for weld joints, no, you can’t “move” them after they’re created… a weld joint is permanent and you can’t slide it around.

Brent

Just wanted to give little feedback about how I solved it in case someone else faces a similar issue:

Regardless of whether I use sprites or particle emitters, the problem of having to move the thruster flames relative to the spaceship as the space shiprotates, remains. The only way I could solve this was to remove the weld joint and instead set the position of the thruster flames in an event frame listener.

In a sprite listener in the “began”, “next” and “ended” phases, I updated an index to know exactly in which of the sprite frames the spaceship is when rotating. This index is then read in the event fram listener and the position of the thruster flames is set accordingly.

It’s a bit tricky to explain but if someone needs a more thorough explanantion, please let me know.

i’m late to this discussion and probably don’t follow everything, but i’d maybe set it up like…

if your thrusters were single-flame sprites, thus three total bodies and two separate welds to hold it all together, then I think it would have “just worked”.

you’d want to “draw” your sprites such that any implied “motion” between frames is included in the sprites, so that all frames share the same internal reference.  (that is, say you have 16x16 worth of actual drawn pixels that can moves up and down by 8 pixels between frames, so you’d really want 16x32 as dimensions, so that the “zero y” for each frame can occur at the same location)  that’ll keep your frames aligned without having to manually shift the sprite.

then during the initial physics setup you’ll have to specify offset coordinates (as engine centers presumably aren’t at hull center) for the sprites and welds, but that’s a one-time thing (and presumably at a known fixed rotation) rather than a per-frame thing at an arbitrary rotation.

having got all of that set up there should be no need to manually per-frame change the x/y position of the sprites.

@davebollinger: thanks for your reply. The setup you are describing works well unless you vant to be able to scale the thruster flames in both x and y directions.

Assume a spaceship with its nose pointed upwards on the screen. At the bottom of it, left and right, are the flames coming out of the engines. As the spaceship rotates (i.e. rolls along the y axis), the sprites have to move in the x direction. This movement can, as you say, be “built in” into the sprites by just positioning the flames diffrently in each sprite frame (which then has to be wider than the actual flame itself  to have room for the movement).

Scaling in the y direction is no problem, but scaling in the x direction poses a problem since scaling is done relative to the anchor point of the frame. Since the thruster flames are placed in different positions within the frames, they will move in the x direction just as an effect of the scaling itself. To compensate for this, I would have to move the “weld point”, which is not possible.

Or did I misunderstand you?

nope, it was my misunderstanding – by “rotation” i thought you meant z-spin (asteroids) not y-roll (galaga), what i wrote wouldn’t work for galaga.  your last-written solution seems best - forget the welds, just reposition the flames in an enter frame listener.

perhaps at least set the anchor at top center, and position each flame right at the “nozzle exit” of its engine, so that scaling won’t ALSO require adjusting coordinates.  then table the frame offsets (and scales if appropriate, if “discrete” values) to simplify that a bit, ex:

-- assuming they're asymmetric about x-center (due to baked in perspective) -- then you'll need separate l/r tables (ie can't just do +/- of a single value) leftFlame.x = shapeship.x + leftFlameOffsets[yRollIndex] -- presumably negative values rightflame.x = shapeship.x + rightFlameOffsets[yRollIndex] -- presumably positive values leftFlame.xScale = flameScales[thrustPowerIndex] -- etc

Yes, Galaga was the kind of view/rotation I meant (never crossed my mind to refer to classic games, sorry).

I have set the y anchor to zero in order to avoid having to adjust the y position. The flame is positioned at the nozzle and the scaling just affects how long the flame is while always starting at the nozzle.

Thanks for your input, Its really valuable to have someone question my ideas, espcecially when I think I might have found a solution.

btw, just food for thought…

if your sprite is hand-drawn none of this will apply, but… (many “if’s” follow)

IF your sprite is 3D-rendered

IF the true xz-center of the model was used as origin of y roll

IF you know the amount of rotation used per frame

and IF any one of the following

  1. was rendered with an orthographic projection (no perspective distortion)

  2. was rendered with a “distant long lens” (to flatten perspective distortion to the degree it can be ignored)

   (otoh, a near camera with a wide lens would *exaggerate* perspective distortion == bad)

  1. you know enough about the camera setup to correct for the perspective distortion

  (it’s a simple “1/z” -type operation, but there are some “constants” you’d need to know, or at least have a good guess at)

THEN, you could *exactly* calculate the x-offsets for your engines per frame.  imagine a circle in the x-z plane, centered on the y-axis, of radius engine-distance-from-center-y.  the position of your engines, as the ship rolls on y, will be the cosine of that angle times that radius.  (at zero degrees, it will be exactly that radius, at +/-45 degrees it’ll be sqrt(2)/2 that radius, etc)

fwiw, hth

@Divergent Monkey,

You could try using a “Piston” joint for this. It’s basically like a joint that allows an object to “slide along a line” which, assuming you set it up properly, you could use to let your thrusters slide left and right. You can also set limits on the range of sliding.

https://docs.coronalabs.com/guide/physics/physicsJoints/index.html#piston-joint

Brent

@Brent,

I looked into that but I need to be able to control the thruster positions manually on a per-frame basis as the spaceship rotates. As far as I can tell, manually setting the x position and let it stay there is not possible with piston joints.

I’m not sure exactly what level of precise control you need, but you should be able to set/reset the piston joint “limits” in runtime, and then move the object (on the joint) to either side of the joint’s limit.

https://docs.coronalabs.com/api/type/Joint/setLimits.html

Actual “moving” of that object would be done by toggling the motor speed between 0 and whatever speed seems reasonable:

https://docs.coronalabs.com/api/type/Joint/motorSpeed.html

Brent

Hi @Divergent Monkey,

Could you post some screenshots of what you want this to look like? Perhaps using “hybrid” draw mode to show the position of the physics bodies?

Have you considered using particle emitters for the thrusters instead of sprites? IMHO those look really nice, and you could easily control them (independently) in terms of how much flame they’re outputting.

Brent

Hello @Brent,

Even though I really like them visually, I have always avoided particle emitters for performnce reasons. Maybe I’m overly (unjustly) cautious?

Anyway, I’m going to go with your suggestion and check out Particle Designer and see if that works better. I know it’s going to look better than my “home made” thruster flame. From what I have gathered this far, I can dynamically change “size”, position and angle, which mean that they would fit my project perfectly. Thanks for the tip!

Just for the record though: is it advisable (or even possible) to move the relative x/y positions of two objects joined by a weld joint once the joint has been made?

@Brent: I have played around with the particle emitters a little but I still haven’t figured out how to dynamically change an emitter value after its creation. In my game, the spaceship can have different speeds and the emitter “size” (i.e. its lifespan) has to change accordingly to reflect that. Is there some function by which I can dynamically set the parameters and will they in that case overrride what was set at the creation of the emitter?

Hi again,

If you look at this document, you’ll see that any emitter property can be changed post-creation of the emitter. Just change the property value on the emitter object:

https://docs.coronalabs.com/api/type/EmitterObject/index.html

As for weld joints, no, you can’t “move” them after they’re created… a weld joint is permanent and you can’t slide it around.

Brent