/**
* Copyright shuetsu ( http://wonderfl.net/user/shuetsu )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/kqS3c
*/
// forked from shuetsu's Survival
package {
import flash.events.Event;
import flash.geom.Point;
import flash.media.Sound;
import flash.display.Sprite;
import com.bit101.components.Slider;
[SWF(width=465, height=465, frameRate=60, backgroundColor=0xeeeeee)]
public class Survival extends Sprite {
public const PLANT_COUNT:int = 300;
public const HERB_COUNT:int = 50;
public const PRED_COUNT:int = 10;
public const PLANT_MAX_COUNT:int = 500;
public const HERB_MAX_COUNT:int = 500;
public const PRED_MAX_COUNT:int = 500;
public var plants:Array = new Array();
public var herbivores:Array = new Array();
public var predators:Array = new Array();
private var plantRate:Slider;
private var herbRate:Slider;
private var predRate:Slider;
public function Survival() {
for (var i:int = 0; i < PLANT_COUNT; i++) {
plants.push(new Plant(
this,
new XY(Math.random() * 465, Math.random() * 465)));
}
for (i = 0; i < HERB_COUNT; i++) {
herbivores.push(new Herbivore(
this,
new XY(Math.random() * 465, Math.random() * 465)));
}
for (i = 0; i < PRED_COUNT; i++) {
predators.push(new Predator(
this,
new XY(Math.random() * 465, Math.random() * 465)));
}
plantRate = new Slider(Slider.HORIZONTAL, this, 2, 0);
herbRate = new Slider(Slider.HORIZONTAL, this, 2, 10);
predRate = new Slider(Slider.HORIZONTAL, this, 2, 20);
plantRate.value = 50;
herbRate.value = 50;
predRate.value = 50;
addEventListener(Event.ENTER_FRAME, onEnter);
}
public function onEnter(e:Event):void {
plants = plants.filter(function(item:*, index:int, array:Array):Boolean {
return item.life();
})
herbivores = herbivores.filter(function(item:*, index:int, array:Array):Boolean {
return item.life(plants);
})
predators = predators.filter(function(item:*, index:int, array:Array):Boolean {
return item.life(herbivores);
})
if (plants.length < PLANT_MAX_COUNT) {
var newPlants:Array = new Array();
for each(var plant:Plant in plants){
var newPlant:Plant = plant.multiply(toRate(plantRate.value));
if (newPlant != null){
newPlants.push(newPlant);
}
}
plants = plants.concat(newPlants);
}
if (herbivores.length < HERB_MAX_COUNT) {
var newHerbivores:Array = new Array();
for each(var herbivore:Herbivore in herbivores){
var newHerbivore:Herbivore = herbivore.multiply(toRate(herbRate.value));
if (newHerbivore != null){
newHerbivores.push(newHerbivore);
}
}
herbivores = herbivores.concat(newHerbivores);
}
if (predators.length < PRED_MAX_COUNT) {
var newPredators:Array = new Array();
for each(var predator:Predator in predators){
var newPredator:Predator = predator.multiply(toRate(predRate.value));
if (newPredator != null){
newPredators.push(newPredator);
}
}
predators = predators.concat(newPredators);
}
for each (herbivore in herbivores) {
herbivore.move();
}
for each (predator in predators) {
predator.move();
}
graphics.clear();
graphics.beginFill(0x00ff00);
graphics.drawRect(105, 0, plants.length * 360 / PLANT_MAX_COUNT, 10);
graphics.endFill();
graphics.beginFill(0x4040ff);
graphics.drawRect(105, 10, herbivores.length * 360 / HERB_MAX_COUNT, 10);
graphics.endFill();
graphics.beginFill(0xff0000);
graphics.drawRect(105, 20, predators.length * 360 / PRED_MAX_COUNT, 10);
graphics.endFill();
}
private function toRate(v:int):Number{
if (v >= 50){
return (150 - v) / 100;
}else{
return (100 - v) / 50;
}
}
}
}
const PRED_LIFE_MIN:int = 500;
const PRED_LIFE_MAX:int = 1000;
const PRED_FILL:int = 200;
const PRED_STARV:int = 100;
const PRED_MULTIPLY_INTERVAL_MIN:int = 200;
const PRED_MULTIPLY_INTERVAL_MAX:int = 400;
const HERB_LIFE_MIN:int = 400;
const HERB_LIFE_MAX:int = 800;
const HERB_FILL:int = 200;
const HERB_STARV:int = 150;
const HERB_MULTIPLY_INTERVAL_MIN:int = 200;
const HERB_MULTIPLY_INTERVAL_MAX:int = 350;
const PLANT_LIFE_MIN:int = 400;
const PLANT_LIFE_MAX:int = 700;
const PLANT_MULTIPLY_INTERVAL_MIN:int = 200;
const PLANT_MULTIPLY_INTERVAL_MAX:int = 400;
import flash.display.Sprite;
import flash.display.Shape;
import flash.display.Graphics;
import flash.filters.BlurFilter;
// xy
class XY {
public var x:Number;
public var y:Number;
public function XY(x:Number, y:Number) {
var _x:Number = x;
var _y:Number = y;
while (_x < 0){
_x += 465;
}
while (_x > 465){
_x -=465;
}
while (_y < 35){
_y += 430;
}
while (_y > 465){
_y -= 430;
}
this.x = _x;
this.y = _y;
}
public function distance(xy:XY):Number {
var dx:Number = x - xy.x;
var dy:Number = y - xy.y;
return Math.sqrt(dx * dx + dy * dy);
}
public function angle(xy:XY):Number {
var dx:Number = x - xy.x;
var dy:Number = y - xy.y;
return Math.atan2(dy, dx);
}
}
class Speed {
public var angle:Number;
public var speed:Number;
public function Speed(angle:Number, speed:Number) {
this.angle = angle;
this.speed = speed;
}
public function move(xy:XY):XY {
return new XY(xy.x + Math.cos(angle) * speed, xy.y + Math.sin(angle) * speed);
}
public static function normarizeAngle(r:Number):Number {
var _r:Number = r;
while (_r > Math.PI) {
_r -= 2 * Math.PI;
}
while (_r < -Math.PI) {
_r += 2 * Math.PI;
}
return _r;
}
}
// 肉食動物
class Predator {
public var multiplyInterval:int;
public var pos:XY;
public var speed:Speed;
public var canvas:Sprite;
public var count:int;
public var countMax:Number;
public var sprite:Sprite = new Sprite();
public var fill:int = 0;
public var target:Herbivore = null;
public var eat:Boolean = false;
public function Predator(canvas:Sprite, pos:XY):void {
this.pos = pos;
this.speed = new Speed(Math.random() * Math.PI * 2, Math.random() * 3 + 2);
this.countMax = countMax;
this.canvas = canvas;
this.count = 0;
this.countMax = Math.random() * (PRED_LIFE_MAX - PRED_LIFE_MIN) + PRED_LIFE_MIN;
this.fill = Math.random() * PRED_FILL;
this.multiplyInterval = Math.random() * (PRED_MULTIPLY_INTERVAL_MAX - PRED_MULTIPLY_INTERVAL_MIN)
+ PRED_MULTIPLY_INTERVAL_MIN;
sprite.graphics.beginFill(0xff0000);
sprite.graphics.lineTo(-5, -5);
sprite.graphics.lineTo(10, 0);
sprite.graphics.lineTo(-5, 5);
sprite.graphics.endFill();
canvas.addChild(sprite);
}
public function life(herbivores:Array):Boolean {
count++;
fill--;
if (target == null && fill <= 0) {
for each (var herbivore:Herbivore in herbivores) {
if (pos.distance(herbivore.pos) < 50) {
target = herbivore;
break;
}
}
}
if (target != null && target.dead){
target = null;
}
if(target != null) {
if(pos.distance(target.pos) <= 10) {
target.remove();
herbivores.splice(herbivores.indexOf(target), 1);
fill = PRED_FILL;
eat = true;
}
}
if (target != null){
if (pos.distance(target.pos) > 400){
target = null;
}
}
if (target != null) {
var r:Number = Speed.normarizeAngle(Speed.normarizeAngle(speed.angle) - pos.angle(target.pos));
if(r > 0.1) {
speed.angle += 0.1;
} else if (r < -0.1) {
speed.angle -= 0.1;
} else {
speed.angle += r;
}
}
pos = speed.move(pos);
if (count >= countMax || fill < -PRED_STARV) {
canvas.removeChild(sprite);
return false;
} else {
return true;
}
}
public function move():void {
if (fill > 0){
sprite.scaleX = 1 + fill / PRED_FILL;
sprite.scaleY = 1 + fill / PRED_FILL;
}else{
sprite.scaleX = 1;
sprite.scaleY = 1;
}
sprite.rotationZ = speed.angle * 180 / Math.PI;
sprite.x = pos.x;
sprite.y = pos.y;
}
public function multiply(rate:Number):Predator {
var t:int = multiplyInterval * rate;
if (fill > 0 && count % t == 0) {
return new Predator(canvas,
new XY(pos.x + (Math.random() * 20 - 10),
pos.y + (Math.random() * 20 - 10)));
} else {
return null;
}
}
}
// 草食動物
class Herbivore {
public var multiplyInterval:int;
public var pos:XY;
public var speed:Speed;
public var canvas:Sprite;
public var count:int;
public var countMax:Number;
public var sprite:Sprite = new Sprite();
public var fill:int = 0;
public var target:Plant = null;
public var eat:Boolean = false;
public var dead:Boolean = false;
public function Herbivore(canvas:Sprite, pos:XY):void {
this.pos = pos;
this.speed = new Speed(Math.random() * Math.PI * 2, Math.random() * 1 + 1);
this.countMax = countMax;
this.canvas = canvas;
this.count = 0;
this.countMax = Math.random() * (HERB_LIFE_MAX - HERB_LIFE_MIN) + HERB_LIFE_MIN;
this.fill = Math.random() * HERB_FILL;
this.multiplyInterval = Math.random() * (HERB_MULTIPLY_INTERVAL_MAX - HERB_MULTIPLY_INTERVAL_MIN)
+ HERB_MULTIPLY_INTERVAL_MIN;
sprite.graphics.beginFill(0x4040ff);
sprite.graphics.drawCircle(0,0,5);
sprite.graphics.endFill();
canvas.addChild(sprite);
}
public function life(plants:Array):Boolean {
count++;
fill--;
if (target == null) {
for each (var plant:Plant in plants) {
if (pos.distance(plant.pos) < 50) {
target = plant;
break;
}
}
}
if (target != null && target.dead){
target = null;
}
if(target != null && fill <= 0) {
if(pos.distance(target.pos) <= 10) {
target.remove();
plants.splice(plants.indexOf(target), 1);
fill = HERB_FILL;
eat = true;
}
}
if (target != null){
if (pos.distance(target.pos) > 400){
target = null;
}
}
if (target != null) {
var r:Number = Speed.normarizeAngle(Speed.normarizeAngle(speed.angle) - pos.angle(target.pos));
if(r > 0.1) {
speed.angle += 0.1;
} else if (r < -0.1) {
speed.angle -= 0.1;
} else {
speed.angle += r;
}
}
pos = speed.move(pos);
if (count >= countMax || fill < -HERB_STARV) {
remove();
return false;
} else {
return true;
}
}
public function move():void {
if (fill > 0){
sprite.scaleX = 1 + fill / HERB_FILL;
sprite.scaleY = 1 + fill / HERB_FILL;
}else{
sprite.scaleX = 1;
sprite.scaleY = 1;
}
sprite.x = pos.x;
sprite.y = pos.y;
}
public function multiply(rate:Number):Herbivore {
var t:int = multiplyInterval * rate;
if (fill > 0 && count % t == 0) {
return new Herbivore(canvas,
new XY(pos.x + (Math.random() * 20 - 10),
pos.y + (Math.random() * 20 - 10)));
} else {
return null;
}
}
public function remove():void{
canvas.removeChild(sprite);
dead = true;
}
}
// 植物
class Plant {
public var multiplyInterval:int;
public var pos:XY;
public var canvas:Sprite;
public var count:int;
public var countMax:Number;
public var dead:Boolean = false;
public var sprite:Sprite = new Sprite();
public function Plant(canvas:Sprite, pos:XY):void {
this.pos = pos;
this.countMax = countMax;
this.canvas = canvas;
this.count = 0;
this.countMax = Math.random() * (PLANT_LIFE_MAX - PLANT_LIFE_MIN) + PLANT_LIFE_MIN;
this.multiplyInterval = Math.random() * (PLANT_MULTIPLY_INTERVAL_MAX - PLANT_MULTIPLY_INTERVAL_MIN)
+ PLANT_MULTIPLY_INTERVAL_MIN;
sprite.graphics.beginFill(0x00ff00);
sprite.graphics.drawRect(pos.x, pos.y, 10, 10);
sprite.graphics.endFill();
sprite.filters = [new BlurFilter()];
canvas.addChild(sprite);
}
public function life():Boolean {
count++;
if (count >= countMax) {
remove();
return false;
} else {
return true;
}
}
public function remove():void{
canvas.removeChild(sprite);
dead = true;
}
public function multiply(rate:Number):Plant {
var t:int = multiplyInterval * rate;
if (count % t == 0) {
return new Plant(canvas,
new XY(pos.x + (Math.random() * 60 - 30),
pos.y + (Math.random() * 60 - 30)));
} else {
return null;
}
}
}