In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

code on 2009-1-24

Get Adobe Flash player
by gyuque 24 Jan 2009
package
{
	import flash.display.*;
	import flash.events.*;

	[SWF(width="465", height="465", backgroundColor="0x000000", frameRate="31")]
	public class WallPong extends Sprite
	{
		private var mField:Field;
		private var mBall:Ball;
		private var mBar:Bar;

		function WallPong()
		{
			mField = new Field(10, 10, 445, 445);
			addChild(mField);

			mBall = new Ball();
			addChild(mBall);
			mBall.setPosition(232, 200);
			mBall.setVelo(5, -5);

			mBar = new Bar();
			mBar.setRange(10 + 32, 10 + 445 - 32);
			addChild(mBar);
			mBar.x = 232;
			mBar.y = 420;

			mBall.addCollision(mField);
			mBall.addCollision(mBar);

			addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}

		private function onEnterFrame(e:Event):void
		{
			tick();
			updatePosition();
			draw();
		}

		private function tick():void
		{
			if (mBall.y > 500) {
				mBall.setPosition(232, 200);
				mBall.setVelo(5, -5);
			}

			mBar.setPos(mouseX);
			mBall.tick();
		}

		private function updatePosition():void
		{
			mBall.updatePosition();
		}

		private function draw():void
		{
			mBall.draw();
		}
	}
}

import flash.display.*;
const CIRCLE:int = 1;

class CollisionData
{
	public var canceled:Number;
	public var sender:ICollisionProvider;
	public var N:Vec2;
}

interface ICollisionObject
{

	function get shapeType():int;
	function get circleRadius():Number;
	function get currentPosition():Vec2;
	function get currentVelocity():Vec2;
	function onCollision(d:CollisionData):void;
}

interface ICollisionProvider
{
	function hittest(obj:ICollisionObject):Boolean;
}

class Bar extends Sprite implements ICollisionProvider
{
	import flash.geom.*;
	public static const GRAD_C:Array = [0xffede0, 0xeed6c2];
	public static const GRAD_A:Array = [1, 1];
	public static const GRAD_R:Array = [0, 255];

	public static const W:Number = 60;
	public static const R:Number = 80;
	public static const OFS:Number = 75;
	public static const ARG:Number = 0.45;

	private var mXmin:Number = 0, mXmax:Number = 10;

	function Bar():void
	{
		drawBase();
	}

	public function setRange(min:Number, max:Number):void
	{
		mXmin = min;
		mXmax = max;
	}

	public function setPos(px:Number):void
	{
		if (px < mXmin) px = mXmin;
		if (px > mXmax) px = mXmax;

		x = px;
	}

	private function drawBase():void
	{
		var m:Matrix = new Matrix();
		m.createGradientBox(30, 30, 0, -15, -14);
		var g:Graphics = graphics;
		g.clear();
		g.beginGradientFill(GradientType.RADIAL, GRAD_C, GRAD_A, GRAD_R, m);
		g.drawCircle(0, OFS, R);

		var ms:Sprite = new Sprite();
		addChild(ms);
		mask = ms;

		var mg:Graphics = ms.graphics;
		mg.clear();
		mg.beginFill(0);
		mg.drawRect(-W/2, -5, W, 10);
/*
		g.lineStyle(0, 0xff0000);
		g.moveTo(0, OFS);
		g.lineTo(0 + Math.sin(0.45)*100, OFS - Math.cos(0.45)*100);
*/
	}

	private var posC:Vec2 = new Vec2();
	public function hittest(obj:ICollisionObject):Boolean
	{
		var pos:Vec2 = obj.currentPosition;
		var v:Vec2   = obj.currentVelocity;

		if (pos.y > (y+3) || v.y < 0) return false;

		posC.x = x;
		posC.y = y + OFS;

		posC.x = (pos.x + v.x) - posC.x;
		posC.y = (pos.y + v.y) - posC.y;
		var d:Number = Math2D.norm(posC.x, posC.y);

		if ((d-obj.circleRadius) < R)
		{
			var next_x:Number = pos.x + v.x;
			if (next_x > (x -W/2) && next_x < (x +W/2)) {
				var ratio:Number = (R-(d-obj.circleRadius)) / Math2D.norm(v.x, v.y);
				if (ratio < 0) ratio = -ratio;
	
				var cd:CollisionData = new CollisionData();
				cd.canceled = ratio;
				cd.sender   = this;
				cd.N        = posC.clone().normalize();
				obj.onCollision(cd);

				return true;
			}
		}

		return false;
	}
}

class Ball extends Sprite implements ICollisionObject
{
	import flash.geom.*;
	public static const GRAD_C:Array = [0xffffff, 0x77aaff, 0x5588aa];
	public static const GRAD_A:Array = [1, 1, 1];
	public static const GRAD_R:Array = [0, 90, 255];

	public static const R:int = 10;

	private var mPos:Vec2  = new Vec2();
	private var mVelo:Vec2 = new Vec2(0, 0);
	private var mCols:Array = [];

	private var mF:Vec2 = new Vec2(0, 0);

	function Ball()
	{
		drawBase();
	}

	public function addCollision(c:ICollisionProvider):void
	{
		mCols.push(c);
	}

	public function setPosition(_x:Number, _y:Number):void
	{
		mPos.x = _x;
		mPos.y = _y;
	}

	public function addForce(fx:Number, fy:Number):void
	{
		mF.x = fx;
		mF.y = fy;
	}

	public function setVelo(_x:Number, _y:Number):void
	{
		mVelo.x = _x;
		mVelo.y = _y;
	}

	private function drawBase():void
	{
		var m:Matrix = new Matrix();
		m.createGradientBox(20, 20, 0, -14, -14);
		var g:Graphics = graphics;
		g.clear();
		g.beginGradientFill(GradientType.RADIAL, GRAD_C, GRAD_A, GRAD_R, m);
		g.drawCircle(0, 0, R);
	}

	public function tick():void
	{
		mVelo.add(mF);
		mF.x = 0;
		mF.y = 0;

		var c:ICollisionProvider;
		for each(c in mCols) {
			if (c.hittest(this)) {
			}
		}
	}

	public function updatePosition():void
	{
		mPos.x += mVelo.x;
		mPos.y += mVelo.y;
	}

	public function draw():void
	{
		x = mPos.x;
		y = mPos.y;
	}

	// collision

	public function get shapeType():int
	{
		return CIRCLE;
	}

	public function get currentPosition():Vec2
	{
		return mPos;
	}

	public function get currentVelocity():Vec2
	{
		return mVelo;
	}

	public function onCollision(d:CollisionData):void
	{
		var iN:Vec2 = new Vec2(-d.N.x, -d.N.y);
		var vy:Number = Vec2.dp(iN, mVelo);


		var fv:Vec2 = d.N.smul(vy * 2).add(mVelo);
		mVelo.smul(1 - d.canceled);

		var spd:Number = Math2D.norm(fv.x, fv.y);
		if (spd < 18) {
			spd += 0.2;
			fv.normalize().smul(spd);
		}
		addForce(fv.x - mVelo.x, fv.y - mVelo.y);
	}

	public function get circleRadius():Number
	{
		return R;
	}
}

class Field extends Sprite implements ICollisionProvider
{
	private var mWidth:int;
	private var mHeight:int;

	private var mPos:Vec2;

	function Field(x1:Number, y1:Number, w:int, h:int)
	{
		mPos = new Vec2(x1, y1);
		mWidth = w;
		mHeight = h;

		drawBase(x1, y1);
	}

	private function drawBase(x1:int, y1:int):void
	{

		var g:Graphics = graphics;
		g.clear();
		g.beginFill(0x444444);
		g.drawRect(x1 - 100, y1, 100, 500);
		g.drawRect(x1 + mWidth, y1, 100, 500);
		g.drawRect(x1 - 100, y1 - 100, mWidth + 200, 100);
	}

	public function hittest(obj:ICollisionObject):Boolean
	{
		if (checkVerticalWall(obj, mPos.x + mWidth, -1))
			return true;

		if (checkVerticalWall(obj, mPos.x, 1))
			return true;

		if (checkHorizontalWall(obj, mPos.y, 1))
			return true;

		return false;
	}

	private function checkVerticalWall(obj:ICollisionObject, wx:Number, nx:Number):Boolean
	{
		var pos:Vec2 = obj.currentPosition;
		var v:Vec2   = obj.currentVelocity;
		if ((v.x * nx) >= 0) return false;
		
		var next_x:Number = pos.x + v.x;
		var r:Number = (nx<0) ? obj.circleRadius : -obj.circleRadius;
		if ((nx>0 && (next_x+r) < wx) || (nx<0 && (next_x+r) > wx)) {
			var ratio:Number = (wx - (next_x+r)) / v.x;
			if (ratio < 0) ratio = -ratio;

			var cd:CollisionData = new CollisionData();
			cd.canceled = ratio;
			cd.sender   = this;
			cd.N        = new Vec2(nx, 0);
			obj.onCollision(cd);

			return true;
		}

		return false;
	}

	private function checkHorizontalWall(obj:ICollisionObject, wy:Number, ny:Number):Boolean
	{
		var pos:Vec2 = obj.currentPosition;
		var v:Vec2   = obj.currentVelocity;
		if ((v.y * ny) >= 0) return false;
		
		var next_y:Number = pos.y + v.y;
		var r:Number = (ny<0) ? obj.circleRadius : -obj.circleRadius;
		if ((ny>0 && (next_y+r) < wy) || (ny<0 && (next_y+r) > wy)) {
			var ratio:Number = (wy - (next_y+r)) / v.y;
			if (ratio < 0) ratio = -ratio;

			var cd:CollisionData = new CollisionData();
			cd.canceled = ratio;
			cd.sender   = this;
			cd.N        = new Vec2(0, ny);
			obj.onCollision(cd);

			return true;
		}

		return false;
	}

}

// math util
class Vec2
{
	function Vec2(aX:Number = 0, aY:Number = 0)
	{
		x = aX;
		y = aY;
	}

	public var x:Number;
	public var y:Number;

	public static function dp(v1:Vec2, v2:Vec2):Number
	{
		return v1.x*v2.x + v1.y*v2.y;
	}

	public function smul(k:Number):Vec2
	{
		x *= k;
		y *= k;

		return this;
	}

	public function add(v:Vec2):Vec2
	{
		x += v.x;
		y += v.y;

		return this;
	}

	public function normalize():Vec2
	{
		var nrm:Number = Math2D.norm(x, y);
		if (nrm != 0)
		{
			x /= nrm;
			y /= nrm;
		}

		return this;
	}

	public function clone():Vec2
	{
		return new Vec2(x, y);
	}

	public function left():Vec2
	{
		return Math2D.leftN(this);
	}

	public function right():Vec2
	{
		return Math2D.rightN(this);
	}

	public function zero():Vec2
	{
		x = 0;
		y = 0;

		return this;
	}

	public function trans(m:M22):Vec2
	{
		var _x:Number = x;
		var _y:Number = y;
		
		x = _x*m._11 + _y*m._12;
		y = _x*m._21 + _y*m._22;

		return this;
	}
}

class Math2D
{
	public static function nearZero(n:Number):Boolean
	{ return (n > -0.001) && (n < 0.001); }

	public static function norm(x:Number, y:Number):Number
	{ return Math.sqrt(x*x + y*y); }

	public static function leftN(v:Vec2):Vec2
	{
		var y:Number = v.y;
		v.y = -v.x;
		v.x = y;

		return v;
	}

	public static function rightN(v:Vec2):Vec2
	{
		var y:Number = v.y;
		v.y = v.x;
		v.x = -y;

		return v;
	}

	public static function makeAtoB(a:Vec2, b:Vec2):Vec2
	{
		return new Vec2(b.x-a.x, b.y-a.y);
	}

	public static function chkLineCross(A:Vec2,B:Vec2, C:Vec2,D:Vec2, AB_as_ray:Boolean, CD_as_seg:Boolean = true):Vec2
	{
		var vAB:Vec2 = makeAtoB(A, B);
		var vCD:Vec2 = makeAtoB(C, D);
		var vCA:Vec2 = makeAtoB(C, A);

		var M:M22 = new M22();
	
		M._11 = vCD.x;
		M._21 = vCD.y;
		M._12 = -vAB.x;
		M._22 = -vAB.y;

		var Minv:M22 = M.getInvert();
		if (Minv == null)
			return null;

		vCA.trans(Minv);
		
		if ((vCA.y > 1.0 && !AB_as_ray) || vCA.y < 0.0)
			return null;
		/* else AB is segment */

		if (CD_as_seg)
		{
			if (vCA.x > 1.0 || vCA.x < 0.0)
				return null;
		}

		/* else length is infinity */
		
		return vAB.smul(vCA.y).add(A);
	}
}

class M22
{
	public var _11:Number = 1;
	public var _12:Number = 0;
	public var _21:Number = 0;
	public var _22:Number = 1;

	public function getInvert():M22
	{
		var out:M22 = new M22();
		var det:Number = _11 * _22 - _12 * _21;
		if (Math2D.nearZero(det))
			return null;
	
		out._11 = _22 / det;
		out._22 = _11 / det;
	
		out._12 = -_12 / det;
		out._21 = -_21 / det;
	
		return out;
	}	

}