In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

食物連鎖シミュレーション

肉食動物、草食動物、植物、植物の種子による食物連鎖シミュレーション
ルール
・肉食動物は、草食動物を捕食する。
・草食動物は、植物を捕食する。
・植物は、捕食されると消滅する。
・肉食動物と草食動物は、時間と共にライフが減少する。
・肉食動物は、ライフが0になると植物の種子となる。
・草食動物は、ライフが0、または捕食されると植物の種子となる。
・植物の種子は、一定時間後、植物となる。
・肉食動物と草食動物は、残りライフが少なくなると空腹になる。
・肉食動物は、ランダムに動き回るが、空腹時は視界に入った草食動物へ向かう。
・草食動物は、ランダムに動き回るが、肉食動物が視界に入ると逃げる。しかし、空腹時は視界に入った植物へ向かう。
・肉食動物と草食動物は、空腹時は移動速度が速くなる。しかし、その分ライフも消耗する。また、その時視界に捕食対象がいない時は、ランダムに動き回り対象を探す。
・肉食動物と草食動物は、捕食後、一定時間再捕食しない。
・肉食動物と草食動物は、一定数捕食を行うと、交尾を行い繁殖する。

視線
・白線は、捕食対象への視線を表す。
・桃線は、交尾対象への視線を表す。
・点線は、草食動物が肉食動物から逃げているのを表す。

個体数やルール作り等、色々問題あるかと思うんですが、上手い事ループしてくれないかと。
あと重いです。すいません。
Get Adobe Flash player
by h6k 15 May 2010
/**
 * Copyright h6k ( http://wonderfl.net/user/h6k )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/fmLI
 */

package {
    import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Rectangle;
	import flash.geom.Point;
	import flash.text.TextField;
	import flash.text.TextFieldType;
	import flash.text.TextFieldAutoSize;
	import flash.utils.getTimer;
	
		/**
		 * 肉食動物、草食動物、植物、植物の種子による食物連鎖シミュレーション
		 * ルール
		 * ・肉食動物は、草食動物を捕食する。
		 * ・草食動物は、植物を捕食する。
		 * ・植物は、捕食されると消滅する。
		 * ・肉食動物と草食動物は、時間と共にライフが減少する。
		 * ・肉食動物は、ライフが0になると植物の種子となる。
		 * ・草食動物は、ライフが0、または捕食されると植物の種子となる。
		 * ・植物の種子は、一定時間後、植物となる。
		 * ・肉食動物と草食動物は、残りライフが少なくなると空腹になる。
		 * ・肉食動物は、ランダムに動き回るが、空腹時は視界に入った草食動物へ向かう。
		 * ・草食動物は、ランダムに動き回るが、肉食動物が視界に入ると逃げる。しかし、空腹時は視界に入った植物へ向かう。
		 * ・肉食動物と草食動物は、空腹時は移動速度が速くなる。しかし、その分ライフも消耗する。また、その時視界に捕食対象がいない時は、ランダムに動き回り対象を探す。
		 * ・肉食動物と草食動物は、捕食後、一定時間再捕食しない。
		 * ・肉食動物と草食動物は、一定数捕食を行うと、交尾を行い繁殖する。
		 * 
		 * 視線
		 * ・白線は、捕食対象への視線を表す。
		 * ・桃線は、交尾対象への視線を表す。
		 * ・点線は、草食動物が肉食動物から逃げているのを表す。
		 * 
		 * 個体数やルール作り等、色々問題あるかと思うんですが、上手い事ループしてくれないかと。
		 * あと重いです。すいません。
		 */
		 
    public class FlashTest extends Sprite {
		private const _sz:int = 16;							// サイズ
		private const _c:int = _sz / 2;						// 中心
		private const _range:int = Math.pow(_sz * 5, 2);		// 視野
		private const _sw:int = stage.stageWidth;				// ステージサイズ
		private const _sh:int = stage.stageHeight - 100;
		private const _d:int = _sw * _sh;						// 検索用
		private const _sz2:int = _sz * _sz;
		private const _rec:int = 300;						// 回復量
		private const _sWait:int = 100;						// 植物になるまでのウェイト
		private const _eWait:int = 100;						// 再捕食までのウェイト
		
		private const _gmax:int = stage.stageHeight - _sh - 41;	// グラフMAX
		private const _gmin:int = stage.stageHeight - 21;			// グラフMIN
		
		// 0:ランダム, 1:捕食対象へ向かう, 2:逃げる, 3:交尾対象へ向かう
		private const _RANDOM:int = 0, _EAT:int = 1, _RUNAWAY:int = 2, _BIRTH:int = 3;
		
		private var _bmd:BitmapData = new BitmapData(stage.stageWidth, stage.stageHeight, false, 0);
		private var _bg:Rectangle = new Rectangle(0, 0, _sw, stage.stageHeight);
		private var _status:Rectangle = new Rectangle(10, _sh + 10, _sw - 20, stage.stageHeight - _sh - 20);
		
		private var _ani:Array;
		private var _circle:Array;
		private var _startNum:Array;
		private var _graph:Array;
		private var _aniNum:Array;
		
		private var _tfld:TextField;
		private var _frame:uint;
		private var _bframe:uint;
		private var _fps:int;
		private var _sec:uint;
		
        public function FlashTest() {
            // write as3 code here..
			// ステージ作成
			_bmd.fillRect(_status, 0x333333);
			stage.addChild(new Bitmap(_bmd));
			
			// ステータス
			var i:int;
			var nfld:Array = new Array(3);
			_startNum = new Array(3);
			for (i = 0; i < 3; i++) {
				nfld[i] = new TextField();
				nfld[i].mouseEnabled = false;
				nfld[i].textColor = 0xFFFFFF;
				nfld[i].x = 20;
				nfld[i].y = i * 20 + _sh + 20;
				stage.addChild(nfld[i]);
				
				_startNum[i] = new TextField();
				_startNum[i].type = TextFieldType.INPUT;
				_startNum[i].border = true;
				_startNum[i].borderColor = 0xFFFFFF;
				_startNum[i].x = 60;
				_startNum[i].y = i * 20 + _sh + 20;
				_startNum[i].width = 50;
				_startNum[i].height = 20;
				_startNum[i].textColor = 0xFFFFFF;
				stage.addChild(_startNum[i]);
			}
			nfld[0].text = "肉食";
			nfld[1].text = "植物";
			nfld[2].text = "草食";
			// 初期個体数設定
			_startNum[0].text = 10;	// 肉食
			_startNum[1].text = 200;	// 植物
			_startNum[2].text = 50;	// 草食
			
			// 開始ボタン
			var bfld:TextField = new TextField();
			bfld.textColor = 0xFFFFFF;
			bfld.border = true;
			bfld.borderColor = 0xFFFFFF;
			bfld.mouseEnabled = false;
			bfld.autoSize = TextFieldAutoSize.LEFT;
			bfld.text = "開始";
			var btn:Sprite = new Sprite();
			btn.x = 120;
			btn.y = _sh + 60;
			btn.mouseEnabled = true;
			btn.buttonMode = true;
			btn.addChild(bfld);
			btn.addEventListener(MouseEvent.CLICK, onStart);
			stage.addChild(btn);
			
			// 個体数表示用
			_tfld = new TextField();
			_tfld.width = 110;
			_tfld.height = stage.stageHeight - _sh - 20;
			_tfld.x = _sw - _tfld.width - 10;
			_tfld.y = _sh + 10;
			_tfld.textColor = 0xFFFFFF;
			_tfld.mouseEnabled = false;
			stage.addChild(_tfld);
			
			// 固体を円で表す
			var sp:Sprite;
			var col:uint;
			_circle = new Array(6);
			for (i = 0; i < _circle.length; i++) {
				sp = new Sprite();
				switch(i) {
					case 0:
						// 肉食
						col = 0xFF0000;
						break;
					case 1:
						// 植物
						col = 0x00FF00;
						break;
					case 2:
						// 草食
						col = 0x0000FF;
						break;
					case 3:
						// 肉食空腹
						col = 0xFF6666;
						break;
					case 4:
						// 草食空腹
						col = 0x6666FF;
						break;
					case 5:
						// 種子
						col = 0x999999;
						break;
				}
				sp.graphics.beginFill(col, 1);
				if (i != 5) {
					sp.graphics.drawCircle(_c, _c, _c);
				} else {
					sp.graphics.drawCircle(_c, _c, _c / 4);
				}
				sp.graphics.endFill();
				_circle[i] = new BitmapData(_sz, _sz, true, 0x000000);	// 背景透過
				_circle[i].draw(sp);
			}
        }
        
        // 開始ボタンを押した
		private function onStart(e:MouseEvent):void {
			// 初期化
			_frame = _bframe = _fps = 0;
			_sec = getTimer();
			_ani = new Array();
			
			// グラフ用
			var i:int;
			_graph = new Array(150);
			for (i = 0; i < _graph.length; i++) {
				_graph[i] = [-1000, -1000, -1000, -1000];
			}
			
			_aniNum = new Array(4);
			// 種子
			_aniNum[3] = 0;
			// 植物
			_aniNum[1] = (int)(_startNum[1].text);
			for (i = 0; i < _aniNum[1]; i++) {
				_ani[i] = new Animal(Math.random() * (_sw - _sz), Math.random() * (_sh - _sz), 0x00FF00, 1, 0);
			}
			// 草食
			_aniNum[2] = _ani.length + (int)(_startNum[2].text);
			for (i = _ani.length; i < _aniNum[2]; i++) {
				_ani[i] = new Animal(Math.random() * (_sw - _sz), Math.random() * (_sh - _sz), 0x0000FF, 500, 3);
			}
			// 肉食
			_aniNum[0] = _ani.length + (int)(_startNum[0].text);
			for (i = _ani.length; i < _aniNum[0]; i++) {
				_ani[i] = new Animal(Math.random() * (_sw - _sz), Math.random() * (_sh - _sz), 0xFF0000, 500, 3);
			}
			
			stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
		}
		
		// メインループ
		private function onEnterFrame(e:Event):void {
			_bmd.lock();
			_bmd.fillRect(_bg, 0x000000);
			
			var tar:Object;
			var i:int, j:int, cid:int;
			var k:int, d:int, distance:int;			// 距離計測用
			var len:int = _ani.length;				// 種子~肉食の数
			var nNo:int = len - _aniNum[0];			// 最初の肉食の要素番号
			var sNo:int = _aniNum[3] + _aniNum[1];	// 最初の草食の要素番号
			for (i = 0; i < len; i++) {
				tar = _ani[i];
				if (tar.life > 0) {
					d = _d;
					k = 0;
					switch(tar.col) {
						case 0xFF0000:
							// 寿命
							/*
							if (++tar.years % 2000 == 0) {
								tar.life = 0;
								tar.eat = 0;
							}
							*/
							// 描画
							if (tar.life > tar.hungry) { cid = 0; } else { cid = 3; }
							_bmd.copyPixels(_circle[cid], _circle[cid].rect, new Point(tar.x, tar.y));
							
							// 当たり判定(草食~肉食)
							for (j = sNo; j < len; j++) {
								if (_ani[j].life > 0) {
									// 相手も生きてる
									distance = Math.pow(_ani[j].x - tar.x, 2) + Math.pow(_ani[j].y - tar.y, 2);
									if (distance < _sz2) {
										// 当たっている
										switch(_ani[j].col) {
											case 0x0000FF:
												// 肉食→草食
												if (_frame - tar.eFrame > _eWait) {
													// 前回食べた時から指定フレーム数が経過
													tar.eat++;
													tar.eFrame = _frame;
													tar.life += _rec;
													if (tar.life > tar.max) { tar.life = tar.max; }
													// 種子になる
													changeSeed(_ani[j]);
												}
												break;
											case 0xFF0000:
												// 肉食→肉食
												if (tar.eat >= tar.ready && _ani[j].eat >= _ani[j].ready && j != i) {
													// お互い交配準備ができてる
													tar.eat = 0;
													_ani[j].eat = 0;
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													//_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
												}
												break;
										}
									}
									
									// 一番近いのを検索
									if((tar.type == _EAT && _ani[j].col == 0x0000FF) || (tar.type == _BIRTH && _ani[j].col == 0xFF0000 && _ani[j].eat >= _ani[j].ready && j != i)) {
										if (distance < d) {
											d = distance;
											k = j;
										}
									}
								}
							}
							
							// ある程度近い時だけ方向変更(_RANDOMの時はスルー)
							if (d < _range) {
								changeDirection(tar, k);
								drawView(tar, k);
							}
							// 移動
							move(tar);
							break;
						case 0x00FF00:
							// 描画
							_bmd.copyPixels(_circle[1], _circle[1].rect, new Point(tar.x, tar.y));
							break;
						case 0x0000FF:
							// 寿命
							/*
							if (++tar.years % 2000 == 0) {
								tar.life = 0;
								tar.eat = 0;
							}
							*/
							// 描画
							if (tar.life > tar.hungry) { cid = 2; } else { cid = 4; }
							_bmd.copyPixels(_circle[cid], _circle[cid].rect, new Point(tar.x, tar.y));
							
							// 当たり判定
							for (j = _aniNum[3]; j < len; j++) {
								if (_ani[j].life > 0) {
									// 相手も生きてる
									distance = Math.pow(_ani[j].x - tar.x, 2) + Math.pow(_ani[j].y - tar.y, 2);
									if (distance < _sz2 && j < nNo) {
										// 当たっている(肉食との判定は除く)
										switch(_ani[j].col) {
											case 0x00FF00:
												// 草食→植物
												if (_frame - tar.eFrame > _eWait) {
													// 前回食べた時から指定フレーム数が経過
													tar.eat++;
													tar.eFrame = _frame;
													tar.life += _rec;
													if (tar.life > tar.max) { tar.life = tar.max; }
													// 消去
													_ani[j].life = -100;
												}
												break;
											case 0x0000FF:
											// 草食→草食
												if (tar.eat >= tar.ready && _ani[j].eat >= tar.ready && j != i) {
													tar.eat = 0;
													_ani[j].eat = 0;
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
													_ani[_ani.length] = new Animal(tar.x, tar.y, tar.col, 500, 3);
												}
												break;
										}
									}
									
									// 自分以外で一番近いのを検索
									if ((tar.type == _RANDOM && _ani[j].col == 0xFF0000) || (tar.type == _EAT && _ani[j].col == 0x00FF00) || (tar.type == _BIRTH && _ani[j].col == 0x0000FF && _ani[j].eat >= _ani[j].ready && j != i)) {
										if (distance < d) {
											d = distance;
											k = j;
										}
									}
								}
							}
							
							// ある程度近い時だけ方向変更
							if (d < _range) {
								if (_ani[k].col == 0xFF0000) { tar.type = _RUNAWAY; }
								changeDirection(tar, k);
								drawView(tar, k);
							}
							// 移動
							move(tar);
							break;
					}
				} else if (tar.col != 0x000000) {
					// life無し
					changeSeed(tar);
				} else if (tar.life == 0) {
					// tar.col = 0x000000
					_bmd.copyPixels(_circle[5], _circle[5].rect, new Point(tar.x, tar.y));
					if (tar.wait < _sWait) { tar.wait++; } else {
						// 指定フレーム経過後、植物になる
						tar.life = 1;
						tar.col = 0x00FF00;
					}
				}
			}
			
			// 配列再生成
			var tmp:Array = [];
			// 描画順にソート
			tmp = tmp.concat(zSort(0));
			_aniNum[3] = tmp.length;
			tmp = tmp.concat(zSort(0x00FF00));
			_aniNum[1] = tmp.length - _aniNum[3];
			tmp = tmp.concat(zSort(0x0000FF));
			_aniNum[2] = tmp.length - _aniNum[3] - _aniNum[1];
			tmp = tmp.concat(zSort(0xFF0000));
			_aniNum[0] = tmp.length - _aniNum[3] - _aniNum[1] - _aniNum[2];
			_ani = tmp;
			/*
			for (i = 0; i < _ani.length; i++) {
				if (_ani[i].life > -10) { tmp.push(_ani[i]); }
			}
			_ani = tmp;
			*/
			
			// グラフデータをシフト
			_graph.shift();
			_graph.push([_aniNum[0], _aniNum[1], _aniNum[2], _aniNum[3]]);
			
			// 過去も含めた最大値を取得
			var max:int = -1;
			var tmax:int;
			len = _graph.length;
			for (i = 0; i < len; i++) {
				tmax = Math.max(_graph[i][0], _graph[i][1], _graph[i][2], _graph[i][3]);
				if (max < tmax) { max = tmax; }
			}
			
			// 最大値に合わせて描画
			_bmd.fillRect(_status, 0x333333);
			var x:int, y:int;
			for (i = 0; i < len; i++) {
				x = i + 170;
				y = _gmin - (_gmax * _graph[i][0] / max);
				_bmd.setPixel(x, y, 0xFF0000);
				
				y = _gmin - (_gmax * _graph[i][1] / max);
				_bmd.setPixel(x, y, 0x00FF00);
				
				y = _gmin - (_gmax * _graph[i][2] / max);
				_bmd.setPixel(x, y, 0x0000FF);
				
				y = _gmin - (_gmax * _graph[i][3] / max);
				_bmd.setPixel(x, y, 0x999999);
			}
			_bmd.unlock();
			
			// ステータス
			_frame++;
			var t:uint = getTimer();
			if (t - _sec >= 1000) {
				_fps = Math.round((_frame - _bframe) * 1000 / (t - _sec));
				_bframe = _frame;
				_sec = t;
			}
			_tfld.text = "肉食(赤):" + _aniNum[0] + "\n植物(緑):" + _aniNum[1] + "\n種子(灰):" + _aniNum[3] + "\n草食(青):" + _aniNum[2] + "\nFPS:" + _fps + " / " + stage.frameRate;
		}
		
		// 描画順にソート
		private function zSort(col:uint):Array {
			var tmp:Array = [];
			var tmp2:Array = [];
			var len:int = _ani.length;
			for (var i:int = 0; i < len; i++) {
				if (_ani[i].life != -100) {
					if (_ani[i].col == col) { tmp.push(_ani[i]); } else { tmp2.push(_ani[i]);  }
				}
			}
			_ani = tmp2;
			return tmp;
		}
		
		// 種子に変わる
		private function changeSeed(tar:Object):void {
			// 上下左右斜めにランダムで増やす
			if (tar.eat > 0) {
				// 左
				if(tar.x - _sz > _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x - _sz, tar.y, 0, 0, 0);
				}
				// 右
				if(tar.x + _sz < _sw - _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x + _sz, tar.y, 0, 0, 0);
				}
				// 上
				if (tar.y - _sz > _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x, tar.y - _sz, 0, 0, 0);
				}
				// 下
				if (tar.y + _sz < _sh - _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x, tar.y + _sz, 0, 0, 0);
				}
				/*
				// 左上
				if(tar.x - _sz > _sz && tar.y - _sz > _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x - _sz, tar.y - _sz, 0, 0, 0);
				}
				// 右上
				if(tar.x + _sz < _sw - _sz&& tar.y - _sz > _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x + _sz, tar.y - _sz, 0, 0, 0);
				}
				// 左下
				if (tar.x - _sz > _sz && tar.y + _sz < _sh - _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x - _sz, tar.y + _sz, 0, 0, 0);
				}
				// 右下
				if (tar.x + _sz < _sw - _sz && tar.y + _sz < _sh - _sz && Math.random() * 2 > 1) {
					_ani[_ani.length] = new Animal(tar.x + _sz, tar.y + _sz, 0, 0, 0);
				}
				*/
			}
			
			tar.life = 0
			tar.col = 0x000000;
			tar.wait = 0;
		}
		
		// 方向変換
		private function changeDirection(tar:Object, k:int):void {
			var diffx:int = tar.x - _ani[k].x;
			var diffy:int = tar.y - _ani[k].y;
			
			if (diffx < 0 && diffy < 0) {
				// 対象が右下
				if (Math.abs(diffx) > Math.abs(diffy)) {
					// x幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 1;
							break;
						case _RUNAWAY:
							tar.direction = 3;
							break;
					}
				} else {
					// y幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 2;
							break;
						case _RUNAWAY:
							tar.direction = 0;
							break;
					}
				}
			} else if (diffx > 0 && diffy < 0) {
				// 対象が左下
				if (Math.abs(diffx) > Math.abs(diffy)) {
					// x幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 3;
							break;
						case _RUNAWAY:
							tar.direction = 1;
							break;
					}
				} else {
					// y幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 2;
							break;
						case _RUNAWAY:
							tar.direction = 0;
							break;
					}
				}
			} else if (diffx < 0 && diffy > 0) {
				// 対象が右上
				if (Math.abs(diffx) > Math.abs(diffy)) {
					// x幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 1;
							break;
						case _RUNAWAY:
							tar.direction = 3;
							break;
					}
				} else {
					// y幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 0;
							break;
						case _RUNAWAY:
							tar.direction = 2;
							break;
					}
				}
			} else if(diffx > 0 && diffy > 0) {
				// 対象が左上
				if (Math.abs(diffx) > Math.abs(diffy)) {
					// x幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 3;
							break;
						case _RUNAWAY:
							tar.direction = 1;
							break;
					}
				} else {
					// y幅が大きい
					switch(tar.type) {
						case _EAT:
						case _BIRTH:
							tar.direction = 0;
							break;
						case _RUNAWAY:
							tar.direction = 2;
							break;
					}
				}
			}
		}
		
		// 視線描画
		private function drawView(tar:Object, k:int):void {
			switch(tar.type) {
				case _EAT:
					// ロックオン
					drawDottedLine(tar.x + _c, tar.y + _c, _ani[k].x + _c, _ani[k].y + _c, 0xFFFFFF, 1);
					break;
				case _RUNAWAY:
					// 逃げる
					drawDottedLine(tar.x + _c, tar.y + _c, _ani[k].x + _c, _ani[k].y + _c, 0xFFFF00, 4);
					break;
				case _BIRTH:
					// 交尾
					drawDottedLine(tar.x + _c, tar.y + _c, _ani[k].x + _c, _ani[k].y + _c, 0xFF00FF, 1);
					break;
			}
		}
		
		private function drawDottedLine(fromx:int, fromy:int, tox:int, toy:int, col:uint, interval:int):void {
			// y = ax + b
			var a:Number = (toy - fromy) / (tox - fromx);	// 傾き
			var b:Number = fromy - (fromx * a);			// 切片
			var x:int;
			var y:int;
			if (Math.abs(tox - fromx) > Math.abs(toy - fromy)) {
				// X幅が大きい
				if(fromx < tox) {
					for (x = fromx; x < tox; x += interval) {
						_bmd.setPixel(x, a * x + b, col);
					}
				} else {
					for (x = tox; x < fromx; x += interval) {
						_bmd.setPixel(x, a * x + b, col);
					}
				}
			} else {
				// Y幅が大きい
				if (fromy < toy) {
					for (y = fromy; y < toy; y += interval) {
						_bmd.setPixel((y - b) / a, y, col);
					}
				} else {
					for (y = toy; y < fromy; y += interval) {
						_bmd.setPixel((y - b) / a, y, col);
					}
				}
			}
		}
		
		// 移動
		private function move(tar:Object):void {
			// 方向と繰り返し回数を決定
			if (--tar.repeat < 0) {
				tar.direction = Math.random() * 5;
				tar.repeat = Math.random() * 100;
			}
			
			if (tar.life < tar.hungry) {
				// 空腹時はスピードアップ
				tar.dx = tar.dy = 2;
				tar.life -= 2;
				tar.type = _EAT;
				// 強制的に動かす
				if (tar.direction == 4) { tar.direction = Math.random() * 4; }
			} else {
				// 普段
				tar.dx = tar.dy = 1;
				tar.life--;
				if (tar.eat >= tar.ready) { tar.type = _BIRTH; } else { tar.type = _RANDOM; }
			}
			
			switch(tar.direction) {
				case 0:
					// 上
					if (tar.y > tar.dy) { tar.y -= tar.dy; }
					break;
				case 1:
					// 右
					if (tar.x < _sw - _sz) { tar.x += tar.dx; }
					break;
				case 2:
					// 下
					if(tar.y < _sh - _sz) { tar.y += tar.dy; }
					break;
				case 3:
					// 左
					if (tar.x > tar.dx) { tar.x -= tar.dx; }
					break;
			}
		}
    }
}

class Animal
{
	public var x:int, y:int, col:uint, life:int, max:int, hungry:int, ready:int;
	public var direction:int, repeat:int, eat:int, eFrame:uint, years:uint;
	public var type:int, dx:int, dy:int, wait:int;
	public function Animal(x:int, y:int, col:uint, life:int, ready:int):void {
		this.x = x;				// 座標
		this.y = y;
		this.col = col;			// 色
		this.life = life;		// ライフ
		this.max = life;			// MAX
		this.hungry = life / 3;	// 空腹
		this.ready = ready;		// 交尾までの捕食数
		this.direction = 0;		// 方向
		this.repeat = 0;			// 移動の繰り返し回数
		this.eat = 0;			// 捕食数
		this.eFrame = 0;			// 捕食時のフレーム
		this.years = 0;			// 寿命
	}
}