Blobland
// forked from AceDecade's Pink Blob
// forked from AceDecade's Dynamic Outline
package{
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.KeyboardEvent;
import flash.ui.Mouse;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.utils.getTimer;
public class FlashTest extends Sprite{
public var Keys:Array = new Array(255);
public var blobs:Number = 15;
public var clouds:Number = 15;
public var trees:Number = 4;
public var pertree:Number = 10;
public var maxx:Number = 25;
public var maxy:Number = 25;
public var maxsize:Number = 15;
public var minsize:Number = 5;
public var maxspeed:Number = 0.5;
public static const DEG_RAD:Number = Math.PI/180;
public var timer:Number = 0;
public var acceleration:Number = 2.5;
public var steps:Number = 60;
public var cloudcolor:uint = 0xcccccc;
public var blobcolor:uint = 0xffcccc;
public var treecolor:uint = 0x99cc99;
public var linewidth:Number = 2;
public var Clouds:Array = new Array();
public var Disps:Array = new Array();
public var fps:TextField = new TextField();
public var blob:Object = new Object();
public function FlashTest(){
blob.x = 225;
blob.y = 325;
blob.vx = 0;
blob.vy = 0;
blob.ax = 0.7;
blob.ay = 0.3;
blob.mx = 5;
blob.my = 5;
addChild(fps);
fps.height = 15;
fps.width = 50;
steps = 360/steps;
stage.addEventListener(Event.ENTER_FRAME,main);
stage.addEventListener(MouseEvent.MOUSE_DOWN,mousedown);
stage.addEventListener(KeyboardEvent.KEY_DOWN,keydown);
stage.addEventListener(KeyboardEvent.KEY_UP,keyup);
init();
}
public function init():void{
blob.Circles = new Array([blob.x,blob.y,20,400,0,0]);
blob.color = blobcolor;
blob.z = blob.y+25;
Disps.push(blob);
for(var i:int=0;i<blobs;i++){
var W:Number = blob.x+range(maxx,-maxx);
var H:Number = blob.y+range(maxy,-maxy);
var S:Number = range(maxsize,minsize);
blob.Circles.push([W,H,S,Math.pow(S,2),0,0]);
}
for(i=0;i<clouds;i++){
W = range(stage.stageWidth-50,50);
H = range(100);
S = range(30,15);
var VX:Number = range(3,1);
Clouds.push([W,H,S,Math.pow(S,2),VX,0]);
}
for(i=0;i<trees;i++){
var t:Object = new Object();
Disps.push(t);
t.x = range(stage.stageWidth);
t.y = range(stage.stageHeight,200);
t.z = t.y;
t.color = treecolor;
t.Circles = new Array([t.x,t.y-65,20,400,0,0]);
for(var j:int=0;j<pertree;j++){
W = t.x+range(25,-25);
H = t.y+range(25,-25)-65;
S = range(15,10);
t.Circles.push([W,H,S,Math.pow(S,2),0,0]);
}
}
}
public function main(e:Event):void{
updateFPS();
if(isKeyDown(65) || isKeyDown(37)){
blob.vx -= blob.ax;
}else if(isKeyDown(68) || isKeyDown(39)){
blob.vx += blob.ax;
}else if(blob.vx > blob.ax){
blob.vx -= blob.ax;
}else if(blob.vx < -blob.ax){
blob.vx += blob.ax;
}else{
blob.vx = 0;
}
if(isKeyDown(87) || isKeyDown(38)){
blob.vy -= blob.ay;
}else if(isKeyDown(83) || isKeyDown(40)){
blob.vy += blob.ay;
}else if(blob.vy > blob.ay){
blob.vy -= blob.ay;
}else if(blob.vy < -blob.ay){
blob.vy += blob.ay;
}else{
blob.vy = 0;
}
if(blob.vx > blob.mx){
blob.vx = blob.mx;
}else if(blob.vx < -blob.mx){
blob.vx = -blob.mx;
}
if(blob.vy > blob.my){
blob.vy = blob.my;
}else if(blob.vy < -blob.my){
blob.vy = -blob.my;
}
if(blob.y < 150){
blob.vy += blob.ay*2;
}
for(var i:int=0;i<Disps.length;i++){
if(Disps[i] != blob){
var tx:Number = blob.x-Disps[i].x;
if((tx ^ (tx >> 31)) - (tx >> 31) < 25){
var ty:Number = blob.z-Disps[i].z;
var tz:Number = ty+blob.vy;
if((tz ^ (tz >> 31)) - (tz >> 31) < 10){
var dy:Number = blob.z-Disps[i].z;
if(dy > 0){
dy -= 11;
}else if(dy < 0){
dy += 11;
}
blob.y -= dy;
for(var j:int=0;j<blob.Circles.length;j++){
blob.Circles[j][1] -= dy;
}
blob.vy = 0;
}
}
}
}
blob.x += blob.vx;
blob.y += blob.vy;
blob.z = blob.y+25;
for(i=0;i<Clouds.length;i++){
var a:Array = Clouds[i];
a[0] += a[4];
a[1] += a[5];
if(a[0]-a[2] > stage.stageWidth){
a[0] = -a[2];
a[1] = range(100);
}
}
render();
for(i=0;i<blob.Circles.length;i++){
a = blob.Circles[i];
a[0] += blob.vx;
a[1] += blob.vy;
if(a[0] > blob.x){
a[4] -= acceleration/a[2];
}else if(a[0] < blob.x){
a[4] += acceleration/a[2];
}
if(a[1] > blob.y){
a[5] -= acceleration/a[2];
}else if(a[1] < blob.y){
a[5] += acceleration/a[2];
}
a[0] += a[4];
a[1] += a[5];
}
}
public function updateFPS():void{
var d:Number = getTimer();
fps.text = Math.round(1000/(d-timer)).toString()+" fps";
timer = d;
}
public function render():void{
drawbg();
drawSet(Clouds,cloudcolor);
Disps.sortOn("z",Array.NUMERIC);
for(var i:int=0;i<Disps.length;i++){
if(Disps[i] == blob){
drawSet(Disps[i].Circles,blobcolor);
drawFace();
}else{
var X:Number = Disps[i].x;
var Y:Number = Disps[i].y-65;
with(graphics){
lineStyle(linewidth,0x000000,1);
beginFill(0xb1937b);
moveTo(X-15/2,Y);
curveTo(X,Y+40,X-10,Y+65);
curveTo(X,Y+63,X+10,Y+65);
curveTo(X,Y+40,X+8,Y+0);
endFill();
}
drawSet(Disps[i].Circles,treecolor);
}
}
}
public function drawFace():void{
with(graphics){
lineStyle(1, 0x000000, 1);
moveTo(blob.x+14.35, blob.y+0.9);
curveTo(blob.x+21, blob.y+5,blob.x-13.63, blob.y+3.53);
beginFill(0x990000);
moveTo(blob.x-27.25/2, blob.y+7.05/2);
curveTo(blob.x-23/2, blob.y+30.75/2, blob.x, blob.y+31.45/2);
curveTo(blob.x+23/2, blob.y+30.75/2, blob.x+25.15/2, blob.y+7.3/2);
endFill();
beginFill(0xff99cc);
moveTo(blob.x+8.3/2, blob.y+29.9/2);
curveTo(blob.x+10/2, blob.y+18.75/2, blob.x-4.75/2, blob.y+18.5/2);
curveTo(blob.x-18.5/2, blob.y+18.5/2, blob.x-18.25/2, blob.y+24.9/2);
curveTo(blob.x-7/2, blob.y+34/2, blob.x+8.3/2, blob.y+29.9/2);
endFill();
moveTo(blob.x-23.95/2, blob.y-3.45/2);
curveTo(blob.x-14.95/2, blob.y-8.15/2, blob.x-3.95/2, blob.y-3.45/2);
beginFill(0xffffff);
moveTo(blob.x+-18.85/2, blob.y-5.8/2);
curveTo(blob.x-27.5/2, blob.y-28.5/2, blob.x-14.65/2, blob.y-29.4/2);
curveTo(blob.x, blob.y-28.5/2, blob.x-10.85/2, blob.y-5.8/2);
endFill();
beginFill(0x000000);
drawEllipse(blob.x-14.95/2, blob.y-25.45/2, 7/2, 14/2);
endFill();
moveTo(blob.x+6.05/2, blob.y-3.45/2);
curveTo(blob.x+15.05/2, blob.y-8.15/2, blob.x+26.05/2, blob.y-3.45/2);
beginFill(0xffffff);
moveTo(blob.x+11.15/2, blob.y-5.8/2);
curveTo(blob.x+2.5/2, blob.y-28.5/2, blob.x+15.35/2, blob.y-29.4/2);
curveTo(blob.x+30/2, blob.y-28.5/2, blob.x+19.15/2, blob.y-5.8/2);
endFill();
beginFill(0x000000);
drawEllipse(blob.x+15.05/2, blob.y-25.45/2, 7/2, 14/2);
endFill();
}
}
public function drawbg():void{
with(graphics){
clear();
lineStyle(0,0x000000,0);
beginFill(0xccccff);
drawRect(0,0,465,150);
endFill();
beginFill(0xccffcc);
drawRect(0,150,465,310);
endFill();
lineStyle(2,0x000000,1);
moveTo(0,150);
lineTo(465,150);
}
}
public function drawSet(A:Array,c:uint):void{
for(var i:int=0;i<A.length;i++){
with(graphics){
lineStyle(0,0x000000,0);
beginFill(c);
drawCircle(A[i][0],A[i][1],A[i][2]);
endFill();
lineStyle(linewidth,0x000000,1);
}
var dx:Number=0;
var dy:Number=0;
var mark:Boolean = false;
for(var j:Number=0;j<=360;j+=steps){
var X:Number = A[i][0]+Math.cos(j*DEG_RAD)*A[i][2];
var Y:Number = A[i][1]+Math.sin(j*DEG_RAD)*A[i][2];
var h:Boolean = false;
for(var k:int=0;k<A.length;k++){
if(i != k){
var d:Number = Math.pow(X-A[k][0],2)+Math.pow(Y-A[k][1],2);
if(d < A[k][3]){
k = A.length;
h = true;
}
}
}
if(!h){
if(mark){
graphics.moveTo(dx,dy);
dx = X;
dy = Y;
graphics.lineTo(dx,dy);
}else{
dx = X;
dy = Y;
mark = true;
}
}else{
mark = false;
}
}
}
}
public function mousedown(e:MouseEvent):void{
//reset();
//render();
}
public function keydown(e:KeyboardEvent):void{
Keys[e.keyCode] = true;
}
public function keyup(e:KeyboardEvent):void{
Keys[e.keyCode] = false;
}
public function isKeyDown(n:Number):Boolean{
return Keys[n];
}
public function reset():void{
graphics.clear();
Clouds = new Array();
Disps = new Array();
init();
}
public function range(M:Number,m:Number=0):Number{
return Math.random()*(M-m)+m;
}
}
}