Skip to content


[AS 3] Squishing Effect

So Gahlord from over at www.n0d3.org has been wanting to see a squishing effect applied on an object (ball) upon a collision (right wall). Below is a simple animation to demonstrate. The effect can be influenced by changing the objects mass as it calculates the spring distance.

Squishing effect:

Here is the standard Ball.as class file:

package {
	import flash.display.Sprite;

	public class Ball extends Sprite {
		public var radius:Number;
		public var diameter:Number;
		private var color:uint;

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

		public function Ball(radius:Number=20, color:uint=0xb3d830) {
			this.radius = radius;
			this.color = color;
			this.diameter = radius * 2;
			init();
		}
		public function init():void {
			graphics.beginFill(color);
			graphics.drawCircle(0, 0, radius);
			graphics.endFill();
		}
	}
}

Here is the document class Throw.as:

package
{
	/* resources: http://ww2.slcc.edu/schools/hum_sci/physics/tutor/2210/kinetic_energy/ */

	import flash.display.Sprite;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat; 

	public class Throw extends Sprite
	{
		private var ball:Ball;
		private var vx:Number;
		private var vy:Number;
		private var bounce:Number = -0.7;
		private var gravity:Number = .86;

		private var mass:Number = 10;
		private var springConstant:Number = 1200; // represents 1200 N/m
		private var springDistance:Number;

		private var oldX:Number;
		private var oldY:Number;

		private var ballSpringDistance:TextField;

		public function Throw()
		{
			init();
		}

		private function init():void
		{
			ball = new Ball(30, Math.random() * 0xffffff);
			ball.x = stage.stageWidth / 2;
			ball.y = stage.stageHeight / 2;

			vx = 0;
			vy = 0;
			addChild(ball);

			ball.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);

			CreateTextField();
			ballSpringDistance.text = "Throw the ball fast or slow against the right wall";
		}

		private function onEnterFrame(event:Event):void
		{
			vy += gravity;
			ball.x += vx;
			ball.y += vy;

			var ltWall:Number = 0;
			var rtWall:Number = stage.stageWidth;
			var topWall:Number = 0;
			var botWall:Number = stage.stageHeight;

			if(ball.x + ball.radius > rtWall)
			{
				springDistance = Math.round((vx * Math.sqrt(mass / 1200)));

				// SQUISH
				ball.width = ball.diameter - springDistance;
				ball.height = ball.diameter + springDistance;

				ball.x = rtWall - ball.radius + (springDistance / 2);

				//trace ("Kinetic Energy: " + (-1 * .5 * mass * vx * vx));
				// distance = velocity times the square root of the mass divided by the spring constant (1200 N/m)
				// trace ("Distance: " + Math.round((vx * Math.sqrt(mass / 1200))));
				ballSpringDistance.y = ball.y - 10;
				ballSpringDistance.x = ball.x - 180;
				ballSpringDistance.text = "Squash: " + Math.round((vx * Math.sqrt(mass / 1200)));

				// stop the ball from traveling:
				removeEventListener(Event.ENTER_FRAME, onEnterFrame);

				init();

			}
			else if(ball.x - ball.radius < ltWall)
			{
				ball.x = ltWall + ball.radius;
				vx *= bounce;
			}
			if(ball.y + ball.radius > botWall)
			{
				ball.y = botWall - ball.radius;
				vy *= bounce;
			}
			else if(ball.y - ball.radius < topWall)
			{
				ball.y = topWall + ball.radius;
				vy *= bounce;
			} else {

			}
		}

		private function onMouseDown(event:MouseEvent):void
		{
			oldX = ball.x;
			oldY = ball.y;
			stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			ball.startDrag();

			removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			addEventListener(Event.ENTER_FRAME, trackVelocity);
		}

		private function onMouseUp(event:MouseEvent):void
		{
			stage.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
			ball.stopDrag();
			removeEventListener(Event.ENTER_FRAME, trackVelocity);
			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		private function trackVelocity(event:Event):void
		{
			vx = ball.x - oldX;
			vy = ball.y - oldY;
			oldX = ball.x;
			oldY = ball.y;
		}

		private function CreateTextField():void
        {
            // pulled this from:
            // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/text/TextField.html#includeExamplesSummary
            ballSpringDistance = new TextField();
            ballSpringDistance.autoSize = TextFieldAutoSize.LEFT;
            ballSpringDistance.background = false;
            ballSpringDistance.border = false;
			ballSpringDistance.multiline = true;

            var format:TextFormat = new TextFormat();
            format.font = "Arial";
            format.color = 0xffffff;
            format.size = 12;
            format.underline = false;  

			ballSpringDistance.defaultTextFormat = format;
            addChild(ballSpringDistance);
        }
	}
}

Posted in Actionscript 3, Physics.


One Response

Stay in touch with the conversation, subscribe to the RSS feed for comments on this post.

  1. panta says

    LOL Super funny ;)
    I squashed a ball at a value of 50 (tnx to my razer copperhead mouse :D )

    I bet you to do more.



Some HTML is OK

or, reply to this post via trackback.