弹幕运动效果

  1. 图示
    1. 螺旋线与圆形散射:
    2. 其它散射:
  2. 心形线公式
  3. 心形散射 AS 实现主要代码
  4. 效果演示

弹幕运动效果有很多的应用,如视频弹幕,弹幕游戏中子弹轨迹,粒子特效等。
而实现弹幕运动很多都是基于几何数学,不同的公式和参数都呈现不同的效果。
如下图示

图示

螺旋线与圆形散射:

其它散射:

心形线公式

坐标值

{x=ρcosθy=ρsinθ\begin{cases} x=\rho\cos{\theta }\\ y=\rho\sin{\theta} \end{cases}

心脏线公式

{x=2cosθcos2θy=2sinθsin2θ\begin{cases} x=2\cos{\theta}-\cos{2\theta}\\ y=2\sin{\theta}-\sin{2\theta} \end{cases}

心形线公式[1]

{x=16sin3θy=13cosθ5cos2θ2cos3θcos4θ\begin{cases} x=16\sin^3\theta\\ y=13\cos\theta-5\cos2\theta-2\cos3\theta-\cos4\theta \end{cases}

心形散射 AS 实现主要代码

将一个视频剪辑起名为 Star,省略颜色代码和启动代码,主要代码如下:

package {
	import flash.display.*;
	import flash.events.*;
	import flash.geom.*;

	public class Star extends MovieClip {
		private var speed: Number; //星星走位速度
		private var rho: Number; //ρ长
		private var theta: Number; //θ弧度

		private var sizeX: Number; //横拉伸值
		private var sizeY: Number; //纵拉伸值

		private var cx: Number; //中心位置x
		private var cy: Number; //中心位置y 
		private var dx: Number; //到中心x差
		private var dy: Number; //到中心y差
		private var bx: Number; //初始位置x
		private var by: Number; //初始位置y

		public function Star(cx, cy, theta: Number) {

			this.theta = theta;
			this.cx = cx;
			this.cy = cy;

			theta = theta % (2 * Math.PI);
			speed = 0.5;
			rho = 1;
			sizeX = 6;
			sizeY = 6;

			x = 16 * Math.pow(Math.sin(theta), 3);
			y = 13 * Math.cos(theta) - 5 * Math.cos(2 * theta) - 2 * Math.cos(3 * theta) - Math.cos(4 * theta);

			x = sizeX * x + cx;
			y = sizeY * -y + cy;

			bx = x;
			by = y;

			dx = x - cx;
			dy = y - cy;
			
			addEventListener(Event.ENTER_FRAME, moveStar);

		}
		public function moveStar(event: Event) {

			if (dx > 0) {
				x = rho * Math.cos(Math.atan(dy / dx)) + bx;
				y = rho * Math.sin(Math.atan(dy / dx)) + by;
			} else if (dx < 0) {
				x = -rho * Math.cos(Math.atan(dy / dx)) + bx;
				y = -rho * Math.sin(Math.atan(dy / dx)) + by;
			} else if (dx == 0) {
				y = dy > 0 ? y += speed : y -= speed;
			}

			rho += speed;

			if (this.x > stage.stageWidth || this.x < 0 || this.y > stage.stageHeight || this.y < 0) {
				deleteStar();
			}

		}
		public function deleteStar() {
			removeEventListener(Event.ENTER_FRAME, moveStar);
			MovieClip(parent).removeStar(this);
			parent.removeChild(this);
		}
	}
}

效果演示


  1. https://zhuanlan.zhihu.com/p/69353260 ↩︎


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以邮件至feicyblog@hotmail.com