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


    摩擦力:

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

    上图示意了该过程,物体以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;
    			}
    		}
    	}
    }
    

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

    作者:菩提树下的杨过
    出处:http://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    C++中几种字符串表示方法
    oracle11g卸载(win10)
    Dbvisualizer 连接oracle数据库
    严重: Exception starting filter struts2 Unable to load configuration.
    eclipse启动Tomcat服务输入http://localhost:8080/报404
    Tomcat内存溢出解决办法
    A Java Runtime Environment(JRE) or Java Development Kit (JDK) must be available in order to run Eclipse.
    Spring容器装配bean的方式
    Spring容器的基本实现
    spring环境搭建
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1705240.html
Copyright © 2020-2023  润新知