﻿<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>as4game &#187; vertors for flash</title>
	<atom:link href="http://www.as4game.com/blog/archives/category/actionscript/flash%e5%90%91%e9%87%8f/feed" rel="self" type="application/rss+xml" />
	<link>http://www.as4game.com/blog</link>
	<description>actionscript for game</description>
	<lastBuildDate>Tue, 15 Feb 2011 07:54:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Flash向量-12-球和圆弧</title>
		<link>http://www.as4game.com/blog/archives/546</link>
		<comments>http://www.as4game.com/blog/archives/546#comments</comments>
		<pubDate>Wed, 23 Sep 2009 03:56:32 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=546</guid>
		<description><![CDATA[
现在，让我们一起研究下如何处理运动的球和圆弧。圆弧式圆的一部分，不同的是圆石360度的，而圆弧不足360度。对于球和球的碰撞，之可能存在一个碰撞点。对于球和圆弧的碰撞，可能有……不是1个，也不是2个，而是4个碰撞点。



图中，左边，运动的球从原画的外面碰撞到圆弧，中间，球从圆弧的里面碰撞到圆弧，右边，球碰到了圆弧的端点（圆弧有2个端点，球可能同时碰到这2个端点）


为了定义一个圆，我们需要中心点和半径。为了定义一个圆弧，除了需要中心点和半径，还需要它的起始端点的角度和终终止端点的角度。



例如，我们可以这样定义圆弧：


arc={p0:{x:170, y:90}, r:30, ang1:135, ang2:315};


圆弧的中心点在x=170,，y=90，它的半径为30，起点角度为135度，终点角度为315度。知道了这些，我们可以计算出圆弧的起点和终点的坐标：


ang1rad=ang1*Math.PI/180;
ang2rad=ang2*Math.PI/180;
v1.p0={
x:p0.x+r*Math.cos(ang1rad),
y:p0.y+r*Math.sin(ang1rad)
};
v1.p1={
x:p0.x+r*Math.cos(ang2rad),
y:p0.y+r*Math.sin(ang2rad)
};


向量1是圆弧的起点到终点连线向量。

碰撞

可以使用球和球章节介绍的方法，检测球和圆弧外面的碰撞。当碰撞发生的时候，我们再来检测这个碰撞的位置是否在圆弧上存在。



我们需要找到球和圆弧相切的点p3。我们知道了发生碰撞时球心的位置，所以我们可以画一个向量v2，从圆弧中心到碰撞时球的中心。


v2={p0:arc.p0, p1:ball.p3};


点p3在在这个向量上，它和圆弧中心的距离为圆弧的半径(它和球的中心的距离为球的半径)：


p3={
x:arc.p0.x+v2.dx*arc.r,
y:arc.p0.y+v2.dy*arc.r
};


然后我们画一个向量，从圆弧的起点到点p3：


v3={p0:v1.p0, p1:p3};


只有当v3和v1的左法线的点乘大于0时，p3才在圆弧上。


if(dotP(v3, v1LeftNormal)>=0){
  //collision
}else{
  //not on the arc
}


如果碰撞发生在圆弧的外侧，我们可以忽略其他3种情况。然而，如果碰撞点p3，不在圆弧上面，我们就要考虑球是否碰到圆弧的端点，还是碰到了圆弧的内侧。


对于端点，我们可以继续使用球和球的系统，假设端点是看不见的球，半径为0，坐落在端点坐标。和球碰撞的圆弧是：


ballvsBall(ball, arc.p0, arc.r);


我们可以这样检测端点碰撞：


ballvsBall(ball, v1.p0, 0);
ballvsBall(ball, v1.p1, 0);


对于球和圆弧内部碰撞，我们使用外部碰撞系统的略加修改版。外部碰撞检测方法是：


r=arc.r+ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x-moveBack*v.dx,
y:ball.p2.y-moveBack*v.dy};


内部碰撞检测方法：


r=arc.r-ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x+moveBack*v.dx,
y:ball.p2.y+moveBack*v.dy};


由于球可能和圆弧的多个点碰撞，我们可以取最短路径。


下面的例子中展示了球和圆弧的碰撞，你可以体验下：



你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p>
现在，让我们一起研究下如何处理运动的球和圆弧。圆弧式圆的一部分，不同的是圆石360度的，而圆弧不足360度。对于球和球的碰撞，之可能存在一个碰撞点。对于球和圆弧的碰撞，可能有……不是1个，也不是2个，而是4个碰撞点。
</p>
<p><img src="http://www.as4game.com/vectors/tut12_1.gif" alt="" /></p>
<p>
图中，左边，运动的球从原画的外面碰撞到圆弧，中间，球从圆弧的里面碰撞到圆弧，右边，球碰到了圆弧的端点（圆弧有2个端点，球可能同时碰到这2个端点）
</p>
<p>
为了定义一个圆，我们需要中心点和半径。为了定义一个圆弧，除了需要中心点和半径，还需要它的起始端点的角度和终终止端点的角度。
</p>
<p><img src="http://www.as4game.com/vectors/tut12_2.gif" alt="" /></p>
<p>
例如，我们可以这样定义圆弧：
</p>
<pre class="brush:as3">
arc={p0:{x:170, y:90}, r:30, ang1:135, ang2:315};
</pre>
<p>
圆弧的中心点在x=170,，y=90，它的半径为30，起点角度为135度，终点角度为315度。知道了这些，我们可以计算出圆弧的起点和终点的坐标：
</p>
<pre class="brush:as3">
ang1rad=ang1*Math.PI/180;
ang2rad=ang2*Math.PI/180;
v1.p0={
x:p0.x+r*Math.cos(ang1rad),
y:p0.y+r*Math.sin(ang1rad)
};
v1.p1={
x:p0.x+r*Math.cos(ang2rad),
y:p0.y+r*Math.sin(ang2rad)
};
</pre>
<p>
向量1是圆弧的起点到终点连线向量。
</p>
<p><strong>碰撞</strong></p>
<p>
可以使用球和球章节介绍的方法，检测球和圆弧外面的碰撞。当碰撞发生的时候，我们再来检测这个碰撞的位置是否在圆弧上存在。
</p>
<p><img src="http://www.tonypa.pri.ee/vectors/tut12_3.gif" alt="" /></p>
<p>
我们需要找到球和圆弧相切的点p3。我们知道了发生碰撞时球心的位置，所以我们可以画一个向量v2，从圆弧中心到碰撞时球的中心。
</p>
<pre class="brush:as3">
v2={p0:arc.p0, p1:ball.p3};
</pre>
<p>
点p3在在这个向量上，它和圆弧中心的距离为圆弧的半径(它和球的中心的距离为球的半径)：
</p>
<pre class="brush:as3">
p3={
x:arc.p0.x+v2.dx*arc.r,
y:arc.p0.y+v2.dy*arc.r
};
</pre>
<p>
然后我们画一个向量，从圆弧的起点到点p3：
</p>
<pre class="brush:as3">
v3={p0:v1.p0, p1:p3};
</pre>
<p>
只有当v3和v1的左法线的点乘大于0时，p3才在圆弧上。
</p>
<pre class="brush:as3">
if(dotP(v3, v1LeftNormal)>=0){
  //collision
}else{
  //not on the arc
}
</pre>
<p>
如果碰撞发生在圆弧的外侧，我们可以忽略其他3种情况。然而，如果碰撞点p3，不在圆弧上面，我们就要考虑球是否碰到圆弧的端点，还是碰到了圆弧的内侧。
</p>
<p>
对于端点，我们可以继续使用球和球的系统，假设端点是看不见的球，半径为0，坐落在端点坐标。和球碰撞的圆弧是：
</p>
<pre class="brush:as3">
ballvsBall(ball, arc.p0, arc.r);
</pre>
<p>
我们可以这样检测端点碰撞：
</p>
<pre class="brush:as3">
ballvsBall(ball, v1.p0, 0);
ballvsBall(ball, v1.p1, 0);
</pre>
<p>
对于球和圆弧内部碰撞，我们使用外部碰撞系统的略加修改版。外部碰撞检测方法是：
</p>
<pre class="brush:as3">
r=arc.r+ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x-moveBack*v.dx,
y:ball.p2.y-moveBack*v.dy};
</pre>
<p>
内部碰撞检测方法：
</p>
<pre class="brush:as3">
r=arc.r-ball.r;
moveBack=Math.sqrt(r*r-vn.len*vn.len);
ball.p3={
x:ball.p2.x+moveBack*v.dx,
y:ball.p2.y+moveBack*v.dy};
</pre>
<p>
由于球可能和圆弧的多个点碰撞，我们可以取最短路径。
</p>
<p>
下面的例子中展示了球和圆弧的碰撞，你可以体验下：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect12.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect12.swf" ></embed></object></p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect12.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/546/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-11-两个高速运动的球</title>
		<link>http://www.as4game.com/blog/archives/532</link>
		<comments>http://www.as4game.com/blog/archives/532#comments</comments>
		<pubDate>Tue, 22 Sep 2009 04:01:20 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=532</guid>
		<description><![CDATA[
运动的球心情肯定不错吧，因为它能动并且还能游览这个世界。但是，如果另外一个球决定不再原地不动，而也运动起来，那么会发生什么事情呢？我们很有必要研究一下这个。在这种情况下，我们之前介绍的碰撞检测方法可能会失败。让我们看看相同的例子：



球1按照红色运动向量来运动，球2按照蓝色运动向量来运动。如果要正确的进行碰撞检测的话，我们需要把每个球的运动向量考虑在内。



图中，当两球相撞时，球1到达了p2，而球2到达了p3。幸亏我们用了向量，我们可以非常容易的将2个向量相加。这样，我们就不用考虑2个运动的球，我们用球1的运动向量减去球2的运动向量，然后我们可以用学过的“一个运动的球和一个静态的球”的模型。【as4game注：这一段说的就是初中学的相对运动，把2个球的运动转化成1个球的运动】



用球1的运动向量减去球2的运动向量，就得到了向量v3：


v3={};
v3.p0=ball1.p0;
v3.vx=ball1.vx-ball2.vx;
v3.vy=ball1.vy-ball2.vy;


现在，我们可以使用上一章学习的方法来进行碰撞检测，假设球1要移动v3这么多，而v2原地不动。如果球1在p4这一点碰到球2。我们计算出新的向量v4，它是球1碰到球2时，自己的运动向量。


game.v4={p0:ball1.p0, p1:p4};


因为我们知道2个球都在运动，我们可以找到变量“t”，它的值为v4的长度除以v3的长度。


t=v4.len/v3.len;


变量“t”的值在0到1之间。当它等于1，碰撞发生在球的运动向量的终点，当它等于0，碰撞发生在球的运动向量的起点。为了计算2个球发生碰撞时的位置，我们需要将将它们的运动向量乘以t：


ball1.p1.x=ball1.p0.x+t*ball1.vx;
ball1.p1.y=ball1.p0.y+t*ball1.vy;
ball2.p1.x=ball2.p0.x+t*ball2.vx;
ball2.p1.y=ball2.p0.y+t*ball2.vy;


我制作了2个运动的球的例子：



你可以拖动球的运动向量的终点。


你可以下载fla源文件。

2个球的弹性

在找到了碰撞点之后，我们可以改变球的运动向量，可以参考章节球和球章节。但是到目前为止，我们只学过一个球运动时的反弹。当2个球都在运动，它们的运动会相互影响，使得他们的运动向量都需要重新计算。
弹性取决于2个球的质量。为了简化问题，我们假设2个球的质量相等【as4game注：如果要考虑质量不相等的情况，可以用动量守恒定理和能量守恒定律2个方程来计算】。在这种情况下，他们中心连线方向的速度会交换：



vc是球心连线向量，vcn是它的法线。现在我们将运动向量v1和v2在vc和vcn上进行投影：



v1被分解成v1a和v1b，同样v2被分解成v2a和v2b。然后v1a和v2a会交换，然后用v1b和v2a来计算球1的新运动向量，用v1a和v2b来计算球2的新运动向量。


下面的例子中，一些球在运动，他们彼此反弹：



你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p>
运动的球心情肯定不错吧，因为它能动并且还能游览这个世界。但是，如果另外一个球决定不再原地不动，而也运动起来，那么会发生什么事情呢？我们很有必要研究一下这个。在这种情况下，我们之前介绍的碰撞检测方法可能会失败。让我们看看相同的例子：
</p>
<p><img src="http://www.as4game.com/vectors/tut11_1.gif" alt="" /></p>
<p>
球1按照红色运动向量来运动，球2按照蓝色运动向量来运动。如果要正确的进行碰撞检测的话，我们需要把每个球的运动向量考虑在内。
</p>
<p><img src="http://www.as4game.com/vectors/tut11_3.gif" alt="" /></p>
<p>
图中，当两球相撞时，球1到达了p2，而球2到达了p3。幸亏我们用了向量，我们可以非常容易的将2个向量相加。这样，我们就不用考虑2个运动的球，我们用球1的运动向量减去球2的运动向量，然后我们可以用<img src="http://www.as4game.com/blog/archives/502" alt="不记得的话，可以看看" />学过的“一个运动的球和一个静态的球”的模型。【as4game注：这一段说的就是初中学的相对运动，把2个球的运动转化成1个球的运动】
</p>
<p><img src="http://www.as4game.com/vectors/tut11_4.gif" alt="" /></p>
<p>
用球1的运动向量减去球2的运动向量，就得到了向量v3：
</p>
<pre class="brush:as3;">
v3={};
v3.p0=ball1.p0;
v3.vx=ball1.vx-ball2.vx;
v3.vy=ball1.vy-ball2.vy;
</pre>
<p>
现在，我们可以使用上一章学习的方法来进行碰撞检测，假设球1要移动v3这么多，而v2原地不动。如果球1在p4这一点碰到球2。我们计算出新的向量v4，它是球1碰到球2时，自己的运动向量。
</p>
<pre class="brush:as3;">
game.v4={p0:ball1.p0, p1:p4};
</pre>
<p>
因为我们知道2个球都在运动，我们可以找到变量“t”，它的值为v4的长度除以v3的长度。
</p>
<pre class="brush:as3;">
t=v4.len/v3.len;
</pre>
<p>
变量“t”的值在0到1之间。当它等于1，碰撞发生在球的运动向量的终点，当它等于0，碰撞发生在球的运动向量的起点。为了计算2个球发生碰撞时的位置，我们需要将将它们的运动向量乘以t：
</p>
<pre class="brush:as3;">
ball1.p1.x=ball1.p0.x+t*ball1.vx;
ball1.p1.y=ball1.p0.y+t*ball1.vy;
ball2.p1.x=ball2.p0.x+t*ball2.vx;
ball2.p1.y=ball2.p0.y+t*ball2.vy;
</pre>
<p>
我制作了2个运动的球的例子：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect11.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect11.swf" ></embed></object></p>
<p>
你可以拖动球的运动向量的终点。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect11.fla" target="_blank">fla源文件</a>。
</p>
<p><strong>2个球的弹性</strong></p>
<p>
在找到了碰撞点之后，我们可以改变球的运动向量，可以参考章节<a target="_blank" href="http://www.as4game.com/blog/archives/468">球和球</a>章节。但是到目前为止，我们只学过一个球运动时的反弹。当2个球都在运动，它们的运动会相互影响，使得他们的运动向量都需要重新计算。<br />
弹性取决于2个球的质量。为了简化问题，我们假设2个球的质量相等【as4game注：如果要考虑质量不相等的情况，可以用动量守恒定理和能量守恒定律2个方程来计算】。在这种情况下，他们中心连线方向的速度会交换：
</p>
<p><img src="http://www.as4game.com/vectors/tut11_5.gif" alt="" /></p>
<p>
vc是球心连线向量，vcn是它的法线。现在我们将运动向量v1和v2在vc和vcn上进行投影：
</p>
<p><img src="http://www.as4game.com/vectors/tut11_6.gif" alt="" /></p>
<p>
v1被分解成v1a和v1b，同样v2被分解成v2a和v2b。然后v1a和v2a会交换，然后用v1b和v2a来计算球1的新运动向量，用v1a和v2b来计算球2的新运动向量。
</p>
<p>
下面的例子中，一些球在运动，他们彼此反弹：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect11a.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect11a.swf" ></embed></object></p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect11a.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/532/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-10-高速运动的球</title>
		<link>http://www.as4game.com/blog/archives/502</link>
		<comments>http://www.as4game.com/blog/archives/502#comments</comments>
		<pubDate>Wed, 16 Sep 2009 10:40:35 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=502</guid>
		<description><![CDATA[
在上一节里面，我们学会了如何检测2个球的碰撞，和如何找到碰撞后的运动方向。看起来非常既好用，又简单，但是其实是有问题的：球不能运动的太快，否者碰撞检测会失效。以下是这种情形的一个说明：



图中，球1（红色）位于p0，以速度v移动。在下一个运动周期里面，它会到达p1的位置（绿色）。我们在上一个周期和本次的周期都会检测球1和球2是否发生碰撞。由于不论是在起点还是在终点，球1和球2的距离足够的大，我们检测不到球1和球2的碰撞。但是从图中可以看出，事实上球1和球2确实发生了碰撞。



上图中，球1和球2会在位置p3发生碰撞。可以这样来计算p3：


首先我们找到移动之前2个球的中心连线的向量：


vc={};
vc.p0=ball1.p0;
vc.p1=ball2.p0;


现在，我们计算出p2，它是运动向量上与球2距离最小的点。这个点很容易找到，只需要将向量vc在运动向量上进行投影，如果你已经不记得如何计算投影，可以在基础知识章节中查找。


我们绘制一个向量vn，从点p2到球2的中心点。这个向量和运动向量的法线方向相同。


vp=projectVector(vc, v.dx, v.dy);
p2={x:v.p0.x+vp.vx, y:v.p0.y+vp.vy};
vn={};
vn.p0=p2;
vn.p1=ball2.p0;


现在，我们可以比较这个向量的长度和两个球的半径之和。如果vn比半径之和大，那么不会发生碰撞。如果vn的长度和半径之和相等，那么刚好插肩而过。如果vn的长度小于半径之和，那么碰撞在到达p2这一点之前发生了。


totalRadius=ball1.r+ball2.r;
var diff=totalRadius-vn.len;
if(diff>0){
  //collision
}else{
  //no collision
}


当检测到球发生了碰撞，应该将球1从点p2移回点p3。但是怎么计算p3呢？如果你仔细看看上面的图片，很可能会发现，球2的中心点，p2和p3构成了一个三角形。我们对三角形非常的熟悉了，虽然还不足以让我们爱上她，但是已经足以让我们找到p3。首先，我们知道点p2到球心的长度，也就是向量vn的长度。然后，我们可以求得点p3到球2中心的长度，等于球的半径之和。现在，就可以使用古老而好用的勾股定理，来计算第三边（从p2到p3）的长度。


moveBack=Math.sqrt(totalRadius*totalRadius-vn.len*vn.len);
p3={x:p2.x-moveBack*v.dx, y:p2.y-moveBack*v.dy};
v3={p0:v.p0, p1:p3};


所以，我们将运动向量v从p2反向移动moveBack这么长的距离。有可能p3在向量v的外面，此时意味着碰撞不在本次运动循环中发生，但是但是有可能是在过去或者未来发生。我们只处理此刻的碰撞，我们要求p3必须落在向量v上面：


if(game.v3.len0){
  //collision
  game.ob1.p0=game.p3;
}


首先，从球1中心到p3的长度必须小于向量v的长度。同时2个向量必须放心相同，这一点可以通过计算点乘来确定。


这种检测方法的前提是，球在最开始的时候没有发生碰撞，如果遇到这种情况的话，在计算碰撞之前要小心哦。


我制作了一个例子，运动的球碰撞其他的球：



你可以拖动那些球，也可以拖动运动向量的终点。红色的圆代表球1的开始运动的时候，绿色是球1的运动完成的时候，蓝色是球2。


你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p>
在上一节里面，我们学会了如何检测2个球的碰撞，和如何找到碰撞后的运动方向。看起来非常既好用，又简单，但是其实是有问题的：球不能运动的太快，否者碰撞检测会失效。以下是这种情形的一个说明：
</p>
<p><img src="http://www.as4game.com/vectors/tut10_1.gif" alt="速度过快，碰撞检测失效" /></p>
<p>
图中，球1（红色）位于p0，以速度v移动。在下一个运动周期里面，它会到达p1的位置（绿色）。我们在上一个周期和本次的周期都会检测球1和球2是否发生碰撞。由于不论是在起点还是在终点，球1和球2的距离足够的大，我们检测不到球1和球2的碰撞。但是从图中可以看出，事实上球1和球2确实发生了碰撞。
</p>
<p><img src="http://www.as4game.com/vectors/tut10_2.gif" alt="" /></p>
<p>
上图中，球1和球2会在位置p3发生碰撞。可以这样来计算p3：
</p>
<p>
首先我们找到移动之前2个球的中心连线的向量：
</p>
<pre class="brush:as3">
vc={};
vc.p0=ball1.p0;
vc.p1=ball2.p0;
</pre>
<p>
现在，我们计算出p2，它是运动向量上与球2距离最小的点。这个点很容易找到，只需要将向量vc在运动向量上进行投影，如果你已经不记得如何计算投影，可以在<a href="http://www.as4game.com/blog/?p=304" target="_blank">基础知识</a>章节中查找。
</p>
<p>
我们绘制一个向量vn，从点p2到球2的中心点。这个向量和运动向量的法线方向相同。
</p>
<pre class="brush:as3">
vp=projectVector(vc, v.dx, v.dy);
p2={x:v.p0.x+vp.vx, y:v.p0.y+vp.vy};
vn={};
vn.p0=p2;
vn.p1=ball2.p0;
</pre>
<p>
现在，我们可以比较这个向量的长度和两个球的半径之和。如果vn比半径之和大，那么不会发生碰撞。如果vn的长度和半径之和相等，那么刚好插肩而过。如果vn的长度小于半径之和，那么碰撞在到达p2这一点之前发生了。
</p>
<pre class="brush:as3">
totalRadius=ball1.r+ball2.r;
var diff=totalRadius-vn.len;
if(diff>0){
  //collision
}else{
  //no collision
}
</pre>
<p>
当检测到球发生了碰撞，应该将球1从点p2移回点p3。但是怎么计算p3呢？如果你仔细看看上面的图片，很可能会发现，球2的中心点，p2和p3构成了一个三角形。我们对三角形非常的熟悉了，虽然还不足以让我们爱上她，但是已经足以让我们找到p3。首先，我们知道点p2到球心的长度，也就是向量vn的长度。然后，我们可以求得点p3到球2中心的长度，等于球的半径之和。现在，就可以使用古老而好用的勾股定理，来计算第三边（从p2到p3）的长度。
</p>
<pre class="brush:as3">
moveBack=Math.sqrt(totalRadius*totalRadius-vn.len*vn.len);
p3={x:p2.x-moveBack*v.dx, y:p2.y-moveBack*v.dy};
v3={p0:v.p0, p1:p3};
</pre>
<p>
所以，我们将运动向量v从p2反向移动moveBack这么长的距离。有可能p3在向量v的外面，此时意味着碰撞不在本次运动循环中发生，但是但是有可能是在过去或者未来发生。我们只处理此刻的碰撞，我们要求p3必须落在向量v上面：
</p>
<pre class="brush:as3">
if(game.v3.len<ob.len and dotP(game.v3, ob)>0){
  //collision
  game.ob1.p0=game.p3;
}
</pre>
<p>
首先，从球1中心到p3的长度必须小于向量v的长度。同时2个向量必须放心相同，这一点可以通过计算点乘来确定。
</p>
<p>
这种检测方法的前提是，球在最开始的时候没有发生碰撞，如果遇到这种情况的话，在计算碰撞之前要小心哦。
</p>
<p>
我制作了一个例子，运动的球碰撞其他的球：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect10.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect10.swf" ></embed></object></p>
<p>
你可以拖动那些球，也可以拖动运动向量的终点。红色的圆代表球1的开始运动的时候，绿色是球1的运动完成的时候，蓝色是球2。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect10.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/502/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-9-球和球</title>
		<link>http://www.as4game.com/blog/archives/489</link>
		<comments>http://www.as4game.com/blog/archives/489#comments</comments>
		<pubDate>Thu, 10 Sep 2009 13:40:23 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=489</guid>
		<description><![CDATA[
首先，我们看看如何判断2个球发生碰撞。然后，再思考碰撞发生之后，球该怎么运动。



图中有球1（红色）和球2（蓝色）。2个球的球心之间的向量为v（绿色）。只有当v的长度小于两个球的半径只和时，两个球才发生了碰撞。我们需要做的是让2个球刚刚紧挨着，为了达到这个目的，我们需要将球1向v的方向移动一段距离：


pen=v.len-(b1.r+b2.r)


现在，2个球刚好紧贴，我们需要研究下运动向量如何变化。想象一下在两个球之间有一个无形的墙壁，墙壁的方式和球心连线向量的法线方向相同。



图中，黑色向量是向量v的法线，将它作为墙壁向量，用之前的方法计算球1的反弹运动向量。


以下是一个例子，一个球在舞台上移动，另外有几个静态的球。



尝试拖动那些静态的球。


你可以下载fla源文件。

把它装起来
你可能想让一个球在另外一个球里面。


假设，b2是大球，b1是小球。判断小球是否移出的条件是：


b2.r]]></description>
			<content:encoded><![CDATA[<p>
首先，我们看看如何判断2个球发生碰撞。然后，再思考碰撞发生之后，球该怎么运动。
</p>
<p><img src="http://www.as4game.com/vectors/tut09_1.gif" alt="2个球的碰撞" /></p>
<p>
图中有球1（红色）和球2（蓝色）。2个球的球心之间的向量为v（绿色）。只有当v的长度小于两个球的半径只和时，两个球才发生了碰撞。我们需要做的是让2个球刚刚紧挨着，为了达到这个目的，我们需要将球1向v的方向移动一段距离：
</p>
<pre>
pen=v.len-(b1.r+b2.r)
</pre>
<p>
现在，2个球刚好紧贴，我们需要研究下运动向量如何变化。想象一下在两个球之间有一个无形的墙壁，墙壁的方式和球心连线向量的法线方向相同。
</p>
<p><img src="http://www.as4game.com/vectors/tut09_2.gif" alt="2个球碰撞之后的运动向量的改变" /></p>
<p>
图中，黑色向量是向量v的法线，将它作为墙壁向量，用之前的方法计算球1的反弹运动向量。
</p>
<p>
以下是一个例子，一个球在舞台上移动，另外有几个静态的球。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect9.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect9.swf" ></embed></object></p>
<p>
尝试拖动那些静态的球。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect9.fla" target="_blank">fla源文件</a>。
</p>
<p><strong>把它装起来</strong><br />
你可能想让一个球在另外一个球里面。<br />
<object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect9a.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect9a.swf" ></embed></object></p>
<p>
假设，b2是大球，b1是小球。判断小球是否移出的条件是：
</p>
<pre>
b2.r<(b1.r+v.len)
</pre>
<p>
当这种情况发生的时候，我们需要将它移动回去，移动多少呢：
</p>
<pre>
var pen=b2.r-(b1.r+v.len)
</pre>
<p>
另外，要注意，计算反弹的时候，我们使用左法线（而不再是右法线）：
</p>
<pre>
var vbounce={dx:-v.dy, dy:v.dx, lx:-v.dx, ly:-v.dy};
</pre>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect9a.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/489/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Flash向量-8-球和角</title>
		<link>http://www.as4game.com/blog/archives/468</link>
		<comments>http://www.as4game.com/blog/archives/468#comments</comments>
		<pubDate>Fri, 04 Sep 2009 14:23:07 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=468</guid>
		<description><![CDATA[
不是所有的墙壁都会无限延伸，他们通常从某处出发，然后在某处结束。我们把这称为起点和终点。现在我要计算球与墙壁的角碰撞时的位置点和碰撞后的运动向量。



红色的是墙壁向量，灰色的是球的运动向量，可能碰到墙壁，也可能碰到墙角。在findIntersection函数里面，我们检测到距离球最近的墙壁，并找到让球“从相交状态回到紧贴状态的那个向量”。
墙壁向量为v2，球的运动向量是v1。先找到从墙壁的起点到球的中心的向量v3：


v3.vx=v1.p1.x-v2.p0.x;
v3.vy=v1.p1.y-v2.p0.y;


然后计算v3和墙壁向量v2的点乘：


var dp=v3.vx*v2.dx + v3.vy*v2.dy;


如果点乘为负数的话，说明球离墙壁的起点很近。并且那个移动回去的向量是向量v3。


if(dp0){
  var v=v4;
}


然而，如果这个时候，点乘为0或者负数，那么墙壁的边缘和球很近。此时，我们从墙壁起点到球中心的向量v3在墙壁法线上进行投影。球将会从墙壁法线方向移动回去，就像上一节一样。


else{
  var v=projectVector(v3, v2.lx, v2.ly);
}


最后我们返回当前的向量。


return v;


记住球的反弹向量将和球的返回向量垂直。当球碰到墙壁的时候，我们可以用墙壁向量来计算新的移动向量。当球碰到墙角的时候，从墙壁的终点到球中心的向量的法线就可以派上用场了。
尝试拖动墙壁试一试，观察球与墙壁的碰撞。



因为我们只检测了球的运动向量的终点，所以当球的速度非常快的时候，有可能球会穿过墙壁。为了避免这种情况，你应该确保球的速度永远不会超过它的半径。


你可以分别下载球与一个墙壁和多个墙壁碰撞的例子。
]]></description>
			<content:encoded><![CDATA[<p>
不是所有的墙壁都会无限延伸，他们通常从某处出发，然后在某处结束。我们把这称为起点和终点。现在我要计算球与墙壁的角碰撞时的位置点和碰撞后的运动向量。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect8.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect8.swf" ></embed></object></p>
<p>
红色的是墙壁向量，灰色的是球的运动向量，可能碰到墙壁，也可能碰到墙角。在findIntersection函数里面，我们检测到距离球最近的墙壁，并找到让球“从相交状态回到紧贴状态的那个向量”。<br />
墙壁向量为v2，球的运动向量是v1。先找到从墙壁的起点到球的中心的向量v3：
</p>
<pre class="brush:as3">
v3.vx=v1.p1.x-v2.p0.x;
v3.vy=v1.p1.y-v2.p0.y;
</pre>
<p>
然后计算v3和墙壁向量v2的点乘：
</p>
<pre class="brush:as3">
var dp=v3.vx*v2.dx + v3.vy*v2.dy;
</pre>
<p>
如果点乘为负数的话，说明球离墙壁的起点很近。并且那个移动回去的向量是向量v3。
</p>
<pre class="brush:as3">
if(dp<0){
  var v=v3;
}
</pre>
<p>
如果点乘是0，或者正数，我就检测球是不是和墙壁的终点很近。所以，首先，找到墙壁的终点到球中心的向量：
</p>
<pre class="brush:as3">
else{
  var v4={};
  v4.vx=v1.p1.x-v2.p1.x;
  v4.vy=v1.p1.y-v2.p1.y;
</pre>
<p>
并且和第一个点类似，我们可以再次计向量算v4和墙壁的点乘。
</p>
<pre class="brush:as3">
var dp=v4.vx*v2.dx + v4.vy*v2.dy;
</pre>
<p>
如果点乘是正数，球会碰到终点，而v4是用于将球移开：
</p>
<pre class="brush:as3">
if(dp>0){
  var v=v4;
}
</pre>
<p>
然而，如果这个时候，点乘为0或者负数，那么墙壁的边缘和球很近。此时，我们从墙壁起点到球中心的向量v3在墙壁法线上进行投影。球将会从墙壁法线方向移动回去，就像上一节一样。
</p>
<pre class="brush:as3">
else{
  var v=projectVector(v3, v2.lx, v2.ly);
}
</pre>
<p>
最后我们返回当前的向量。
</p>
<pre class="brush:as3">
return v;
</pre>
<p>
记住球的反弹向量将和球的返回向量垂直。当球碰到墙壁的时候，我们可以用墙壁向量来计算新的移动向量。当球碰到墙角的时候，从墙壁的终点到球中心的向量的法线就可以派上用场了。<br />
尝试拖动墙壁试一试，观察球与墙壁的碰撞。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect8a.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect8a.swf" ></embed></object></p>
<p>
因为我们只检测了球的运动向量的终点，所以当球的速度非常快的时候，有可能球会穿过墙壁。为了避免这种情况，你应该确保球的速度永远不会超过它的半径。
</p>
<p>
你可以分别下载球与<a target="_blank" href="http://www.as4game.com/vectors/vect8.fla">一个墙壁</a>和<a target="_blank" href="http://www.as4game.com/vectors/vect8a.fla">多个墙壁</a>碰撞的例子。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/468/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-7-球和线</title>
		<link>http://www.as4game.com/blog/archives/440</link>
		<comments>http://www.as4game.com/blog/archives/440#comments</comments>
		<pubDate>Thu, 03 Sep 2009 14:00:45 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=440</guid>
		<description><![CDATA[球和线

到现在你可能已经厌倦了总是只有一个移动的点。倒不是说点本身有什么不好，它们是好的，但是毕竟，点只是点。你能在你的周围能看到多少个点？我相信不会很多。最后，我们将向前迈进一大步，开始移动一些更加真实的东东西 &#8211; 球。


我相信你在生活中看到过很多的球，所以你知道他们和点有什么不同。球是有宽度的。在我们的2D例子中，球是用圆来表示的，它有圆心坐标并且有半径。


game.myOb={r:10};
game.myOb.p0={x:150, y:100};


已知一个运动的球的半径是10，另外我们知道球的中心坐标，它的移动向量和半径，我们要计算球撞上墙壁的会在哪儿。



图中，灰色的圈圈表示球的中心与墙壁的交点。事实上球在更早的时候就碰到墙壁了。球碰到墙壁的时候，球的位置应该这样的，将墙壁向量（green）向它的法线方向移动一个半径的距离，然后求出这个新的向量和球的运动向量（红色）的交点。所以，我们可以不使用墙壁向量，而是用一个方向相同，起点位置不同的向量。

Axes method

球和线的交点也可以用别的方法来计算。下面就来研究下如何通过一些简单的投影来确定球是否与墙壁碰撞。



图中，我们可以看到，球处于他的运动向量的终点p1处。我们绘制一个蓝色的向量，从墙壁向量的起点（v2.p0）出发，到达球的中心。现在我们将这个新的向量在墙壁的法线上进行投影，得到向量v3（红色）。为了将球紧贴墙壁放置，我需要将它向墙壁的法线方向移动：


ball.r-v3.len


在示例代码中，我们计算出墙壁法线的单位向量：


v.lx = v.dy;
v.ly = -v.dx;


在runme函数里，我们检查所有的墙壁：


for(var i=1; i=0){
    //move object away from the wall
    ob.p1.x+=w.lx*pen;
    ob.p1.y+=w.ly*pen;
    //change movement
    var vb=bounce(ob, w);
    ob.vx=vb.vx;
    ob.vy=vb.vy;
  }
}


对于每一个墙壁，如果球撞进去了，我们就计算出撞进去的距离，再将球拉回来，然后用之前同样的方法去计算反弹之后的向量。


计算撞进去的距离的函数：


function findIntersection(v1, v2){
  //vector between center [...]]]></description>
			<content:encoded><![CDATA[<p><strong>球和线</strong></p>
<p>
到现在你可能已经厌倦了总是只有一个移动的点。倒不是说点本身有什么不好，它们是好的，但是毕竟，点只是点。你能在你的周围能看到多少个点？我相信不会很多。最后，我们将向前迈进一大步，开始移动一些更加真实的东东西 &#8211; 球。
</p>
<p>
我相信你在生活中看到过很多的球，所以你知道他们和点有什么不同。球是有宽度的。在我们的2D例子中，球是用圆来表示的，它有圆心坐标并且有半径。
</p>
<pre class="brush:as3">
game.myOb={r:10};
game.myOb.p0={x:150, y:100};
</pre>
<p>
已知一个运动的球的半径是10，另外我们知道球的中心坐标，它的移动向量和半径，我们要计算球撞上墙壁的会在哪儿。
</p>
<p><img src="http://www.tonypa.pri.ee/vectors/tut07_1.gif" alt="" /></p>
<p>
图中，灰色的圈圈表示球的中心与墙壁的交点。事实上球在更早的时候就碰到墙壁了。球碰到墙壁的时候，球的位置应该这样的，将墙壁向量（green）向它的法线方向移动一个半径的距离，然后求出这个新的向量和球的运动向量（红色）的交点。所以，我们可以不使用墙壁向量，而是用一个方向相同，起点位置不同的向量。
</p>
<p><strong>Axes method</strong></p>
<p>
球和线的交点也可以用别的方法来计算。下面就来研究下如何通过一些简单的投影来确定球是否与墙壁碰撞。
</p>
<p><img src="http://www.as4game.com/vectors/tut07_2.gif" alt="" /></p>
<p>
图中，我们可以看到，球处于他的运动向量的终点p1处。我们绘制一个蓝色的向量，从墙壁向量的起点（v2.p0）出发，到达球的中心。现在我们将这个新的向量在墙壁的法线上进行投影，得到向量v3（红色）。为了将球紧贴墙壁放置，我需要将它向墙壁的法线方向移动：
</p>
<pre class="brush:as3">
ball.r-v3.len
</pre>
<p>
在示例代码中，我们计算出墙壁法线的单位向量：
</p>
<pre class="brush:as3">
v.lx = v.dy;
v.ly = -v.dx;
</pre>
<p>
在runme函数里，我们检查所有的墙壁：
</p>
<pre class="brush:as3">
for(var i=1; i<5; i++){
  var w=game["v"+i];
  //if we have hit the wall
  var pen=ob.r-findIntersection(ob, w);
  if(pen>=0){
    //move object away from the wall
    ob.p1.x+=w.lx*pen;
    ob.p1.y+=w.ly*pen;
    //change movement
    var vb=bounce(ob, w);
    ob.vx=vb.vx;
    ob.vy=vb.vy;
  }
}
</pre>
<p>
对于每一个墙壁，如果球撞进去了，我们就计算出撞进去的距离，再将球拉回来，然后用之前同样的方法去计算反弹之后的向量。
</p>
<p>
计算撞进去的距离的函数：
</p>
<pre class="brush:as3">
function findIntersection(v1, v2){
  //vector between center of ball
  //and starting point of wall
  var v3={};
  v3.vx=v1.p1.x-v2.p0.x;
  v3.vy=v1.p1.y-v2.p0.y;
  //project this vector on the normal of the wall
  var v=projectVector(v3, v2.lx, v2.ly);
  //find length of projection
  v.len=Math.sqrt(v.vx*v.vx+v.vy*v.vy);
  return v.len;
}
</pre>
<p>
在这个例子中，尝试拖动墙壁四个角的点：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect7.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect7.swf" ></embed></object></p>
<p>
注意，这个例子并没有考虑墙壁的长度，所有的墙壁都被认为是无限长的。这种方式可以用来保证球在盒子里面，而不会出去。在下一章节里面，我们会研究如何处理球和墙壁的角的碰撞。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect7.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/440/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-6-弹性</title>
		<link>http://www.as4game.com/blog/archives/423</link>
		<comments>http://www.as4game.com/blog/archives/423#comments</comments>
		<pubDate>Mon, 31 Aug 2009 12:48:27 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=423</guid>
		<description><![CDATA[
一旦碰撞发生，通常会在阻挡的地反发生反弹。当你的头撞到墙的时候是一个非常明显的例子（我不建议你这样尝试，那只会导致你头疼），但是如果观察一些事物比如球，会非常容易的发现球碰到障碍物的时候，很少继续向前或者正好停在那附近。


让我们研究下，在碰撞发生之后，如何计算新的运动向量。



图中，红线是运动向量，绿线是墙壁，黑线是墙壁的法线，而蓝线是碰撞发生后的新的运动向量。粗线是运动向量在墙壁和墙壁的法线上的投影。


原始运动向量和新的运动向量之间的不同是很明显的。看不出来吗？ok，你可以看一下他们的投影，在墙壁上的投影是一样的，在墙壁的法线上的投影方向相反。从这一点，我们很容易构建一个运动物体与墙壁之间的反弹系统：


找到交点
找到运动向量的投影
将法线上的投影反向
投影相加


如果你已经忘记了什么是投影，你可以在基础知识章节中查看。


v1是运动向量，v2是墙壁向量，v2的左法线是：


v2.lx = v2.vy;
v2.ly = -v2.vx;


v1，v2的点乘是：


dp1 = v1.vx*v2.vx + v1.vy*v2.vy;


运动向量在v2上的投影：


proj1.vx=dp1*v2.dx;
proj1.vy=dp1*v2.dy;


v1和v2法线的点乘：


dp2 = v1.vx*v2.lx + v1.vy*v2.ly;


运动向量在v2上的投影（注意，我们需要将左法线除以长度，将其归一化）


proj2.vx=dp*(v2.lx/v2.len);
proj2.vy=dp*(v2.ly/v2.len);


将投影反向：


proj2.vx*=-1;
proj2.vy*=-1;


通过投影相加，计算出新的向量：


v1.vx=proj1.vx+proj2.vx;
v1.vy=proj1.vy+proj2.vy;


在下面的例子中，你可以拖动一些点，来观察运动向量的变化：


你可以下载fla源文件。
真实的反弹和摩擦

在真实的世界中，没有物体可以永远运动，因为摩擦会损耗能量，而弹性碰撞也不是完全的。完全弹性碰撞意味着碰撞前后运动向量的长度不变。为了将反弹过程中的能量损失考虑进来，我们需要赋予物体2个属性：“弹性系数”和“摩擦系数”：


ob.b=0.99;
ob.f=0.99;


为了计算新的运动向量，我们可以分别将投影和两个物体的b和f相乘。弹性系数影响墙壁法线上的投影，摩擦系数影响墙壁上的投影。


v1.vx=v1.f*v2.f*proj1.vx+v1.b*v2.b*proj2.vx;
v1.vy=v1.f*v2.f*proj1.vy+v1.b*v2.b*proj2.vy;


如果每个物体的f和b都等于1，会发生什么呢？将会发生完全弹性碰撞，在碰撞的过程中，什么也没有损失。运动将以同样的强度继续。举个例子，如果没有弹性（b=0），那么运动向量在发生碰撞之后将与墙壁平行，物体将粘在墙壁上。想象一下球飞到油或者胶水上的样子。


当然，你也可以将弹性系数设置为大于1，在那种情况下，碰撞将加速物体的移动。一个比较好的例子是弹球游戏中的杠子，球碰到的时候，会有增加额外的速度。


在这个例子中，球在舞台上运动，有重力，并且有许多的墙壁。



运动的点会遍历所有的墙壁，自从上次检测到现在的时间里，是否会和他们发生碰撞。如果会碰到多个墙壁，交点最近的墙壁会被选择。然后将物体的终点会设置到交点的位置，并计算出新的运动向量。然后再将终点从交点的位置向新的运动向量的方向移动，移动多少呢？用原来的运动向量的长度减去从起点到交点的长度，就是这么多。



你至少还可以从2个方面来增强这个系统：
1.因为对象上一次绘制在p0，而下一次绘制在p1，我们看不到它曾经在交点附件呆过。这可能导致对象看起来像直接从p0到p1。虽然这样做逻辑上是不正确的，但是可以让人亲眼看到点曾经碰到墙壁。
2.当对象撞到一个墙壁之后，可能撞到第2个墙壁。而目前的方式，我们只考虑了最近的墙壁的碰撞。为了更加精确一些，我们可以在碰撞发生之后，立即在检查新的向量与所有的墙壁之间的碰撞，这个时候之需要检查从交点到p1的向量（图中的蓝线）。


你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p>
一旦碰撞发生，通常会在阻挡的地反发生反弹。当你的头撞到墙的时候是一个非常明显的例子（我不建议你这样尝试，那只会导致你头疼），但是如果观察一些事物比如球，会非常容易的发现球碰到障碍物的时候，很少继续向前或者正好停在那附近。
</p>
<p>
让我们研究下，在碰撞发生之后，如何计算新的运动向量。
</p>
<p><img src="http://www.as4game.com/vectors/tut06_1.gif" alt="" /></p>
<p>
图中，红线是运动向量，绿线是墙壁，黑线是墙壁的法线，而蓝线是碰撞发生后的新的运动向量。粗线是运动向量在墙壁和墙壁的法线上的投影。
</p>
<p>
原始运动向量和新的运动向量之间的不同是很明显的。看不出来吗？ok，你可以看一下他们的投影，在墙壁上的投影是一样的，在墙壁的法线上的投影方向相反。从这一点，我们很容易构建一个运动物体与墙壁之间的反弹系统：
</p>
<ul>
<li>找到交点</li>
<li>找到运动向量的投影</li>
<li>将法线上的投影反向</li>
<li>投影相加</li>
</ul>
<p>
如果你已经忘记了什么是投影，你可以在<a href="http://www.as4game.com/blog/?p=304" target="_blank">基础知识</a>章节中查看。
</p>
<p>
v1是运动向量，v2是墙壁向量，v2的左法线是：
</p>
<pre class="brush:as3">
v2.lx = v2.vy;
v2.ly = -v2.vx;
</pre>
<p>
v1，v2的点乘是：
</p>
<pre class="brush:as3">
dp1 = v1.vx*v2.vx + v1.vy*v2.vy;
</pre>
<p>
运动向量在v2上的投影：
</p>
<pre class="brush:as3">
proj1.vx=dp1*v2.dx;
proj1.vy=dp1*v2.dy;
</pre>
<p>
v1和v2法线的点乘：
</p>
<pre class="brush:as3">
dp2 = v1.vx*v2.lx + v1.vy*v2.ly;
</pre>
<p>
运动向量在v2上的投影（注意，我们需要将左法线除以长度，将其归一化）
</p>
<pre class="brush:as3">
proj2.vx=dp*(v2.lx/v2.len);
proj2.vy=dp*(v2.ly/v2.len);
</pre>
<p>
将投影反向：
</p>
<pre class="brush:as3">
proj2.vx*=-1;
proj2.vy*=-1;
</pre>
<p>
通过投影相加，计算出新的向量：
</p>
<pre class="brush:as3">
v1.vx=proj1.vx+proj2.vx;
v1.vy=proj1.vy+proj2.vy;
</pre>
<p>
在下面的例子中，你可以拖动一些点，来观察运动向量的变化：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect6.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect6.swf" ></embed></object><br />
你可以下载<a href="http://www.as4game.com/vectors/vect6.fla" target="_blank">fla源文件</a>。<br />
<strong>真实的反弹和摩擦</strong></p>
<p>
在真实的世界中，没有物体可以永远运动，因为摩擦会损耗能量，而弹性碰撞也不是完全的。完全弹性碰撞意味着碰撞前后运动向量的长度不变。为了将反弹过程中的能量损失考虑进来，我们需要赋予物体2个属性：“弹性系数”和“摩擦系数”：
</p>
<pre class="brush:as3">
ob.b=0.99;
ob.f=0.99;
</pre>
<p>
为了计算新的运动向量，我们可以分别将投影和两个物体的b和f相乘。弹性系数影响墙壁法线上的投影，摩擦系数影响墙壁上的投影。
</p>
<pre class="brush:as3">
v1.vx=v1.f*v2.f*proj1.vx+v1.b*v2.b*proj2.vx;
v1.vy=v1.f*v2.f*proj1.vy+v1.b*v2.b*proj2.vy;
</pre>
<p>
如果每个物体的f和b都等于1，会发生什么呢？将会发生完全弹性碰撞，在碰撞的过程中，什么也没有损失。运动将以同样的强度继续。举个例子，如果没有弹性（b=0），那么运动向量在发生碰撞之后将与墙壁平行，物体将粘在墙壁上。想象一下球飞到油或者胶水上的样子。
</p>
<p>
当然，你也可以将弹性系数设置为大于1，在那种情况下，碰撞将加速物体的移动。一个比较好的例子是弹球游戏中的杠子，球碰到的时候，会有增加额外的速度。
</p>
<p>
在这个例子中，球在舞台上运动，有重力，并且有许多的墙壁。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect6a.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect6a.swf" ></embed></object></p>
<p>
运动的点会遍历所有的墙壁，自从上次检测到现在的时间里，是否会和他们发生碰撞。如果会碰到多个墙壁，交点最近的墙壁会被选择。然后将物体的终点会设置到交点的位置，并计算出新的运动向量。然后再将终点从交点的位置向新的运动向量的方向移动，移动多少呢？用原来的运动向量的长度减去从起点到交点的长度，就是这么多。
</p>
<p><img src="http://www.as4game.com/vectors/tut06_2.gif" alt="" /></p>
<p>
你至少还可以从2个方面来增强这个系统：<br />
1.因为对象上一次绘制在p0，而下一次绘制在p1，我们看不到它曾经在交点附件呆过。这可能导致对象看起来像直接从p0到p1。虽然这样做逻辑上是不正确的，但是可以让人亲眼看到点曾经碰到墙壁。<br />
2.当对象撞到一个墙壁之后，可能撞到第2个墙壁。而目前的方式，我们只考虑了最近的墙壁的碰撞。为了更加精确一些，我们可以在碰撞发生之后，立即在检查新的向量与所有的墙壁之间的碰撞，这个时候之需要检查从交点到p1的向量（图中的蓝线）。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect6a.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/423/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-5-相交</title>
		<link>http://www.as4game.com/blog/archives/412</link>
		<comments>http://www.as4game.com/blog/archives/412#comments</comments>
		<pubDate>Sun, 30 Aug 2009 13:33:52 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=412</guid>
		<description><![CDATA[
现在你已经知道如何来移动物体了，现实世界中，移动的对象迟早是要碰到什么东东的。举个例子，如果移动的对象就是你本人，并且你很幸运的话，你碰到的东西很软，比如床，但是有时候你可能碰到坚硬的东西，砖头墙，水泥板，关闭的门，以及这个世界上的其他的一些等待你或者其他运动的物体去碰撞的坚硬物体。所以，疼痛的一个好处就是让人们知道什么东西可以去碰撞。


我们知道对象的移动向量，我们也知道墙壁所构成的向量。我们要求得 是否，何时，何地，物体会和墙壁碰撞。换句话说就是：“2个向量在哪里相交？”


首先，让我们看看什么时候2个向量不想交。向量平行的时候不相交。并且平行向量的单位向量是相等的（方向可以不相同，它们可以使反向的）：


(v1.dx==v2.dx and v1.dy==v2.dy) or
(v1.dx==-v2.dx and v1.dy==-v2.dy)


如果它们不平行，那么相交时迟早的事情。绿线是移动向量，红线是墙壁，蓝线在它们的起点之间：



交点的坐标可以这样计算：


v3={vx:v2.p0.x-v1.p0.x, vy:v2.p0.y-v1.p0.y};
var t=perP(v3, v2)/perP(v1, v2);
ip={};
ip.x=v1.p0.x+v1.vx*t;
ip.y=v1.p0.y+v1.vy*t;
function perP(va, vb){
	pp = va.vx*vb.vy - va.vy*vb.vx;
	return pp;
}


首先，我们计算出在它们起点之间的向量v3。上面的函数是用来计算2个向量的垂直点乘（perp dot product）【as4game注：垂直点乘这个概念，在中文的数学教科书我是没发现过的。参考网址】。
垂直点乘和点乘非常相似，不同的是用v1的法线取代v1。点乘是：


dp = v1.vx*v2.vx + v1.vy*v2.vy;


v1的法线是：


v.rx = -v.vy;
v.ry = v.vx;


然后我们用v1的法线代替v1：


pp = -v1.vy*v2.vx + v1.vx*v2.vy;


这就是垂直点乘了。


当两个垂直点乘的比例正好为1，那么交点就正好在移动向量的终点上。当为0-1之间的值时，那么交点就在v1上，当为负数交点就在向量的起点之前，当为大于1的数，交点就在向量的终点之后。
当然如果你想找到在另外一个向量上的交点，你也需要为v2计算t值：


v3={vx:v1.p0.x-v2.p0.x, vy:v1.p0.y-v2.p0.y};
var t=perP(v3, v1)/perP(v2, v1);


在下面的例子中，你可以尝试拖动那些点，然后观察向量的交点：



如果你对求交点的实际算法感兴趣，可以在这里查看。


你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p>
现在你已经知道如何来移动物体了，现实世界中，移动的对象迟早是要碰到什么东东的。举个例子，如果移动的对象就是你本人，并且你很幸运的话，你碰到的东西很软，比如床，但是有时候你可能碰到坚硬的东西，砖头墙，水泥板，关闭的门，以及这个世界上的其他的一些等待你或者其他运动的物体去碰撞的坚硬物体。所以，疼痛的一个好处就是让人们知道什么东西可以去碰撞。
</p>
<p>
我们知道对象的移动向量，我们也知道墙壁所构成的向量。我们要求得 是否，何时，何地，物体会和墙壁碰撞。换句话说就是：“2个向量在哪里相交？”
</p>
<p>
首先，让我们看看什么时候2个向量不想交。向量平行的时候不相交。并且平行向量的单位向量是相等的（方向可以不相同，它们可以使反向的）：
</p>
<pre class="brush:as3">
(v1.dx==v2.dx and v1.dy==v2.dy) or
(v1.dx==-v2.dx and v1.dy==-v2.dy)
</pre>
<p>
如果它们不平行，那么相交时迟早的事情。绿线是移动向量，红线是墙壁，蓝线在它们的起点之间：
</p>
<p><img src="http://www.as4game.com/vectors/tut05_1.gif" alt="" /></p>
<p>
交点的坐标可以这样计算：
</p>
<pre class="brush:as3">
v3={vx:v2.p0.x-v1.p0.x, vy:v2.p0.y-v1.p0.y};
var t=perP(v3, v2)/perP(v1, v2);
ip={};
ip.x=v1.p0.x+v1.vx*t;
ip.y=v1.p0.y+v1.vy*t;
function perP(va, vb){
	pp = va.vx*vb.vy - va.vy*vb.vx;
	return pp;
}
</pre>
<p>
首先，我们计算出在它们起点之间的向量v3。上面的函数是用来计算2个向量的垂直点乘（perp dot product）【as4game注：垂直点乘这个概念，在中文的数学教科书我是没发现过的。<a href="http://mathworld.wolfram.com/PerpDotProduct.html" target="_blank">参考网址</a>】。<br />
垂直点乘和点乘非常相似，不同的是用v1的法线取代v1。点乘是：
</p>
<pre class="brush:as3">
dp = v1.vx*v2.vx + v1.vy*v2.vy;
</pre>
<p>
v1的法线是：
</p>
<pre class="brush:as3">
v.rx = -v.vy;
v.ry = v.vx;
</pre>
<p>
然后我们用v1的法线代替v1：
</p>
<pre class="brush:as3">
pp = -v1.vy*v2.vx + v1.vx*v2.vy;
</pre>
<p>
这就是垂直点乘了。
</p>
<p>
当两个垂直点乘的比例正好为1，那么交点就正好在移动向量的终点上。当为0-1之间的值时，那么交点就在v1上，当为负数交点就在向量的起点之前，当为大于1的数，交点就在向量的终点之后。<br />
当然如果你想找到在另外一个向量上的交点，你也需要为v2计算t值：
</p>
<pre class="brush:as3">
v3={vx:v1.p0.x-v2.p0.x, vy:v1.p0.y-v2.p0.y};
var t=perP(v3, v1)/perP(v2, v1);
</pre>
<p>
在下面的例子中，你可以尝试拖动那些点，然后观察向量的交点：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect5.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect5.swf" ></embed></object></p>
<p>
如果你对求交点的实际算法感兴趣，可以在<a href="http://softsurfer.com/Archive/algorithm_0104/algorithm_0104B.htm" target="_blank">这里</a>查看。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect5.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/412/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-4-速度和加速度</title>
		<link>http://www.as4game.com/blog/archives/375</link>
		<comments>http://www.as4game.com/blog/archives/375#comments</comments>
		<pubDate>Sun, 30 Aug 2009 12:11:03 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=375</guid>
		<description><![CDATA[使用向量来移动

希望你在阅读本节之前，已经阅读了之前的基本章节。此刻，你应该已经知道什么是点，什么是向量，和如何计算向量的各种属性。并且你一直在等待能够亲自动手在一些真实的游戏中使用向量。让我们开始研究下如何使用向量来移动物体。


在这个例子中，红色的点就是我们的对象。通过方向键，你可以改变运动向量的x，y分量。



首先，我们定义一个对象：


myOb={};
myOb.p0={x:100, y:150};
myOb.vx=3;
myOb.vy=1;


对象的起点是x=100，y=150，移动向量的值是vx=3，vy=1。对象的新位置是向量的终点p1，它是在函数updateVector中进行计算的。如果你已经不记得如何查找p1的值，可以在Flash向量-基础知识章节中查找。


在MovieClip正确的放置了以后，我们会把终点p1作为在drawAll 函数中再一次计算位置时的起点。


每次按下方向键，x，y的分量就会增或者减。函数getKeys和releaseKeys处理这一逻辑。主函数runMe在每一帧都会执行，并且它会调用updateVector和drawAll函数来计算新位置并对mc进行定位。并且在这个例子中，你会发现，当对象移出舞台的时候，会重新出现到舞台的另外一边。


记住在进行计算的过程中，永远不要使用MovieClip的_x，_y属性，它应该是在计算过程完成以后，最后一步讲MovieClip放置到正确的位置。

帧还是时间
我们看下函数updateVector是如何找到结束点p1的新坐标的：

var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;
v.p1={};
v.p1.x=v.p0.x+v.vx*time;
v.p1.y=v.p0.y+v.vy*time;
v.lastTime=thisTime;


Flash是基于帧的程序，它会尽量以帧频的速度来执行所有的动画和脚本。在enterframe里面来处理所有的计算是很常见的，但这事实上并不是很好的方式。假设你写的代码是每一帧让对象的x坐标增加1。如果你将帧频设置为20，那么代码在每一帧里面会执行20次，从而使得对象每一帧移动20的像素。


你大概就是这样想的吧。但事实上，没有flash可以准确的按照帧频来执行。帧频只是flash想达到的最大值，但是通常都做不到。在浏览器中运行的flash比较吃力，因为浏览器本身占用一些cpu，有些计算机本身就比较慢，人们也可能有其他的程序在运行，所有的这些原因都会导致帧频下降20-25%。


“真的是这样吗？”，你可能在怀疑。它还在运行啊，坐标也会计算，MovieClip的位置也会改变的啊。是的，但是你已经失去了对你的游戏的控制了。你无法确保在一段时间之后，MovieClip位置在哪里，它的运动速度如何。如果你的flash是设计成用来测试人们的反应速度的，如果帧频下降50%，那么低帧频的人玩就比正常帧频下玩的人有巨大的优势。这是flash游戏的一种常见作弊方法，你可以很容易的降低帧频，并取得游戏胜利。


解决的办法是不要将计算基于帧数，而是实际的时间。在基于帧的游戏里面，声明速度vx=3意味着MovieClip每次能够执行的时候都会移动3个像素。在基于时间的游戏里面声明速度vx=3意味着MovieClip每秒钟移动3个像素。在基于时间的游戏里面，帧速的下降不会导致不可预知的结果，你仍然可以准确的知道MovieClip在哪里，不论是1秒钟之后，10秒钟之后或者1个小时之后。较慢的帧速在基于时间的影片里面会影响移动的平滑，对象在舞台上被绘制的次数，在每秒钟内会减少，从而导致“跳帧”，但是每一次绘制的时候，它将绘制到准确的位置。


我们使用getTimer函数来计算时间：


var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;


getTimer函数返回影片从开始到现在的毫秒数。在运动计算的时候，我们需要知道距离上一次计算的时间，所以我们用当前的时间减去上一次的时间。并且因为时间是用毫秒来计算的，我们需要将它除以100来得到秒。当然，你也可以使用 像素/毫秒 作为速度向量的单位，但是注意得出的值将非常的小。


终点的新坐标要根据逝去的时间来计算：


v.p1.x=v.p0.x+v.vx*time;


让我们来试一下到底对不对。加入我们的MovieClip在x=150，y=10的位置，速度为vx=1，如果帧速设置为20，时间间隔的变化，不管是5毫秒还是50毫秒。例如，假设是5毫秒，意味着每次移动的距离为v.p1.x=v.p0.x+0.05，1秒钟内移动20次，移动距离20*0.05=1 像素。也恰恰符合速度v1。再看看假设时间间隔50的情况，MovieClip每秒钟会在舞台上绘制2次，最后的位置是2*0.5=1像素。


你可以下载fla源文件。

加速度

就像速度向量能随着时间改变物体的位置一样，加速度向量可以随着时间改变物体的速度。



我们先将物体的加速度设置为0：


myOb.ax=0;
myOb.ay=0;


之后，当方向键被按下的时候，我们就改变加速度向量的x，y分量。在update函数里，我们会把加速度向量，添加到速度向量。使用加速度的时候要小心，如果你不限制速度的话，它会不断的增加下去。


v.vx=v.vx+v.ax;
v.vy=v.vy+v.ay;


同样要注意，要想完全停止物体的移动，我们不仅要将速度向量设置为0，还应该将加速度设置为0，否则物体是不会停下来的。


你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p><strong>使用向量来移动</strong></p>
<p>
希望你在阅读本节之前，已经阅读了之前的基本章节。此刻，你应该已经知道什么是点，什么是向量，和如何计算向量的各种属性。并且你一直在等待能够亲自动手在一些真实的游戏中使用向量。让我们开始研究下如何使用向量来移动物体。
</p>
<p>
在这个例子中，红色的点就是我们的对象。通过方向键，你可以改变运动向量的x，y分量。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect4.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect4.swf" ></embed></object></p>
<p>
首先，我们定义一个对象：
</p>
<pre class="brush:as3">
myOb={};
myOb.p0={x:100, y:150};
myOb.vx=3;
myOb.vy=1;
</pre>
<p>
对象的起点是x=100，y=150，移动向量的值是vx=3，vy=1。对象的新位置是向量的终点p1，它是在函数updateVector中进行计算的。如果你已经不记得如何查找p1的值，可以在<a href="http://www.as4game.com/blog/?p=304" target="_blank">Flash向量-基础知识</a>章节中查找。
</p>
<p>
在MovieClip正确的放置了以后，我们会把终点p1作为在drawAll 函数中再一次计算位置时的起点。
</p>
<p>
每次按下方向键，x，y的分量就会增或者减。函数getKeys和releaseKeys处理这一逻辑。主函数runMe在每一帧都会执行，并且它会调用updateVector和drawAll函数来计算新位置并对mc进行定位。并且在这个例子中，你会发现，当对象移出舞台的时候，会重新出现到舞台的另外一边。
</p>
<p>
记住在进行计算的过程中，永远不要使用MovieClip的_x，_y属性，它应该是在计算过程完成以后，最后一步讲MovieClip放置到正确的位置。
</p>
<p><strong>帧还是时间</strong></p>
<p>我们看下函数updateVector是如何找到结束点p1的新坐标的：</p>
<pre class="brush:as3">
var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;
v.p1={};
v.p1.x=v.p0.x+v.vx*time;
v.p1.y=v.p0.y+v.vy*time;
v.lastTime=thisTime;
</pre>
<p>
Flash是基于帧的程序，它会尽量以帧频的速度来执行所有的动画和脚本。在enterframe里面来处理所有的计算是很常见的，但这事实上并不是很好的方式。假设你写的代码是每一帧让对象的x坐标增加1。如果你将帧频设置为20，那么代码在每一帧里面会执行20次，从而使得对象每一帧移动20的像素。
</p>
<p>
你大概就是这样想的吧。但事实上，没有flash可以准确的按照帧频来执行。帧频只是flash想达到的最大值，但是通常都做不到。在浏览器中运行的flash比较吃力，因为浏览器本身占用一些cpu，有些计算机本身就比较慢，人们也可能有其他的程序在运行，所有的这些原因都会导致帧频下降20-25%。
</p>
<p>
“真的是这样吗？”，你可能在怀疑。它还在运行啊，坐标也会计算，MovieClip的位置也会改变的啊。是的，但是你已经失去了对你的游戏的控制了。你无法确保在一段时间之后，MovieClip位置在哪里，它的运动速度如何。如果你的flash是设计成用来测试人们的反应速度的，如果帧频下降50%，那么低帧频的人玩就比正常帧频下玩的人有巨大的优势。这是flash游戏的一种常见作弊方法，你可以很容易的降低帧频，并取得游戏胜利。
</p>
<p>
解决的办法是不要将计算基于帧数，而是实际的时间。在基于帧的游戏里面，声明速度vx=3意味着MovieClip每次能够执行的时候都会移动3个像素。在基于时间的游戏里面声明速度vx=3意味着MovieClip每秒钟移动3个像素。在基于时间的游戏里面，帧速的下降不会导致不可预知的结果，你仍然可以准确的知道MovieClip在哪里，不论是1秒钟之后，10秒钟之后或者1个小时之后。较慢的帧速在基于时间的影片里面会影响移动的平滑，对象在舞台上被绘制的次数，在每秒钟内会减少，从而导致“跳帧”，但是每一次绘制的时候，它将绘制到准确的位置。
</p>
<p>
我们使用getTimer函数来计算时间：
</p>
<pre class="brush:as3">
var thisTime=getTimer();
var time=(thisTime-v.lastTime)/100;
</pre>
<p>
getTimer函数返回影片从开始到现在的毫秒数。在运动计算的时候，我们需要知道距离上一次计算的时间，所以我们用当前的时间减去上一次的时间。并且因为时间是用毫秒来计算的，我们需要将它除以100来得到秒。当然，你也可以使用 像素/毫秒 作为速度向量的单位，但是注意得出的值将非常的小。
</p>
<p>
终点的新坐标要根据逝去的时间来计算：
</p>
<pre class="brush:as3">
v.p1.x=v.p0.x+v.vx*time;
</pre>
<p>
让我们来试一下到底对不对。加入我们的MovieClip在x=150，y=10的位置，速度为vx=1，如果帧速设置为20，时间间隔的变化，不管是5毫秒还是50毫秒。例如，假设是5毫秒，意味着每次移动的距离为v.p1.x=v.p0.x+0.05，1秒钟内移动20次，移动距离20*0.05=1 像素。也恰恰符合速度v1。再看看假设时间间隔50的情况，MovieClip每秒钟会在舞台上绘制2次，最后的位置是2*0.5=1像素。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect4.fla" target="_blank">fla源文件</a>。
</p>
<p><strong>加速度</strong></p>
<p>
就像速度向量能随着时间改变物体的位置一样，加速度向量可以随着时间改变物体的速度。
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect4a.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect4a.swf" ></embed></object></p>
<p>
我们先将物体的加速度设置为0：
</p>
<pre class="brush:as3">
myOb.ax=0;
myOb.ay=0;
</pre>
<p>
之后，当方向键被按下的时候，我们就改变加速度向量的x，y分量。在update函数里，我们会把加速度向量，添加到速度向量。使用加速度的时候要小心，如果你不限制速度的话，它会不断的增加下去。
</p>
<pre class="brush:as3">
v.vx=v.vx+v.ax;
v.vy=v.vy+v.ay;
</pre>
<p>
同样要注意，要想完全停止物体的移动，我们不仅要将速度向量设置为0，还应该将加速度设置为0，否则物体是不会停下来的。
</p>
<p>
你可以下载<a href="http://www.as4game.com/vectors/vect4a.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/375/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Flash向量-3-加法和投影</title>
		<link>http://www.as4game.com/blog/archives/558</link>
		<comments>http://www.as4game.com/blog/archives/558#comments</comments>
		<pubDate>Sun, 30 Aug 2009 11:04:38 +0000</pubDate>
		<dc:creator>as4game</dc:creator>
				<category><![CDATA[vertors for flash]]></category>

		<guid isPermaLink="false">http://www.as4game.com/blog/?p=558</guid>
		<description><![CDATA[基础。处理多个向量。
1个单独的向量，在很多的时候，让你觉得已经足够的智能和强大，去应付这个世界上的各种问题。然而事实上，你很少只需要1个向量，通常，你需要使用2个，3个甚至更多的向量。所以管理多个向量是非常重要的，否则它们会脱离你的控制，要知道和一个失控的向量战斗不是一件好玩的事情。


首先，多数情况下，有多个向量影响物体。一个例子就是重力：当物体本身在移动（用一个向量表示），而重力会把物体往下拉。重力和其他的力一样，可以用一个向量来表示。此时就有2个向量，你需要找到2个向量的综合效果，以确定物体到底该怎么移动。为了将2个向量加起来，你需要把他们的分量加起来：


resultv={};
resultv.vx=v1.vx+v2.vx;
resultv.vy=v1.vy+v2.vy;


如果你有更多的向量，你可以用同样的办法，把它们都加起来。

向量的投影。

有时候我们非常需要知道2个向量的方向关系，他们到底是把我们的物体往同一个方向牵引，还是一东一西呢。


dp = v1.vx*v2.vx + v1.vy*v2.vy;


我们将2个向量的x分量相乘，y分量相乘，然后在相加。得到结果dp，称为“向量v1和向量v2的点乘”。dp并不是一个向量，而是一个数字，如果是正数，那么2个向量的方向是相同的（夹角小于90度），如果是负数，那么2个向量的方向是相反的（夹角大于90度）。


下面说下2个向量的投影问题。将向量在其他任意的坐标系（向量v2和它的法线构成了一个坐标系）里面进行转换是非常有用的，这样投影的分量就可以单独变化。计算v1在v2上的投影的办法是：


proj.vx=dp*v2.dx;
proj.vy=dp*v2.dy;


向量的投影也是一个向量。我们先计算出2个向量的点乘，再乘以向量v2的归一化向量，就得到了投影。


以下是我制作的一个关于投影向量的例子。你可以四处拖动那些点，以观察投影分量的变化：


黑线是向量v1，蓝线是向量v2以及它的法线，绿线和红线分别是v1在v2和v2的法线上的投影。你可以下载fla源文件。
]]></description>
			<content:encoded><![CDATA[<p><strong>基础。处理多个向量。</strong></p>
<p>1个单独的向量，在很多的时候，让你觉得已经足够的智能和强大，去应付这个世界上的各种问题。然而事实上，你很少只需要1个向量，通常，你需要使用2个，3个甚至更多的向量。所以管理多个向量是非常重要的，否则它们会脱离你的控制，要知道和一个失控的向量战斗不是一件好玩的事情。
</p>
<p>
首先，多数情况下，有多个向量影响物体。一个例子就是重力：当物体本身在移动（用一个向量表示），而重力会把物体往下拉。重力和其他的力一样，可以用一个向量来表示。此时就有2个向量，你需要找到2个向量的综合效果，以确定物体到底该怎么移动。为了将2个向量加起来，你需要把他们的分量加起来：
</p>
<pre class="brush:as3">
resultv={};
resultv.vx=v1.vx+v2.vx;
resultv.vy=v1.vy+v2.vy;
</pre>
<p>
如果你有更多的向量，你可以用同样的办法，把它们都加起来。
</p>
<p><strong>向量的投影。</strong></p>
<p>
有时候我们非常需要知道2个向量的方向关系，他们到底是把我们的物体往同一个方向牵引，还是一东一西呢。
</p>
<pre class="brush:as3">
dp = v1.vx*v2.vx + v1.vy*v2.vy;
</pre>
<p>
我们将2个向量的x分量相乘，y分量相乘，然后在相加。得到结果dp，称为“向量v1和向量v2的点乘”。dp并不是一个向量，而是一个数字，如果是正数，那么2个向量的方向是相同的（夹角小于90度），如果是负数，那么2个向量的方向是相反的（夹角大于90度）。
</p>
<p>
下面说下2个向量的投影问题。将向量在其他任意的坐标系（向量v2和它的法线构成了一个坐标系）里面进行转换是非常有用的，这样投影的分量就可以单独变化。计算v1在v2上的投影的办法是：
</p>
<pre class="brush:as3">
proj.vx=dp*v2.dx;
proj.vy=dp*v2.dy;
</pre>
<p>
向量的投影也是一个向量。我们先计算出2个向量的点乘，再乘以向量v2的归一化向量，就得到了投影。
</p>
<p>
以下是我制作的一个关于投影向量的例子。你可以四处拖动那些点，以观察投影分量的变化：
</p>
<p><object width="300" height="200"><param name="movie" value="http://www.as4game.com/vectors/vect3.swf" /><embed width="300" height="200" type="application/x-shockwave-flash" src="http://www.as4game.com/vectors/vect3.swf" ></embed></object><br />
黑线是向量v1，蓝线是向量v2以及它的法线，绿线和红线分别是v1在v2和v2的法线上的投影。你可以下载<a href="http://www.as4game.com/vectors/vect3.fla" target="_blank">fla源文件</a>。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.as4game.com/blog/archives/558/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

