用starling实现有动态显示内容的软皮书翻页动画

实现原理很简单,大致分成3个步骤:

1. 使用RenderTexture.draw方法在显示对象displayObj上截取一张截图纹理,并将该纹理传给下面会介绍到的Animation对象,该对象的作用是在获取到现有截图纹理后生成一张看上去与displayObj相同的image覆盖在displayObj之上,从而遮挡displayObj将要产生的显示更新。

2. 更新displayObj,并用一个新的RenderTexture对象以同样的方法获取到新的截图纹理,并交给animation。

3. 在获取了新旧两张纹理之后,animation以这两张纹理为基础做计算而产生翻页效果,整个过程中displayObj始终会被animation遮挡而不可见。当animation的翻页动画完成时,animation将显示为新的最新的那张截图覆盖在displayObj智商,此时将animation.visible置为false,displayObj从而可见!


下面介绍下我的自定义类:

MixedImage.as

package utils
{
	import flash.geom.Point;
	
	import starling.display.Sprite;
	import starling.textures.Texture;
	import starling.utils.deg2rad;

	/**
	 * 混合图片,以三张图片的纹理拼合来描述一张被翻阅的图片
	 * @author JixiaoKe(363959579@qq.com)
	 */	
	public class MixedImage extends Sprite
	{
		private var original:Texture;
		private var another:Texture;
		private var bookHeight:Number;
		private var bookWidth:Number;
		public function MixedImage(bookWidth:Number, bookHeight:Number)
		{
			this.bookWidth = bookWidth;
			this.bookHeight = bookHeight;
		}
		//旧面两页
		private var cacheImage_0:QuadImage;
		private var cacheImage_1:QuadImage;
		//新面
		private var cacheImage_2:QuadImage;
		
		public function set originalTexture(texture:Texture):void
		{
			if(original && original == texture)
				return;
			original = texture;
			if(!cacheImage_0)
			{
				cacheImage_0 = new QuadImage(original);
				this.addChild(cacheImage_0);
				cacheImage_1 = new QuadImage(original);
				this.addChild(cacheImage_1);
				cacheImage_0.touchable = cacheImage_1.touchable = false;
			}else
			{
				cacheImage_1.texture = original;
				cacheImage_0.texture = original;
			}
		}
		public function set anotherTexture(texture:Texture):void
		{
			if(another && another == texture)
				return;
			another = texture;
			if(!cacheImage_2)
			{
				cacheImage_2 = new QuadImage(another);
				this.addChild(cacheImage_2);
			}else
			{
				cacheImage_2.texture = texture;
			}
		}
		
		//拖动点
		private var _dragPoint:Point = new Point();
		//拖动衍生第四个点
		private var _dragPointCopy:Point = new Point();
		//纸张边缘点:下
		private var _edgePoint:Point = new Point();
		//纸张边缘点:上与右
		private var _edgePointCopy:Point = new Point();
		
		private var currentPointCount:int;
		
		/**重置四个顶点坐标*/
		private function resetAllTexCoords(image:QuadImage):void
		{
			image.setTexCoordsTo(0, 0, 0);
			image.setTexCoordsTo(1, 1, 0);
			image.setTexCoordsTo(2, 0, 1);
			image.setTexCoordsTo(3, 1.0, 1.0);
		}
		
		public function readjustSizeHandler(image:QuadImage):void
		{
			image.readjustSize();
			resetAllTexCoords(image);
			image.vertexDataChanged();
		}
		
		private function readjustSize():void
		{
			readjustSizeHandler(cacheImage_0);
			readjustSizeHandler(cacheImage_1);
			readjustSizeHandler(cacheImage_2);
		}
		
		override public function dispose():void
		{
			this.original = null;
			this.another = null;
			if(cacheImage_0)
				cacheImage_0.removeFromParent(true);
			if(cacheImage_1)
				cacheImage_1.removeFromParent(true);
			if(cacheImage_2)
				cacheImage_2.removeFromParent(true);
			super.dispose();
		}
		
		/**
		 * 
		 * @param quadBatch
		 * @param progress	[0-1]	翻页进度(0为开始,至1为完成)
		 * @param leftToRight
		 * 
		 */		
		public function setLocation(progress:Number, pageUp:Boolean):void
		{
			var radius:Number;
			var angle:Number;		//拖拽点相对于圆心的旋转角度
			var degAngle:Number;	//angle对应的弧度值
			var tempAngle:Number	//_edgePointCopy相对于圆心的旋转角度
			var degTemp:Number;
			if(pageUp)
			{
				angle = -180 + progress*180;
				degAngle = deg2rad( angle );
				tempAngle = -180 + progress*90;
				degTemp = deg2rad( tempAngle );
				radius = bookWidth * progress / 2;
				
				_edgePoint.x = radius;
				_edgePoint.y = bookHeight;
				_dragPoint.x = _edgePoint.x + radius * Math.cos( degAngle );
				_dragPoint.y = _edgePoint.y + radius * Math.sin( degAngle );
				
				_edgePointCopy.y = radius * Math.tan( -degTemp ) + _edgePoint.y;
				if(_edgePointCopy.y < 0)		//有四个有效点
				{
					currentPointCount = 4;
					var d:Number;
					d = -_edgePointCopy.y;
					_edgePointCopy.x = radius * d / (d + bookHeight);
					_edgePointCopy.y = 0;
					_dragPointCopy.x = _edgePointCopy.x + _edgePointCopy.x * Math.cos( degAngle );
					_dragPointCopy.y = _edgePointCopy.y + _edgePointCopy.x * Math.sin( degAngle );
				}
				else
				{
					currentPointCount = 3;
					_edgePointCopy.x = 0;
					_dragPointCopy.x = _dragPointCopy.y = 0;
				}
			}
			else
			{
				angle = 0 - progress * 180;
				degAngle = deg2rad( angle );
				tempAngle = 0 - progress*90;
				degTemp = deg2rad( tempAngle );
				radius = bookWidth * progress / 2;
				
				_edgePoint.x = bookWidth - radius;
				_edgePoint.y = bookHeight;
				
				_dragPoint.x = _edgePoint.x + radius * Math.cos( degAngle );
				_dragPoint.y = _edgePoint.y + radius * Math.sin( degAngle );
				
				_edgePointCopy.y = _edgePoint.y + radius * Math.tan( degTemp );
				if(_edgePointCopy.y < 0)
				{
					currentPointCount = 4;
					
					d = -_edgePointCopy.y;
					_edgePointCopy.x = bookWidth - radius * d / (d + bookHeight);
					_edgePointCopy.y = 0;
					_dragPointCopy.x = _edgePointCopy.x + (bookWidth - _edgePointCopy.x) * Math.cos( degAngle );
					_dragPointCopy.y = _edgePointCopy.y + (bookWidth - _edgePointCopy.x) * Math.sin( degAngle );
				}
				else
				{
					currentPointCount = 3;
					
					_edgePointCopy.x = bookWidth;
					_dragPointCopy.x = bookWidth;
					_dragPointCopy.y = 0;
				}
			}
			
			readjustSize();
			createView(pageUp);
		}
		
		private function createView(pageUp:Boolean):void
		{
			if(currentPointCount == 3)
				cacheImage_1.visible = true;
			else
				cacheImage_1.visible = false;
			if(pageUp)
			{
				if(currentPointCount == 3)
				{
					cacheImage_0.setPosition(0, 0, 0);
					cacheImage_0.setTexCoordsTo(0, 0, 0);
					cacheImage_0.setPosition(1, bookWidth/2, 0);
					cacheImage_0.setTexCoordsTo(1, 1, 0);
					cacheImage_0.setPosition(2, 0, _edgePointCopy.y);
					cacheImage_0.setTexCoordsTo(2, 0, _edgePointCopy.y/bookHeight);
					cacheImage_0.setPosition(3, bookWidth/2, _edgePointCopy.y);
					cacheImage_0.setTexCoordsTo(3, 1, _edgePointCopy.y/bookHeight);
					cacheImage_0.vertexDataChanged();
					cacheImage_1.setPosition(0, 0, _edgePointCopy.y);
					cacheImage_1.setTexCoordsTo(0, 0, _edgePointCopy.y/bookHeight);
					cacheImage_1.setPosition(1, bookWidth/2, _edgePointCopy.y);
					cacheImage_1.setTexCoordsTo(1, 1, _edgePointCopy.y/bookHeight);
					cacheImage_1.setPosition(2, _edgePoint.x, bookHeight);
					cacheImage_1.setTexCoordsTo(2, _edgePoint.x*2/bookWidth , 1);
					cacheImage_1.setPosition(3, bookWidth/2, bookHeight);
					cacheImage_1.vertexDataChanged();
					cacheImage_2.setPosition(0, 0, _edgePointCopy.y);
					cacheImage_2.setTexCoordsTo(0, 1, _edgePointCopy.y/bookHeight);
					cacheImage_2.setPosition(1, _edgePointCopy.x, _edgePointCopy.y);
					cacheImage_2.setTexCoordsTo(1, 1, _edgePointCopy.y/bookHeight);
					cacheImage_2.setPosition(2, _edgePoint.x, _edgePoint.y);
					cacheImage_2.setTexCoordsTo(2, 1-_edgePoint.x*2/bookWidth, 1);
					cacheImage_2.setPosition(3, _dragPoint.x, _dragPoint.y);
					cacheImage_2.vertexDataChanged();
				}else if(currentPointCount == 4)
				{
					cacheImage_0.setPosition(0, _edgePointCopy.x, 0);
					cacheImage_0.setTexCoordsTo(0, _edgePointCopy.x*2/bookWidth, 0);
					cacheImage_0.setPosition(1, bookWidth/2, 0);
					cacheImage_0.setPosition(2, _edgePoint.x, bookHeight);
					cacheImage_0.setTexCoordsTo(2, _edgePoint.x*2/bookWidth, 1);
					cacheImage_0.setPosition(3, bookWidth/2, bookHeight);
					cacheImage_0.vertexDataChanged();
					cacheImage_2.setPosition(0, _edgePointCopy.x, 0);
					cacheImage_2.setTexCoordsTo(0, 1-_edgePointCopy.x*2/bookWidth, 0);
					cacheImage_2.setPosition(1, _dragPointCopy.x, _dragPointCopy.y);
					cacheImage_2.setPosition(2, _edgePoint.x, bookHeight);
					cacheImage_2.setTexCoordsTo(2, 1-_edgePoint.x*2/bookWidth, 1);
					cacheImage_2.setPosition(3, _dragPoint.x, _dragPoint.y);
					cacheImage_2.vertexDataChanged();
				}
			}
			else
			{
				if(currentPointCount == 3)
				{
					cacheImage_0.setPosition(0, bookWidth/2, 0);
					cacheImage_0.setTexCoordsTo(0, 0, 0);
					cacheImage_0.setPosition(1, bookWidth, 0);
					cacheImage_0.setTexCoordsTo(1, 1, 0);
					cacheImage_0.setPosition(2, bookWidth/2, _edgePointCopy.y);
					cacheImage_0.setTexCoordsTo(2, 0, _edgePointCopy.y/bookHeight);
					cacheImage_0.setPosition(3, bookWidth, _edgePointCopy.y);
					cacheImage_0.setTexCoordsTo(3, 1, _edgePointCopy.y/bookHeight);
					cacheImage_0.vertexDataChanged();
					cacheImage_1.setPosition(0, bookWidth/2, _edgePointCopy.y);
					cacheImage_1.setTexCoordsTo(0, 0, _edgePointCopy.y/bookHeight);
					cacheImage_1.setPosition(1, bookWidth, _edgePointCopy.y);
					cacheImage_1.setTexCoordsTo(1, 1, _edgePointCopy.y/bookHeight);
					cacheImage_1.setPosition(2, bookWidth/2, bookHeight);
					cacheImage_1.setPosition(3, _edgePoint.x, bookHeight);
					cacheImage_1.setTexCoordsTo(3, (_edgePoint.x - bookWidth/2)*2/bookWidth, 1);
					cacheImage_1.vertexDataChanged();
					cacheImage_2.setPosition(0, bookWidth, _edgePointCopy.y);
					cacheImage_2.setTexCoordsTo(0, 0, _edgePointCopy.y/bookHeight);
					cacheImage_2.setPosition(1, bookWidth, _edgePointCopy.y);
					cacheImage_2.setTexCoordsTo(1, 0, _edgePointCopy.y/bookHeight);
					cacheImage_2.setPosition(2, _dragPoint.x, _dragPoint.y);
					cacheImage_2.setPosition(3, _edgePoint.x, bookHeight);
					cacheImage_2.setTexCoordsTo(3, 1 - (_edgePoint.x - bookWidth/2)*2/bookWidth, 1);
					cacheImage_2.vertexDataChanged();
				}
				else if(currentPointCount == 4)
				{
					cacheImage_0.setPosition(0, bookWidth/2, 0);
					cacheImage_0.setPosition(1, _edgePointCopy.x, 0);
					cacheImage_0.setTexCoordsTo(1, (_edgePointCopy.x - bookWidth/2)*2/bookWidth, 0);
					cacheImage_0.setPosition(2, bookWidth/2, bookHeight);
					cacheImage_0.setPosition(3, _edgePoint.x, bookHeight);
					cacheImage_0.setTexCoordsTo(3, (_edgePoint.x - bookWidth/2)*2/bookWidth, 1);
					cacheImage_0.vertexDataChanged();
					cacheImage_2.setPosition(0, _dragPointCopy.x, _dragPointCopy.y);
					cacheImage_2.setPosition(1, _edgePointCopy.x, 0);
					cacheImage_2.setTexCoordsTo(1, 1-(_edgePointCopy.x - bookWidth/2)*2/bookWidth, 0);
					cacheImage_2.setPosition(2, _dragPoint.x, _dragPoint.y);
					cacheImage_2.setPosition(3, _edgePoint.x, bookHeight);
					cacheImage_2.setTexCoordsTo(3, 1-(_edgePoint.x - bookWidth/2)*2/bookWidth, 1);
					cacheImage_2.vertexDataChanged();
				}
			}
		}
	}
}
import flash.geom.Point;

import starling.display.Image;
import starling.textures.Texture;

class QuadImage extends Image
{
	public function QuadImage(texture:Texture)
	{
		super(texture);
	}
	
	/**
	 * 更新顶点纹理坐标值 (范围 0-1). 
	 */		
	internal function setTexCoordsTo(vertexID:int, u:Number, v:Number):void
	{
		/* 
		 *	由于  starling.display.Image 自带的setTextCoordsTo()方法是在starling 1.4之后发布的api,
		 *	而我在写这段代码时1.4还未发布,所以才有了这个自定义方法。也因此需要最下方自定义的vertexDataChanged()方法!
		 *	虽然在1.4之前有setTexCoords方法,但要求第二个参数是一个point对象这一点很蛋疼!我很懒!
		*/
		this.mVertexData.setTexCoords(vertexID, u, v);
	}
	
	/**	更新顶点位置.	*/		
	internal function setPosition(vertexID:int, x:Number, y:Number):void
	{
		this.mVertexData.setPosition(vertexID, x, y);
	}
	
	/**	在手动改变'mVertexData'的内容后调用此方法*/	
	internal function vertexDataChanged():void
	{
		this.onVertexDataChanged();
	}
}

该类公开了三个自定义接口:

/** 用于指定该混合图片的正面纹理 */	
public function set originalTexture(texture:Texture):void;
/** 用于指定该混合图片的背面纹理 */
public function set anotherTexture(texture:Texture):void;
/** 指定当前翻页进度,进度为 0 - 1之间。pageUp用于指定翻页进行的方向 */
public function setLocation(progress:Number, pageUp:Boolean):void;

animation对象持续调用mixImage.setLocation()方法来传入持续增长的progress参数,从而产生翻页动画。


Animation类:

package utils
{
	import flash.geom.Rectangle;
	
	import starling.display.Image;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.textures.Texture;
	
	public class Animation extends Sprite
	{
		public function Animation(width:Number, height:Number)
		{
			bookWidth = width;
			bookHeight = height;
//			maxHeight = Math.ceil( Math.sqrt(bookWidth*bookWidth + bookHeight*bookHeight) );
			
			initialize();
		}
		private var bookWidth:Number = 0;
		private var bookHeight:Number = 0;
		private var maxHeight:Number;
		/**
		 * 软页
		 */		
		private var softImage:MixedImage;
		private var cacheImageL:Image;
		private var cacheImageR:Image;
		
		protected function initialize():void
		{
			initSoftImage();
			this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		private function initSoftImage():void
		{
			softImage = new MixedImage(bookWidth, bookHeight);
			this.addChild(softImage);
		}
		
		/**
		 * 时间轴方法
		 */		
		private function onEnterFrame():void
		{
			if(!isActive)
				return;
			progress += this.velocity;
			if(progress >= 1)
			{
				progress = 1;
				softImage.setLocation(progress, pageUp);
				complete();
			}
			else
			{
				softImage.setLocation(progress, pageUp);
			}
		}
		
		/**
		 * 动画开关标记
		 */		
		private var isActive:Boolean = false;
		private var pageUp:Boolean = false;
		/**
		 * 动画开始,播放前需使用setPageTexture指定相关纹理
		 * @param pageUp
		 * @param velocity
		 */		
		public function start(pageUp:Boolean = false, velocity = 0.05):void
		{
			softImage.originalTexture = (pageUp)?page_3:page_2;
			softImage.anotherTexture = (pageUp)?page_2:page_3;
			cacheImageL.texture = page_1;
			cacheImageR.texture = page_4;
			this.pageUp = pageUp;
			this.velocity = velocity;
			progress = 0;
			isActive = true;
		}
		
		/**
		 * 动画播放进度[0 - 1]
		 */		
		private var progress:Number;
		private var velocity:Number;
		
		/**
		 * 动画播放完成
		 */		
		private function complete():void
		{
			this.stop();
			dispatchEvent(new Event(Event.COMPLETE));
		}
		/**
		 * 动画停止
		 */		
		public function stop():void
		{
			isActive = false;
		}
		/**
		 * 验证动画是否正在播放
		 * @return 
		 * 
		 */		
		public function isRunning():Boolean
		{
			return isActive;
		}
		
		//4页纹理
		private var page_1:Texture;
		private var page_2:Texture;
		private var page_3:Texture;
		private var page_4:Texture;
		
		/**
		 * 按页码由小到大顺序传入,
		 * @param tx_1
		 * @param tx_2
		 */		
		public function setSoftPageTexture(tx_1:Texture, tx_2:Texture):void
		{
			page_1 = Texture.fromTexture( tx_1, new Rectangle(0, 0, bookWidth/2, bookHeight) );
			page_2 = Texture.fromTexture( tx_1, new Rectangle(bookWidth/2, 0, bookWidth/2, bookHeight) );
			page_3 = Texture.fromTexture( tx_2, new Rectangle(0, 0, bookWidth/2, bookHeight) );;
			page_4 = Texture.fromTexture( tx_2, new Rectangle(bookWidth/2, 0, bookWidth/2, bookHeight) );
		}
		
		/**
		 * 指定不变纹理,用于重绘固定显示页
		 * @param page_L
		 * @param page_R
		 * 
		 */		
		public function setFixPageTexture(page_L:Texture, page_R:Texture):void
		{
			if(!page_1 || (page_1 && page_1 != page_L))
			{
				page_1 = page_L;
				if(cacheImageL)
					cacheImageL.texture = page_1;
				else
				{
					cacheImageL = new Image(page_1);
					this.addChildAt( cacheImageL, 0 );
					cacheImageL.touchable = false;
				}
			}
			if(!page_2 || (page_2 && page_2 != page_R))
			{
				page_2 = page_R;
				if(cacheImageR)
					cacheImageR.texture = page_2;
				else
				{
					cacheImageR = new Image(page_2);
					cacheImageR.x = this.bookWidth/2;
					this.addChildAt( cacheImageR, 0 );
					cacheImageR.touchable = false;
					
				}
			}
		}
		
		override public function dispose():void
		{
			if(this.hasEventListener(Event.ENTER_FRAME))
				this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
			if(softImage)
				softImage.removeFromParent(true);
			if(cacheImageL)
				cacheImageL.removeFromParent(true);
			if(cacheImageR)
				cacheImageR.removeFromParent(true);
			super.dispose();
		}
	}
}

该类公开了五个用于外部调用的自定义方法:

/** 用于判断当前动画是否已启动 */
public function isRunning():Boolean;
/** 停止动画播放 */
public function stop():void;
/** 获取到初始显示纹理后,通过该方法传入纹理,动画内部将显示一张图片覆盖原显示对象 */
public function setFixPageTexture(page_L:Texture, page_R:Texture):void;
/** 新旧两张纹理获取之后,通过该按页码大小依次传入两张纹理后,调用start()方法即可播放动画 */
public function setSoftPageTexture(tx_1:Texture, tx_2:Texture):void;
/** 动画开始播放,播放完成后将该类实例将派发starling.events.Event.COMPLETE事件!velocity 参数用来指定翻页速度  */
public function start(pageUp:Boolean = false, velocity = 0.05):void;


下面是测试用主类,starling的环境配置就不再赘述!

由于我使用的是air环境,所以加载方式跟web环境下的加载会有所不同!有兴趣自己完成吧!

package
{
	import flash.geom.Rectangle;
	
	import starling.display.Image;
	import starling.display.Quad;
	import starling.display.Sprite;
	import starling.events.Event;
	import starling.events.Touch;
	import starling.events.TouchEvent;
	import starling.events.TouchPhase;
	import starling.text.TextField;
	import starling.textures.RenderTexture;
	import starling.textures.Texture;
	import starling.utils.AssetManager;
	
	import utils.Animation;
	
	public class Main extends Sprite
	{
		public function Main()
		{
			super();
			init();
		}
		
		private var assets:AssetManager;
		private var img:Image;						//背景图片
		private var vec:Vector.<Texture>;			//纹理序列
		private var ani:Animation;					//动画对象
		private var main:Sprite;					//显示对象容器
		private var t_l:TextField;					//页码文本左
		private var t_r:TextField;					//页码文本右
		private var crtRender:RenderTexture;		//用于保存翻页前的纹理
		private var crtL:Texture;
		private var crtR:Texture;
		private var tarRender:RenderTexture;		//用于保存最终显示效果纹理,即翻页后的纹理
		private var tarL:Texture;
		private var tarR:Texture;
		
		private function init():void
		{
			main = new Sprite();
			this.addChild( main );
			
			crtRender = new RenderTexture(800, 480);
			tarRender = new RenderTexture(800, 480);
			
			//加载图片资源
			assets = new AssetManager();
			//air下加载
			assets.enqueue(File.applicationDirectory.resolvePath("assets/imgs"));
			assets.loadQueue( function(r:Number):void{
				if(r == 1)
					loadComplete();
			});
		}
		
		private function loadComplete():void
		{
			trace("loadComplete");
			vec = new Vector.<Texture>();
			
			var tx:Texture;
			for(var i:int = 0;i<int.MAX_VALUE;i++)
			{
				tx = assets.getTexture(String(i));
				if(!tx)
					break;
				vec[i] = tx;
			}
			
			//初始化现实图片
			img = new Image(vec[0]);
			main.addChild( img );
			
			//页码
			t_l = new TextField(100, 30, "", "Verdana", 18, 0xffffff);
			t_r = new TextField(100, 30, "", "Verdana", 18, 0xffffff);
			t_l.x = 150, t_r.x = 550;
			t_l.y = t_r.y = 240;
			main.addChild( t_l );
			main.addChild( t_r );
			t_l.text = "Page 1";
			t_r.text = "Page 2";
			
			//添加一个比较粗糙的阴影
			var quad:Quad = new Quad(100, 480, 0x000000);
			quad.x = 400;
			main.addChild( quad );
			quad.setVertexAlpha(0, .8);
			quad.setVertexAlpha(1, 0);
			quad.setVertexAlpha(2, .8);
			quad.setVertexAlpha(3, 0);
			quad = new Quad(80, 480, 0x000000);
			quad.x = 400 - quad.width;
			main.addChild( quad );
			quad.setVertexAlpha(0, 0);
			quad.setVertexAlpha(1, .8);
			quad.setVertexAlpha(2, 0);
			quad.setVertexAlpha(3, .8);
			
			//初始化翻页动画
			ani = new Animation( 800, 480 );
			this.addChild( ani );
			ani.visible = false;
			ani.addEventListener(Event.COMPLETE, aniComplete);
			
			this.addEventListener(TouchEvent.TOUCH, onTouch);
		}
		//动画完成
		private function aniComplete():void
		{
			//隐藏动画组件,于是就显示出了实际画面
			ani.visible = false;
			crtRender.clear();
			tarRender.clear();
		}
		
		private function onTouch(e:TouchEvent):void
		{
			//动画播放中
			if(ani.isRunning())
				return;
			
			var touch:Touch = e.getTouch(this);
			if(touch)
			{
				if(touch.phase == TouchPhase.BEGAN)
				{
					startP = touch.getLocation(this).x;
				}
				else if(touch.phase == TouchPhase.ENDED)
				{
					var p:int = touch.getLocation(this).x;
					
					//判断翻动方向
					if(p != startP)
						pageUp = (p > startP);
					else
						return;
					
					//判断页码是否超出
					if( (pageUp && crt == 0) || ((!pageUp) && crt == vec.length-1))
						return;
					
					//获取当前显示对象纹理数据
					crtRender.draw( main );
					crtL = Texture.fromTexture( crtRender, new Rectangle(0, 0, 400, 480));
					crtR = Texture.fromTexture( crtRender, new Rectangle(400, 0, 400, 480));
					
					//显示ani对象,遮挡img
					ani.setFixPageTexture( crtL, crtR );
					ani.visible = true;
					
					//变更img纹理
					crt += pageUp ? - 1 : 1;
					img.texture = vec[crt];
					img.readjustSize();
					
					//重写页码
					t_l.text = "Page " + (crt*2+1);
					t_r.text = "Page " + 2*(crt+1);
					
					//获取用于替换旧纹理的新纹理数据
					tarRender.draw( main );
					tarL = Texture.fromTexture( tarRender, new Rectangle(0, 0, 400, 480));
					tarR = Texture.fromTexture( tarRender, new Rectangle(400, 0, 400, 480));
					if( pageUp )
						ani.setSoftPageTexture( tarRender, crtRender );		//
					else
						ani.setSoftPageTexture( crtRender, tarRender );
//					if( pageUp )
//						ani.setSoftPageTexture( tarL, tarR, crtL, crtR );		//
//					else
//						ani.setSoftPageTexture( crtL, crtR ,tarL, tarR );
					ani.start( pageUp, 0.05 );
				}
			}
		}
		private var startP:int = 0;
		private var pageUp:Boolean;
		private var crt:int = 0;
		
		override public function dispose():void
		{
			//太麻烦了,不写了……
			super.dispose();
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值