多角度回弹
算法实现:
ActionScirpt3.0实现:
1.构建小球精灵
Ball.as
package
{
import flash.display.Sprite;
public class Ball extends Sprite
{
public var radius:Number;
public var color:uint;
public var vx:Number=0;
public var vy:Number=0;
public function Ball (radius:Number,color:uint)
{
this.radius=radius;
this.color=color;
Init ();
}
public function Init ():void
{
graphics.beginFill (color);
graphics.drawCircle (0,0,radius);
graphics.endFill ();
}
}
}
2.构建多角度回弹
package
{
import flash.display.Sprite;
public class Ball extends Sprite
{
public var radius:Number;
public var color:uint;
public var vx:Number=0;
public var vy:Number=0;
public function Ball (radius:Number,color:uint)
{
this.radius=radius;
this.color=color;
Init ();
}
public function Init ():void
{
graphics.beginFill (color);
graphics.drawCircle (0,0,radius);
graphics.endFill ();
}
}
}
MultiAngleBounce.as
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
public class MultiAngleBounce extends Sprite
{
private var ball:Ball;
private var lines:Array;
private var numLines:int=5;
private var gravity:Number=0.3;
private var bounce:Number=-0.6;
public function MultiAngleBounce ()
{
Init ();
}
private function Init ():void
{
ball=new Ball(20,Math.random()*0xFFFFFF);
addChild (ball);
ball.x=100;
ball.y=0;
lines=new Array();
for (var i:int=0; i<numLines; i++)
{
var line:Sprite=new Sprite();
line.graphics.lineStyle (1);
line.graphics.moveTo (-50,0);
line.graphics.lineTo (50,0);
addChild (line);
lines.push (line);
}
lines[0].x=100;
lines[0].y=100;
lines[0].rotation=30;
lines[1].x=100;
lines[1].y=230;
lines[1].rotation=45;
lines[2].x=250;
lines[2].y=180;
lines[2].rotation=-30;
lines[3].x=150;
lines[3].y=330;
lines[3].rotation=10;
lines[4].x=230;
lines[4].y=250;
lines[4].rotation=-30;
addEventListener (Event.ENTER_FRAME,EnterFrame);
}
private function EnterFrame (e:Event):void
{
ball.vy+=gravity;
ball.x+=ball.vx;
ball.y+=ball.vy;
if (ball.x+ball.radius>stage.stageWidth)
{
ball.x=stage.stageWidth-ball.radius;
ball.vx*=bounce;
}
else if (ball.x-ball.radius<0)
{
ball.x=ball.radius;
ball.vx*=bounce;
}
if (ball.y+ball.radius>stage.stageHeight)
{
ball.y=stage.stageHeight-ball.radius;
ball.vy*=bounce;
}
else if (ball.y-ball.radius<0)
{
ball.y=ball.radius;
ball.vy*=bounce;
}
for (var i:int=0; i<numLines; i++)
{
CheckLine (lines[i]);
}
}
private function CheckLine (line:Sprite):void
{
var bounds:Rectangle=line.getBounds(this);
if (ball.x>bounds.left && ball.x<bounds.right)
{
var angle:Number=line.rotation*Math.PI/180;
var x1:Number=ball.x-line.x;
var y1:Number=ball.y-line.y;
var y2:Number=Math.cos(angle)*y1-Math.sin(angle)*x1;
var vy1:Number=Math.cos(angle)* ball.vy-Math.sin(angle)*ball.vx;
if (y2+ball.radius>0 && y2<vy1)//y2为负值
{
var x2:Number=Math.cos(angle)*x1+Math.sin(angle)*y1;
var vx1:Number=Math.cos(angle)* ball.vx+Math.sin(angle)*ball.vy;
y2=-ball.radius;
vy1*=bounce;
x1=Math.cos(angle)*x2-Math.sin(angle)*y2;
y1=Math.cos(angle)*y2+Math.sin(angle)*x2;
ball.vx=Math.cos(angle)*vx1-Math.sin(angle)*vy1;
ball.vy=Math.cos(angle)*vy1+Math.sin(angle)*vx1;
ball.x=line.x+x1;
ball.y=line.y+y1;
}
}
}
}
}
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
public class MultiAngleBounce extends Sprite
{
private var ball:Ball;
private var lines:Array;
private var numLines:int=5;
private var gravity:Number=0.3;
private var bounce:Number=-0.6;
public function MultiAngleBounce ()
{
Init ();
}
private function Init ():void
{
ball=new Ball(20,Math.random()*0xFFFFFF);
addChild (ball);
ball.x=100;
ball.y=0;
lines=new Array();
for (var i:int=0; i<numLines; i++)
{
var line:Sprite=new Sprite();
line.graphics.lineStyle (1);
line.graphics.moveTo (-50,0);
line.graphics.lineTo (50,0);
addChild (line);
lines.push (line);
}
lines[0].x=100;
lines[0].y=100;
lines[0].rotation=30;
lines[1].x=100;
lines[1].y=230;
lines[1].rotation=45;
lines[2].x=250;
lines[2].y=180;
lines[2].rotation=-30;
lines[3].x=150;
lines[3].y=330;
lines[3].rotation=10;
lines[4].x=230;
lines[4].y=250;
lines[4].rotation=-30;
addEventListener (Event.ENTER_FRAME,EnterFrame);
}
private function EnterFrame (e:Event):void
{
ball.vy+=gravity;
ball.x+=ball.vx;
ball.y+=ball.vy;
if (ball.x+ball.radius>stage.stageWidth)
{
ball.x=stage.stageWidth-ball.radius;
ball.vx*=bounce;
}
else if (ball.x-ball.radius<0)
{
ball.x=ball.radius;
ball.vx*=bounce;
}
if (ball.y+ball.radius>stage.stageHeight)
{
ball.y=stage.stageHeight-ball.radius;
ball.vy*=bounce;
}
else if (ball.y-ball.radius<0)
{
ball.y=ball.radius;
ball.vy*=bounce;
}
for (var i:int=0; i<numLines; i++)
{
CheckLine (lines[i]);
}
}
private function CheckLine (line:Sprite):void
{
var bounds:Rectangle=line.getBounds(this);
if (ball.x>bounds.left && ball.x<bounds.right)
{
var angle:Number=line.rotation*Math.PI/180;
var x1:Number=ball.x-line.x;
var y1:Number=ball.y-line.y;
var y2:Number=Math.cos(angle)*y1-Math.sin(angle)*x1;
var vy1:Number=Math.cos(angle)* ball.vy-Math.sin(angle)*ball.vx;
if (y2+ball.radius>0 && y2<vy1)//y2为负值
{
var x2:Number=Math.cos(angle)*x1+Math.sin(angle)*y1;
var vx1:Number=Math.cos(angle)* ball.vx+Math.sin(angle)*ball.vy;
y2=-ball.radius;
vy1*=bounce;
x1=Math.cos(angle)*x2-Math.sin(angle)*y2;
y1=Math.cos(angle)*y2+Math.sin(angle)*x2;
ball.vx=Math.cos(angle)*vx1-Math.sin(angle)*vy1;
ball.vy=Math.cos(angle)*vy1+Math.sin(angle)*vx1;
ball.x=line.x+x1;
ball.y=line.y+y1;
}
}
}
}
}