Fruit Ninja
/**
* Copyright lizhi ( http://wonderfl.net/user/lizhi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/edWH
*/
package
{
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
/**
* ...
* @author lizhi http://game-develop.net/
*/
[SWF(width=465,height=465,backgroundColor=0xffffff,frameRate=25)]
public class Main extends Sprite
{
private var info:TextField;
private var score:int = 0;
private var lost:int = 0;
private var time:int = 0;
private var particles:Array = [];
private var rubbishs:Array = [];
private var lines:Array = [];
private var cutlayer:Shape = new Shape;
private var lastX:Number;
private var lastY:Number;
public function Main():void
{
info = new TextField;
addChild(info);
info.autoSize = TextFieldAutoSize.LEFT;
info.multiline = true;
addChild(cutlayer);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMD);
addEventListener(Event.ENTER_FRAME, update);
}
private function onMD(e:MouseEvent):void
{
lastX = mouseX;
lastY = mouseY;
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMM);
stage.addEventListener(MouseEvent.MOUSE_UP, onMU);
}
private function onMU(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMM);
stage.removeEventListener(MouseEvent.MOUSE_UP, onMU);
}
private function onMM(e:MouseEvent):void
{
var line:Line = new Line;
line.x1 = lastX;
line.y1 = lastY;
lastX = mouseX;
lastY = mouseY;
line.x2 = lastX;
line.y2 = lastY;
lines.push(line);
}
private function update(e:Event):void
{
graphics.clear();
for (var i:int = particles.length - 1; i >= 0; i--)
{
var p:Particle = particles[i];
p.update(graphics);
if (p.y > stage.stageHeight)
{
if(p.state==0)lost++;
particles.splice(i, 1);
}
}
for (i = rubbishs.length - 1; i >= 0; i--)
{
p = rubbishs[i];
p.r-=.3;
if(p.r<=0)p.r=0;
p.update(graphics);
if (p.y > stage.stageHeight)
{
rubbishs.splice(i, 1);
}
}
cutlayer.graphics.clear();
cutlayer.graphics.lineStyle(0, 0xff0000);
for (i = lines.length - 1; i >= 0; i--)
{
var line:Line = lines[i];
if (line.state == 0)
{
for (var j:int = particles.length - 1; j >= 0;j-- )
{
p = particles[j];
var intersectionObj:Object = intersection(line.x1, line.y1, line.x2, line.y2, p.x, p.y, p.r);
if (p.state == 0 && intersectionObj!=null)
{
p.state = 1;
p.cut(intersectionObj.x1, intersectionObj.y1, intersectionObj.x2, intersectionObj.y2);
var p2:Particle = new Particle;
p2.x = p.x;
p2.y = p.y;
p2.vx = p.vx;
p2.vy = p.vy;
p2.r = p.r;
p2.av = p.av;
p2.state = p.state;
p2.cut(intersectionObj.x2, intersectionObj.y2, intersectionObj.x1, intersectionObj.y1);
particles.push(p2);
score++;
rubbish(p.x,p.y);
}
}
}
line.state++;
if (line.state > 10)
{
lines.splice(i, 1);
}
cutlayer.graphics.moveTo(line.x1, line.y1);
cutlayer.graphics.lineTo(line.x2, line.y2);
}
info.text = "lost:" + lost + " score:" + score + " time:" + int(time / stage.frameRate);
time++;
if (Math.random() < Math.atan(0.02 + time / 100000))
{
addFruit();
}
}
private function addFruit():void
{
var p:Particle = new Particle;
p.x = stage.stageWidth * (0.3 + 0.4 * Math.random());
p.y = stage.stageHeight;
p.vx = 5 * (Math.random() - .5);
p.vy = -(20 + 20 * Math.random());
p.r = 15 + 25 * Math.random();
p.a = Math.PI * 2 * Math.random();
p.av = 0.1*(Math.random()-0.5);
particles.push(p);
}
private function rubbish(x:Number, y:Number):void {
var c:int = 100 * Math.random();
while(c-->0){
var p:Particle = new Particle;
p.x = x;
p.y = y;
p.r = 10 + 2 * Math.random();
p.a = Math.PI * 2 * Math.random();
p.av = 0.1 * (Math.random() - 0.5);
var s:Number = 10*Math.random();
p.vx = s * Math.cos(p.a);
p.vy = s * Math.sin(p.a);
rubbishs.push(p);
}
}
//http://www.thecodeway.com/blog/?p=1873
private function intersection(x1:Number, y1:Number, x2:Number, y2:Number, x3:Number, y3:Number, r:Number):Object
{
var A:Number = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
var B:Number = 2 * ((x2 - x1) * (x1 - x3) + (y2 - y1) * (y1 - y3));
var C:Number = x3 * x3 + y3 * y3 + x1 * x1 + y1 * y1 - 2 * (x3 * x1 + y3 * y1) - r * r;
var bb_plus_4ac:Number = B * B - 4 * A * C;
if (bb_plus_4ac > 0)
{
var sqrt:Number = Math.sqrt(bb_plus_4ac);
var u1:Number = (-B + sqrt) / 2 / A;
var u2:Number = (-B - sqrt) / 2 / A;
var cutx1:Number = x1 + (x2 - x1) * u1;
var cuty1:Number = y1 + (y2 - y1) * u1;
var cutx2:Number = x1 + (x2 - x1) * u2;
var cuty2:Number = y1 + (y2 - y1) * u2;
var obj:Object = { x1:cutx1, y1:cuty1, x2:cutx2, y2:cuty2 };
if (u1 > 0 && u1 < 1)
{
return obj;
}
if (u2 > 0 && u2 < 1)
{
return obj;
}
}
return null;
}
}
}
import flash.geom.Point;
import flash.display.Graphics;
class Line
{
public var x1:Number;
public var y1:Number;
public var x2:Number;
public var y2:Number;
public var state:int = 0;
public function Line()
{
}
}
class Particle
{
public var x:Number;
public var y:Number;
public var g:Number = 0.5;
public var vx:Number;
public var vy:Number;
public var friction:Number = 0.95;
public var r:Number;
public var color:uint = 0xffffff * Math.random();
public var state:int = 0;
private var a1:Number;
private var a2:Number;
public var av:Number;
public var a:Number = 0;
public function Particle()
{
}
public function update(grap:Graphics):void
{
vx *= friction;
x += vx;
vy += g;
vy *= friction;
y += vy;
a += av;
grap.lineStyle(0);
if (state == 0) {
grap.moveTo(x + r * Math.cos(a), y + r * Math.sin(a));
grap.lineTo(x, y);
grap.drawCircle(x, y, r);
}else {
a1 += av;
a2 += av;
drawArc(grap, x, y, r, (a2 - a1) * 180 / Math.PI, a1 * 180 / Math.PI);
}
}
public function cut(x1:Number, y1:Number, x2:Number, y2:Number):void {
a1 = Math.atan2(y1 - y, x1 - x);
a2 = Math.atan2(y2 - y, x2 - x);
if (x1 > x2) {
vx += 3;
av += 0.05;
}else {
vx -= 3;
av -= 0.05;
}
}
//http://as3-classes.googlecode.com
public function drawArc(grap:Graphics,nX:Number, nY:Number, nRadius:Number, nArc:Number, nStartingAngle:Number = 0):void
{
// The angle of each of the eight segments is 45 degrees (360 divided by eight),
// which equals p/4 radians.
if (nArc < 0) {
nArc += 360;
}
if (nArc > 360)
{
nArc = 360;
}
nArc = Math.PI / 180 * nArc;
var nAngleDelta:Number = nArc / 8;
// Find the distance from the circle's center to the control points
// for the curves.
var nCtrlDist:Number = nRadius / Math.cos(nAngleDelta / 2);
nStartingAngle *= Math.PI / 180;
var nAngle:Number = nStartingAngle;
var nCtrlX:Number;
var nCtrlY:Number;
var nAnchorX:Number;
var nAnchorY:Number;
var nStartingX:Number = nX + Math.cos(nStartingAngle) * nRadius;
var nStartingY:Number = nY + Math.sin(nStartingAngle) * nRadius;
// Move to the starting point, one radius to the right of the circle's center.
grap.moveTo(nStartingX, nStartingY);
// Repeat eight times to create eight segments.
for (var i:Number = 0; i < 8; i++)
{
// Increment the angle by angleDelta (p/4) to create the whole circle (2p).
nAngle += nAngleDelta;
// The control points are derived using sine and cosine.
nCtrlX = nX + Math.cos(nAngle - (nAngleDelta / 2)) * (nCtrlDist);
nCtrlY = nY + Math.sin(nAngle - (nAngleDelta / 2)) * (nCtrlDist);
// The anchor points (end points of the curve) can be found similarly to the
// control points.
nAnchorX = nX + Math.cos(nAngle) * nRadius;
nAnchorY = nY + Math.sin(nAngle) * nRadius;
// Draw the segment.
grap.curveTo(nCtrlX, nCtrlY, nAnchorX, nAnchorY);
}
}
}