Flash/Flex学习笔记(25):摩擦力与屏幕环绕

简介: 摩擦力: 假如一个物体在某个方向上沿直线运行,摩擦力会使该方向上的速度越来越小,直到停止。 上图示意了该过程,物体以moveAngle角度正向运动,最终的速度speed矢量为vx矢量与vy矢量的矢量和,在每个单位时间内的位移即Speed矢量的大小,分解到x,y轴后,即为vx与vy;加入摩擦力后,speed矢量每单位时间将减少Friction值,也就是视觉上的越来越慢。

摩擦力:

假如一个物体在某个方向上沿直线运行,摩擦力会使该方向上的速度越来越小,直到停止。
img_2b66744ea301609e12a357f75a092272.jpg

上图示意了该过程,物体以moveAngle角度正向运动,最终的速度speed矢量为vx矢量与vy矢量的矢量和,在每个单位时间内的位移即Speed矢量的大小,分解到x,y轴后,即为vx与vy;加入摩擦力后,speed矢量每单位时间将减少Friction值,也就是视觉上的越来越慢。

var ball:Ball = new Ball(10);
ball.x = stage.stageWidth/2;
ball.y = stage.stageHeight/2;
addChild(ball);
Mouse.cursor = MouseCursor.BUTTON;
var Velocity:Number = 10;//速度最大值
var friction = 0.4;//摩擦力因子
stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,MouseUpHandler);

function MouseDownHandler(e:MouseEvent):void{
	graphics.clear();
	//初始化小球位置以速度
	ball.x = stage.stageWidth/2;
	ball.y = stage.stageHeight/2;
	ball.vx = (Math.random()*2-1) * Velocity;
	ball.vy = (Math.random()*2-1) * Velocity;	
	graphics.moveTo(ball.x,ball.y);
	graphics.lineStyle(1,0xcccccc,1);
}

function MouseUpHandler(e:MouseEvent):void{	
	addEventListener(Event.ENTER_FRAME,EnterFrameHandler);
}

function EnterFrameHandler(e:Event):void{
	ball.x += ball.vx;
	ball.y += ball.vy;
	
	var speed:Number = Math.sqrt(ball.vx*ball.vx + ball.vy*ball.vy);
	var moveAngle = Math.atan2(ball.vy,ball.vx);
	
	speed -= friction;
	
	//减速后的新速度
	ball.vx = speed*Math.cos(moveAngle);
	ball.vy = speed*Math.sin(moveAngle);
	
	//防止减速过度,就成反向运动
	if (speed<=friction){
		ball.vx = 0;
		ball.vy = 0;
		removeEventListener(Event.ENTER_FRAME,EnterFrameHandler);
	}	
	graphics.lineTo(ball.x,ball.y);
	
}

上面这种方法从物理意义上讲最接近现实情况,不过有些复杂,在实际开发中还有一种更简单的办法,虽然不怎么严密,但从视觉效果上很难看出问题

var ball:Ball = new Ball(10);
ball.x = stage.stageWidth/2;
ball.y = stage.stageHeight/2;
addChild(ball);
Mouse.cursor = MouseCursor.BUTTON;
var Velocity:Number = 10;
var friction = 0.9;//摩擦力因子(小于1大于0即可)
stage.addEventListener(MouseEvent.MOUSE_DOWN,MouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP,MouseUpHandler);

function MouseDownHandler(e:MouseEvent):void{
	graphics.clear();	
	ball.x = stage.stageWidth/2;
	ball.y = stage.stageHeight/2;
	ball.vx = (Math.random()*2-1) * Velocity;
	ball.vy = (Math.random()*2-1) * Velocity;	
	graphics.moveTo(ball.x,ball.y);
	graphics.lineStyle(1,0xcccccc,1);
}

function MouseUpHandler(e:MouseEvent):void{	
	addEventListener(Event.ENTER_FRAME,EnterFrameHandler);
}

function EnterFrameHandler(e:Event):void{
	ball.x += ball.vx;
	ball.y += ball.vy;
	
	ball.vx = ball.vx * friction;//直接让x轴速度不断衰减
	ball.vy = ball.vy * friction;//直接让y轴速度不断衰减	
	
	if (Math.abs(ball.vx)<=0.0001 || Math.abs(ball.vy)<=0.0001){
		ball.vx = 0;
		ball.vy = 0;
		removeEventListener(Event.ENTER_FRAME,EnterFrameHandler);
	}	
	
	//trace(ball.vx);
	//trace(ball.vy);
	graphics.lineTo(ball.x,ball.y);
	
}

屏幕环绕:

这个叫法也许从字面上不太直观,说得更白一点就是:一个物体如果在运动过程中跑出了舞台边界,开发人员就要想办法让其从舞台的另一端出现,并继续运动,以保持连贯。前面的一篇文章 Flash/Flex学习笔记(23):运动学原理 中有一个飞船的示例,加入屏幕环绕处理后,代码如下:

package {
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import fl.controls.Label;
	
	public class ShipSim2 extends Sprite {
		
		private var ship:Ship;
		private var vr:Number=0;
		private var thrust:Number=0;
		private var vx:Number=0;
		private var vy:Number=0;		
		
		public function ShipSim2() {
			init();
		}
		
		private function init():void {
			stage.scaleMode=StageScaleMode.NO_SCALE;
			stage.align=StageAlign.TOP_LEFT;			
			
			ship = new Ship();
			addChild(ship);
			ship.x=stage.stageWidth/2;
			ship.y=stage.stageHeight/2;
			addEventListener(Event.ENTER_FRAME, EnterFrameHandler);
			stage.addEventListener(KeyboardEvent.KEY_DOWN, KeyDownHandler);
			stage.addEventListener(KeyboardEvent.KEY_UP, KeyUpHandler);
		}
		
		private function KeyDownHandler(event:KeyboardEvent):void {
			switch (event.keyCode) {
				case Keyboard.LEFT :
					vr=-5;
					break;
				case Keyboard.RIGHT :
					vr=5;
					break;
				case Keyboard.UP :
					thrust=0.2;
					ship.draw(true);
					break;
				default :
					break;
			}
		}
		
		private function KeyUpHandler(event:KeyboardEvent):void {
			vr=0;			
			thrust=0;
			ship.draw(false);
		}
		
		private function EnterFrameHandler(event:Event):void {
			ship.rotation+=vr;
			var angle:Number=ship.rotation*Math.PI/180;
			var ax:Number=Math.cos(angle)*thrust;
			var ay:Number=Math.sin(angle)*thrust;
			vx+=ax;
			vy+=ay;
			ship.x+=vx;
			ship.y+=vy;
			var left:Number=0;
			var right:Number=stage.stageWidth;
			var top:Number=0;
			var bottom:Number=stage.stageHeight;
			//屏幕环绕处理
			if (ship.x>right + ship.width/2) {
				ship.x=left-ship.width/2;
			} else if (ship.x < left - ship.width/2) {
				ship.x=right+ship.width/2;
			}
			if (ship.y-ship.height/2>bottom) {
				ship.y=top-ship.height/2;
			} else if (ship.y < top - ship.height / 2) {
				ship.y=bottom+ship.height/2;
			}
		}
	}
}

最后把这二者结合起来,看下效果:

目录
相关文章
|
7月前
|
前端开发 安全 容器
flex为1的父元素被子元素挤出屏幕怎么办?
【8月更文挑战第24天】flex为1的父元素被子元素挤出屏幕怎么办?
78 2
flex为1的父元素被子元素挤出屏幕怎么办?
|
2天前
|
开发者 容器
鸿蒙开发:弹性布局Flex
在实际的开发中,需要掌握主轴与交叉轴的关系、换行规则及子元素属性,同时注意性能与兼容性问题,还有一点,Flex组件在渲染时存在二次布局过程,因此在对性能有严格要求的场景下建议使用Column、Row代替。
24 10
鸿蒙开发:弹性布局Flex
|
6月前
|
开发者 容器
flex 布局属性在实际项目中的应用场景有哪些?
flex 布局属性在实际项目中的应用场景有哪些?
|
5月前
|
前端开发 UED 容器
使用 Flex 布局实现垂直居中效果
【10月更文挑战第7天】
553 57
|
4月前
|
容器
Bootstrap5 Flex(弹性)布局4
排序:.order 类可设置弹性子元素的排序,范围从 .order-1 至 .order-12,数字越小优先级越高。外边距:.ms-auto 和 .me-auto 分别用于设置子元素的右侧和左侧外边距为 auto。包裹:.flex-nowrap(默认)、.flex-wrap 和 .flex-wrap-reverse 用于控制弹性容器中的子元素是否换行及换行方向。
|
3月前
|
容器
Bootstrap5 Flex(弹性)布局6
使用 `.align-self-*` 类可控制指定子元素的对齐方式,包括 `.align-self-start`, `.align-self-end`, `.align-self-center`, `.align-self-baseline`, 和 `.align-self-stretch`。示例代码展示了如何在一个弹性布局中应用这些类,以实现不同设备上的响应式设计。
Bootstrap5 Flex(弹性)布局5
使用 .align-content-* 控制多行子元素在垂直方向上的堆叠方式,如 .align-content-start、.align-content-center 等。对于单行子元素,使用 .align-items-* 控制对齐,例如 .align-items-start、.align-items-center 等。示例代码展示了不同对齐效果的应用。
Bootstrap5 Flex(弹性)布局2
介绍Flex布局的水平和垂直方向控制。`.flex-row`使子元素水平排列,默认左对齐;`.flex-row-reverse`则右对齐。`.flex-column`让子元素垂直排列;`.flex-column-reverse`则反向排列。示例展示了不同类的效果,通过改变类名实现布局调整。
|
4月前
|
前端开发 UED 容器
在 CSS 中使用 Flex 布局实现页面自适应时需要注意什么?
【10月更文挑战第22天】在使用 Flex 布局实现页面自适应时,需要对其基本原理和特性有深入的理解,同时结合具体的布局需求和场景,进行细致的调整和优化。通过合理的设置和注意事项的把握,才能实现理想的自适应效果,提升用户体验。还可以根据实际情况进行更深入的探索和实践,以不断提升 Flex 布局的应用能力。
Bootstrap5 Flex(弹性)布局3
`.justify-content-*` 类用于调整弹性子元素的对齐方式,支持 start、end、center、between、around 等值。`.flex-fill` 类使所有子元素等宽,而 `.flex-grow-1` 则让指定子元素占据剩余空间。这些类在布局设计中非常实用。