├── .gitignore ├── README.md ├── demo_3d_cloud.png ├── demo_image_wrapper.png ├── demo_page_flip.png └── src ├── CloudDemo-app.xml ├── CloudDemo.as ├── ImageWrapper-app.xml ├── ImageWrapper.as ├── Main-app.xml ├── Main.as ├── ZTest-app.xml ├── assets ├── ad.png ├── ad.xml ├── bg.jpg ├── cloud10.png ├── flash-pf.png ├── flash-pf.xml └── high-light.png ├── cloud └── Game.as ├── test ├── Game.as └── pf │ ├── ImagePage.as │ ├── PageFlipContainer.as │ └── ShadowUtil.as └── wrap ├── Game2.as └── SuperImage.as /.gitignore: -------------------------------------------------------------------------------- 1 | # Build and Release Folders 2 | bin/ 3 | bin-debug/ 4 | bin-release/ 5 | 6 | # Other files and folders 7 | .settings/ 8 | 9 | # Project files, i.e. `.project`, `.actionScriptProperties` and `.flexProperties` 10 | # should NOT be excluded as they contain compiler settings and other important 11 | # information for Eclipse / Flash Builder. 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | StarlingPageFlip 2 | ================ 3 | 4 | Some Starling demos: Page Flip, 3D Cloud, Image Wrapper 5 | 6 | 这里整理了一下之前做过的基于Starling的3个例子的源码,包括: 7 | 8 | 1. 翻书效果,和你看到很多Flash翻书效果是一致的,换成Starling方式来实现 9 | 10 | ![github](https://github.com/NeoGuo/StarlingPageFlip/blob/master/demo_page_flip.png?raw=true "github") 11 | 12 | 2. 3D穿云过雾效果,体验一下孙悟空的感觉 13 | 14 | ![github](https://github.com/NeoGuo/StarlingPageFlip/blob/master/demo_3d_cloud.png?raw=true "github") 15 | 16 | 3. 广告切换,软件中常用 17 | 18 | ![github](https://github.com/NeoGuo/StarlingPageFlip/blob/master/demo_image_wrapper.png?raw=true "github") 19 | -------------------------------------------------------------------------------- /demo_3d_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/demo_3d_cloud.png -------------------------------------------------------------------------------- /demo_image_wrapper.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/demo_image_wrapper.png -------------------------------------------------------------------------------- /demo_page_flip.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/demo_page_flip.png -------------------------------------------------------------------------------- /src/CloudDemo-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 18 | com.test.CloudDemo 19 | 20 | 21 | CloudDemo 22 | 23 | 25 | CloudDemo 26 | 27 | 30 | 0.0.0 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | [此值将由 Flash Builder 在输出 app.xml 中覆盖] 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | landscape 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | direct 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | false 113 | true 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 153 | 154 | 157 | 158 | 159 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 208 | 209 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | 261 | 262 | 264 | 265 | 266 | 267 | 268 | ]]> 269 | 270 | 271 | UIDeviceFamily 273 | 274 | 1 275 | 2 276 | 277 | ]]> 278 | high 279 | 280 | 281 | -------------------------------------------------------------------------------- /src/CloudDemo.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import cloud.*; 4 | 5 | import flash.display.Sprite; 6 | import flash.display.StageAlign; 7 | import flash.display.StageScaleMode; 8 | import flash.events.Event; 9 | import flash.events.MouseEvent; 10 | import flash.geom.Rectangle; 11 | import flash.utils.setTimeout; 12 | 13 | import starling.core.Starling; 14 | 15 | /** 16 | * Cloud 17 | * @author shaorui 18 | */ 19 | [SWF(width="960",height="640",frameRate="60",backgroundColor="#000000")] 20 | public class CloudDemo extends Sprite 21 | { 22 | private var myStarling:Starling; 23 | 24 | public function CloudDemo() 25 | { 26 | if(stage != null) 27 | { 28 | addToStageHandler(); 29 | } 30 | else 31 | { 32 | addEventListener(Event.ADDED_TO_STAGE,addToStageHandler); 33 | } 34 | } 35 | /**waiting for loaded*/ 36 | protected function addToStageHandler(event:Event=null):void 37 | { 38 | removeEventListener(Event.ADDED_TO_STAGE,addToStageHandler); 39 | stage.align = StageAlign.TOP_LEFT; 40 | stage.scaleMode = StageScaleMode.NO_SCALE; 41 | setTimeout(initApp,100); 42 | } 43 | /**INIT*/ 44 | private function initApp():void 45 | { 46 | myStarling = new Starling(Game,stage); 47 | myStarling.showStats=true; 48 | myStarling.start(); 49 | this.addEventListener(MouseEvent.MOUSE_DOWN,stopRender); 50 | } 51 | 52 | protected function stopRender(event:MouseEvent):void 53 | { 54 | myStarling.viewPort = new Rectangle(0,0,32,32); 55 | myStarling.stop(); 56 | } 57 | } 58 | } -------------------------------------------------------------------------------- /src/ImageWrapper-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 18 | com.test.ImageWrapper 19 | 20 | 21 | ImageWrapper 22 | 23 | 25 | ImageWrapper 26 | 27 | 30 | 0.0.0 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | [此值将由 Flash Builder 在输出 app.xml 中覆盖] 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | landscape 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | direct 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | false 113 | false 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 153 | 154 | 157 | 158 | 159 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 208 | 209 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | 261 | 262 | 264 | 265 | 266 | 267 | 268 | ]]> 269 | 270 | 271 | UIDeviceFamily 273 | 274 | 1 275 | 2 276 | 277 | ]]> 278 | high 279 | 280 | 281 | -------------------------------------------------------------------------------- /src/ImageWrapper.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.display.Shape; 4 | import flash.display.Sprite; 5 | import flash.display.StageAlign; 6 | import flash.display.StageScaleMode; 7 | import flash.events.Event; 8 | import flash.utils.setTimeout; 9 | 10 | import starling.core.Starling; 11 | 12 | import wrap.*; 13 | 14 | [SWF(width="960",height="640",frameRate="60",backgroundColor="#FFFFFF")] 15 | public class ImageWrapper extends Sprite 16 | { 17 | private var myStarling:Starling; 18 | 19 | public function ImageWrapper() 20 | { 21 | if(stage != null) 22 | { 23 | addToStageHandler(); 24 | } 25 | else 26 | { 27 | addEventListener(Event.ADDED_TO_STAGE,addToStageHandler); 28 | } 29 | } 30 | /**waiting for loaded*/ 31 | protected function addToStageHandler(event:Event=null):void 32 | { 33 | removeEventListener(Event.ADDED_TO_STAGE,addToStageHandler); 34 | stage.align = StageAlign.TOP_LEFT; 35 | stage.scaleMode = StageScaleMode.NO_SCALE; 36 | setTimeout(initApp,100); 37 | } 38 | /**INIT*/ 39 | private function initApp():void 40 | { 41 | myStarling = new Starling(Game2,stage); 42 | myStarling.showStats=true; 43 | myStarling.start(); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/Main-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 18 | com.todoair.StarlingBookSoft 19 | 20 | 21 | Main 22 | 23 | 25 | Main 26 | 27 | 30 | 1.0.0 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | [此值将由 Flash Builder 在输出 app.xml 中覆盖] 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | landscape 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | direct 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | false 113 | true 114 | true 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 153 | 154 | 157 | 158 | 159 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 208 | 209 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | 261 | 262 | 264 | 265 | 266 | 267 | 268 | ]]> 269 | 270 | 271 | UIDeviceFamily 273 | 274 | 2 275 | 276 | ]]> 277 | high 278 | 279 | 280 | -------------------------------------------------------------------------------- /src/Main.as: -------------------------------------------------------------------------------- 1 | package 2 | { 3 | import flash.display.Shape; 4 | import flash.display.Sprite; 5 | import flash.display.StageAlign; 6 | import flash.display.StageScaleMode; 7 | import flash.utils.setTimeout; 8 | 9 | import starling.core.Starling; 10 | 11 | import test.Game; 12 | 13 | //[SWF(frameRate="60",width="1000",height="600")] 14 | [SWF(width="960",height="640",frameRate="60",backgroundColor="#2f2f2f")] 15 | public class Main extends Sprite 16 | { 17 | public static var instance:Main; 18 | 19 | public var debugShape:Shape; 20 | 21 | private var myStarling:Starling; 22 | 23 | public function Main() 24 | { 25 | stage.align = StageAlign.TOP_LEFT; 26 | stage.scaleMode = StageScaleMode.NO_SCALE; 27 | setTimeout(initApp,100); 28 | instance = this; 29 | debugShape = new Shape(); 30 | debugShape.x = debugShape.y = 100; 31 | addChild(debugShape); 32 | } 33 | /**INIT*/ 34 | private function initApp():void 35 | { 36 | myStarling = new Starling(Game,stage); 37 | myStarling.showStats=true; 38 | myStarling.start(); 39 | } 40 | } 41 | } -------------------------------------------------------------------------------- /src/ZTest-app.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 15 | 16 | 18 | ZTest 19 | 20 | 21 | ZTest 22 | 23 | 25 | ZTest 26 | 27 | 30 | 0.0.0 31 | 32 | 33 | 34 | 35 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | [此值将由 Flash Builder 在输出 app.xml 中覆盖] 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | landscape 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | false 113 | true 114 | false 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 136 | 153 | 154 | 157 | 158 | 159 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 208 | 209 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 258 | 259 | 260 | 261 | 262 | 264 | 265 | 266 | 267 | 268 | ]]> 269 | 270 | 271 | UIDeviceFamily 273 | 274 | 1 275 | 2 276 | 277 | ]]> 278 | high 279 | 280 | 281 | -------------------------------------------------------------------------------- /src/assets/ad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/src/assets/ad.png -------------------------------------------------------------------------------- /src/assets/ad.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/assets/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/src/assets/bg.jpg -------------------------------------------------------------------------------- /src/assets/cloud10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/src/assets/cloud10.png -------------------------------------------------------------------------------- /src/assets/flash-pf.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/src/assets/flash-pf.png -------------------------------------------------------------------------------- /src/assets/flash-pf.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/assets/high-light.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NeoGuo/StarlingPageFlip/2b71ed27574d6f1658002ded57bf6edab5cedb9e/src/assets/high-light.png -------------------------------------------------------------------------------- /src/cloud/Game.as: -------------------------------------------------------------------------------- 1 | package cloud 2 | { 3 | import flash.display.Bitmap; 4 | import flash.geom.Point; 5 | 6 | import starling.display.Image; 7 | import starling.display.QuadBatch; 8 | import starling.display.Sprite; 9 | import starling.events.Event; 10 | import starling.events.Touch; 11 | import starling.events.TouchEvent; 12 | import starling.events.TouchPhase; 13 | import starling.textures.Texture; 14 | import starling.textures.TextureAtlas; 15 | 16 | import test.pf.PageFlipContainer; 17 | import flash.geom.Rectangle; 18 | 19 | public class Game extends Sprite 20 | { 21 | [Embed(source="../assets/cloud10.png")] 22 | protected const cloudImgClass:Class; 23 | protected var img:Image; 24 | 25 | private var quadBatch:QuadBatch; 26 | private var imgArr:Vector.; 27 | private var imgCount:int = 100; 28 | private var screenWidth:Number = 1024; 29 | private var screenHeight:Number = 768; 30 | private var focal:Number=250; 31 | private var stageRect:Rectangle; 32 | private var vpX:Number; 33 | private var vpY:Number; 34 | 35 | public function Game() 36 | { 37 | super(); 38 | addEventListener(Event.ADDED_TO_STAGE,initGame); 39 | } 40 | /**初始化*/ 41 | private function initGame(...args):void 42 | { 43 | removeEventListener(Event.ADDED_TO_STAGE,initGame); 44 | vpX=stage.stageWidth/2; 45 | vpY=stage.stageHeight/2; 46 | stageRect = new Rectangle(0,0,stage.stageWidth,stage.stageHeight); 47 | //设置蓝天颜色 48 | stage.color = 0x0008a7; 49 | img = Image.fromBitmap(new cloudImgClass(),false); 50 | img.pivotX = img.width/2; 51 | img.pivotY = img.height/2; 52 | quadBatch = new QuadBatch(); 53 | addChild(quadBatch); 54 | imgArr = new Vector.(); 55 | for (var i:int = 0; i < imgCount; i++) 56 | { 57 | var item:CloudItem = new CloudItem(); 58 | item.x = Math.random()*screenWidth; 59 | item.y = screenHeight-200+Math.random()*200; 60 | item.rotation = Math.random()*Math.PI; 61 | setAShape(item); 62 | imgArr.push(item); 63 | } 64 | addEventListener(Event.ENTER_FRAME,enterFrameHandler); 65 | } 66 | /**重置位置*/ 67 | private function setAShape(shape:CloudItem):void 68 | { 69 | shape.scale = 0.001; 70 | shape.startX=screenWidth*Math.random(); 71 | shape.startY=screenHeight/2+screenHeight/2*Math.random()-100; 72 | shape.x = shape.startX; 73 | shape.y = shape.startY; 74 | shape.zpos = Math.random()*800+400; 75 | } 76 | /**Z排序*/ 77 | private function sortArray():void 78 | { 79 | imgArr.sort(zSortFunction); 80 | } 81 | /**排序方法*/ 82 | private function zSortFunction(a:CloudItem,b:CloudItem):Number 83 | { 84 | if(a.zpos > b.zpos) 85 | return -1; 86 | else if(a.zpos < b.zpos) 87 | return 1; 88 | else 89 | return 0; 90 | } 91 | /**判断一个对象是否已经不在屏幕区域*/ 92 | private function shapeAvisible(shape:CloudItem):Boolean 93 | { 94 | var shapeRect:Rectangle = shape.getBounds(this); 95 | return shapeRect.intersects(stageRect); 96 | } 97 | /**每帧调用*/ 98 | private function enterFrameHandler(event:Event=null):void 99 | { 100 | quadBatch.reset(); 101 | var centerPoint:Point = new Point(screenWidth/2,screenHeight/4*3); 102 | var xpos:Number; 103 | var ypos:Number; 104 | var item:CloudItem; 105 | for (var i:int = 0; i < imgCount; i++) 106 | { 107 | item = imgArr[i]; 108 | //reset properties 109 | item.zpos-=4; 110 | var x1:Number = screenWidth/2-item.startX; 111 | var y1:Number = screenHeight/2-item.startY; 112 | if (item.zpos>-focal && shapeAvisible(item)) 113 | { 114 | xpos=centerPoint.x-vpX-x1;//x维度 115 | ypos=centerPoint.y-vpY-y1;//y维度 116 | item.scale=focal/(focal+item.zpos);//缩放产生近大远小,取值在0-1之间; 117 | item.x=vpX+xpos*item.scale; 118 | item.y=vpY+ypos*item.scale; 119 | } 120 | else 121 | { 122 | setAShape(item); 123 | } 124 | } 125 | sortArray(); 126 | for (i = 0; i < imgCount; i++) 127 | { 128 | item = imgArr[i]; 129 | img.x = item.x; 130 | img.y = item.y; 131 | img.scaleX = img.scaleY = item.scale; 132 | img.rotation = item.rotation; 133 | quadBatch.addImage(img); 134 | } 135 | } 136 | /**是否处于拖动状态*/ 137 | private var isDraging:Boolean = false; 138 | /**触碰处理*/ 139 | private function onTouchHandler(event:TouchEvent):void 140 | { 141 | 142 | } 143 | } 144 | } 145 | import flash.geom.Rectangle; 146 | 147 | import starling.display.DisplayObject; 148 | 149 | class CloudItem 150 | { 151 | private var itemWidth:Number = 256; 152 | private var itemHeight:Number = 256; 153 | 154 | public var startX:Number; 155 | public var startY:Number; 156 | public var zpos:Number=0; 157 | 158 | public var x:Number = 0; 159 | public var y:Number = 0; 160 | public var scale:Number = 1; 161 | public var rotation:Number = 0; 162 | 163 | public function getBounds(targetSpace:DisplayObject):Rectangle 164 | { 165 | var w:Number = itemWidth*scale; 166 | var h:Number = itemHeight*scale; 167 | var rect:Rectangle = new Rectangle(x-w/2,y-h/2,w/2,h/2); 168 | return rect; 169 | } 170 | } -------------------------------------------------------------------------------- /src/test/Game.as: -------------------------------------------------------------------------------- 1 | package test 2 | { 3 | import flash.display.Bitmap; 4 | import flash.display.BitmapData; 5 | import flash.geom.Point; 6 | 7 | import starling.core.Starling; 8 | import starling.display.Button; 9 | import starling.display.DisplayObject; 10 | import starling.display.Image; 11 | import starling.display.Sprite; 12 | import starling.events.Event; 13 | import starling.events.Touch; 14 | import starling.events.TouchEvent; 15 | import starling.events.TouchPhase; 16 | import starling.text.BitmapFont; 17 | import starling.text.TextField; 18 | import starling.textures.Texture; 19 | import starling.textures.TextureAtlas; 20 | import starling.utils.Color; 21 | import starling.utils.HAlign; 22 | import starling.utils.VAlign; 23 | 24 | import test.pf.PageFlipContainer; 25 | import test.pf.ShadowUtil; 26 | 27 | public class Game extends Sprite 28 | { 29 | [Embed(source="assets/flash-pf.xml", mimeType="application/octet-stream")] 30 | public static const bookXml:Class; 31 | [Embed(source="../assets/flash-pf.png")] 32 | protected const bookImgClass:Class; 33 | [Embed(source="../assets/bg.jpg")] 34 | protected const btnImgClass:Class; 35 | 36 | private var pageFlipContainer:PageFlipContainer; 37 | 38 | public function Game() 39 | { 40 | super(); 41 | this.addEventListener(Event.ADDED_TO_STAGE,initGame); 42 | } 43 | /**初始化*/ 44 | private function initGame(event:Event):void 45 | { 46 | /*----------------------翻页组件-----------------------*/ 47 | //把图片合集到一起,减少DRW值 48 | var bookImgs:Bitmap = new bookImgClass(); 49 | var xml:XML = XML(new bookXml()); 50 | //这个工具可以给图片加上阴影,提升显示效果 51 | ShadowUtil.addShadow(bookImgs,xml); 52 | var texture:Texture = Texture.fromBitmap(bookImgs,false); 53 | var atlas:TextureAtlas = new TextureAtlas(texture,xml); 54 | //创建一个翻页容器,设置纹理,书的尺寸和总页数 55 | pageFlipContainer = new PageFlipContainer(atlas,800,480,8); 56 | pageFlipContainer.x = 100; 57 | pageFlipContainer.y = 100; 58 | addChild(pageFlipContainer); 59 | //创建一个按钮控制翻页 60 | var btn:Button = new Button(Texture.fromBitmap(new btnImgClass() as Bitmap),"下一页"); 61 | btn.x = 100; 62 | btn.y = 600; 63 | btn.addEventListener(TouchEvent.TOUCH,btnTouchHandler); 64 | //addChild(btn); 65 | } 66 | /**翻页*/ 67 | private function btnTouchHandler(event:TouchEvent):void 68 | { 69 | var touch:Touch = event.getTouch(event.target as DisplayObject); 70 | if(touch != null && touch.phase == TouchPhase.ENDED) 71 | { 72 | var pn:int = pageFlipContainer.pageNumber+1; 73 | if(pn%2==0) 74 | pn+=1; 75 | if(pn >= 8) 76 | pn = 0; 77 | pageFlipContainer.gotoPage(pn); 78 | } 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /src/test/pf/ImagePage.as: -------------------------------------------------------------------------------- 1 | package test.pf 2 | { 3 | import flash.display.Graphics; 4 | import flash.geom.Point; 5 | import flash.geom.Rectangle; 6 | 7 | import starling.display.Image; 8 | import starling.display.QuadBatch; 9 | import starling.display.Sprite; 10 | import starling.textures.Texture; 11 | import starling.utils.VertexData; 12 | 13 | /** 14 | * 可以根据Touch坐标,调整4个顶点位置的图片 15 | * @author shaorui 16 | */ 17 | public class ImagePage extends Image 18 | { 19 | //确定书打开后的高度及宽度 20 | public const BOOK_WIDTH:Number = 800; 21 | public const BOOK_HEIGHT:Number = 480; 22 | 23 | //确定书的四个角的定点及书背的上下两个定点,共六个点 24 | public const LEFT_UP_POINT:Point = new Point(0 , 0); 25 | public const LEFT_BOTTOM_POINT:Point = new Point(0 , BOOK_HEIGHT); 26 | public const RIGHT_UP_POINT:Point = new Point(BOOK_WIDTH , 0); 27 | public const RIGHT_BOTTOM_POINT:Point = new Point(BOOK_WIDTH , BOOK_HEIGHT); 28 | public const MID_UP_POINT:Point = new Point(BOOK_WIDTH/2 , 0); 29 | public const MID_BOTTOM_POINT:Point = new Point(BOOK_WIDTH/2 , BOOK_HEIGHT); 30 | 31 | //四个点确定一个能动的页面 32 | private var _dragPoint:Point = new Point(); 33 | private var _dragPointCopy:Point = new Point(); 34 | private var _edgePoint:Point = new Point(); 35 | private var _edgePointCopy:Point = new Point(); 36 | 37 | //斜率和截距 38 | private var _k1:Number = new Number(0);//_dragPoint到currentPoint线段的斜率 39 | private var _k2:Number = new Number(0);//与_k2垂直的折线斜率 40 | private var _b:Number = new Number(0);//与_k2对应程式的截距 41 | /**@private*/ 42 | private var currentPoint:Point = new Point();//当前热区的页边顶点 43 | private var currentPointCopy:Point = new Point();//当前热区页边顶点的上(下)页边顶点 44 | private var targetPoint:Point = new Point();//翻页后currentPoint所落到的顶点 45 | private var targetPointCopy:Point = new Point();//翻页后currentPointCopy所落到的顶点 46 | private var interPoint:Point = new Point();//在翻页时利用垂直平分线法则求得的平分线中间点 47 | private var interPointCopy:Point = new Point();//当前热区页边顶点的上(下)顶点边和_dragPointCopy间的垂直平分中点 48 | private var swapPoint:Point = new Point();//用于两点交换的暂时储存点 49 | /**@private*/ 50 | private var limitedPoint:Point = new Point();//计算限制区域所需要的限制圆的圆心 51 | private var limitedPointCopy:Point = new Point();//计算限制区域所需要的限制圆的圆心 52 | private const radius:Number = BOOK_WIDTH/2;//计算限制区域所需要的限制半径 53 | private const radiusCopy:Number = Math.sqrt(Math.pow(BOOK_HEIGHT,2) + Math.pow(BOOK_WIDTH/2,2));//计算限制区域所需要的限制半径 54 | 55 | /**是硬皮还是软皮*/ 56 | public var softMode:Boolean; 57 | /**软皮翻页的时候,显示另一面纹理*/ 58 | public var anotherTexture:Texture; 59 | 60 | /**@private*/ 61 | public function ImagePage(texture:Texture) 62 | { 63 | super(texture); 64 | } 65 | /**@override*/ 66 | override public function readjustSize():void 67 | { 68 | super.readjustSize(); 69 | resetAllTexCoords(); 70 | onVertexDataChanged(); 71 | } 72 | /**重置UV坐标*/ 73 | protected function resetAllTexCoords():void 74 | { 75 | mVertexData.setTexCoords(0, 0, 0); 76 | mVertexData.setTexCoords(1, 1, 0); 77 | mVertexData.setTexCoords(2, 0, 1); 78 | mVertexData.setTexCoords(3, 1.0, 1.0); 79 | } 80 | /** 81 | * 设置顶点位置 82 | * @param flipingPageLocation 从-1到1 83 | */ 84 | public function setLocation(flipingPageLocation:Number):void 85 | { 86 | var fpl:Number = Math.abs(flipingPageLocation); 87 | var w:Number = BOOK_WIDTH/2; 88 | var h:Number = BOOK_HEIGHT; 89 | var topOffset:Number = h/8; 90 | if(flipingPageLocation>=0) 91 | { 92 | mVertexData.setPosition(0,w,0); 93 | mVertexData.setPosition(2,w,h); 94 | mVertexData.setPosition(1,w+w*fpl,-topOffset*(1-fpl)); 95 | mVertexData.setPosition(3,w+w*fpl,h+topOffset*(1-fpl)); 96 | } 97 | else 98 | { 99 | mVertexData.setPosition(1,w,0); 100 | mVertexData.setPosition(3,w,h); 101 | mVertexData.setPosition(0,w-w*fpl,-topOffset*(1-fpl)); 102 | mVertexData.setPosition(2,w-w*fpl,h+topOffset*(1-fpl)); 103 | } 104 | resetAllTexCoords(); 105 | } 106 | /**设置顶点位置:软皮模式*/ 107 | public function setLocationSoft(quadBatch:QuadBatch,begainPageLocationX:Number, begainPageLocationY:Number, flipingPageLocationX:Number, flipingPageLocationY:Number):void 108 | { 109 | var bx:Number = begainPageLocationX; 110 | var by:Number = begainPageLocationY; 111 | var fx:Number = flipingPageLocationX; 112 | var fy:Number = flipingPageLocationY; 113 | var w:Number = BOOK_WIDTH/2; 114 | var h:Number = BOOK_HEIGHT; 115 | //从4角启动才有效 116 | if(validateBegainPoint(bx,by)) 117 | { 118 | //判断是从哪个角启动的 119 | currentHotType = getBegainPointType(bx, by); 120 | var mouseLocation:Point = new Point(BOOK_WIDTH/2+fx*BOOK_WIDTH/2,BOOK_HEIGHT/2+fy*BOOK_HEIGHT/2); 121 | _dragPoint.x = mouseLocation.x; 122 | _dragPoint.y = mouseLocation.y; 123 | onTurnPageByHand(mouseLocation); 124 | if(currentPointCount == 3) 125 | { 126 | //在右侧 127 | if(bx > 0) 128 | { 129 | mVertexData.setPosition(0,w,0); 130 | mVertexData.setPosition(1,w,0); 131 | mVertexData.setTexCoords(1, 0, 0); 132 | mVertexData.setPosition(2,w,h); 133 | mVertexData.setPosition(3,_edgePointCopy.x,h); 134 | mVertexData.setTexCoords(3, (_edgePointCopy.x-w)/w, 1); 135 | quadBatch.addImage(this); 136 | readjustSize(); 137 | mVertexData.setPosition(0,w,0); 138 | mVertexData.setPosition(1,2*w,0); 139 | mVertexData.setPosition(2,_edgePointCopy.x,h); 140 | mVertexData.setTexCoords(2, (_edgePointCopy.x-w)/w, 1); 141 | mVertexData.setPosition(3,w*2,_edgePoint.y); 142 | mVertexData.setTexCoords(3,1,_edgePoint.y/h); 143 | quadBatch.addImage(this); 144 | texture = anotherTexture; 145 | readjustSize(); 146 | mVertexData.setPosition(0,w*2,_edgePoint.y); 147 | mVertexData.setTexCoords(0, 0, _edgePoint.y/h); 148 | mVertexData.setPosition(1,w*2,_edgePoint.y); 149 | mVertexData.setTexCoords(1, 0, _edgePoint.y/h); 150 | mVertexData.setPosition(2,_dragPoint.x,_dragPoint.y); 151 | mVertexData.setPosition(3,_edgePointCopy.x,h); 152 | mVertexData.setTexCoords(3, (2*w-_edgePointCopy.x)/w, 1); 153 | quadBatch.addImage(this); 154 | } 155 | else 156 | { 157 | mVertexData.setPosition(2,0,_edgePoint.y); 158 | mVertexData.setTexCoords(2,0,_edgePoint.y/h); 159 | mVertexData.setPosition(3,_edgePointCopy.x,h); 160 | mVertexData.setTexCoords(3,_edgePointCopy.x/w,1); 161 | quadBatch.addImage(this); 162 | readjustSize(); 163 | mVertexData.setPosition(0,w,0); 164 | mVertexData.setTexCoords(0,1,0); 165 | mVertexData.setPosition(1,w,0); 166 | mVertexData.setTexCoords(1,1,0); 167 | mVertexData.setPosition(2,_edgePointCopy.x,h); 168 | mVertexData.setTexCoords(2,_edgePointCopy.x/w,1); 169 | quadBatch.addImage(this); 170 | texture = anotherTexture; 171 | readjustSize(); 172 | mVertexData.setPosition(0,0,_edgePoint.y); 173 | mVertexData.setTexCoords(0,1,_edgePoint.y/h); 174 | mVertexData.setPosition(1,0,_edgePoint.y); 175 | mVertexData.setTexCoords(1,1,_edgePoint.y/h); 176 | mVertexData.setPosition(2,_edgePointCopy.x,h); 177 | mVertexData.setTexCoords(2,(w-_edgePointCopy.x)/w,1); 178 | mVertexData.setPosition(3,_dragPoint.x,_dragPoint.y); 179 | quadBatch.addImage(this); 180 | } 181 | } 182 | if(currentPointCount == 4) 183 | { 184 | //在右侧 185 | if(bx > 0) 186 | { 187 | mVertexData.setPosition(0,w,0); 188 | mVertexData.setPosition(1,_edgePoint.x,0); 189 | mVertexData.setTexCoords(1, (_edgePoint.x-w)/w, 0); 190 | mVertexData.setPosition(2,w,h); 191 | mVertexData.setPosition(3,_edgePointCopy.x,h); 192 | mVertexData.setTexCoords(3, (_edgePointCopy.x-w)/w, 1); 193 | quadBatch.addImage(this); 194 | texture = anotherTexture; 195 | readjustSize(); 196 | mVertexData.setPosition(0,_dragPointCopy.x,_dragPointCopy.y); 197 | mVertexData.setPosition(1,_edgePoint.x,0); 198 | mVertexData.setTexCoords(1, (2*w-_edgePoint.x)/w, 0); 199 | mVertexData.setPosition(2,_dragPoint.x,_dragPoint.y); 200 | mVertexData.setPosition(3,_edgePointCopy.x,h); 201 | mVertexData.setTexCoords(3, (2*w-_edgePointCopy.x)/w, 1); 202 | quadBatch.addImage(this); 203 | } 204 | else 205 | { 206 | mVertexData.setPosition(0,_edgePoint.x,0); 207 | mVertexData.setTexCoords(0,_edgePoint.x/w,0); 208 | mVertexData.setPosition(2,_edgePointCopy.x,h); 209 | mVertexData.setTexCoords(2,_edgePointCopy.x/w,1); 210 | quadBatch.addImage(this); 211 | texture = anotherTexture; 212 | readjustSize(); 213 | mVertexData.setPosition(0,_edgePoint.x,0); 214 | mVertexData.setTexCoords(0,(w-_edgePoint.x)/w,0); 215 | mVertexData.setPosition(1,_dragPointCopy.x,_dragPointCopy.y); 216 | mVertexData.setPosition(2,_edgePointCopy.x,h); 217 | mVertexData.setTexCoords(2,(w-_edgePointCopy.x)/w,1); 218 | mVertexData.setPosition(3,_dragPoint.x,_dragPoint.y); 219 | quadBatch.addImage(this); 220 | } 221 | } 222 | drawPage(_dragPoint , _edgePoint , _edgePointCopy , _dragPointCopy); 223 | } 224 | else 225 | { 226 | setLocation(bx>=0?1:-1); 227 | } 228 | } 229 | /**当前触发角*/ 230 | private var currentHotType:String; 231 | /**实现手动翻页功能根据所在页脚做出不同的翻页判断和绘制*/ 232 | private function onTurnPageByHand(mouseLocation:Point):void 233 | { 234 | if(mouseLocation.x >= 0 && mouseLocation.x <= BOOK_WIDTH) 235 | { 236 | _dragPoint.x += (mouseLocation.x - _dragPoint.x)*0.4; 237 | _dragPoint.y += (mouseLocation.y - _dragPoint.y)*0.4; 238 | } 239 | else 240 | { 241 | switch(currentHotType) 242 | { 243 | case(PageVerticeType.TOP_LEFT): 244 | if(mouseLocation.x > BOOK_WIDTH) 245 | { 246 | _dragPoint.x += (targetPoint.x - _dragPoint.x)*0.5; 247 | _dragPoint.y += (targetPoint.y - _dragPoint.y)*0.5; 248 | } 249 | break; 250 | case(PageVerticeType.BOTTOM_LEFT): 251 | if(mouseLocation.x > BOOK_WIDTH) 252 | { 253 | _dragPoint.x += (targetPoint.x - _dragPoint.x)*0.5; 254 | _dragPoint.y += (targetPoint.y - _dragPoint.y)*0.5; 255 | } 256 | break; 257 | case(PageVerticeType.TOP_RIGHT): 258 | if(mouseLocation.x < 0) 259 | { 260 | _dragPoint.x += (targetPoint.x - _dragPoint.x)*0.5; 261 | _dragPoint.y += (targetPoint.y - _dragPoint.y)*0.5; 262 | } 263 | break; 264 | case(PageVerticeType.BOTTOM_RIGHT): 265 | if(mouseLocation.x < 0) 266 | { 267 | _dragPoint.x += (targetPoint.x - _dragPoint.x)*0.5; 268 | _dragPoint.y += (targetPoint.y - _dragPoint.y)*0.5; 269 | } 270 | break; 271 | } 272 | } 273 | limitationCalculator(_dragPoint); 274 | _dragPointCopy.x = currentPointCopy.x; 275 | _dragPointCopy.y = currentPointCopy.y; 276 | mathematicsCalculator(_dragPoint); 277 | adjustPointCalculator(currentHotType); 278 | } 279 | /**用来限制_dragPoint的活动范围,从而达到翻书时最大和最小可能效果*/ 280 | private function limitationCalculator(_dragPoint:Point):void 281 | { 282 | if(_dragPoint.y > BOOK_HEIGHT-0.1) 283 | _dragPoint.y = BOOK_HEIGHT-0.1; 284 | if(_dragPoint.x <= 0.1) 285 | _dragPoint.x = 0.1; 286 | if(_dragPoint.x > BOOK_WIDTH-0.1) 287 | _dragPoint.x = BOOK_WIDTH-0.1; 288 | _dragPoint.x -= BOOK_WIDTH/2; 289 | _dragPoint.y -= BOOK_HEIGHT/2; 290 | limitedPoint.x -= BOOK_WIDTH/2; 291 | limitedPoint.y -= BOOK_HEIGHT/2; 292 | limitedPointCopy.x -= BOOK_WIDTH/2; 293 | limitedPointCopy.y -= BOOK_HEIGHT/2; 294 | if(currentHotType == PageVerticeType.TOP_LEFT || currentHotType == PageVerticeType.TOP_RIGHT) 295 | { 296 | if(_dragPoint.y >= Math.sqrt(Math.pow(radius,2)-Math.pow(_dragPoint.x,2))+limitedPoint.y) 297 | { 298 | _dragPoint.y = Math.sqrt(Math.pow(radius,2)-Math.pow(_dragPoint.x,2))+limitedPoint.y; 299 | } 300 | if(_dragPoint.y <= -Math.sqrt(Math.pow(radiusCopy,2)-Math.pow(_dragPoint.x,2))+limitedPointCopy.y) 301 | { 302 | _dragPoint.y = -Math.sqrt(Math.pow(radiusCopy,2)-Math.pow(_dragPoint.x,2))+limitedPointCopy.y; 303 | } 304 | } 305 | else 306 | { 307 | if(_dragPoint.y <= -Math.sqrt(Math.pow(radius,2)-Math.pow(_dragPoint.x,2))+limitedPoint.y) 308 | { 309 | _dragPoint.y = -Math.sqrt(Math.pow(radius,2)-Math.pow(_dragPoint.x,2))+limitedPoint.y; 310 | } 311 | if(_dragPoint.y >= Math.sqrt(Math.pow(radiusCopy,2)-Math.pow(_dragPoint.x,2))+limitedPointCopy.y) 312 | { 313 | _dragPoint.y = Math.sqrt(Math.pow(radiusCopy,2)-Math.pow(_dragPoint.x,2))+limitedPointCopy.y; 314 | } 315 | } 316 | _dragPoint.x += BOOK_WIDTH/2; 317 | _dragPoint.y += BOOK_HEIGHT/2; 318 | limitedPoint.x += BOOK_WIDTH/2; 319 | limitedPoint.y += BOOK_HEIGHT/2; 320 | limitedPointCopy.x += BOOK_WIDTH/2; 321 | limitedPointCopy.y += BOOK_HEIGHT/2; 322 | } 323 | /**计算一系列数学系数*/ 324 | private function mathematicsCalculator(_dragPoint:Point):void 325 | { 326 | interPoint = Point.interpolate(_dragPoint,currentPoint,0.5); 327 | _k1 = (_dragPoint.y - currentPoint.y)/(_dragPoint.x - currentPoint.x); 328 | _k2 = -1/_k1; 329 | if(Math.abs(_k2) == Infinity){ 330 | if(_k2 >= 0){ 331 | _k2 = 1000000000000000; 332 | }else{ 333 | _k2 = -1000000000000000;} 334 | } 335 | _b = interPoint.y - _k2*interPoint.x; 336 | _edgePoint.x = currentPoint.x; 337 | if(currentHotType == PageVerticeType.TOP_LEFT || currentHotType == PageVerticeType.BOTTOM_RIGHT) 338 | { 339 | _edgePoint.y = -Math.abs(_k2)*_edgePoint.x + _b; 340 | } 341 | if(currentHotType == PageVerticeType.BOTTOM_LEFT || currentHotType == PageVerticeType.TOP_RIGHT) 342 | { 343 | _edgePoint.y = Math.abs(_k2)*_edgePoint.x + _b; 344 | } 345 | _edgePointCopy.y = currentPoint.y; 346 | _edgePointCopy.x = (_edgePointCopy.y - _b)/_k2; 347 | } 348 | /**当翻页翻至_edgePoint到达下页脚时,开启第四点计算,并修改第四点x,y的值*/ 349 | private function adjustPointCalculator(currentHotType:String):void 350 | { 351 | switch(currentHotType) 352 | { 353 | case(PageVerticeType.TOP_LEFT): 354 | if(_edgePoint.y >= currentPointCopy.y) 355 | { 356 | _edgePoint.y = currentPointCopy.y; 357 | _edgePoint.x = (currentPointCopy.y - _b)/_k2; 358 | _dragPointCopy.x = 2*(_b - (currentPointCopy.y - _k1*currentPointCopy.x))/(_k1 - _k2) - currentPointCopy.x; 359 | _dragPointCopy.y = _k1*_dragPointCopy.x + currentPointCopy.y - _k1*currentPointCopy.x; 360 | } 361 | break; 362 | case(PageVerticeType.BOTTOM_LEFT): 363 | if(_edgePoint.y <= currentPointCopy.y) 364 | { 365 | _edgePoint.y = currentPointCopy.y; 366 | _edgePoint.x = (currentPointCopy.y - _b)/_k2; 367 | _dragPointCopy.x = 2*(_b - (currentPointCopy.y - _k1*currentPointCopy.x))/(_k1 - _k2) - currentPointCopy.x; 368 | _dragPointCopy.y = _k1*_dragPointCopy.x + currentPointCopy.y - _k1*currentPointCopy.x; 369 | } 370 | break; 371 | case(PageVerticeType.TOP_RIGHT): 372 | if(_edgePoint.y >= currentPointCopy.y) 373 | { 374 | _edgePoint.y = currentPointCopy.y; 375 | _edgePoint.x = (currentPointCopy.y - _b)/_k2; 376 | _dragPointCopy.x = 2*(_b - (currentPointCopy.y - _k1*currentPointCopy.x))/(_k1 - _k2) - currentPointCopy.x; 377 | _dragPointCopy.y = _k1*_dragPointCopy.x + currentPointCopy.y - _k1*currentPointCopy.x; 378 | } 379 | break; 380 | case(PageVerticeType.BOTTOM_RIGHT): 381 | if(_edgePoint.y <= currentPointCopy.y) 382 | { 383 | _edgePoint.y = currentPointCopy.y; 384 | _edgePoint.x = (currentPointCopy.y - _b)/_k2; 385 | _dragPointCopy.x = 2*(_b - (currentPointCopy.y - _k1*currentPointCopy.x))/(_k1 - _k2) - currentPointCopy.x; 386 | _dragPointCopy.y = _k1*_dragPointCopy.x + currentPointCopy.y - _k1*currentPointCopy.x; 387 | } 388 | break; 389 | } 390 | } 391 | /**测试用*/ 392 | private function drawPage(point1:Point , point2:Point , point3:Point , point4:Point):void 393 | { 394 | var g:Graphics = Main.instance.debugShape.graphics; 395 | g.clear(); 396 | if(_k1 != 0)//当_k1=0且_dragPoint接近targetPoint时说明页面完全翻过 397 | { 398 | g.lineStyle(1,0x000000,0.6); 399 | g.moveTo(point1.x , point1.y); 400 | //_edgePointCopy红色 401 | g.lineTo(point3.x , point3.y); 402 | //_edgePoint绿色 403 | g.lineTo(point2.x , point2.y); 404 | var fourthDot:Boolean = false; 405 | if(_dragPointCopy.x != currentPointCopy.x && _dragPointCopy.y != currentPointCopy.y) 406 | { 407 | fourthDot = true; 408 | //_dragPointCopy蓝色 409 | g.lineTo(point4.x , point4.y); 410 | } 411 | //_dragPoint 412 | g.lineTo(point1.x , point1.y); 413 | return; 414 | //dots 415 | g.beginFill(0x000000,1); 416 | g.drawCircle(point1.x , point1.y,5); 417 | g.endFill(); 418 | g.beginFill(0x00FF00,1); 419 | g.drawCircle(point2.x , point2.y,5); 420 | g.endFill(); 421 | g.beginFill(0xFF0000,1); 422 | g.drawCircle(point3.x , point3.y,5); 423 | g.endFill(); 424 | if(fourthDot) 425 | { 426 | g.beginFill(0x0000FF,1); 427 | g.drawCircle(point4.x , point4.y,10); 428 | g.endFill(); 429 | } 430 | } 431 | } 432 | /**判断当前有几个可用点*/ 433 | private function get currentPointCount():int 434 | { 435 | if(_dragPointCopy.x != currentPointCopy.x && _dragPointCopy.y != currentPointCopy.y) 436 | return 4; 437 | else 438 | return 3; 439 | } 440 | /**验证用户起始触摸是否有效*/ 441 | public function validateBegainPoint(begainPageLocationX:Number, begainPageLocationY:Number):Boolean 442 | { 443 | var bx:Number = Math.abs(begainPageLocationX); 444 | var by:Number = begainPageLocationY; 445 | if(bx > 0.8 && by > 0.8) 446 | return true; 447 | else 448 | return false; 449 | } 450 | /**判断起始拖动点的顶点位置*/ 451 | public function getBegainPointType(begainPageLocationX:Number, begainPageLocationY:Number):String 452 | { 453 | var bpType:String; 454 | var bx:Number = begainPageLocationX; 455 | var by:Number = begainPageLocationY; 456 | if(bx < 0 && by < 0) 457 | bpType = PageVerticeType.TOP_LEFT; 458 | if(bx > 0 && by < 0) 459 | bpType = PageVerticeType.TOP_RIGHT; 460 | if(bx < 0 && by > 0) 461 | bpType = PageVerticeType.BOTTOM_LEFT; 462 | if(bx > 0 && by > 0) 463 | bpType = PageVerticeType.BOTTOM_RIGHT; 464 | switch(bpType) 465 | { 466 | case(PageVerticeType.TOP_LEFT): 467 | currentPoint = LEFT_UP_POINT; 468 | currentPointCopy = LEFT_BOTTOM_POINT; 469 | targetPoint = RIGHT_UP_POINT; 470 | targetPointCopy = RIGHT_BOTTOM_POINT; 471 | limitedPoint = MID_UP_POINT; 472 | limitedPointCopy = MID_BOTTOM_POINT; 473 | break; 474 | case(PageVerticeType.BOTTOM_LEFT): 475 | currentPoint = LEFT_BOTTOM_POINT; 476 | currentPointCopy = LEFT_UP_POINT; 477 | targetPoint = RIGHT_BOTTOM_POINT; 478 | targetPointCopy = RIGHT_UP_POINT; 479 | limitedPoint = MID_BOTTOM_POINT; 480 | limitedPointCopy = MID_UP_POINT; 481 | break; 482 | case(PageVerticeType.TOP_RIGHT): 483 | currentPoint = RIGHT_UP_POINT; 484 | currentPointCopy = RIGHT_BOTTOM_POINT; 485 | targetPoint = LEFT_UP_POINT; 486 | targetPointCopy = LEFT_BOTTOM_POINT; 487 | limitedPoint = MID_UP_POINT; 488 | limitedPointCopy = MID_BOTTOM_POINT; 489 | break; 490 | case(PageVerticeType.BOTTOM_RIGHT): 491 | currentPoint = RIGHT_BOTTOM_POINT; 492 | currentPointCopy = RIGHT_UP_POINT; 493 | targetPoint = LEFT_BOTTOM_POINT; 494 | targetPointCopy = LEFT_UP_POINT; 495 | limitedPoint = MID_BOTTOM_POINT; 496 | limitedPointCopy = MID_UP_POINT; 497 | break; 498 | } 499 | return bpType; 500 | } 501 | } 502 | } 503 | class PageVerticeType 504 | { 505 | public static const TOP_LEFT:String = "topLeft"; 506 | public static const TOP_RIGHT:String = "topRight"; 507 | public static const BOTTOM_LEFT:String = "bottomLeft"; 508 | public static const BOTTOM_RIGHT:String = "bottomRight"; 509 | } -------------------------------------------------------------------------------- /src/test/pf/PageFlipContainer.as: -------------------------------------------------------------------------------- 1 | package test.pf 2 | { 3 | import flash.display.Bitmap; 4 | import flash.geom.Point; 5 | 6 | import starling.display.Image; 7 | import starling.display.QuadBatch; 8 | import starling.display.Sprite; 9 | import starling.events.Event; 10 | import starling.events.Touch; 11 | import starling.events.TouchEvent; 12 | import starling.events.TouchPhase; 13 | import starling.textures.Texture; 14 | import starling.textures.TextureAtlas; 15 | 16 | /** 17 | * 基于Starling的翻页组件 18 | * @author shaorui 19 | */ 20 | public class PageFlipContainer extends Sprite 21 | { 22 | /**包含内页的图集*/ 23 | private var altas:TextureAtlas; 24 | /**书的宽度*/ 25 | private var bookWidth:Number; 26 | /**书的高度*/ 27 | private var bookHeight:Number; 28 | /**书的总页数*/ 29 | private var bookCount:Number; 30 | /**批处理显示*/ 31 | private var quadBatch:QuadBatch; 32 | /**左侧显示页面页码*/ 33 | private var leftPageNum:int = -1; 34 | /**右侧显示页面页码*/ 35 | private var rightPageNum:int = 0; 36 | /**翻动中的页面编码(正面,反面为+1)*/ 37 | private var flipingPageNum:int = -1; 38 | /**X正在翻页的位置(-1到1),由程序控制,外部无须调用*/ 39 | public var flipingPageLocationX:Number = -1; 40 | /**Y正在翻页的位置(-1到1),由程序控制,外部无须调用*/ 41 | public var flipingPageLocationY:Number = -1; 42 | /**X启动翻页的位置(-1到1),由程序控制,外部无须调用*/ 43 | public var begainPageLocationX:Number = -1; 44 | /**Y启动翻页的位置(-1到1),由程序控制,外部无须调用*/ 45 | public var begainPageLocationY:Number = -1; 46 | /**是否需要更新*/ 47 | private var needUpdate:Boolean = true; 48 | 49 | /**@private*/ 50 | public function PageFlipContainer(altas:TextureAtlas,bookWidth:Number,bookHeight:Number,bookCount:Number) 51 | { 52 | super(); 53 | this.altas = altas; 54 | this.bookWidth = bookWidth; 55 | this.bookHeight = bookHeight; 56 | this.bookCount = bookCount; 57 | initPage(); 58 | } 59 | /**初始化页*/ 60 | private function initPage():void 61 | { 62 | quadBatch = new QuadBatch(); 63 | addChild(quadBatch); 64 | textures = altas.getTextures(); 65 | cacheImage = new Image(textures[0]); 66 | flipImage = new ImagePage(textures[0]); 67 | addEventListener(Event.ENTER_FRAME,enterFrameHandler); 68 | addEventListener(Event.ADDED_TO_STAGE,firstFrameInit); 69 | addEventListener(TouchEvent.TOUCH,onTouchHandler); 70 | } 71 | /**显示的时候初始化第一个画面*/ 72 | private function firstFrameInit():void 73 | { 74 | removeEventListener(Event.ADDED_TO_STAGE,firstFrameInit); 75 | enterFrameHandler(); 76 | needUpdate = false; 77 | } 78 | /**用于缓存纹理的图片*/ 79 | private var cacheImage:Image; 80 | /**翻动的图片*/ 81 | private var flipImage:ImagePage; 82 | /**缓存的纹理数组*/ 83 | private var textures:Vector.; 84 | /**每帧调用*/ 85 | private function enterFrameHandler(event:Event=null):void 86 | { 87 | if(stage == null || !needUpdate) 88 | return; 89 | quadBatch.reset(); 90 | if(flipingPageNum >= 0) 91 | { 92 | leftPageNum = flipingPageNum - 1; 93 | rightPageNum = flipingPageNum + 2; 94 | } 95 | //选择左侧的页面 96 | if(validatePageNumber(leftPageNum)) 97 | { 98 | cacheImage.x = 0; 99 | cacheImage.texture = textures[leftPageNum]; 100 | quadBatch.addImage(cacheImage); 101 | } 102 | //渲染右侧的页面 103 | if(validatePageNumber(rightPageNum)) 104 | { 105 | cacheImage.x = bookWidth/2; 106 | cacheImage.texture = textures[rightPageNum]; 107 | quadBatch.addImage(cacheImage); 108 | } 109 | //渲染正在翻转的页面 110 | if(validatePageNumber(flipingPageNum)) 111 | { 112 | if(flipImage.softMode) 113 | { 114 | flipImage.texture = begainPageLocationX>=0?textures[flipingPageNum]:textures[flipingPageNum+1]; 115 | flipImage.anotherTexture = begainPageLocationX<0?textures[flipingPageNum]:textures[flipingPageNum+1]; 116 | flipImage.readjustSize(); 117 | flipImage.setLocationSoft(quadBatch,begainPageLocationX,begainPageLocationY,flipingPageLocationX,flipingPageLocationY); 118 | } 119 | else 120 | { 121 | flipImage.texture = flipingPageLocationX>=0?textures[flipingPageNum]:textures[flipingPageNum+1]; 122 | flipImage.readjustSize(); 123 | flipImage.setLocation(flipingPageLocationX); 124 | quadBatch.addImage(flipImage); 125 | } 126 | } 127 | } 128 | /**是否处于拖动状态*/ 129 | private var isDraging:Boolean = false; 130 | /**触碰处理*/ 131 | private function onTouchHandler(event:TouchEvent):void 132 | { 133 | var touch:Touch = event.getTouch(this); 134 | if(touch != null && (touch.phase == TouchPhase.BEGAN || touch.phase == TouchPhase.MOVED || touch.phase == TouchPhase.ENDED)) 135 | { 136 | var point:Point = touch.getLocation(this); 137 | var imgWidth:Number = bookWidth/2; 138 | var imgHeight:Number = bookHeight/2; 139 | if(touch.phase == TouchPhase.BEGAN) 140 | { 141 | begainPageLocationX = (point.x-imgWidth)/imgWidth; 142 | begainPageLocationY = (point.y-imgHeight)/imgHeight; 143 | isDraging = true; 144 | if(point.x >= imgWidth) 145 | { 146 | if(validatePageNumber(rightPageNum)) 147 | { 148 | flipingPageNum = rightPageNum; 149 | } 150 | } 151 | else 152 | { 153 | if(validatePageNumber(leftPageNum)) 154 | { 155 | flipingPageNum = leftPageNum-1; 156 | } 157 | } 158 | resetSoftMode(); 159 | if(flipImage.softMode && !flipImage.validateBegainPoint(begainPageLocationX,begainPageLocationY)) 160 | { 161 | isDraging = false; 162 | flipingPageNum = -1; 163 | return; 164 | } 165 | } 166 | else if(touch.phase == TouchPhase.MOVED) 167 | { 168 | if(isDraging) 169 | { 170 | flipingPageLocationX = (point.x-imgWidth)/imgWidth; 171 | flipingPageLocationY = (point.y-imgHeight)/imgHeight; 172 | if(flipingPageLocationX > 1) 173 | flipingPageLocationX = 1; 174 | if(flipingPageLocationX < -1) 175 | flipingPageLocationX = -1; 176 | if(flipingPageLocationY > 1) 177 | flipingPageLocationY = 1; 178 | if(flipingPageLocationY < -1) 179 | flipingPageLocationY = -1; 180 | validateNow(); 181 | } 182 | } 183 | else 184 | { 185 | if(isDraging) 186 | { 187 | finishTouchByMotion(point.x); 188 | isDraging = false; 189 | } 190 | } 191 | } 192 | else 193 | { 194 | needUpdate = false; 195 | } 196 | } 197 | /**设置硬皮还是软皮*/ 198 | private function resetSoftMode():void 199 | { 200 | if(flipingPageNum > 0 && flipingPageNum < (bookCount-2)) 201 | flipImage.softMode = true; 202 | else 203 | flipImage.softMode = false; 204 | } 205 | /**触控结束后,完成翻页过程*/ 206 | private function finishTouchByMotion(endX:Number):void 207 | { 208 | var imgWidth:Number = bookWidth/2; 209 | needUpdate = true; 210 | touchable = false; 211 | addEventListener(Event.ENTER_FRAME,executeMotion); 212 | function executeMotion(event:Event):void 213 | { 214 | if(endX >= imgWidth) 215 | { 216 | flipingPageLocationX += (1-flipingPageLocationX)/4; 217 | flipingPageLocationY = flipingPageLocationX; 218 | if(flipingPageLocationX >= 0.999) 219 | { 220 | flipingPageLocationX = 1; 221 | flipingPageLocationY = 1; 222 | removeEventListener(Event.ENTER_FRAME,executeMotion); 223 | tweenCompleteHandler(); 224 | } 225 | } 226 | else 227 | { 228 | flipingPageLocationX += (-1-flipingPageLocationX)/4; 229 | flipingPageLocationY = -flipingPageLocationX; 230 | if(flipingPageLocationX <= -0.999) 231 | { 232 | flipingPageLocationX = -1; 233 | flipingPageLocationY = 1; 234 | removeEventListener(Event.ENTER_FRAME,executeMotion); 235 | tweenCompleteHandler(); 236 | } 237 | } 238 | } 239 | } 240 | /**动画执行完毕后的重置*/ 241 | private function tweenCompleteHandler():void 242 | { 243 | if(flipingPageLocationX == 1) 244 | { 245 | leftPageNum = flipingPageNum-1; 246 | rightPageNum = flipingPageNum; 247 | } 248 | else if(flipingPageLocationX == -1) 249 | { 250 | leftPageNum = flipingPageNum+1; 251 | rightPageNum = flipingPageNum+2; 252 | } 253 | flipingPageNum = -1; 254 | resetSoftMode(); 255 | validateNow(); 256 | touchable = true; 257 | Main.instance.debugShape.graphics.clear(); 258 | } 259 | /**验证某个页面是否合法*/ 260 | private function validatePageNumber(pageNum:int):Boolean 261 | { 262 | if(pageNum >= 0 && pageNum < bookCount) 263 | return true; 264 | else 265 | return false; 266 | } 267 | /**当前页码*/ 268 | public function get pageNumber():int 269 | { 270 | if(leftPageNum >= 0) 271 | return leftPageNum; 272 | else 273 | return rightPageNum; 274 | } 275 | /**强制更新一次显示*/ 276 | public function validateNow():void 277 | { 278 | needUpdate = true; 279 | enterFrameHandler(); 280 | needUpdate = false; 281 | } 282 | /**跳页*/ 283 | public function gotoPage(pn:int):void 284 | { 285 | if(pn < 0) 286 | pn = 0; 287 | if(pn >= bookCount) 288 | pn = bookCount-1; 289 | if(pn == 0) 290 | { 291 | leftPageNum = -1; 292 | rightPageNum = 0; 293 | } 294 | else if(pn == bookCount-1) 295 | { 296 | leftPageNum = pn; 297 | rightPageNum = -1; 298 | } 299 | else 300 | { 301 | if(pn%2==0) 302 | pn = pn - 1; 303 | leftPageNum = pn; 304 | rightPageNum = pn+1; 305 | } 306 | flipingPageNum = -1; 307 | resetSoftMode(); 308 | validateNow(); 309 | } 310 | } 311 | } -------------------------------------------------------------------------------- /src/test/pf/ShadowUtil.as: -------------------------------------------------------------------------------- 1 | package test.pf 2 | { 3 | import flash.display.Bitmap; 4 | import flash.display.BitmapData; 5 | import flash.geom.Point; 6 | import flash.geom.Rectangle; 7 | 8 | public class ShadowUtil 9 | { 10 | [Embed(source="../../assets/high-light.png")] 11 | private static const shadowImgClass:Class; 12 | 13 | public static function addShadow(bookImgs:Bitmap,xml:XML):void 14 | { 15 | var sourceData:BitmapData = bookImgs.bitmapData; 16 | var shadowData:BitmapData = (new shadowImgClass() as Bitmap).bitmapData; 17 | var count:int = 0; 18 | var bookCount:int = xml.SubTexture.length(); 19 | for each (var node:XML in xml.SubTexture) 20 | { 21 | var x:Number = Number(node.@x); 22 | var y:Number = Number(node.@y); 23 | var w:Number = Number(node.@width); 24 | var h:Number = Number(node.@height); 25 | if(count > 0 && count < bookCount-1) 26 | { 27 | var rect:Rectangle = new Rectangle(0,0,shadowData.width/2,shadowData.height); 28 | if(count%2==0) 29 | rect = new Rectangle(shadowData.width/2,0,shadowData.width/2,shadowData.height); 30 | var point:Point = new Point(x,y); 31 | if(count%2!=0) 32 | point = new Point(x+w-shadowData.width/2,y); 33 | sourceData.copyPixels(shadowData,rect,point,null,null,true); 34 | } 35 | count++; 36 | } 37 | } 38 | } 39 | } -------------------------------------------------------------------------------- /src/wrap/Game2.as: -------------------------------------------------------------------------------- 1 | package wrap 2 | { 3 | import flash.display.Bitmap; 4 | import flash.geom.Point; 5 | 6 | import starling.display.Image; 7 | import starling.display.Quad; 8 | import starling.display.QuadBatch; 9 | import starling.display.Sprite; 10 | import starling.events.Event; 11 | import starling.events.Touch; 12 | import starling.events.TouchEvent; 13 | import starling.events.TouchPhase; 14 | import starling.textures.Texture; 15 | import starling.textures.TextureAtlas; 16 | 17 | import test.pf.PageFlipContainer; 18 | 19 | public class Game2 extends Sprite 20 | { 21 | [Embed(source="assets/ad.xml", mimeType="application/octet-stream")] 22 | public static const adXml:Class; 23 | [Embed(source="../assets/ad.png")] 24 | protected const adImgClass:Class; 25 | 26 | private var cacheImage:SuperImage; 27 | private var quadBatch:QuadBatch; 28 | private var atlas:TextureAtlas; 29 | private var adCount:Number; 30 | private var adWidth:Number; 31 | private var adHeight:Number; 32 | private var currentIndex:Number = 0; 33 | 34 | /**缓存的纹理数组*/ 35 | private var textures:Vector.; 36 | /**缓存的阴影数组*/ 37 | private var shadows:Vector.; 38 | /**是否需要更新*/ 39 | private var needUpdate:Boolean = true; 40 | /**X正在翻页的位置(-1到1),由程序控制,外部无须调用*/ 41 | private var flipingPageLocationX:Number = 0; 42 | /**X启动翻页的位置(-1到1),由程序控制,外部无须调用*/ 43 | private var begainPageLocationX:Number = 0; 44 | 45 | public function Game2() 46 | { 47 | super(); 48 | initGame(); 49 | } 50 | /**初始化*/ 51 | private function initGame():void 52 | { 53 | //把图片合集到一起,减少DRW值 54 | var adImgs:Bitmap = new adImgClass(); 55 | var xml:XML = XML(new adXml()); 56 | //atlas 57 | var texture:Texture = Texture.fromBitmap(adImgs,false); 58 | adImgs.bitmapData.dispose(); 59 | adImgs = null; 60 | atlas = new TextureAtlas(texture,xml); 61 | textures = atlas.getTextures("a"); 62 | shadows = atlas.getTextures("s"); 63 | var firstTexture:Texture = textures[0]; 64 | cacheImage = new SuperImage(firstTexture); 65 | adWidth = cacheImage.width; 66 | adHeight = cacheImage.height; 67 | adCount = textures.length; 68 | //listners 69 | addEventListener(Event.ENTER_FRAME,enterFrameHandler); 70 | addEventListener(Event.ADDED_TO_STAGE,firstFrameInit); 71 | addEventListener(TouchEvent.TOUCH,onTouchHandler); 72 | } 73 | /**显示的时候初始化第一个画面*/ 74 | private function firstFrameInit(...args):void 75 | { 76 | removeEventListener(Event.ADDED_TO_STAGE,firstFrameInit); 77 | //bg 78 | var bg:Quad = new Quad(stage.stageWidth,stage.stageHeight/2,0x0008a7); 79 | addChild(bg); 80 | //batch 81 | quadBatch = new QuadBatch(); 82 | addChild(quadBatch); 83 | currentIndex = 0; 84 | enterFrameHandler(); 85 | needUpdate = false; 86 | } 87 | //private var breakMotion:Boolean = false; 88 | /**每帧调用*/ 89 | private function enterFrameHandler(event:Event=null):void 90 | { 91 | if(stage == null || !needUpdate) 92 | return; 93 | quadBatch.reset(); 94 | var yOffset:Number = 0; 95 | //依次绘制每一个图片(超出显示区域的不予绘制) 96 | var xCenter:Number = stage.stageWidth/2; 97 | var needAddImages:Vector. = new Vector.(); 98 | for (var i:int = 0; i < adCount; i++) 99 | { 100 | var distance:Number = adWidth-40; 101 | var xLocation:Number = xCenter+(i-currentIndex)*distance-adWidth/2; 102 | if(Math.abs(i-currentIndex) >= 2) 103 | { 104 | xLocation -= (adWidth-80); 105 | } 106 | var targetRotation:Number = 0; 107 | if(xLocation+adWidth>0 && xLocation < stage.stageWidth) 108 | { 109 | targetRotation = (xLocation+adWidth/2-xCenter)/(xCenter*10)*180; 110 | cacheImage = new SuperImage(shadows[i]); 111 | cacheImage.y = (stage.stageHeight-adHeight)/2-yOffset; 112 | cacheImage.x = xLocation; 113 | cacheImage.rotationY = targetRotation; 114 | if(i>currentIndex) 115 | needAddImages.unshift(cacheImage); 116 | else 117 | needAddImages.push(cacheImage); 118 | cacheImage = new SuperImage(textures[i]); 119 | cacheImage.y = (stage.stageHeight-adHeight)/2-yOffset; 120 | cacheImage.x = xLocation; 121 | cacheImage.rotationY = targetRotation; 122 | if(i>currentIndex) 123 | needAddImages.unshift(cacheImage); 124 | else 125 | needAddImages.push(cacheImage); 126 | } 127 | } 128 | for each (var image:Image in needAddImages) 129 | { 130 | quadBatch.addImage(image); 131 | image.dispose(); 132 | } 133 | needAddImages.length=0; 134 | } 135 | /**是否处于拖动状态*/ 136 | private var isDraging:Boolean = false; 137 | /**开始拖动的时候的图片当前索引*/ 138 | private var onDragPageIndex:Number = 0; 139 | /**目标索引*/ 140 | private var targetIndex:int; 141 | /**触碰处理*/ 142 | private function onTouchHandler(event:TouchEvent):void 143 | { 144 | var touch:Touch = event.getTouch(this); 145 | var imgWidth:Number = stage.stageWidth/2; 146 | if(touch != null && (touch.phase == TouchPhase.BEGAN || touch.phase == TouchPhase.MOVED || touch.phase == TouchPhase.ENDED)) 147 | { 148 | var point:Point = touch.getLocation(this); 149 | if(touch.phase == TouchPhase.BEGAN) 150 | { 151 | tweenCompleteHandler(); 152 | begainPageLocationX = (point.x-imgWidth)/imgWidth; 153 | onDragPageIndex = currentIndex; 154 | isDraging = true; 155 | } 156 | else if(touch.phase == TouchPhase.MOVED) 157 | { 158 | if(isDraging) 159 | { 160 | flipingPageLocationX = (point.x-imgWidth)/imgWidth; 161 | currentIndex = onDragPageIndex-(flipingPageLocationX-begainPageLocationX); 162 | if(currentIndex<0) 163 | currentIndex = 0; 164 | if(currentIndex>(adCount-1)) 165 | currentIndex = adCount-1; 166 | validateNow(); 167 | } 168 | } 169 | else 170 | { 171 | if(isDraging) 172 | { 173 | finishTouchByMotion(point.x); 174 | isDraging = false; 175 | } 176 | } 177 | } 178 | else 179 | { 180 | //needUpdate = false; 181 | } 182 | } 183 | /**触控结束后,完成翻页过程*/ 184 | private function finishTouchByMotion(endX:Number):void 185 | { 186 | var imgWidth:Number = stage.stageWidth/2; 187 | targetIndex = Math.round(currentIndex); 188 | var endNumber:Number = currentIndex-int(currentIndex); 189 | if(flipingPageLocationX<0 && endNumber>0.2) 190 | targetIndex = Math.ceil(currentIndex); 191 | if(flipingPageLocationX>0 && endNumber>0.5) 192 | targetIndex = Math.floor(currentIndex); 193 | needUpdate = true; 194 | addEventListener(Event.ENTER_FRAME,executeMotion); 195 | } 196 | /**execute motion*/ 197 | private function executeMotion(event:Event):void 198 | { 199 | currentIndex += (targetIndex-currentIndex)/4; 200 | if(Math.abs(currentIndex-targetIndex) <= 0.001) 201 | { 202 | currentIndex = targetIndex; 203 | tweenCompleteHandler(); 204 | } 205 | } 206 | /**动画执行完毕后的重置*/ 207 | private function tweenCompleteHandler():void 208 | { 209 | removeEventListener(Event.ENTER_FRAME,executeMotion); 210 | if(currentIndex < 0) 211 | currentIndex = 0; 212 | if(currentIndex > adCount-1) 213 | currentIndex = adCount-1; 214 | flipingPageLocationX = 0; 215 | begainPageLocationX = 0; 216 | validateNow(); 217 | } 218 | /**强制更新一次显示*/ 219 | public function validateNow():void 220 | { 221 | needUpdate = true; 222 | enterFrameHandler(); 223 | needUpdate = false; 224 | } 225 | } 226 | } -------------------------------------------------------------------------------- /src/wrap/SuperImage.as: -------------------------------------------------------------------------------- 1 | package wrap 2 | { 3 | import starling.display.Image; 4 | import starling.textures.Texture; 5 | /** 6 | * 增加了rotationY的Image 7 | * @author shaorui 8 | */ 9 | public class SuperImage extends Image 10 | { 11 | /**图片宽度*/ 12 | public var imageWidth:Number = 0; 13 | /**图片高度*/ 14 | public var imageHeight:Number = 0; 15 | /**@private*/ 16 | private var _rotationY:Number = 0; 17 | /**@private*/ 18 | public function SuperImage(texture:Texture) 19 | { 20 | super(texture); 21 | this.imageWidth = texture.width; 22 | this.imageHeight = texture.height; 23 | } 24 | /**@override*/ 25 | override public function readjustSize():void 26 | { 27 | super.readjustSize(); 28 | this.imageWidth = texture.width; 29 | this.imageHeight = texture.height; 30 | _rotationY = 0; 31 | //resetAllTexCoords(); 32 | onVertexDataChanged(); 33 | } 34 | /**重置UV坐标*/ 35 | protected function resetAllTexCoords():void 36 | { 37 | mVertexData.setTexCoords(0, 0, 0); 38 | mVertexData.setTexCoords(1, 1, 0); 39 | mVertexData.setTexCoords(2, 0, 1); 40 | mVertexData.setTexCoords(3, 1.0, 1.0); 41 | } 42 | /**@override*/ 43 | override public function set texture(value:Texture):void 44 | { 45 | super.texture = value; 46 | readjustSize(); 47 | } 48 | /**和Flash的那个一样*/ 49 | public function get rotationY():Number 50 | { 51 | return _rotationY; 52 | } 53 | public function set rotationY(value:Number):void 54 | { 55 | _rotationY = value; 56 | var w:Number = imageWidth; 57 | var h:Number = imageHeight; 58 | var xOffset:Number = Math.abs(w*(value/180)); 59 | var yOffset:Number = h*(value/180)/2; 60 | mVertexData.setPosition(0,0+xOffset,0+yOffset); 61 | mVertexData.setPosition(1,w-xOffset,0-yOffset); 62 | mVertexData.setPosition(2,0+xOffset,h-yOffset); 63 | mVertexData.setPosition(3,w-xOffset,h+yOffset); 64 | } 65 | } 66 | } --------------------------------------------------------------------------------