1 /**
2 * Copyright lizhi ( http://wonderfl.net/user/lizhi )
3 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
4 * Downloaded from: http://wonderfl.net/c/53o6
5 */
6
7 package
8 {
9 import flash.display.Bitmap;
10 import flash.display.BitmapData;
11 import flash.display.Shape;
12 import flash.display.Sprite;
13 import flash.events.Event;
14 import flash.events.MouseEvent;
15 import flash.filters.BitmapFilter;
16 import flash.filters.BlurFilter;
17 import flash.filters.GlowFilter;
18 import flash.geom.ColorTransform;
19 import flash.text.TextField;
20 import flash.text.TextFieldAutoSize;
21
22 /**
23 * ...
24 * @author lizhi http://game-develop.net/
25 */
26 [SWF(width=465,height=465,backgroundColor=0xffffff,frameRate=25)]
27 public class Apple extends Sprite
28 {
29 private var info:TextField;
30 private var score:int = 0;
31 private var lost:int = 0;
32 private var time:int = 0;
33 private var particles:Array = [];
34 private var rubbishs:Array = [];
35 private var lines:Array = [];
36 private var cutlayer:Shape = new Shape;
37 private var cutBmdLayer:BitmapData;
38 private var cutlayerFilter:BitmapFilter;
39 private var cutlayerCT:ColorTransform;
40
41
42 private var flayer:Shape = new Shape;
43 private var fBmdLayer:BitmapData;
44 private var flayerFilter:BitmapFilter;
45 private var flayerCT:ColorTransform;
46
47 private var lastX:Number;
48 private var lastY:Number;
49
50 public function Apple():void
51 {
52 info = new TextField;
53 info.autoSize = TextFieldAutoSize.LEFT;
54 info.multiline = true;
55 fBmdLayer = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0);
56 addChild(new Bitmap(fBmdLayer));
57 flayerFilter = new BlurFilter;
58 flayerCT = new ColorTransform(1, 1, 1, 0.5);
59
60 cutBmdLayer = new BitmapData(stage.stageWidth, stage.stageHeight, true, 0);
61 var cutImage:Bitmap = new Bitmap(cutBmdLayer);
62 addChild(cutImage);
63 addChild(info);
64 cutImage.filters = [new GlowFilter(0, 1, 6, 6, 2, 1)];
65 cutlayerFilter = new BlurFilter(2,2,3);
66 cutlayerCT = new ColorTransform(1, 1, 1, 0.9);
67
68 stage.addEventListener(MouseEvent.MOUSE_DOWN, onMD);
69 addEventListener(Event.ENTER_FRAME, update);
70
71 }
72
73 private function onMD(e:MouseEvent):void
74 {
75 lastX = mouseX;
76 lastY = mouseY;
77 stage.addEventListener(MouseEvent.MOUSE_MOVE, onMM);
78 stage.addEventListener(MouseEvent.MOUSE_UP, onMU);
79 }
80
81 private function onMU(e:MouseEvent):void
82 {
83 stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMM);
84 stage.removeEventListener(MouseEvent.MOUSE_UP, onMU);
85 }
86
87 private function onMM(e:MouseEvent):void
88 {
89 var line:Line = new Line;
90 line.x1 = lastX;
91 line.y1 = lastY;
92 lastX = mouseX;
93 lastY = mouseY;
94 line.x2 = lastX;
95 line.y2 = lastY;
96 //if(line.length>50)
97 lines.push(line);
98 }
99
100 private function update(e:Event):void
101 {
102 var graphics:flash.display.Graphics = flayer.graphics;
103 graphics.clear();
104 for (var i:int = particles.length - 1; i >= 0; i--)
105 {
106 var p:Particle = particles[i];
107 p.update(graphics);
108 if (p.y > stage.stageHeight)
109 {
110 if(p.state==0)lost++;
111 particles.splice(i, 1);
112 }
113 }
114 for (i = rubbishs.length - 1; i >= 0; i--)
115 {
116 p = rubbishs[i];
117 p.update(graphics);
118 if (p.y > stage.stageHeight)
119 {
120 rubbishs.splice(i, 1);
121 }
122 }
123 cutlayer.graphics.clear();
124 cutlayer.graphics.lineStyle(0, 0xff0000);
125 for (i = lines.length - 1; i >= 0; i--)
126 {
127 var line:Line = lines[i];
128 if (line.state == 0)
129 {
130 for (var j:int = particles.length - 1; j >= 0;j-- )
131 {
132 p = particles[j];
133 var intersectionObj:Object = intersection(line.x1, line.y1, line.x2, line.y2, p.x, p.y, p.r);
134 if (p.state == 0 && intersectionObj!=null)
135 {
136 p.state = 1;
137 p.cut(intersectionObj.x1, intersectionObj.y1, intersectionObj.x2, intersectionObj.y2);
138 var p2:Particle = new Particle;
139 p2.x = p.x;
140 p2.y = p.y;
141 p2.vx = p.vx;
142 p2.vy = p.vy;
143 p2.r = p.r;
144 p2.av = p.av;
145 p2.lineColor = p.lineColor;
146 p2.color = p.color;
147 p2.state = p.state;
148 p2.cut(intersectionObj.x2, intersectionObj.y2, intersectionObj.x1, intersectionObj.y1);
149 particles.push(p2);
150 score++;
151 rubbish(p.x,p.y,p.color);
152 }
153 }
154 }
155 line.state++;
156 if (line.state > 10)
157 {
158 lines.splice(i, 1);
159 }
160 cutlayer.graphics.moveTo(line.x1, line.y1);
161 cutlayer.graphics.lineTo(line.x2, line.y2);
162 }
163 cutBmdLayer.colorTransform(cutBmdLayer.rect, cutlayerCT);
164 cutBmdLayer.applyFilter(cutBmdLayer, cutBmdLayer.rect, cutBmdLayer.rect.topLeft, cutlayerFilter);
165 cutBmdLayer.draw(cutlayer);
166
167 fBmdLayer.colorTransform(fBmdLayer.rect, flayerCT);
168 fBmdLayer.applyFilter(fBmdLayer, fBmdLayer.rect, fBmdLayer.rect.topLeft, flayerFilter);
169 fBmdLayer.draw(flayer);
170
171 info.text = "lost:" + lost + " score:" + score + " time:" + int(time / stage.frameRate);
172 time++;
173 if (Math.random() < Math.atan(0.02 + time / 100000))
174 {
175 addFruit();
176 }
177 }
178
179 private function addFruit():void
180 {
181 var p:Particle = new Particle;
182 p.x = stage.stageWidth * (0.3 + 0.4 * Math.random());
183 p.y = stage.stageHeight;
184 p.vx = 5 * (Math.random() - .5);
185 p.vy = -(20 + 20 * Math.random());
186 p.r = 15 + 25 * Math.random();
187 p.a = Math.PI * 2 * Math.random();
188 p.av = 0.1*(Math.random()-0.5);
189 particles.push(p);
190 }
191 private function rubbish(x:Number, y:Number,color:uint):void {
192 var c:int = 100 * Math.random();
193 while(c-->0){
194 var p:Particle = new Particle;
195 p.color = color;
196 p.lineColor = color;
197 p.x = x;
198 p.y = y;
199 p.r = 0 + 1 * Math.random();
200 p.a = Math.PI * 2 * Math.random();
201 p.av = 0.1 * (Math.random() - 0.5);
202 var s:Number = 10*Math.random();
203 p.vx = s * Math.cos(p.a);
204 p.vy = s * Math.sin(p.a);
205 rubbishs.push(p);
206 }
207 }
208
209 //http://www.thecodeway.com/blog/?p=1873
210 private function intersection(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, r:Number):Object
211 {
212 var A:Number = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
213 var B:Number = 2 * ((x2 - x1) * (x1 - x3) + (y2 - y1) * (y1 - y3));
214 var C:Number = x3 * x3 + y3 * y3 + x1 * x1 + y1 * y1 - 2 * (x3 * x1 + y3 * y1) - r * r;
215 var bb_plus_4ac:Number = B * B - 4 * A * C;
216 if (bb_plus_4ac > 0)
217 {
218 var sqrt:Number = Math.sqrt(bb_plus_4ac);
219 var u1:Number = (-B + sqrt) / 2 / A;
220 var u2:Number = (-B - sqrt) / 2 / A;
221 var cutx1:Number = x1 + (x2 - x1) * u1;
222 var cuty1:Number = y1 + (y2 - y1) * u1;
223 var cutx2:Number = x1 + (x2 - x1) * u2;
224 var cuty2:Number = y1 + (y2 - y1) * u2;
225 var obj:Object = { x1:cutx1, y1:cuty1, x2:cutx2, y2:cuty2 };
226 if (u1 > 0 && u1 < 1)
227 {
228 return obj;
229 }
230 if (u2 > 0 && u2 < 1)
231 {
232 return obj;
233 }
234 }
235 return null;
236 }
237 }
238
239 }
240 import flash.geom.Point;
241 import flash.display.Graphics;
242
243 class Line
244 {
245 public var x1:Number;
246 public var y1:Number;
247 public var x2:Number;
248 public var y2:Number;
249 public var state:int = 0;
250 public function get length():Number {
251 return Math.sqrt((x2-x1)*(x2-x1)+(y2-y1)*(y2-y1));
252 }
253 public function Line()
254 {
255
256 }
257
258 }
259
260 class Particle
261 {
262 public var x:Number;
263 public var y:Number;
264
265 public var g:Number = 0.5;
266 public var vx:Number;
267 public var vy:Number;
268 public var friction:Number = 0.95;
269
270 public var r:Number;
271 public var lineColor:uint = 0xffffff * Math.random();
272 public var color:uint = 0xffffff * Math.random();
273 public var state:int = 0;
274
275 private var a1:Number;
276 private var a2:Number;
277 public var av:Number;
278 public var a:Number = 0;
279 public function Particle()
280 {
281 }
282
283 public function update(grap:Graphics):void
284 {
285 vx *= friction;
286 x += vx;
287 vy += g;
288 vy *= friction;
289 y += vy;
290 a += av;
291
292 grap.beginFill(color);
293 grap.lineStyle(3,lineColor);
294 if (state == 0) {
295 grap.moveTo(x + r * Math.cos(a), y + r * Math.sin(a));
296 grap.lineTo(x, y);
297 grap.drawCircle(x, y, r);
298 }else {
299 a1 += av;
300 a2 += av;
301 drawArc(grap, x, y, r, (a2 - a1) * 180 / Math.PI, a1 * 180 / Math.PI);
302 }
303
304 }
305
306 public function cut(x1:Number, y1:Number, x2:Number, y2:Number):void {
307 a1 = Math.atan2(y1 - y, x1 - x);
308 a2 = Math.atan2(y2 - y, x2 - x);
309 if (x1 > x2) {
310 vx += 3;
311 av += 0.05;
312 }else {
313 vx -= 3;
314 av -= 0.05;
315 }
316 }
317
318 //http://as3-classes.googlecode.com
319 public function drawArc(grap:Graphics,nX:Number, nY:Number, nRadius:Number, nArc:Number, nStartingAngle:Number = 0):void
320 {
321 // The angle of each of the eight segments is 45 degrees (360 divided by eight),
322 // which equals p/4 radians.
323 if (nArc < 0) {
324 nArc += 360;
325 }
326 if (nArc > 360)
327 {
328 nArc = 360;
329 }
330 nArc = Math.PI / 180 * nArc;
331 var nAngleDelta:Number = nArc / 8;
332
333 // Find the distance from the circle's center to the control points
334 // for the curves.
335 var nCtrlDist:Number = nRadius / Math.cos(nAngleDelta / 2);
336
337 nStartingAngle *= Math.PI / 180;
338
339 var nAngle:Number = nStartingAngle;
340 var nCtrlX:Number;
341 var nCtrlY:Number;
342 var nAnchorX:Number;
343 var nAnchorY:Number;
344
345 var nStartingX:Number = nX + Math.cos(nStartingAngle) * nRadius;
346 var nStartingY:Number = nY + Math.sin(nStartingAngle) * nRadius;
347
348
349 // Move to the starting point, one radius to the right of the circle's center.
350 grap.moveTo(nStartingX, nStartingY);
351 // Repeat eight times to create eight segments.
352 for (var i:Number = 0; i < 8; i++)
353 {
354 // Increment the angle by angleDelta (p/4) to create the whole circle (2p).
355 nAngle += nAngleDelta;
356
357 // The control points are derived using sine and cosine.
358 nCtrlX = nX + Math.cos(nAngle - (nAngleDelta / 2)) * (nCtrlDist);
359 nCtrlY = nY + Math.sin(nAngle - (nAngleDelta / 2)) * (nCtrlDist);
360
361 // The anchor points (end points of the curve) can be found similarly to the
362 // control points.
363 nAnchorX = nX + Math.cos(nAngle) * nRadius;
364 nAnchorY = nY + Math.sin(nAngle) * nRadius;
365
366 // Draw the segment.
367 grap.curveTo(nCtrlX, nCtrlY, nAnchorX, nAnchorY);
368 }
369 }
370 }