前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Flex Actionscript 3 小球碰撞 多球碰撞

Flex Actionscript 3 小球碰撞 多球碰撞

作者头像
用户1258909
发布2018-07-03 12:23:40
1K0
发布2018-07-03 12:23:40
举报
文章被收录于专栏:拂晓风起拂晓风起

没怎么玩过图形学,最近都需要做,又要复习物理和数学了~~~

以下是初成的作品,其实最终目的也不是这个球碰撞了,只是试试,有bug~~(就是球会偶尔粘在一起,是因为速度太快)

需要解决粘连问题,就需要加入“下一点位置”来做提前的碰撞预判。

可以简单加入下一点标记一下,在Ball类中,加EnterFrame监听,每一帧计算下一帧的位置,然后碰撞的测试函数改为使用nextX和nextY计算,而不是x和y。

效果如下:

直接上代码(没有更新“下一点标记”):

代码语言:javascript
复制
package
{
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.text.engine.Kerning;
	
	import flashx.textLayout.formats.BackgroundColor;
	
	[SWF(width = "600", height = "500", backgroundColor = "#000000", frameRate = "30")] 
	public class Main extends Sprite
	{
		private var ballList:Vector.<Ball> = new Vector.<Ball>;
		public function Main()
		{
			this.graphics.beginFill(0xFFFFFF);
			this.graphics.drawRect(0, 0, 600, 500);
			this.graphics.endFill();
			
			var colorArray:Array = [0x222222, 0x123456, 0xff2200, 0x11ff44, 0x4411ff, 0x132e00, 0x1df144, 0x40110f];
			
			//随机初始化每个MC的运动速度和方向
			for (var i:int = 0; i<8; i++) 
			{
				var radius:int = 30;
				var ball:Ball = new Ball(colorArray[i], radius);
				ball.speed.x = -5 + 10*Math.random();
				ball.speed.y = -5 + 10*Math.random();
				ball.x = i*60 + 5;
				ball.y = i*60 + 5;
				ballList.push(ball);
				
				this.addChild(ball);
			}
			
			var sw:Number = this.width;
			var sh:Number = this.height;
			
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function onEnterFrame(event:Event):void
		{
			for (var i:int = 0; i<ballList.length; i++) 
			{
				var ball:Ball = ballList[i];
				//如果到了边界,就反射
				if ((ball.x < 0) || (ball.x + 2*ball.radius > 600))
				{
					ball.speed.x *= -1;
				}
				if ((ball.y < 0) || (ball.y + 2*ball.radius > 500)) 
				{
					ball.speed.y *= -1;
				}
				//检测所有MC之间是否有碰撞,有就根据情况改变“增量”方向
				for (var j:int = i+1; j<ballList.length; j++) 
				{
					if (collisionTest(ball, ballList[j])) 
					{
						collide(ball, ballList[j]);
					}
				}
				//移动一个“增量”         
				ball.x += ball.speed.x;
				ball.y += ball.speed.y;
			}
		}

		//碰撞函数,根据两球碰撞方向和自身运动方向合成新的增量值
		private function collide(ball1:Ball, ball2:Ball):void 
		{
			//http://tina0152.blog.163.com/blog/static/119447958200910229109326/
			var x1:int = ball1.x + ball1.radius;
			var y1:int = ball1.y + ball1.radius;
			var x2:int = ball2.x + ball2.radius;
			var y2:int = ball2.y + ball2.radius;
			
			//s向量是球心连线上的
			var s:KVector = new KVector(x2-x1, y2-y1);
			s = s.unitfy();
			//t向量是s的垂直线上的
			var t:KVector = s.rotateClockwise(Math.PI/2);
			t = t.unitfy();
			var v1:KVector = ball1.speed;
			var v2:KVector = ball2.speed;
			
			//先算v1(v1x, v1y)在s和t轴的投影值,分别设为v1s和v1t
			//再算v2(v2x, v2y)在s和t轴的投影值,分别设为v2s和v2t:
			var v1s:Number = v1.dotMultiply(s);
			var v1t:Number = v1.dotMultiply(t);
			var v2s:Number = v2.dotMultiply(s);
			var v2t:Number = v2.dotMultiply(t);
			
			//简单做法,当质量一样,直接交换速度
			var temp:Number = v1s;
			v1s = v2s;
			v2s = temp;
			
			//首先求出v1t和v2t在t轴的向量v1t'和v2t'(将数值变为向量)
			//再求出v1s'和v2s'在s轴的向量v1s'和v2s'(将数值变为向量)
			var v1tVector:KVector = t.multiply(v1t);
			var v1sVector:KVector = s.multiply(v1s);
			var v2tVector:KVector = t.multiply(v2t);
			var v2sVector:KVector = s.multiply(v2s);
			
			ball1.speed = v1tVector.add(v1sVector);
			ball2.speed = v2tVector.add(v2sVector);
		}
		
		//碰撞侦测
		private function collisionTest(ball1:Ball, ball2:Ball):Boolean
		{
			var deltaX:Number = ball1.x + ball1.radius - (ball2.x + ball2.radius);
			var deltaY:Number = ball1.y + ball1.radius - (ball2.y + ball2.radius);
			var a:Number=Math.sqrt(deltaX*deltaX + deltaY*deltaY);
			if(a <= ball1.radius+ball2.radius)
			{	
				return true;
			}
			else
			{
				return false;
			}
		}
		
	}
}
代码语言:javascript
复制
package
{
	import flash.display.Sprite;
	
	public class Ball extends Sprite
	{
		private var _radius:int = 0;
		private var _speed:KVector = null;
		
		public function Ball(color:uint, radius:int)
		{
			super();
			this.radius = radius;
			this.graphics.beginFill(color, 0.6);
			this.graphics.drawCircle(radius,radius,radius);
			this.graphics.endFill();
			speed = new KVector();
		}

		public function get radius():int
		{
			return _radius;
		}

		public function set radius(value:int):void
		{
			_radius = value;
		}

		public function get speed():KVector
		{
			return _speed;
		}

		public function set speed(value:KVector):void
		{
			_speed = value;
		}



	}
}
代码语言:javascript
复制
package
{
	public class KVector
	{
		private var _x:Number = 0;
		private var _y:Number = 0;
		public function KVector(x:Number = 0,y:Number = 0)
		{
			this.x = x;
			this.y = y;
		}
		public function add(value:KVector):KVector
		{
			var vector:KVector = new KVector();
			vector.x = x + value.x;
			vector.y = y + value.y;
			return vector;
		}
		
		public function dotMultiply(vector:KVector):Number
		{
			return x * vector.x + y * vector.y;
		}
		public function multiply(value:Number):KVector
		{
			var vector:KVector = new KVector();
			vector.x = x*value;
			vector.y = y*value;
			return vector;
		}
		public function unitfy():KVector
		{
			var vector:KVector = new KVector();
			vector.x = x/Math.sqrt(x*x + y*y);
			vector.y = y/Math.sqrt(x*x + y*y);
			return vector;
		}
		public function divide(value:Number):KVector
		{
			var vector:KVector = new KVector();
			vector.x = x/value;
			vector.y = y/value;
			return vector;
		}
		
		/**
		 * angle是数学的弧度,以Math.PI为180度
		 */ 
		public function rotateClockwise(angle:Number):KVector
		{
			var vector:KVector = new KVector();
			vector.x = x*Math.cos(angle) + y*Math.sin(angle);
			vector.y = -x*Math.sin(angle) + y*Math.cos(angle);
			return vector;
		}

		public function get x():Number
		{
			return _x;
		}

		public function set x(value:Number):void
		{
			_x = value;
		}

		public function get y():Number
		{
			return _y;
		}

		public function set y(value:Number):void
		{
			_y = value;
		}


	}
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2011-09-06 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档