1

For a while now I've been trying to hack Photonstorm's Power Tools 'Spring' plugin for Flixel. I've dabbled in a few formulas but I've not gotten what I've sort of wanted until now.

I've managed to hack this into the plugin: http://illogictree.com/blog/2010/01/1345/

Which makes the example look like this now: hackedtool

Which is good. It behaves pretty much the way I'd like it to feel. Except for a problem. I'd like for the ball on the string to be directly below the mouse. Any idea on how to do that?

And before you ask, code: //The plugin hack

 package org.flixel.plugin.photonstorm.BaseTypes 
    {
    import org.flixel.*;
    import org.flixel.plugin.photonstorm.FlxExtendedSprite;

    public class MouseSpring 
    {
        public var sprite:FlxExtendedSprite;

        /**
         * The tension of the spring, smaller numbers create springs closer to the mouse pointer
         * @default 0.1
         */
        public var tension:Number = 0.1;

        /**
         * The friction applied to the spring as it moves
         * @default 0.95
         */
        public var friction:Number = 0.95;

        /**
         * The gravity controls how far "down" the spring hangs (use a negative value for it to hang up!)
         * @default 0
         */
        public var gravity:Number = 0;

        private var retainVelocity:Boolean = false;

        private var vx:Number = 0;
        private var vy:Number = 0;

        private var dx:Number = 0;
        private var dy:Number = 0;

        private var ax:Number = 0;
        private var ay:Number = 0;

        /**
         * Adds a spring between the mouse and a Sprite.
         * 
         * @param   sprite              The FlxExtendedSprite to which this spring is attached
         * @param   retainVelocity      true to retain the velocity of the spring when the mouse is released, or false to clear it
         * @param   tension             The tension of the spring, smaller numbers create springs closer to the mouse pointer
         * @param   friction            The friction applied to the spring as it moves
         * @param   gravity             The gravity controls how far "down" the spring hangs (use a negative value for it to hang up!)
         */
        public function MouseSpring(sprite:FlxExtendedSprite, retainVelocity:Boolean = false, tension:Number = 0.1, friction:Number = 0.95, gravity:Number = 0)
        {
            this.sprite = sprite;
            this.retainVelocity = retainVelocity;
            this.tension = tension; //bounciness
            this.friction = friction; //how tight
            this.gravity = gravity; //mass
        }

        /**
         * Updates the spring physics and repositions the sprite
         */
        public function update():void
        {
            dx = FlxG.mouse.x - sprite.springX;
            dy = FlxG.mouse.y - sprite.springY;

            ax = dx * tension;
            ay = dy * tension;

            //ax = Math.cos(dx * tension);
            //ay = Math.sin(dy * tension);

            vx += ax;
            vy += ay;

            //vy += gravity;
            //vx *= friction;
            //vy *= friction;

            //This is where I've hacked it in:
            vx = ax + ( 1.0 / gravity ) * (-friction * ax - tension * ( FlxG.mouse.x - dx  ) + sprite.springX * gravity ) * FlxG.elapsed;
            vy= ay + ( 1.0 / gravity ) * ( -friction * ay - tension * ( FlxG.mouse.y - dy ) + sprite.springY * gravity ) * FlxG.elapsed;            

            sprite.x += vx;
            sprite.y += vy;
        }

        /**
         * Resets the internal spring physics
         */
        public function reset():void
        {
            vx = 0;
            vy = 0;

            dx = 0;
            dy = 0;

            ax = 0;
            ay = 0;
        }       
         }
       }

Applying the object to the state:

        ball1 = new FlxExtendedSprite(160, 120, AssetsRegistry.redPNG);
        //Argument 1:onPressed: true if the spring should only be active     when the mouse is pressed down on this sprite
        //Argument 2:retainVelocity: true to retain the velocity of the     spring when the mouse is released, or false to clear it
        //Argument 3:tension: The tension of the spring, smaller numbers     create springs closer to the mouse pointer
        //Argument 4:friction: The friction applied to the spring as it     moves
        //Argument 5:gravity: The gravity controls how far "down" the      spring hangs (use a negative value for it to hang up!)
        ball1.enableMouseSpring(false, false, 0.1, 0.95, -5);
        ball1.springOffsetX = 0;
        ball1.springOffsetY = 0;

Also, any help for loosening up the spring to make it more rope or string like would help too!

Thanks in advance!

xhunterko
  • 49
  • 7

1 Answers1

1

If you want it to be directly under the mouse, remove all x calculations and replace it with the mouseX param from the stage. The spring will now only move in the y dimension.

To adjust the springiness, play with the values for these:

this.tension = tension; //bounciness
this.friction = friction; //how tight
this.gravity = gravity; //mass

Some combination will get you what you're looking for.

Gone3d
  • 1,189
  • 1
  • 8
  • 20
  • Well, I tweaked with those and it feels a little better. I'd still like to get a string or rope feel though. I've looked at a few but those entail nodes and joints and other such things. Are there other methods to use then that? – xhunterko Dec 01 '12 at 23:29
  • Tension is going to be the param you want to use so see what works better - high or low. One should act more like a rope. Friction is what causes the delay in catching up to the mouse, the more friction, the more the effect occurs, so tweek that a bit up or down to see what helps. Gravity shouldn't make much difference and leave it alone until you get the other two working. – Gone3d Dec 02 '12 at 14:06