Под иерархией проекта я говорю про содержимое проекта, то какие классы в нем содержатся и какие пакеты есть

Код AS3:
package
{
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import flash.geom.Point;
import game.data.BattleData;
import game.data.BattleDataSpawnPoint;
import game.data.CharacterData;
import game.model.BattleModel;
import game.view.BattleView;
[SWF(frameRate="60", width="800", height="600")]
public class Game extends Sprite
{
private const _model:BattleModel = new BattleModel();
private const _view:BattleView = new BattleView();
public function Game()
{
//init data
var battle_1:BattleData = BattleData.find("battle_1");
battle_1.time = 60 * 30;
battle_1.spawnPoints = new Vector.<BattleDataSpawnPoint>(4, true);
battle_1.spawnPoints[0] = new BattleDataSpawnPoint(new Point(-100, -100), CharacterData.find("character_1"));
battle_1.spawnPoints[1] = new BattleDataSpawnPoint(new Point(100, 150), CharacterData.find("character_2"));
battle_1.spawnPoints[2] = new BattleDataSpawnPoint(new Point(-100, 100), CharacterData.find("character_3"));
battle_1.spawnPoints[3] = new BattleDataSpawnPoint(new Point(180, -100), CharacterData.find("character_4"));
var character_1:CharacterData = CharacterData.find("character_1");
character_1.damage = 3;
character_1.health = 10000;
character_1.speed = 0.4;
character_1.aggroRadius = 260;
character_1.attackRadius = 20;
character_1.color = 0xff0000;
var character_2:CharacterData = CharacterData.find("character_2");
character_2.damage = 2;
character_2.health = 70;
character_2.speed = 0.3;
character_2.aggroRadius = 160;
character_2.attackRadius = 25;
character_2.color = 0x00ff00;
var character_3:CharacterData = CharacterData.find("character_3");
character_3.damage = 3;
character_3.health = 700;
character_3.speed = 0.1;
character_3.aggroRadius = 130;
character_3.attackRadius = 40;
character_3.color = 0x0000ff;
var character_4:CharacterData = CharacterData.find("character_4");
character_4.damage = 4;
character_4.health = 300;
character_4.speed = 0.1;
character_4.aggroRadius = 100;
character_4.attackRadius = 35;
character_4.color = 0xff00ff;
//start battle
_model.start(BattleData.find("battle_1"));
//init view
_view.setup(_model);
addChild(_view);
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(event:Event):void
{
_model.update();
_view.x = stage.stageWidth / 2;
_view.y = stage.stageHeight / 2;
_view.update();
}
}
}
package game.data
{
import flash.utils.Dictionary;
public class BattleData
{
private static const map:Dictionary = new Dictionary();
public static function find(key:String):BattleData
{
return map[key] ||= new BattleData(key);
}
public var key:String;
public var spawnPoints:Vector.<BattleDataSpawnPoint>;
public var time:int;
public function BattleData(key:String)
{
this.key = key;
}
}
}
package game.data
{
import flash.geom.Point;
public class BattleDataSpawnPoint
{
public var point:Point;
public var character:CharacterData;
public function BattleDataSpawnPoint(point:Point, character:CharacterData)
{
this.point = point;
this.character = character;
}
}
}
package game.data
{
import flash.utils.Dictionary;
public class CharacterData
{
private static const map:Dictionary = new Dictionary();
public static function find(key:String):CharacterData
{
return map[key] ||= new CharacterData(key);
}
public var key:String;
public var health:uint;
public var speed:Number;
public var damage:Number;
public var aggroRadius:Number;
public var attackRadius:Number;
public var color:uint;
public function CharacterData(key:String)
{
this.key = key;
}
}
}
package game.model
{
import game.data.BattleData;
import game.data.BattleDataSpawnPoint;
public class BattleModel
{
private var _data:BattleData;
public const characters:Vector.<CharacterModel> = new Vector.<CharacterModel>();
public function BattleModel()
{
}
public function start(data:BattleData):void
{
_data = data;
for each (var point:BattleDataSpawnPoint in data.spawnPoints)
{
characters.push(new CharacterModel(this, point.character, point.point));
}
}
public function finish():void
{
characters.length = 0;
_data = null;
}
public function update():void
{
for each (var character:CharacterModel in characters)
{
character.update();
}
}
public function findEnemy(character:CharacterModel):CharacterModel
{
var distance:Number = Number.MAX_VALUE;
var target:CharacterModel = null;
for each (var testCharacter:CharacterModel in characters)
{
if(testCharacter == character || testCharacter.health == 0) continue;
var deltaX:Number = character.x - testCharacter.x;
var deltaY:Number = character.y - testCharacter.y;
var testDistance:Number = deltaX * deltaX + deltaY * deltaY;
if(testDistance < distance)
{
distance = testDistance;
target = testCharacter;
}
}
return target;
}
}
}
package game.model
{
import flash.geom.Point;
import game.data.CharacterData;
public class CharacterModel
{
private var _battle:BattleModel;
private var _data:CharacterData;
private var _health:uint;
private var _speed:Number;
private var _damage:uint;
private var _x:Number;
private var _y:Number;
private var _rotation:Number;
public function get data():CharacterData
{
return _data;
}
public function get health():uint
{
return _health;
}
public function get x():Number
{
return _x;
}
public function get y():Number
{
return _y;
}
public function get rotation():Number
{
return _rotation;
}
public function CharacterModel(battle:BattleModel, data:CharacterData, position:Point)
{
_battle = battle;
_data = data;
_health = data.health;
_speed = data.speed;
_damage = data.damage;
_x = position.x;
_y = position.y;
_rotation = 0;
}
public function update():void
{
if(_health == 0) return;
var enemy:CharacterModel = _battle.findEnemy(this);
if(enemy == null) return;
var deltaX:Number = enemy.x - x;
var deltaY:Number = enemy.y - y;
var distance:Number = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
if(distance < _data.aggroRadius)
{
_rotation = Math.atan2(deltaY, deltaX);
if(distance < _data.attackRadius)
{
enemy.hit(_damage);
}
else
{
deltaX /= distance;
deltaY /= distance;
_x += deltaX;
_y += deltaY;
}
}
}
public function hit(damage:uint):void
{
if(_health <= damage)
{
_health = 0;
}
else
{
_health -= damage;
}
}
}
}
package game.view
{
import flash.display.Sprite;
import game.model.BattleModel;
import game.model.CharacterModel;
public class BattleView extends Sprite
{
private var _model:BattleModel;
private const _characters:Vector.<CharacterView> = new Vector.<CharacterView>();
public function BattleView()
{
}
public function setup(model:BattleModel):void
{
_model = model;
for each (var characterModel:CharacterModel in model.characters)
{
var characterView:CharacterView = new CharacterView(characterModel);
_characters.push(characterView);
addChild(characterView);
}
}
public function update():void
{
for each (var characterView:CharacterView in _characters)
{
characterView.update();
}
}
}
}
package game.view
{
import flash.display.Sprite;
import game.model.CharacterModel;
public class CharacterView extends Sprite
{
private var _model:CharacterModel;
public function CharacterView(model:CharacterModel)
{
_model = model;
}
public function update():void
{
if(_model.health == 0)
{
visible = false;
return;
}
graphics.clear();
graphics.beginFill(_model.data.color, _model.health / _model.data.health);
graphics.drawCircle(0, 0, 8);
graphics.endFill();
graphics.lineStyle(1, _model.data.color, _model.health / _model.data.health);
graphics.drawCircle(0, 0, _model.data.aggroRadius);
graphics.lineStyle(2, _model.data.color, _model.health / _model.data.health);
graphics.drawCircle(0, 0, _model.data.attackRadius);
graphics.moveTo(0, 0);
graphics.lineTo(_model.data.attackRadius, 0);
x = _model.x;
y = _model.y;
rotation = _model.rotation * 180 / Math.PI;
}
}
}