forked from: Wonderfl Tower Defense
TDが好きです。初心者なので牛歩で進みますが、o8queさんのTDコードをありがたくいじらせてもらいますッ
【現状】 敵メイキング
o8queさんのおかげでいろいろ解決。大変、勉強になりました。んで、敵は一通り作り終えた感じ。後半の敵がほぼ初見殺しな出方をするが、テストなので。
【次回】 ステージセレクト挑戦
スキルとか足そうと思ったら、先に全体に手を加えたほうが良さそうなので、暫定のセレクト画面づくりに挑戦。なかなか難しそうだ。
※「ワード上でコードいじって、ワンダフルで実行してみる」を繰り返してます。チェックしてるときは頻繁に更新されるので、動かなくなったり画面が崩れたりします。ご容赦ください。
/**
* Copyright beginners_high ( http://wonderfl.net/user/beginners_high )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/1sKW
*/
//forked from o8que's Wonderfl Tower Defense
//初ワンダフルで大好きなタワーディフェンスゲーム!をフォーク
//フォーク元とだいぶ内容が違ってきたので、o8que氏の説明書きを変更させてもらいました(2010.10.6)
/* ------------------------------------------------------
* The Gate TD
* ~forked from o8que's [Wonderfl Tower Defense] ~
* ------------------------------------------------------
* [タワーの特徴]
* Gun : 安価で地対空両用。レベル5で最大級の射程。
* Gatling : 連射が速く地対空両用。安定したダメージ源になる。
* Cannon : 範囲攻撃で高威力。空中に攻撃できない。
* Venom : 対地。毒の威力は移動速度に比例。毒状態の敵が死ぬと周囲に感染。
* Voltex : 射程内全体へスロウ効果。地対空両用で威力も高めだが高価。
* AntiFly : 高威力の対空専用。現行は貫通弾。<修正予定>
* Base : 土台。タワーを置けない土地にはまず土台を。設置後は売却不能。
*
* [敵の特徴]
* << Feeble >>
* Normal : 特にこれといった特徴はない。
* Swarm : 体力はかなり低いザコだが、大量に出現する。
* Fast : 移動が速い。油断すると一気に攻め込まれるぞ。
* Flying : 飛行型。地形を無視するのでタワー配置に注意。
* << Tough >>
* Immune : ノロマだが体力が高い。スロウと毒を無効化。
* Zombie : 常に傷を再生しながら侵攻してくる。火力で対抗せよ。
* Fupa : 破壊すると羽化して飛行タイプに変化。
* Detour : 飛行型。左右に迂回するので侵攻経路がやっかい。
* << Scary >>
* Shell : 通称3段ロケット。体力が減ると脱皮し、毒やスロウを破棄する。
* Split : 破壊すると移動の速いザコ4体に分裂する。
* Fade : 透明化してタワーの攻撃から逃れる。透明中も範囲攻撃は当たる。
* Decoyer : 飛行型。オトリ弾を発射し、攻撃を拡散させてくるぞ。
* << Insane >>
* Fury : 砲撃や毒でダメージを受けるたびに加速。最大速度はヤバイ。
* Wall : 体力が特大。毒とスロウ無効、わずかに再生能力もある。
* Ghost : 透明化する飛行型。移動は遅めだが危険な敵。
* Random : (未作成)
*
*
* [スキル](予定)
* 敵メイキングが落ち着いたら着手。
* 時間でチャージされ発動可能になるスキルを12種から3つまで装備。
* チャージをオフにするとほかのスキル回復が早まる。
*
* [ゲート](予定)
* スキルの仕組みの目処が立ったら着手。ずいぶん先になりそう。
* ゲートに接触した敵は能力がUP、獲得できる得点とお金もUP。
*
* ------------------------------------------------------
* [HotKey]
* 1-7 : select a tower to place
* 7 : select a base to build
* 0,ESC : cancel a selection
* U : upgrade the selected tower
* S : sell the selected tower
* M : show menu window
* N : send the next wave
* ------------------------------------------------------
* [今後の予定]
* ・アップグレードタイム(1~2秒)の導入
* ・スキル能力の準備と実装(勉強するがすごく大変そう)
* ・ゲートシステムの準備と実装(たぶん簡単)
* ・そのうちステージセレクトで5ステージつくりたい(勉強する)
* ・最後にゴールを自分で配置する仕組み
* ・バランス調整
*
*
*
*
*/
/* ---------------------------------------------------------------------------------------------------------
* Main
* ---------------------------------------------------------------------------------------------------------
*/
package {
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.utils.Dictionary;
public class Main extends Sprite {
// 各状態を表す定数
public static const STATE_READY:int = 0;
public static const STATE_PLAYING:int = 1;
public static const STATE_MENU:int = 2;
public static const STATE_GAMEOVER:int = 3;
private var _states:Vector.<IState>; // 状態のコレクション
private var _currentState:IState; // 現在の状態の参照
private var _previousState:IState; // 一つ前の状態の参照
private var _world:World; // フィールド・タワー・敵等を表示する画面
private var _frontend:Frontend; // ステータス・メニュー等を表示するウインドウ
private var _waveManager:WaveManager; // Waveを管理・表示するウインドウ
private var _nextWaveButtonHandler:Function;
public function get world():World { return _world; }
public function get waveManager():WaveManager { return _waveManager; }
public function Main() {
graphics.beginFill(0x000000);
graphics.drawRect(0, 0, 465, 465);
graphics.endFill();
// 外部アセットを読み込んだ後に初期化を開始する
var imagePaths:Dictionary = ImageFactory.getExternalImagePaths();
var imageHolder:Dictionary = ImageFactory.load();
var preloader:Preloader = new Preloader(this, imagePaths, imageHolder);
preloader.addEventListener(Event.COMPLETE, initialize);
}
// 全体の初期化
private function initialize(e:Event):void {
e.target.removeEventListener(Event.COMPLETE, initialize);
HotKey.setStage(this.stage);
EnemyType.initialize();
BornAbility.initialize();
AccelerateAbility.initialize();
// 各状態の初期化
_states = new Vector.<IState>();
_states[Main.STATE_READY] = new ReadyState(this);
_states[Main.STATE_PLAYING] = new PlayingState(this);
_states[Main.STATE_MENU] = new MenuState(this);
_states[Main.STATE_GAMEOVER] = new GameoverState(this);
// 画面の初期化
addChild(_world = new World( -9, 12));
addChild(_frontend = new Frontend(0, 0));
_frontend.addChild(_waveManager = new WaveManager(0, 415, _world));
// 各ボタンの初期化と、対応するホットキーを設定する
var window:Sprite = _frontend.addChild(ImageFactory.createWindow(365, 415, 100, 50)) as Sprite;
var menuButton:PushButton = new PushButton(window, 5, 4, "Menu (M)", onClickMenuButton);
var nextWaveButton:PushButton = new PushButton(window, 5, 26, "Next Wave (N)", onClickNextWaveButton);
menuButton.width = nextWaveButton.width = 90;
HotKey.bind(Keyboard.M, onClickMenuButton);
HotKey.bind(Keyboard.N, onClickNextWaveButton);
// 初期状態の設定
_currentState = _states[Main.STATE_GAMEOVER];
_currentState.enter();
addEventListener(Event.ENTER_FRAME, mainLoop);
}
private function onClickMenuButton(e:MouseEvent = null):void { changeState(Main.STATE_MENU); }
private function onClickNextWaveButton(e:MouseEvent = null):void { _nextWaveButtonHandler(); }
private function mainLoop(e:Event):void { _currentState.update(); }
// NextWaveボタンを押した時の処理を設定する
public function setNextWaveButtonHandler(handler:Function = null):void {
_nextWaveButtonHandler = (handler != null) ? handler : doNothing;
}
private function doNothing():void { }
// ゲームの状態を変更する
public function changeState(stateType:int):void {
_previousState = _currentState;
_currentState.exit();
_currentState = _states[stateType];
_currentState.enter();
}
// ゲームの状態を一つ前の状態に戻す
public function revertToPreviousState():void {
_currentState.exit();
_currentState = _previousState;
_currentState.enter();
}
}
}
/* ----------------------------------------------------------------------------------------------------------------------
* IState
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
interface IState {
function enter():void;
function update():void;
function exit():void;
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* GameoverState
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
import net.wonderfl.score.basic.BasicScoreForm;
import net.wonderfl.score.basic.BasicScoreRecordViewer;
//public
class GameoverState implements IState {
private var _main:Main;
private var _gameoverScreen:Sprite;
private var _instructionWindow:Sprite;
private var _isBeginning:Boolean;
private var _scoreForm:BasicScoreForm;
private var _ranking:BasicScoreRecordViewer;
public function GameoverState(main:Main) {
_main = main;
_gameoverScreen = createGameoverScreen();
_instructionWindow = createInstructionWindow();
_isBeginning = true;
}
private function createGameoverScreen():Sprite {
var screen:Sprite = new Sprite();
screen.graphics.beginFill(0x000000, 0.5);
screen.graphics.drawRect(0, 0, 465, 465);
screen.graphics.endFill();
new PushButton(screen, 182, 182, "Start Game", onClickStartButton);
return screen;
}
private function onClickStartButton(e:MouseEvent):void { _main.changeState(Main.STATE_READY); }
private function createInstructionWindow():Sprite {
var container:Sprite = new Sprite();
var window1:Sprite = container.addChild(ImageFactory.createWindow(180, 60, 190, 70)) as Sprite;
window1.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Select a tower to build\nby clicking right button.", 12));
window1.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "設置したいタワーを、\n右のボタンから選択できます。", 12));
var window2:Sprite = container.addChild(ImageFactory.createWindow(30, 220, 190, 70)) as Sprite;
window2.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Click on the map\nto build the selected tower.", 12));
window2.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "マップをクリックすると、\n選択したタワーを設置できます。", 12));
var window3:Sprite = container.addChild(ImageFactory.createWindow(240, 270, 190, 70)) as Sprite;
window3.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Click on a tower on the map\nto upgrade or sell it.", 12));
window3.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "マップ上のタワーをクリックすると、\nレベルアップや売却を行えます。", 12));
var window4:Sprite = container.addChild(ImageFactory.createWindow(170, 380, 190, 70)) as Sprite;
window4.addChild(ImageFactory.createInstructionText(5, 7, 190, 24, "Press \"Next Wave\" button\nto send the next wave.", 12));
window4.addChild(ImageFactory.createInstructionText(5, 39, 190, 24, "「Next Wave」ボタンを押すと、\nゲームを進めることができます。", 12));
return container;
}
public function enter():void {
_main.addChild(_gameoverScreen);
if (_isBeginning) {
_main.addChild(_instructionWindow);
}else {
if (_scoreForm != null) { _gameoverScreen.removeChild(_scoreForm); }
_scoreForm = new BasicScoreForm(_gameoverScreen, 92, 10, GameData.instance.score, "Score", showRanking);
showRanking(false);
}
}
private function showRanking(b:Boolean):void {
if (_ranking != null) { _gameoverScreen.removeChild(_ranking); }
_ranking = new BasicScoreRecordViewer(_gameoverScreen, 122, 215, "Ranking", 99, true, null);
}
public function update():void { }
public function exit():void {
if (_isBeginning) {
_main.removeChild(_instructionWindow);
_instructionWindow = null;
}
_isBeginning = false;
_main.removeChild(_gameoverScreen);
_main.world.clear();
_main.waveManager.initialize();
GameData.instance.initialize();
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* ReadyState
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class ReadyState implements IState {
private var _main:Main;
public function ReadyState(main:Main) {
_main = main;
}
public function enter():void {
_main.setNextWaveButtonHandler(startPlaying);
HotKey.enable();
}
private function startPlaying():void { _main.changeState(Main.STATE_PLAYING); }
public function update():void {
_main.world.update();
}
public function exit():void {
HotKey.disable();
_main.setNextWaveButtonHandler(_main.waveManager.sendNextWave);
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* PlayingState
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class PlayingState implements IState {
private var _main:Main;
public function PlayingState(main:Main) {
_main = main;
}
public function enter():void {
GameData.instance.sellingRatio = 0.8;
HotKey.enable();
}
public function update():void {
_main.world.update();
_main.waveManager.update();
// ライフが0になるか、全ての敵を倒したら、ゲームオーバー
if ((GameData.instance.lives <= 0) || (_main.world.numEnemies() == 0 && _main.waveManager.finished())) {
_main.changeState(Main.STATE_GAMEOVER);
}
}
public function exit():void {
HotKey.disable();
GameData.instance.sellingRatio = 1;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* MenuState
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
//public
class MenuState implements IState {
private var _main:Main;
private var _menuScreen:Sprite;
public function MenuState(main:Main) {
_main = main;
_menuScreen = createMenuScreen();
}
private function createMenuScreen():Sprite {
var screen:Sprite = new Sprite();
screen.graphics.beginFill(0x000000, 0.5);
screen.graphics.drawRect(0, 0, 465, 465);
screen.graphics.endFill();
var window:Sprite = screen.addChild(ImageFactory.createWindow(122, 172, 120, 95)) as Sprite;
window.addChild(ImageFactory.createWindow(0, 0, 120, 25));
window.addChild(ImageFactory.createSimpleText(0, 0, 120, 25, "Menu", 12, 0xffffff));
new PushButton(window, 10, 35, "Resume", onClickResumeButton);
new PushButton(window, 10, 65, "Give up", onClickGiveUpButton);
return screen;
}
private function onClickResumeButton(e:MouseEvent):void { _main.revertToPreviousState(); }
private function onClickGiveUpButton(e:MouseEvent):void { _main.changeState(Main.STATE_GAMEOVER); }
public function enter():void { _main.addChild(_menuScreen); }
public function update():void { }
public function exit():void { _main.removeChild(_menuScreen); }
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* World
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.MouseEvent;
//public
class World extends Sprite {
private var _nodes:Vector.<Vector.<Node>>;
private var _starts:Vector.<Start>;
private var _goals:Vector.<Goal>;
private var _towers:Vector.<Tower>;
private var _bullets:Vector.<Bullet>;
private var _groundEnemies:Vector.<Enemy>;
private var _flyingEnemies:Vector.<Enemy>;
private var _towerLayer:Sprite;
private var _enemyLayer:Sprite;
private var _bulletLayer:Sprite;
private var _effectLayer:Sprite;
private var _cursor:Cursor;
public function getNode(col:int, row:int):Node { return _nodes[row][col]; }
public function getStartingPos(startIndex:int):TileBasedPoint {
return _starts[startIndex].getRandomSpawningPosition();
}
public function numEnemies():int { return _groundEnemies.length + _flyingEnemies.length; }
//----------------------------------------------------------------------
//ワールド画面の設置 (画面の開始位置は受け取る) 【F】
public function World(posx:int, posy:int) {
x = posx;
y = posy;
//初期化用パブリックファンクション【F】
initializeNodes();
initializeStarts();
initializeGoals();
_towers = new Vector.<Tower>();
_bullets = new Vector.<Bullet>();
_groundEnemies = new Vector.<Enemy>();
_flyingEnemies = new Vector.<Enemy>();
addChild(new Bitmap(ImageFactory.getImage("World")));
addChild(_towerLayer = new Sprite());
addChild(_enemyLayer = new Sprite());
addChild(_bulletLayer = new Sprite());
addChild(_effectLayer = new Sprite());
addChild(_cursor = new Cursor(this));
_enemyLayer.mouseChildren = _bulletLayer.mouseChildren = false;
_enemyLayer.mouseEnabled = _bulletLayer.mouseEnabled = false;
//画面上をクリックされたら、基本はタワー配置操作とし、いろいろチェックして対応【F】
addEventListener(MouseEvent.CLICK, addTower);
}
private function initializeNodes():void {
_nodes = new Vector.<Vector.<Node>>();
for (var row:int = 0; row < Const.NODE_ROWS; row++) {
_nodes[row] = new Vector.<Node>();
for (var col:int = 0; col < Const.NODE_COLS; col++) {
_nodes[row][col] = new Node(col, row, Config.NODE_TYPE[row][col]);
}
}
}
private function initializeStarts():void {
_starts = Config.getStarts();
}
private function initializeGoals():void {
_goals = Config.getGoals();
for (var i:int = 0; i < _goals.length; i++) {
var goal:Goal = _goals[i];
goal.setNode(_nodes[goal.tileY][goal.tileX]);
goal.search(this);
}
}
//----------------------------------------------------------------------
//World.update の設定【F】
public function update():void {
var i:int;
//まず存在している各タワーのupdate (タワークラスのPbFc)【F】
for (i = 0; i < _towers.length; i++) {
_towers[i].update();
}
//(敵数になるまで)i番目の敵のupdate(エネミークラスのPbFc)【F】
for (i = 0; i < _groundEnemies.length; i++) {
var groundEnemy:Enemy = _groundEnemies[i];
_nodes[groundEnemy.tileY][groundEnemy.tileX].numEnemy--;
_groundEnemies[i].update(this);
_nodes[groundEnemy.tileY][groundEnemy.tileX].numEnemy++;
}
for (i = 0; i < _flyingEnemies.length; i++) {
_flyingEnemies[i].update(this);
}
//弾丸の数だけupdate(bulletクラスのPbFc)【F】
for (i = 0; i < _bullets.length; i++) {
_bullets[i].update();
}
//カーソルもupdate【F】
_cursor.update(mouseX - Const.CURSOR_OFFSET, mouseY - Const.CURSOR_OFFSET);
}
// すべてのタワー・弾・敵を消去する
public function clear():void {
var i:int;
for (i = _towers.length - 1; i >= 0; i--) {
removeTower(_towers[i], true); }
for (i = 0; i < _goals.length; i++) { _goals[i].search(this); }
for (i = _groundEnemies.length - 1; i >= 0; i--) { removeEnemy(_groundEnemies[i]); }
for (i = _flyingEnemies.length - 1; i >= 0; i--) { removeEnemy(_flyingEnemies[i]); }
for (i = _bullets.length - 1; i >= 0; i--) { removeBullet(_bullets[i]); }
initializeNodes();
initializeStarts();
initializeGoals();
}
//----------------------------------------------------
// マウスイベント:タワーを(設置できるなら)設置する【F】
public function addTower(e:MouseEvent):void {
var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(mouseX - Const.CURSOR_OFFSET, mouseY - Const.CURSOR_OFFSET);
position.setTilePos(position.tileX, position.tileY);
//クリックイベントでタイルポジションを取得しておく【F】
var nearestGoal:Goal;
var blocking:Boolean = false;
var tower:Tower = new Tower(position.x, position.y, GameData.instance.selectedTower.type, this);
var type:TowerType = tower.type;
//お金やタイル状態的にタワー設置可能をを調べる(キャンビルド)をまず実行【F】
if (canBuildTower(position.tileX, position.tileY)) {
// 以下キャンビルドOK時の処理【F】
var i:int, j:int;
// タワーが設置される場所をタワー建設不能にする【F】
if (!type.towerbase){
for (var row:int = 0; row < 2; row++) {
for (var col:int = 0; col < 2; col++) {
var node:Node = _nodes[position.tileY + row][position.tileX + col];
node.placeable = false} ;
}
}
// ベースが設置される場所を通行不能&ベース建設不能&タワー建設可能にする【F】
// 以下の経路探査操作はベース設置時のみ【F】
if (type.towerbase){
for(row = 0; row < 2; row++) {
for (col = 0; col < 2; col++) {
node = _nodes[position.tileY + row][position.tileX + col];
node.passable = node.buildable = false;
node.placeable =true } ;
}
// 全ての経路の最探索
for (i = 0; i < _goals.length; i++) {
_goals[i].search(this);
}
// 全てのスタート、全ての敵(地上)、のゴールを更新
// ブロッキングが発生していたら中断
for (i = 0; !blocking && (i < _starts.length); i++) {
var start:Start = _starts[i];
if (start.forFlying) { continue; }
nearestGoal = getNearestGoalFrom(start.posX, start.posY, false);
if (!nearestGoal.hasPath(start.tileX,start.tileY)) { blocking = true; }
}
for (i = 0; !blocking && (i < _groundEnemies.length); i++) {
var enemy:Enemy = _groundEnemies[i];
nearestGoal = getNearestGoalFrom(enemy.posX, enemy.posY, false);
enemy.setGoal(nearestGoal);
if (!enemy.hasPathToGoal()) { blocking = true; }
}
} // ベース設置時のみここまで【F】
// ブロッキングが発生していたら、
// 全ての変更を元に戻してタワー設置失敗で終了
// そうでなければ、実際にタワーを設置する
// ベースじゃない通常タワーはblocking=常にfalseで通過【F】
if (blocking) {
_cursor.blockingAlart();
// 通行不能にした場所を元に戻す
for (row = 0; row < 2; row++) {
for (col = 0; col < 2; col++) {
node = _nodes[position.tileY + row][position.tileX + col];
node.passable = node.buildable = true;
node.placeable = false;
}
}
// 全ての経路を元に戻す
for (i = 0; i < _goals.length; i++) {
_goals[i].revertToPrevious();
}
// 全ての敵(地上)のゴールを更新
for (i = 0; i < _groundEnemies.length; i++) {
_groundEnemies[i].setGoal(getNearestGoalFrom(_groundEnemies[i].posX, _groundEnemies[i].posY, false));
}
}else {
_towers.push(tower);
_towerLayer.addChild(tower);
//ベースはワールド設置時にクリック透過。選択&売却不能。
if (type.towerbase){ tower.mouseEnabled = false }
GameData.instance.gold -= tower.type.getStatus(tower.level).cost;
}
}
}
// そもそも建築できる場所なのかファンクション 【F】
public function canBuildTower(tilex:int, tiley:int):Boolean {
var selectedTower:Tower = GameData.instance.selectedTower;
var _type:TowerType = selectedTower.type;
// タワー選択ボタンを選択中か、十分な所持金があるか調べる
if (selectedTower == null || selectedTower.active || (GameData.instance.gold < selectedTower.type.getStatus(selectedTower.level).cost)) { return false; }
// 引数で指定した場所にタワーが建てられるか調べる
for (var row:int = 0; row < 2; row++) {
for (var col:int = 0; col < 2; col++) {
var node:Node = _nodes[tiley + row][tilex + col];
if (_type.towerbase){
if (!node.buildable || (node.numEnemy > 0)) { return false; }
}else{
if (!node.placeable ) { return false; }
}
}
}
return true;
}
//----------------------------------------------------
// タワーのターゲットを探してそれを返す(いなければnullを返す)
public function findTarget(posx:Number, posy:Number, range:int, ground:Boolean, air:Boolean):Enemy {
var i:int, enemy:Enemy, diffX:Number, diffY:Number;
var rangeSq:int = range * range;
// 地上に攻撃できるなら、地上の敵のターゲットを探す
if (ground) {
for (i = 0; i < _groundEnemies.length; i++) {
enemy = _groundEnemies[i];
diffX = posx - enemy.posX;
diffY = posy - enemy.posY;
if (diffX * diffX + diffY * diffY < rangeSq) {
if (enemy.targetable) { return enemy }
}
}
}
// 空中に攻撃できるなら、飛んでいる敵のターゲットを探す
if (air) {
for (i = 0; i < _flyingEnemies.length; i++) {
enemy = _flyingEnemies[i];
diffX = posx - enemy.posX;
diffY = posy - enemy.posY;
if (diffX * diffX + diffY * diffY < rangeSq) {
if (enemy.targetable) { return enemy } }
}
}
// ターゲットが見つからなければnull
return null;
}
//----------------------------------------------------
// 引数で指定した位置から最も近いゴールを返す
private function getNearestGoalFrom(posx:Number, posy:Number, flying:Boolean):Goal {
var nearest:Goal = _goals[0];
for (var i:int = 1; i < _goals.length; i++) {
if (_goals[i].getCost(posx, posy, flying) < nearest.getCost(posx, posy, flying)) {
nearest = _goals[i];
}
}
return nearest;
}
//----------------------------------------------------
// タワーを消去する
//引数補足「clear=true:画面初期化」「clear=false(void):売却」
public function removeTower(tower:Tower, clear:Boolean = false):void {
var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(tower.x, tower.y);
for (var row:int = 0; row < 2; row++) {
for (var col:int = 0; col < 2; col++) {
var node:Node = _nodes[position.tileY + row][position.tileX + col];
//元々が通路型の土地だったら …clearなら土台も消え通行可能TTF、売却なら土台が残っていて通行不可能FFT
if(Config.NODE_TYPE[position.tileY + row][position.tileX + col] == 0) {
node.passable = node.buildable = clear ; node.placeable = (!clear);
}
//元々が壁型の土地だったら
if(Config.NODE_TYPE[position.tileY + row][position.tileX + col] == 1) {
node.passable = false; node.buildable = clear ; node.placeable = true;
}
}
}
// ブロッキングを考慮せずに
// 全ての経路の最探索と、全ての敵(地上)のゴールを更新
// clear()時は最探索する必要
if (!clear) {
var i:int;
for (i = 0; i < _goals.length; i++) {
_goals[i].search(this);
}
for (i = 0; i < _groundEnemies.length; i++) {
_groundEnemies[i].setGoal(getNearestGoalFrom(_groundEnemies[i].posX, _groundEnemies[i].posY, false));
}
}
_towerLayer.removeChild(tower);
_towers.splice(_towers.indexOf(tower), 1);
}
//----------------------------------------------------
// 弾を出現させる
public function addBullet(bullet:Bullet):void {
_bullets.push(bullet);
_bulletLayer.addChild(bullet);
}
// 弾を消去する
public function removeBullet(bullet:Bullet):void {
_bulletLayer.removeChild(bullet);
_bullets.splice(_bullets.indexOf(bullet), 1);
}
//----------------------------------------------------
// 敵を出現させる
public function addEnemy(enemy:Enemy):void {
enemy.setGoal(getNearestGoalFrom(enemy.posX, enemy.posY, enemy.type.flying));
if (enemy.type.flying) {
_flyingEnemies.push(enemy);
}else {
_groundEnemies.push(enemy);
_nodes[enemy.tileY][enemy.tileX].numEnemy++;
}
_enemyLayer.addChild(enemy);
}
// 敵を消去する
public function removeEnemy(enemy:Enemy):void {
_enemyLayer.removeChild(enemy);
if (enemy.type.flying) {
_flyingEnemies.splice(_flyingEnemies.indexOf(enemy), 1);
}else {
_nodes[enemy.tileY][enemy.tileX].numEnemy--;
_groundEnemies.splice(_groundEnemies.indexOf(enemy), 1);
}
}
// エフェクトを発生させる
public function addEffect(effect:Sprite):void {
_effectLayer.addChild(effect);
}
// 範囲攻撃
public function damageSurroundingEnemies(bullet:Bullet):void {
var i:int, enemy:Enemy;
if (bullet.ground) {
for (i = _groundEnemies.length - 1; i >= 0; i--) {
enemy = _groundEnemies[i];
if (bullet.isHitTarget(enemy, bullet.splashRadius)) { bullet.damageTarget(enemy); }
}
}
if (bullet.air) {
for (i = _flyingEnemies.length - 1; i >= 0; i--) {
enemy = _flyingEnemies[i];
if (bullet.isHitTarget(enemy, bullet.splashRadius)) { bullet.damageTarget(enemy); }
}
}
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Node
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class Node {
private var _center:TileBasedPoint; // 中心の座標
private var _passable:Boolean; // 敵が通れるかどうか
private var _buildable:Boolean; // 足場を建てられるかどうか【F】
private var _placeable:Boolean; // タワーを建てられるかどうか【F】
private var _numEnemy:int; // このノード上にいる敵の数
public function get tileX():int { return _center.tileX; }
public function get tileY():int { return _center.tileY; }
public function get centerX():Number { return _center.x; }
public function get centerY():Number { return _center.y; }
public function get passable():Boolean { return _passable; }
public function get buildable():Boolean { return _buildable; }
public function get placeable():Boolean { return _placeable; } //追加【F】
public function get numEnemy():int { return _numEnemy; }
public function set passable(value:Boolean):void { _passable = value; }
public function set buildable(value:Boolean):void { _buildable = value; }
public function set placeable(value:Boolean):void { _placeable = value; } //追加【F】
public function set numEnemy(value:int):void { _numEnemy = value; }
public function Node(tilex:int, tiley:int, type:int) {
_center = TileBasedPoint.createFromTilePos(tilex, tiley);
_center.x += Const.NODE_SIZE / 2;
_center.y += Const.NODE_SIZE / 2;
switch(type) { // 追加【F】
case 0: { _passable = true; _buildable = true; _placeable =false; break; } // 通路となる土地。土台を置けるが、タワーを置けない【F】
case 1: { _passable = false; _buildable = false; _placeable =true; break; } // 土台と同等の土地。通過できないがタワーを置ける【F】
case 2: { _passable = true; _buildable = false; _placeable = false; break; } // 敵の出入り口。通過できるが、何も置けない【F】
case 3: { _passable = false; _buildable = false; _placeable = false; break; } // ゲーム中、何も置けない土地【F】
}
_numEnemy = 0;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Start
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class Start {
private var _position:TileBasedPoint;
private var _width:int;
private var _forFlying:Boolean;
public function get posX():Number { return _position.x; }
public function get posY():Number { return _position.y; }
public function get tileX():int { return _position.tileX; }
public function get tileY():int { return _position.tileY; }
public function get forFlying():Boolean { return _forFlying; }
public function Start(tilex:int, tiley:int, width:int, forFlying:Boolean) {
_position = TileBasedPoint.createFromTilePos(tilex, tiley);
_width = width * Const.NODE_SIZE;
_forFlying = forFlying;
}
// ランダムな出現位置を取得する
public function getRandomSpawningPosition():TileBasedPoint {
var posx:int = int(_position.x + ((2 * _width * Math.random()) - _width));
var posy:int = int(_position.y + Const.NODE_SIZE);
return TileBasedPoint.createFromWorldPos(posx, posy);
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Goal
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class Goal {
private static const DX:Array = [0, -1, 1, 0, -1, 1, -1, 1];
private static const DY:Array = [ -1, 0, 0, 1, -1, -1, 1, 1];
private static const DCOST:Array = [1, 1, 1, 1, Math.SQRT2, Math.SQRT2, Math.SQRT2, Math.SQRT2];
private var _center:TileBasedPoint;
private var _node:Node;
private var _openNodes:Vector.<Node>; // 保留ノードリスト
private var _nodeCost:Vector.<Vector.<Number>>; // 各ノードの移動コスト
private var _nodeNext:Vector.<Vector.<Node>>; // 各ノードの次の経路となるノード
private var _previousNodeCost:Vector.<Vector.<Number>>; // 以前のnodeCost
private var _previousNodeNext:Vector.<Vector.<Node>>; // 以前のnodeNext
public function get tileX():int { return _center.tileX; }
public function get tileY():int { return _center.tileY; }
public function Goal(tilex:int, tiley:int) {
_center = TileBasedPoint.createFromTilePos(tilex, tiley);
_center.setWorldPos(_center.x + Const.NODE_SIZE / 2, _center.y + Const.NODE_SIZE / 2);
_openNodes = new Vector.<Node>();
_nodeCost = null; _nodeNext = null;
}
public function setNode(node:Node):void { _node = node; }
// 引数で指定した位置から、ゴールまでのコストを返す
public function getCost(posx:Number, posy:Number, flying:Boolean):Number {
if (flying) {
var diffx:Number = _center.x - posx;
var diffy:Number = _center.y - posy;
return diffx * diffx + diffy * diffy;
}
var postion:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
return _nodeCost[postion.tileY][postion.tileX];
}
// 引数で指定した位置から、ゴールへ向かう経路が存在しているかどうか
public function hasPath(tilex:int, tiley:int):Boolean {
return _nodeCost[tiley][tilex] != Number.MAX_VALUE;
}
// 引数で指定した位置から、ゴールへ向かう為の次のノードを返す
public function getNext(posx:Number, posy:Number, flying:Boolean):Node {
if (flying) {
return _node;
}
var position:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
return _nodeNext[position.tileY][position.tileX];
}
// Dijkstra法による経路探索
public function search(world:World):void {
setup(world);
while (_openNodes.length > 0) {
var subject:Node = _openNodes.pop() as Node;
// 周囲8方向のノードを訪問する
for (var i:int = 0; i < 8; i++) {
// 画面外の存在しないノードを指すなら次の周囲ノードへ進む
if (!isValid(subject.tileX + Goal.DX[i], subject.tileY + Goal.DY[i])) { continue; }
// 通れないノード、計算済み(確定)ノード、直進することができないノードなら次の周囲ノードへ進む
var test:Node = world.getNode(subject.tileX + Goal.DX[i], subject.tileY + Goal.DY[i]);
if (!test.passable || isCalculatedNode(test) || !canGoStraightTo(subject, test, world)) { continue; }
// 移動コストを計算する
_nodeCost[test.tileY][test.tileX] = _nodeCost[subject.tileY][subject.tileX] + Goal.DCOST[i];
// 次の経路ノードをsubjectノードに設定する
_nodeNext[test.tileY][test.tileX] = subject;
// 保留ノードリストに追加する
insertToOpenNodes(test);
}
}
}
// 探索前の準備
private function setup(world:World):void {
_previousNodeCost = _nodeCost;
_previousNodeNext = _nodeNext;
_nodeCost = new Vector.<Vector.<Number>>();
_nodeNext = new Vector.<Vector.<Node>>();
for (var row:int = 0; row < Const.NODE_ROWS; row++) {
_nodeCost[row] = new Vector.<Number>();
_nodeNext[row] = new Vector.<Node>();
for (var col:int = 0; col < Const.NODE_COLS; col++) {
_nodeCost[row][col] = Number.MAX_VALUE;
_nodeNext[row][col] = world.getNode(col, row);
}
}
// Goalのノードを経路探索のスタートノードとする
_nodeCost[_center.tileY][_center.tileX] = 0;
_openNodes.push(_node);
}
// indexの値が有効な値かどうか
private function isValid(col:int, row:int):Boolean {
return (col >= 0) && (col < Const.NODE_COLS) && (row >= 0) && (row < Const.NODE_ROWS);
}
// 既にコストを計算済みのノードかどうか
private function isCalculatedNode(node:Node):Boolean {
return _nodeCost[node.tileY][node.tileX] != Number.MAX_VALUE;
}
// subjectノードからtestノードへ直進できるかどうか
private function canGoStraightTo(subject:Node, test:Node, world:World):Boolean {
return world.getNode(subject.tileX, test.tileY).passable && world.getNode(test.tileX, subject.tileY).passable;
}
// nodeを保留ノードリストの適切な場所に挿入する
private function insertToOpenNodes(node:Node):void {
var insertIndex:int;
var nodeCost:Number = _nodeCost[node.tileY][node.tileX];
for (insertIndex = 0; insertIndex < _openNodes.length; insertIndex++) {
var openNode:Node = _openNodes[insertIndex];
if (nodeCost > _nodeCost[openNode.tileY][openNode.tileX]) { break; }
}
_openNodes.splice(insertIndex, 0, node);
}
// 最探索更新前の経路情報に戻す
public function revertToPrevious():void {
_nodeCost = _previousNodeCost;
_nodeNext = _previousNodeNext;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Tower
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
//public
class Tower extends Sprite {
private var _center:TileBasedPoint;
private var _type:TowerType; // 種類
private var _level:int; // 現在のレベル
private var _world:World;
private var _target:Enemy; // 現在のターゲット
private var _reloadCount:Number; // 100を超えたら弾発射
private var _body:Sprite;
private var _levelText:TextField;
public function get tileX():int { return _center.tileX; }
public function get tileY():int { return _center.tileY; }
public function get type():TowerType { return _type; }
public function get level():int { return _level; }
public function get active():Boolean { return _world != null; }
//----------------------------------------------------
public function Tower(posx:int, posy:int, type:TowerType, world:World = null) {
x = posx;
y = posy;
_center = TileBasedPoint.createFromWorldPos(posx + Const.TOWER_SIZE / 2, posy + Const.TOWER_SIZE / 2);
_type = type;
_level = 1;
_world = world;
_target = null;
_reloadCount = 0;
draw();
buttonMode = true;
mouseChildren = false;
addEventListener(MouseEvent.CLICK, clickTower, false, 0, true);
}
//----------------------------------------------------
// タワーの画像を描画する
private function draw():void {
addChild(new Bitmap(ImageFactory.getImage("Circle")));
_body = addChild(new Sprite()) as Sprite;
var bitmap:Bitmap = _body.addChild(new Bitmap(ImageFactory.getImage(_type.name), "auto", true)) as Bitmap;
bitmap.x = bitmap.y = int( -Const.TOWER_SIZE / 2);
_body.x = _body.y = int(Const.TOWER_SIZE / 2);
if (active) {
if ( !_type.towerbase ) { _body.rotation = 360 * Math.random() - 180};
if ( !_type.towerbase ) { addChild(_levelText = ImageFactory.createBorderedText(Const.TOWER_SIZE - 10, Const.TOWER_SIZE - 10, 10, 10, _level.toString(), 10, 0xffffff, 0x000000))};
}
}
// タワーをクリックしたとき
public function clickTower(e:MouseEvent = null):void {
GameData.instance.selectedTower = this;
}
//----------------------------------------------------
public function update():void {
var range:int = _type.getStatus(_level).range;
// ターゲット無しorターゲットがやられていたorターゲットが消えたなら、新しいターゲットを探す
if (_target == null || _target.isDead() || (!_target.targetable) ) {
_target = _world.findTarget(_center.x, _center.y, range, _type.ground, _type.air);
}
// リロードカウントを進める
if (_reloadCount < 100) { _reloadCount += _type.getStatus(_level).reloadSpeed; }
if (_target != null) {
var rangeSq:int = range * range;
var diffX:Number = _target.posX - _center.x;
var diffY:Number = _target.posY - _center.y;
if (diffX * diffX + diffY * diffY < rangeSq) {
_body.rotation = _type.adjustBodyRotation(diffX, diffY, _body.rotation);
// リロードを終えていて、ターゲットがいるなら弾を発射する
if (_reloadCount >= 100 && _target != null) {
_reloadCount = 0;
_world.addBullet(type.createBullet(_center.x, _center.y, _level, _target, _world));
}
}else {
// ターゲットが射程外になっていたらターゲットから外す
_target = null;
}
}
}
public function upgrade():void {
// 既に最高レベルになっていたら終了
if (!_type.hasStatus(_level + 1)) { return; }
// アップグレードするだけの所持金があれば、アップグレード
var upgradeCost:int = _type.getStatus(_level + 1).cost - _type.getStatus(_level).cost;
if (upgradeCost <= GameData.instance.gold) {
_level++;
_levelText.text = _level.toString();
GameData.instance.gold -= upgradeCost;
GameData.instance.selectedTower = this;
}
}
public function sell():void {
_world.removeTower(this);
GameData.instance.gold += _type.getStatus(_level).cost * GameData.instance.sellingRatio;
GameData.instance.selectedTower = null;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* TowerType
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.BitmapData;
//public
class TowerType {
private var _name:String; // 種類名
private var _towerbase:Boolean; //足場(タワーベース)型か【F】
private var _ground:Boolean; // 対地攻撃可能か
private var _air:Boolean; // 対空攻撃可能か
private var _slow:int; // スロー効果量
private var _venom:int; //毒攻撃力
private var _splash:int; // 範囲攻撃サイズ
private var _status:Vector.<TowerStatus>; // (レベルごとの)各ステータス
public function get name():String { return _name; }
public function get ground():Boolean { return _ground; }
public function get towerbase():Boolean { return _towerbase; }
public function get air():Boolean { return _air; }
public function get slow():int { return _slow; }
public function get venom():int { return _venom; }
public function get splash():int { return _splash; }
public function getStatus(level:int):TowerStatus { return _status[level - 1]; }
// ※インスタンスは Config.getTowerType() から生成する
public function TowerType(name:String, towerbase:Boolean ,ground:Boolean, air:Boolean, slowing:int, splash:int, venom:int) {
_name = name;
_towerbase=towerbase;
_ground = ground;
_air = air;
_slow = slowing;
_splash = splash;
_venom = venom;
_status = Config.getTowerStatus(_name);
}
// 指定したレベルのステータスがあるかどうか
public function hasStatus(level:int):Boolean {
return level <= _status.length;
}
// 種類に応じて、砲頭の角度を調整する
public function adjustBodyRotation(diffx:Number, diffy:Number, currentRotation:Number):Number {
switch(_name) {
case "Voltex": { return currentRotation + 10; }
default: { return Math.atan2(diffy, diffx) * 180 / Math.PI; }
}
}
// 種類に応じた弾を生成する
public function createBullet(posx:int, posy:int, level:int, target:Enemy, world:World):Bullet {
var image:BitmapData = ImageFactory.getImage("Bullet_" + _name);
var pos:TileBasedPoint = TileBasedPoint.createFromWorldPos(posx, posy);
var status:TowerStatus = getStatus(level);
switch(_name) {
// Bullet引数内訳(pos:TileBasedPoint, life:int, power:int, radius:int, speed:int, ground:Boolean, air:Boolean, level:int
// slow:int,venom:int, homing:Boolean, pierce:Boolean, target:Enemy, image:BitmapData, world:World)
//case "Arrow":
//{ return new Bullet(pos, status.range, status.damage, _splash, 8, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
case "Gun":
{ return new Bullet(pos, status.range, status.damage, _splash, (12+2*level), _ground, _air, level, _slow, _venom, true, false, target, image, world); }
case "Gatling":
{ return new Bullet(pos, status.range, status.damage, _splash, 24, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
case "Cannon":
{ return new Bullet(pos, status.range, status.damage, _splash, 8, _ground, _air, level, _slow, _venom, true, false, target, image, world); }
case "Venom":
{ return new Bullet(pos, status.range, status.damage, _splash, 10, _ground, _air, level, _slow, _venom, true, false, target, image, world); }
case "Voltex":
{ return new Bullet(pos, 0, status.damage, status.range, 0, _ground, _air, level, _slow, _venom, false, false, target, image, world); }
case "AntiFly":
{ return new Bullet(pos, 900, status.damage, (Const.ENEMY_SIZE + Const.BULLET_SIZE) / 2, Const.NODE_SIZE, _ground, _air, level, _slow, _venom, false, true, target, image, world); }
}
return null; // never called
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* TowerStatus
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class TowerStatus {
private var _level:int; // レベル
private var _cost:int; // コスト
private var _damage:int; // ダメージ
private var _range:int; // 射程
private var _firerate:Number; // 射撃間隔(発/秒)
private var _reloadSpeed:Number;
public function get level():int { return _level; }
public function get cost():int { return _cost; }
public function get damage():int { return _damage; }
public function get range():int { return _range; }
public function get firerate():Number { return _firerate; }
public function get reloadSpeed():Number { return _reloadSpeed; }
// ※インスタンスは Config.getTowerStatus() から生成する
public function TowerStatus(level:int, cost:int, damage:int, range:int, firerate:Number) {
_level = level;
_cost = cost;
_damage = damage;
_range = range;
_firerate = firerate;
_reloadSpeed = _firerate * 100 / Const.FRAME_RATE;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Bullet
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.geom.Point;
//public
class Bullet extends Sprite {
private var _life:int; // 寿命(最大射程)
private var _power:int; // 威力
private var _splashRadius:int; // 範囲攻撃の半径(範囲攻撃で無いなら0)
private var _speed:int; // 速さ
private var _ground:Boolean; // 地上の敵に当たるか
private var _air:Boolean; // 空中の敵にあたるか
private var _level:int; // 発射弾のレベル
private var _slow:int; // スロー効果量
private var _venom:int; // 毒効果量
private var _homing:Boolean; // 追尾能力
private var _pierce:Boolean; // 貫通力
private var _target:Enemy; // ターゲット
private var _world:World;
private var _position:TileBasedPoint; // 位置
private var _velocity:Point; // 速度
public function get splashRadius():int { return _splashRadius; }
public function get ground():Boolean { return _ground; }
public function get air():Boolean { return _air; }
public function Bullet(
pos:TileBasedPoint,
life:int, power:int, radius:int, speed:int,
ground:Boolean, air:Boolean, level:int, slow:int, venom:int,
homing:Boolean, pierce:Boolean,
target:Enemy, image:BitmapData, world:World)
{
_life = life;
_power = power;
_splashRadius = radius;
_speed = speed;
_ground = ground;
_air = air;
_level = level;
_slow = slow;
_venom = venom;
_homing = homing;
_pierce = pierce;
_target = target;
_world = world;
_position = pos;
x = int(_position.x);
y = int(_position.y);
_velocity = new Point();
changeVelocity();
draw(image);
}
private function draw(image:BitmapData):void {
var bitmap:Bitmap = new Bitmap(image);
bitmap.x = bitmap.y = -int(Const.BULLET_SIZE / 2);
addChild(bitmap);
}
// 速度を変更し、向きを変える
private function changeVelocity():void {
var diffX:Number = _target.posX - _position.x;
var diffY:Number = _target.posY - _position.y;
var radian:Number = Math.atan2(diffY, diffX);
_velocity.x = _speed * Math.cos(radian);
_velocity.y = _speed * Math.sin(radian);
var degree:Number = radian * 180 / Math.PI;
rotation = degree;
}
public function update():void {
// 移動する
_life -= _speed;
x = int(_position.x += _velocity.x);
y = int(_position.y += _velocity.y);
if (_homing) { changeVelocity(); }
// 画面外に出たら、消滅する
if (_position.x < 0 || _position.x > 465 || _position.y < 0 || _position.y > 465) {
_world.removeBullet(this);
return;
}
// 射程外に出たら、(範囲攻撃の弾なら周辺の敵にダメージを与え)消滅する
// 範囲攻撃の弾なら範囲アニメを出すspreadEffects(位置x、位置y、スプレッドサイズ、色、時間)
if (_life <= 0) {
if (_splashRadius > 0) {
if(_slow > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x000000,3))
}else if(_venom > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x00aa00,1))
}else {_world.addEffect(new splashEffect(x, y, _splashRadius,0xff5500,1))};
_world.damageSurroundingEnemies(this);
}
_world.removeBullet(this);
return;
}
// 貫通力ありなら、(ターゲットを問わず)周辺の敵にダメージを与える
// ターゲットが死んでいたら、直線軌道に変更
// ターゲットに当たっていたら、ダメージを与え消滅する
if (_pierce) {
_world.damageSurroundingEnemies(this);
}else if (_target.isDead()) {
_homing = false;
}else if (isHitTarget(_target, (Const.BULLET_SIZE + Const.ENEMY_SIZE) / 2)) {
if (_splashRadius > 0) {
if(_slow > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x000000,3))
}else if(_venom > 0){_world.addEffect(new splashEffect(x, y, _splashRadius,0x00aa00,1))
}else {_world.addEffect(new splashEffect(x, y, _splashRadius,0xff5500,1))};
_world.damageSurroundingEnemies(this);
}else { damageTarget(_target); }
_world.removeBullet(this);
return;
}
}
public function isHitTarget(target:Enemy, radius:Number):Boolean {
var diffX:Number = target.posX - _position.x;
var diffY:Number = target.posY - _position.y;
return diffX * diffX + diffY * diffY < radius * radius;
}
public function damageTarget(target:Enemy):void {
target.damage(_power, _level, _slow,_venom);
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Enemy
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.filters.GlowFilter;
import flash.geom.Point;
//public
class Enemy extends Sprite {
private var _world:World;
private var _center:TileBasedPoint; // 中心の座標
private var _velocity:Point; // 速度ベクトル
private var _currentSpeed:Number; //速度の変更時に参照する基本速度の値
private var _type:EnemyType; // 種族
private var _HP:int; // 現在のHP
private var _maxHP:int; // 最大HP
private var _point:int; // 倒した時のポイント
private var _money:int; // 倒した時のお金
private var _targetable:Boolean; // 索敵可能かどうか
private var _isBaby:Boolean; //出産能力で生まれた場合TRUE(ゲートやスキルの効果を子どもにも継続させる場合に参照)
private var _babyNum:int; //出産能力がある場合の出産合計数
private var _liveCount:int; //出現時間カウント(ランダムな位相差あり)
private var _slowingCount:int; //スロウ効果の時間カウント
private var _attackedSlow:int; //スロウ効果によって減少した速度値(一時変化)
private var _venomingCount:int; //毒効果の時間カウント
private var _venomingLevel:int; //毒効果の最大レベルを継続する
private var _regeneAmount:Number; //小数で累積する回復量のカウント
private var _fadeAlpha:Number; //フェイド能力のアルファ値
private var _BA:BornAbility; //出産能力
private var _AA:AccelerateAbility; //加速能力
private var _image:Sprite;
private var _HPbar:Sprite;
private var _goal:Goal;
private var _nextNode:Node;
public function get posX():Number { return _center.x; }
public function get posY():Number { return _center.y; }
public function get tileX():int { return _center.tileX; }
public function get tileY():int { return _center.tileY; }
public function get type():EnemyType { return _type; }
public function get targetable():Boolean { return _targetable; }
public function get BA():BornAbility { return _BA; }
public function get AA():AccelerateAbility { return _AA; }
public function isDead():Boolean { return _HP <= 0; }
public function isBaby():Boolean { return _isBaby; }
public function babyNum():int { return _babyNum; }
public function setGoal(value:Goal):void {
_goal = value;
_nextNode = _goal.getNext(_center.x, _center.y, _type.flying);
}
public function Enemy(center:TileBasedPoint, type:EnemyType, HP:int, point:int, money:int, world:World ,isBaby:Boolean) {
_world = world;
_isBaby = isBaby;
_center = center;
x = int(_center.x);
y = int(_center.y);
_type = type;
_velocity = new Point(0,0); //移動の速度ベクトルは出現時ゼロ
_currentSpeed = type.speed; //ベクトルの長さとなる移動速度はタイプの値
_HP = _maxHP = HP;
_point = point;
_money = money;
_liveCount = Math.floor( (Math.random()*Const.FRAME_RATE) ); //ランダムな位相差あり
_slowingCount = 0;
_attackedSlow = 100;
_venomingCount = 0;
_venomingLevel = 1;
_regeneAmount = 0 ;
_BA = BAbility(); //出産能力のデータセット
_babyNum = 0;
_AA = AAbility(); //加速能力のデータセット
_targetable = true ;
draw();
}
private function BAbility():BornAbility {
if ( _type.born ) { return BornAbility.getBornData( _type.name );
}else { return null };
}
private function AAbility():AccelerateAbility {
if ( _type.accelerate ) { return AccelerateAbility.getAccelerateData( _type.name );
}else { return null };
}
private function draw():void {
_image = addChild(new Sprite()) as Sprite;
var bitmap:Bitmap = _image.addChild(new Bitmap(ImageFactory.getImage(_type.name), "auto", true)) as Bitmap;
bitmap.x = bitmap.y = int( -Const.ENEMY_SIZE / 2);
var HPbarBackground:Sprite = addChild(new Sprite()) as Sprite;
HPbarBackground.x = -Const.ENEMY_SIZE / 2;
HPbarBackground.y = -(Const.ENEMY_SIZE / 2 + 2);
HPbarBackground.graphics.beginFill(0xff0000);
HPbarBackground.graphics.drawRect(0, 0, Const.ENEMY_SIZE, 1);
HPbarBackground.graphics.endFill();
_HPbar = HPbarBackground.addChild(new Sprite()) as Sprite;
_HPbar.graphics.beginFill(0xffff00);
_HPbar.graphics.drawRect(0, 0, Const.ENEMY_SIZE, 1);
_HPbar.graphics.endFill();
}
public function update(world:World):void {
_liveCount ++;
if (_BA != null && _babyNum >= _BA.limit) { _BA = null };
// スロー状態を更新
if (_slowingCount > 0) { _slowingCount--; }
else {
_image.filters = CONDITION_GOOD;
_attackedSlow = 100 ;
}
//毒状態を更新(_venomingLevelは毒被弾時にタワーレベルを継承)
if (_venomingCount > 0) {
_venomingCount--;
var venomDamage : Number = _currentSpeed * (0.5 + (_venomingLevel * 0.5) + (Math.floor(_venomingLevel / 5) * 3));
damage(venomDamage,1,0,0);
} else {
_HPbar.filters = CONDITION_GOOD;
}
//regeneration > 0 のときHP回復
if ( _type.regeneration > 0 ) {
_regeneAmount += ((_maxHP / 1000) * _type.regeneration);
if (_regeneAmount >= 1) {
_HP += int(_regeneAmount)
_regeneAmount -= int(_regeneAmount)}
if (_HP >= _maxHP) { _HP = _maxHP } ;
_HPbar.scaleX = _HP / _maxHP;
}
//fade > 0 のときフェイド (_liveCountをフェイド間隔でわった偶奇でチェンジ)
if ( _type.fade > 0 ) {
if (Math.floor((_liveCount / _type.fade) % 2) == 0) { ;
if ( ((_liveCount % _type.fade) / _type.fade) < 0.2 ) { _fadeAlpha = 1 ;
} else { _fadeAlpha = 1 - ((_liveCount % _type.fade) / _type.fade)} ;
this.alpha = _fadeAlpha ;
_targetable = true ;
}
if (Math.floor((_liveCount / _type.fade) % 2) == 1) { ;
_fadeAlpha = 0 ;
this.alpha = _fadeAlpha ;
_targetable = false ;
}
}
// 移動する(スロー効果は0~99%の間)
if (_attackedSlow <= 1) { _attackedSlow = 1 };
if (_attackedSlow >= 100) { _attackedSlow = 100 };
x = int(_center.x += (_velocity.x * (_attackedSlow/100)));
y = int(_center.y += (_velocity.y * (_attackedSlow/100)));
// ゴールに到着していたら、ライフを減らして消滅
if (_center.tileX == _goal.tileX && _center.tileY == _goal.tileY) {
GameData.instance.lives--;
_HP = 0;
_world.removeEnemy(this);
return;
}
// 次に進むべきノードに到着していたら、その次に進むべきノードに更新
if (_center.tileX == _nextNode.tileX && _center.tileY == _nextNode.tileY) {
_nextNode = _goal.getNext(_center.x, _center.y, _type.flying);
}
// 速度と向きの更新
var radian:Number = Math.atan2(_nextNode.centerY - _center.y, _nextNode.centerX - _center.x);
// 【向き変化】加速能力:Angle >0 の場合、向きを変える
if (_AA != null && _AA.Angle > 0 ) {
radian += (_AA.Angle * Math.PI / 180);
}
// 【向き変化】加速能力:sineSlip >0 の場合、向きをぐねぐねさせる
if (_AA != null && _AA.sineSlip > 0 ) {
radian += Math.sin(_liveCount/AA.sineSlip)* 12 *(Math.PI*2)/180 ; //角度の幅は12度内に固定。これ以上だと暴走しやすい
}
// 【速度変化】加速能力:時間条件が満たされたら加速
if (_AA != null && _AA.intervalRun > 0 && (_liveCount % _AA.intervalRun == 0 )) {
_currentSpeed = _AA.SpeedChange(_currentSpeed);
}
// 【速度変化】全キャラ共通:移動速度をわずかにふらつかせる(+-は周期変化)
_currentSpeed += Math.sin(_liveCount)*(Math.random()*0.1) ;
//【速度と向きの計算】
if (_currentSpeed <= _type.MinSpeed) { _currentSpeed = _type.MinSpeed };
if (_currentSpeed >= _type.MaxSpeed) { _currentSpeed = _type.MaxSpeed };
_velocity.x = (_velocity.x + _currentSpeed * Math.cos(radian)) * 0.5;
_velocity.y = (_velocity.y + _currentSpeed * Math.sin(radian)) * 0.5;
var degree:Number = radian * 180 / Math.PI;
_image.rotation = degree;
// 【向き変化】Decoyのみ向きは動きと無関係に回転
if (_type.name == "Decoy-1") { _image.rotation = (_liveCount * 90 / Math.PI) };
if (_type.name == "Decoy-2") { _image.rotation = (_liveCount * 90 / Math.PI) * ( -1) };
if ((_type.name == "Decoy-1" || _type.name == "Decoy-2") && _liveCount > (5 * Const.FRAME_RATE)) { _world.removeEnemy(this) };
// 時限性の出産があれば出産
if (_BA != null && _BA.intervalBorn > 0 && (_liveCount % _BA.intervalBorn == 0 )) {
_babyNum = _BA.EnemyBirth(_babyNum,"interval", this, _center, _maxHP, _point, _money, _world);
if (_BA.selfRemove ) {
_HP = 0;
_BA = null;
_world.removeEnemy(this);}
}
}
private static const CONDITION_GOOD:Array = [];
private static const CONDITION_SLOWED:Array = [new GlowFilter(0x0088ff, 1, 4, 4)];
private static const CONDITION_VENOMED:Array = [new GlowFilter(0x00ff00, 1, 2, 2,255,1,true)];
// ダメージを受ける処理
public function damage(amount:Number, level:int, slow:int, venom:int ):void {
_HP -= amount;
if (_HP <= 0) { DoomAction() } ;
_HPbar.scaleX = _HP / _maxHP;
//以下、生きている場合のみ適用
if (_HP > 0){
// 能力を持っている場合に、HP割合条件による能力の作動
if (_BA != null && _BA.HPrateBorn > 0 && _HP <= (_BA.HPrateBorn * _maxHP)) {
_babyNum = _BA.EnemyBirth(_babyNum,"damaged",this, _center, _maxHP, _point, _money, _world);
if (_BA.selfRemove ) {
_HP = 0;
_world.removeEnemy(this);}
}
if (_AA != null && _AA.HPrateRun > 0 && _HP <= (_AA.HPrateRun * _maxHP)) {
_currentSpeed = _AA.SpeedChange(_currentSpeed);
}
// 攻撃にスロー効果が付いていて、それに免疫が無かったら、スロー状態になる
if (( slow > 0 ) && !_type.immunity) {
_attackedSlow = (100 - slow - level*5) ;
_slowingCount = Const.SLOWING_DURATION;
_image.filters = CONDITION_SLOWED;
}
// 攻撃に毒効果が付いていたら、毒状態になる(高レベルの毒効果優先、途中で低レベルの毒攻撃を受けると持続時間リセット)
if (( venom > 0 ) && !_type.immunity) {
if ( _venomingLevel < level){
_venomingLevel = level } ;
_venomingCount = venom * Const.VENOMING_DURATION;
_HPbar.filters = CONDITION_VENOMED;
}
// 加速能力を持っていて、ダメージ量の加速条件があるとき、ダメージが条件値以上なら加速
if (_AA != null && _AA.damageRun > 0 && amount >= _AA.damageRun) {
var changedSpeed : Number = _AA.SpeedChange(_currentSpeed);
_currentSpeed = changedSpeed;
}
}
}
//-------------------------------------------------
// 死亡時アクション
private function DoomAction():void {
GameData.instance.score += _point;
// 毒状態で死んだときインフェクション発生
if (_venomingCount > 0 ) {
var Infection:BitmapData = ImageFactory.getImage("Infection");
_world.addBullet( new Bullet(_center, 0, 1, 12, 2, true, false, 1, 0, 5, false, false, this, Infection, _world) );
}
// 死亡出産のチェック
if( _BA != null && _BA.deadBorn ){
_babyNum = _BA.EnemyBirth(_babyNum,"dead",this, _center, _maxHP, _point, _money, _world);
if (_BA.descent) { _money = 0 };
}
_world.removeEnemy(this);
GameData.instance.gold += _money;
if(_money > 0){_world.addEffect(new Coin(_center.x, _center.y))};
//return;
}
public function hasPathToGoal():Boolean {
return _goal.hasPath(_center.tileX, _center.tileY);
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* EnemyType
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.utils.Dictionary;
//public
class EnemyType {
private static var _types:Dictionary;
public static function initialize():void { _types = Config.getEnemyType(); }
public static function getType(typeName:String):EnemyType { return _types[typeName]; }
private var _name:String; // 種族名称
private var _speed:Number; // 移動の速さ
private var _MinSpeed:Number; // 移動の最小速度(スロー効果含めない)
private var _MaxSpeed:Number; // 移動の最大速度
private var _flying:Boolean; // 飛んでいるかどうか
private var _immunity:Boolean; // 免疫(状態異常スローに対する)があるかどうか
private var _regeneration:int; // HPの回復量(MaxHPの千分率/フレーム)
private var _fade:int; // フェイド能力量(時間間隔)
private var _born:Boolean; // 出産能力があるかどうか
private var _accelerate:Boolean; // 加速能力があるかどうか
public function get name():String { return _name; }
public function get speed():Number { return _speed; }
public function get MinSpeed():Number { return _MinSpeed; }
public function get MaxSpeed():Number { return _MaxSpeed; }
public function get flying():Boolean { return _flying; }
public function get immunity():Boolean { return _immunity; }
public function get regeneration():int { return _regeneration; }
public function get fade():int { return _fade; }
public function get born():Boolean { return _born; }
public function get accelerate():Boolean { return _accelerate; }
// ※インスタンスは Config.getEnemyType() から生成する
public function EnemyType(name:String, speed:Number, MinSpeed:Number,MaxSpeed:Number,flying:Boolean, immunity:Boolean,
regeneration:int, fade:int, born:Boolean, accelerate:Boolean) {
_name = name;
_speed = speed;
_MinSpeed = MinSpeed;
_MaxSpeed = MaxSpeed;
_flying = flying;
_immunity = immunity;
_regeneration = regeneration;
_fade = fade;
_born = born;
_accelerate = accelerate;
}
}
//}
/*----------------------------------------------------------------------------------------------------------------------
* BornAbility 出産能力管理【F】
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.utils.Dictionary;
//public
class BornAbility {
private static var _parent:Dictionary;
public static function initialize():void { _parent = Config.getBornAbility(); }
public static function getBornData (parentName:String):BornAbility { return _parent[parentName]; }
private var _name:String; //親の名前
private var _childrenName:String; //生まれる子の名前
private var _childrenHP:Number; //生まれる子のHP (親に対する割合)
private var _childrenPoint:Number; //生まれる子のPoint (親に対する割合)
private var _amount:int; //1回の出産で生まれる数
private var _limit:int; //出産数の限界量
private var _intervalBorn:int; //時間制で生まれるとき、その時間間隔
private var _HPrateBorn:Number; //HPの残量で生まれるとき、その残りHP割合
private var _deadBorn:Boolean; //ダメージ量で生まれるとき、生まれる最低ダメージ
private var _descent:Boolean; //相続の有無。TRUEのとき自分はお金を出さず、子がお金を出す
private var _selfRemove:Boolean; //自己消去の有無。TRUEのとき出産と同時におやは消える
private var _childrenFull:Boolean; //子どもが満員のお知らせ。値は計算ごとに更新される
public function get name():String { return _name; }
public function get childrenName():String { return _childrenName; }
public function get childrenHP():Number { return _childrenHP; }
public function get childrenPoint():Number { return _childrenPoint; }
public function get amount():int { return _amount; }
public function get limit():int { return _limit; }
public function get intervalBorn():int { return _intervalBorn; }
public function get HPrateBorn():Number { return _HPrateBorn; }
public function get deadBorn():Boolean { return _deadBorn; }
public function get descent():Boolean { return _descent; }
public function get selfRemove ():Boolean { return _selfRemove; }
public function get childrenFull ():Boolean { return _childrenFull; }
public function EnemyBirth(babyNum:int, chance:String, parent:Enemy, center:TileBasedPoint, MaxHP:int, point:int, money:int, world:World):int{
var _money:int = money;
if ( !_descent ) { _money = 0 } ; //「相続」がfalseの場合、子どもが持つ報酬は0に
for ( var i:int = 1; i <= _amount ; i++){
if (babyNum < limit) {
var enemyChildren:Enemy = new Enemy(TileBasedPoint.createFromWorldPos(center.x, center.y), EnemyType.getType(_childrenName), int(Math.ceil(MaxHP*_childrenHP)), int(Math.ceil(point*_childrenPoint)), _money, world, true);
world.addEnemy(enemyChildren);
babyNum ++;
_childrenFull = false;
}else if (babyNum >= limit) { _childrenFull = true };
}
return babyNum;
}
// ※インスタンスは Config.getBornAbility() から生成する
public function BornAbility(name:String, childrenName:String, childrenHP:Number, childrenPoint:Number, amount:int, limit:int,
intervalBorn:int, HPrateBorn:Number, deadBorn:Boolean, descent:Boolean, selfRemove:Boolean) {
_name = name;
_childrenName = childrenName;
_childrenHP = childrenHP;
_childrenPoint = childrenPoint;
_amount = amount;
_limit = limit;
_intervalBorn = intervalBorn;
_HPrateBorn = HPrateBorn;
_deadBorn = deadBorn;
_descent = descent;
_selfRemove = selfRemove;
_childrenFull = false;
}
}
//}
/*
/*----------------------------------------------------------------------------------------------------------------------
* AccelerateAbility 加速能力管理【F】
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.utils.Dictionary;
//public
class AccelerateAbility {
private static var _runner:Dictionary;
public static function initialize():void { _runner = Config.getAccelerateAbility(); }
public static function getAccelerateData (runnerName:String):AccelerateAbility { return _runner[runnerName]; }
private var _name:String; //能力者のタイプ名
private var _AddPoint:Number; //速度加算量(マイナスあり)
private var _RatePoint:Number; //速度割合変化量
private var _Angle:Number; //飛行角度(度数値)
private var _sineSlip:int; //ふらふら移動するときの周期量
private var _intervalRun:int; //時間制で変化するとき、その時間間隔
private var _HPrateRun:Number; //HPの残量で加速するとき、その残りHP割合
private var _damageRun:Number; //ダメージ量で加速するときの最低ダメージ(割合)
public function get name():String { return _name; }
public function get AddPoint():Number { return _AddPoint; }
public function get RatePoint():Number { return _RatePoint; }
public function get Angle():int { return _Angle; }
public function get sineSlip():int { return _sineSlip; }
public function get intervalRun():int { return _intervalRun; }
public function get HPrateRun():Number { return _HPrateRun; }
public function get damageRun():Number { return _damageRun; }
//---------------------------
public function SpeedChange(speed:Number):Number{
speed = (_RatePoint * speed) + _AddPoint;
return speed ;
}
// ※インスタンスは Config.getAccelerateAbility() から生成する
public function AccelerateAbility(name:String, AddPoint:Number, RatePoint:Number, Angle:Number, sineSlip:int,
intervalRun:int, HPrateRun:Number, damageRun:Number ) {
_name = name;
_AddPoint = AddPoint;
_RatePoint = RatePoint;
_Angle = Angle;
_sineSlip = sineSlip;
_intervalRun = intervalRun;
_HPrateRun = HPrateRun;
_damageRun = damageRun;
}
}
//}
/*
/* ----------------------------------------------------------------------------------------------------------------------
* Coin
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Back;
import org.libspark.betweenas3.easing.Expo;
//public
class Coin extends Sprite {
public function Coin(posx:int, posy:int) {
x = posx;
y = posy;
draw();
BetweenAS3.serial (
BetweenAS3.tween(this, { $y: -16 }, null, 0.4, Back.easeOut),
BetweenAS3.tween(this, { alpha: 0 }, null, 0.4, Expo.easeIn),
BetweenAS3.removeFromParent(this)
).play();
}
private function draw():void {
var bitmap:Bitmap = new Bitmap(ImageFactory.getImage("Coin"));
bitmap.smoothing = true;
bitmap.x = bitmap.y = -4;
addChild(bitmap);
}
}
//}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* SplashEffect 【F】
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import org.libspark.betweenas3.BetweenAS3;
import org.libspark.betweenas3.easing.Expo;
//public
class splashEffect extends Sprite {
//爆発エフェクト (位置x、位置y、スプレッドサイズ、色、時間)
public function splashEffect(posx:int, posy:int, size:int, color:uint ,appearTime:int) {
x = posx;
y = posy;
drawSplash(color);
//サイズ値の半径まで拡大、scaleの拡大は右下に伸びるので、同時に基点座標(左上)を動かし、見た目の場所を固定する
BetweenAS3.serial (
BetweenAS3.tween(this, { $scaleX: size ,$scaleY: size, alpha: 0 ,$x: -size ,$y: -size }, null, appearTime, Expo.easeOut),
BetweenAS3.removeFromParent(this)
).play();
}
private function drawSplash(color:uint):void {
var sprite:Sprite = new Sprite ;
sprite.graphics.beginFill(color,0.8);
sprite.graphics.drawCircle(1,1,1);
sprite.x = sprite.y=0 ;
addChild(sprite);
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Cursor タワー選択などの動作時にカーソルが変化
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
//public
class Cursor extends Sprite {
private var _world:World;
private var _border:Sprite; // 枠線
private var _baseborder:Sprite; //選択中の四角い枠追加【F】
private var _towerImage:Sprite; // タワーの画像
private var _towerBody:Bitmap; // タワー本体の画像
private var _blockingText:TextField; //ブロッキングの文字表示
private var _blockingAlart:int
public function Cursor(world:World) {
_world = world;
_border = createBorder(0xffff00);
_baseborder = createBorder(0xff0000); //選択中の四角い枠追加【F】
_towerImage = new Sprite();
_towerImage.addChild(_towerBody = new Bitmap());
_towerImage.alpha = 0.5;
_blockingText = ImageFactory.createBorderedText(0, 0, 60, 15, "Blocking!", 12, 0xff0000, 0xffffff);
_blockingAlart = 0;
mouseChildren = mouseEnabled = false;
GameData.instance.addEventListener(Const.EVENT_CHANGE_SELECTEDTOWER, onUpdateSelectedTower);
}
// マップ上でタワー選択時に表示する囲み線を生成【F】
private function createBorder(borderColor:uint):Sprite {
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(2, borderColor);
sprite.graphics.drawRect(0, 0, Const.TOWER_SIZE, Const.TOWER_SIZE);
return sprite;
}
//ブロッキング警告
public function blockingAlart():void {
_blockingAlart = 15;
_blockingText.x = -10 ;
_blockingText.y = 2 ;
_blockingText.alpha = 1;
addChild(_blockingText);
}
//
public function update(posx:int, posy:int):void {
var selectedTower:Tower = GameData.instance.selectedTower;
var position:TileBasedPoint;
// (selectedTowerがnullでない)かつ(selectedTower.activeがtrue)とき
if (selectedTower != null && selectedTower.active) {
position = TileBasedPoint.createFromWorldPos(selectedTower.x, selectedTower.y);
}else {
position = TileBasedPoint.createFromWorldPos(posx, posy);
position.setTilePos(position.tileX, position.tileY);
}
x = position.x;
y = position.y;
updateRangeCircle(position.tileX, position.tileY);
updateBlockingAlart();
}
private function updateBlockingAlart():void {
if ( _blockingAlart > 0) {
_blockingAlart-- ;
_blockingText.alpha -= 0.04;
if (_blockingAlart == 0) { removeChild(_blockingText) };
}
}
// 設置可否で変える色の設定
private static const POSSIBLE:uint = 0xffffff;
private static const IMPOSSIBLE:uint = 0xff0000;
private function updateRangeCircle(tilex:int, tiley:int):void {
graphics.clear();
var selectedTower:Tower = GameData.instance.selectedTower;
if (selectedTower == null) { return; }
// 配置できる場所かどうかで、レンジサークルの色を変える【F】
var color:uint = (selectedTower.active || _world.canBuildTower(tilex, tiley)) ? POSSIBLE : IMPOSSIBLE;
graphics.lineStyle(0, color, 0.6);
graphics.beginFill(color, 0.2);
graphics.drawCircle(int(Const.TOWER_SIZE / 2), int(Const.TOWER_SIZE / 2), selectedTower.type.getStatus(selectedTower.level).range);
graphics.endFill();
//配置できない場所ではカーソルが赤い四角になる【F】
if(_world.canBuildTower(tilex, tiley) || selectedTower.active ) {
if (contains(_baseborder)) {removeChild(_baseborder)};
}else{addChild(_baseborder)}
}
private function onUpdateSelectedTower(e:Event):void {
var selectedTower:Tower = GameData.instance.selectedTower;
if (contains(_border)) { removeChild(_border); }
if (contains(_baseborder)) { removeChild(_baseborder); }
if (contains(_towerImage)) { removeChild(_towerImage); }
if (selectedTower == null) { return; }
// タワーが選択中なら囲み線表示
if (selectedTower.active) {
addChild(_border);
}else {
_towerBody.bitmapData = ImageFactory.getImage(selectedTower.type.name);
_towerBody.smoothing = true;
addChild(_towerImage);
}
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Frontend
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.filters.GlowFilter;
import flash.geom.ColorTransform;
import flash.text.TextField;
import flash.ui.Keyboard;
//public
class Frontend extends Sprite {
private var _wave:TextField;
private var _score:TextField;
private var _lives:TextField;
private var _gold:TextField;
private var _backSprite:Sprite; //背景的な使用のスプライト
private var _buttons:Sprite; // ボタンをまとめる表示オブジェクト
private var _towerStatus:TowerStatusWindow; // タワーのステータスを表示するウインドウ
public function Frontend(posx:int, posy:int) {
x = posx;
y = posy;
addChild(createTowerSelectionWindow(365, 0));
addChild(createGameStatusWindow(0, 0));
GameData.instance.addEventListener(Const.EVENT_CHANGE_SELECTEDTOWER, onUpdateSelectedTower);
GameData.instance.addEventListener(Const.EVENT_CHANGE_GAMESTATUS, onUpdateGameStatus);
}
// タワー選択ボタンを配置するウインドウと、タワーのステータスを表示するウインドウを作成する
private function createTowerSelectionWindow(posx:int, posy:int):Sprite {
var towerSelection:Sprite = ImageFactory.createWindow(posx, posy, 100, 417);
towerSelection.addChild(_backSprite = new Sprite());
_backSprite.graphics.beginFill(0x505050);_backSprite.graphics.drawRect(5,30,90,110);
_backSprite.addChild(ImageFactory.createSimpleText(5,-15, 10, 90, "Tower", 10, 0xffffff));
_backSprite.graphics.beginFill(0x505050);_backSprite.graphics.drawRect(5,150,90,70);
// タワー選択ボタンを7つ作成して配置する
towerSelection.addChild(_buttons = new Sprite());
var towertypes:Vector.<TowerType> = Config.getTowerType();
for (var i:int = 0; i < 7; i++) {
//var tower:Tower = _buttons.addChild(new Tower(((i < 4) ? 15 : 53), 32 + 38 * (i % 4), towertypes[i])) as Tower;
var tower:Tower = _buttons.addChild(new Tower(12 + 26 * (i % 3),5 + Math.ceil((i+1)/ 3)*35, towertypes[i])) as Tower;
//tower.addChild(ImageFactory.createSimpleText(((i < 4) ? -12 : 32), 0, 12, 32, String(i + 1), 10, 0xffffff));
tower.scaleX = 0.75; tower.scaleY = 0.75;
HotKey.bind(Keyboard.NUMBER_1 + i, tower.clickTower);
HotKey.bind(Keyboard.NUMPAD_1 + i, tower.clickTower);
}
// 選択キャンセルボタンを作成して配置する
var cancelButton:Sprite = towerSelection.addChild(createCancelButton(12 + 27, 5 + 3*35)) as Sprite;
//cancelButton.addChild(ImageFactory.createSimpleText(32, 0, 12, 32, "0", 10, 0xffffff));
cancelButton.scaleX=0.75; cancelButton.scaleY=0.75;
HotKey.bind(Keyboard.NUMBER_0, isSelectedCancelButton);
HotKey.bind(Keyboard.NUMPAD_0, isSelectedCancelButton);
HotKey.bind(Keyboard.ESCAPE, isSelectedCancelButton);
// 選択ウィンドウ内にテータスウィンドウを設置し隠しておく【F】
towerSelection.addChild(_towerStatus = new TowerStatusWindow(5, 225));
_towerStatus.visible = false;
return towerSelection;
}
// ゲームのステータスを表示するウインドウを作成する
private function createGameStatusWindow(posx:int, posy:int):Sprite {
var gameStatus:Sprite = ImageFactory.createWindow(posx, posy, 463, 25);
gameStatus.addChild(ImageFactory.createBorderedText(14, 0, 40, 25, "Wave :", 12, 0xffffff, 0x808080));
gameStatus.addChild(_wave = ImageFactory.createScoreText(54, 0, 25, 25, "0", 14, 0xffffff));
gameStatus.addChild(ImageFactory.createBorderedText(93, 0, 40, 25, "Score :", 12, 0xffffff, 0x808080));
gameStatus.addChild(_score = ImageFactory.createScoreText(133, 0, 50, 25, "0", 14, 0xffffff));
gameStatus.addChild(ImageFactory.createBorderedText(197, 0, 40, 25, "Lives :", 12, 0xffffff, 0xf00000));
gameStatus.addChild(_lives = ImageFactory.createScoreText(237, 0, 20, 25, "0", 14, 0xff0000));
gameStatus.addChild(ImageFactory.createBorderedText(370, 0, 35, 25, "$ :", 12, 0xffffff, 0xb0b000));
gameStatus.addChild(_gold = ImageFactory.createScoreText(406, 0, 45, 25, "0", 14, 0xffff00));
return gameStatus;
}
// 選択キャンセルボタンを作成する
private function createCancelButton(posx:int, posy:int):Sprite {
var cancel:Sprite = new Sprite();
cancel.x = posx;
cancel.y = posy;
cancel.addChild(new Bitmap(ImageFactory.getImage("Cancel")));
cancel.buttonMode = true;
cancel.addEventListener(MouseEvent.CLICK, isSelectedCancelButton);
return cancel;
}
private function isSelectedCancelButton(e:MouseEvent = null):void { GameData.instance.selectedTower = null; }
//カラートランスフォームで「明るい(値のまま)」と「暗くする(値半減)」を定義【F】
private static const LIGHTEN:ColorTransform = new ColorTransform();
private static const DARKEN:ColorTransform = new ColorTransform(0.5, 0.5, 0.5);
public function onUpdateGameStatus(e:Event):void {
var data:GameData = GameData.instance;
_wave.text = data.wave.toString();
_score.text = data.score.toString();
_lives.text = data.lives.toString();
_gold.text = data.gold.toString();
// タワーが購入できるかどうかで、タワー選択ボタンに明暗をつける
for (var i:int = 0; i < _buttons.numChildren; i++) {
var button:Tower = _buttons.getChildAt(i) as Tower;
button.transform.colorTransform = ((button.type.getStatus(button.level).cost <= data.gold) ? LIGHTEN: DARKEN);
}
// アップグレードボタンの有効/無効を反映させる
if (_towerStatus.visible) { _towerStatus.updateUpgradeButton(); }
}
private static const NON_GLOW:Array = [];
private static const GLOW:Array = [new GlowFilter(0xffff00, 1, 8, 8)];
public function onUpdateSelectedTower(e:Event):void {
var selectedTower:Tower = GameData.instance.selectedTower;
// タワー選択ボタンのハイライトを解除する
for (var i:int = 0; i < _buttons.numChildren; i++) {
_buttons.getChildAt(i).filters = NON_GLOW;
}
if (selectedTower != null) {
_buttons.removeEventListener(MouseEvent.MOUSE_OVER, onMouseOverButton);
_buttons.removeEventListener(MouseEvent.MOUSE_OUT, onMouseOutButton);
_towerStatus.update(selectedTower);
_towerStatus.visible = true;
// 選択されたボタンにハイライトをつける
if (!selectedTower.active) { selectedTower.filters = GLOW; }
}else {
_buttons.addEventListener(MouseEvent.MOUSE_OVER, onMouseOverButton);
_buttons.addEventListener(MouseEvent.MOUSE_OUT, onMouseOutButton);
_towerStatus.visible = false;
}
}
// タワー非選択時、選択ボタンにマウスオーバーでステータスを表示するようにする
private function onMouseOverButton(e:MouseEvent):void {
_towerStatus.update(Tower(e.target));
_towerStatus.visible = true;
}
private function onMouseOutButton(e:MouseEvent):void {
_towerStatus.visible = false;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* TowerStatusWindow タワーステータスウィンドウ
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import com.bit101.components.PushButton;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.ui.Keyboard;
//public
class TowerStatusWindow extends Sprite {
private var _towerName:TextField;
//シンボルスプライトを追加【F】
private var _synbolKinds:Array = ["groundSynbol","airSynbol","slowSynbol","venomSynbol"];
private var _synbolWalking:Sprite;
private var _synbolFlying:Sprite;
private var _synbolSlow:Sprite;
private var _synbolVenom:Sprite;
private var _synbolMarks:Array = ["gradeSynbol","damageSynbol","rangeSynbol","reloadSynbol"];
private var _level:TextField; private var _levelAdd:TextField;
private var _cost:TextField; private var _costAdd:int;
private var _sell:TextField;
private var _damage:TextField; private var _damageAdd:TextField;
private var _range:TextField; private var _rangeAdd:TextField;
private var _firerate:TextField; private var _firerateAdd:TextField;
private var _upgradeButton:PushButton;
private var _sellButton:PushButton;
private static const LIGHTEN:uint = 0xffffff;
private static const DARKEN:uint = 0x606060;
public function TowerStatusWindow(posx:int, posy:int):void {
x = posx;
y = posy;
addChild(ImageFactory.createWindow(0, 0, 90, 190));
addChild(ImageFactory.createWindow(0, 0, 90, 20));
//ImageFactoryで定義したSimpleテキストで文字を作成【F】
addChild(_towerName = ImageFactory.createSimpleText(0, 0, 90, 20, "Tower", 12, 0xffffff));
//タワー属性のシンボルを配置【F】
//シンボルつくって設置。表示更新時にタワーの引数にあわせて見えるor見えない【F】
_synbolWalking = addChild(createSynbol(5,25,0)) as Sprite;
_synbolFlying = addChild(createSynbol(25,25,1)) as Sprite;
_synbolSlow = addChild(createSynbol(45,25,2)) as Sprite;
_synbolVenom = addChild(createSynbol(65,25,3)) as Sprite;
//ステータスのシンボルとステータス文字を配置【F】
//左にシンボル、右に数字を配置。Upgrade情報は別のフィールドで色を変えて配置。【F】
addChild(createStatusSynbol(5,45,0)); //レベル
addChild(_level = ImageFactory.createStatusText(3, 45, 60, 15, "E", 12, 0xffffff));
addChild(_levelAdd = ImageFactory.createStatusText(32, 40, 60, 15, "", 10, 0x22aa22));
addChild(createStatusSynbol(5,70,1)); //攻撃力 (上のアイコンとの高さの差25)
addChild(_damage = ImageFactory.createStatusText(3, 70, 60, 15, "0", 12, 0xffffff));
addChild(_damageAdd = ImageFactory.createStatusText(32, 65, 60, 15, "", 10, 0x22aa22));
addChild(createStatusSynbol(5,95,2)); //範囲
addChild(_range = ImageFactory.createStatusText(3, 95, 60, 15, "0", 12, 0xffffff));
addChild(_rangeAdd = ImageFactory.createStatusText(32, 90, 60, 15, "", 10, 0x22aa22));
addChild(createStatusSynbol(5,120,3)); //装填速度
addChild(_firerate = ImageFactory.createStatusText(3, 120, 60, 15, "0", 12, 0xffffff));
addChild(_firerateAdd = ImageFactory.createStatusText(32, 115, 60, 15, "", 10, 0x22aa22));
//コスト
_upgradeButton = new PushButton(this, 5, 145, " ", upgradeSelectedTower);
addChild(_cost = ImageFactory.createStatusText(5, 146, 80, 15, " ", 10, 0x505050));
_sellButton = new PushButton(this, 5, 166, "", sellSelectedTower);
addChild(_sell = ImageFactory.createStatusText(5, 167, 80, 15, " ", 10, 0x505050));
_upgradeButton.width = _sellButton.width = 80;
// 各ボタンに対応するホットキーを設定する
HotKey.bind(Keyboard.U, upgradeSelectedTower);
HotKey.bind(Keyboard.S, sellSelectedTower);
}
//タワー属性のシンボルマークを設置するファンクション【F】
private function createSynbol(posx:int,posy:int,arrayNum:int):Sprite{
var Synbol:Sprite = new Sprite();
Synbol.x = posx ; Synbol.y = posy ;
Synbol.addChild(new Bitmap(ImageFactory.getImage(_synbolKinds[arrayNum])));
Synbol.visible = true;
return Synbol;
}
//ステータスのシンボルマークを設置するファンクション【F】
private function createStatusSynbol(posx:int,posy:int,arrayNum:int):Sprite{
var Synbol:Sprite = new Sprite();
Synbol.x = posx ; Synbol.y = posy ;
Synbol.addChild(new Bitmap(ImageFactory.getImage(_synbolMarks[arrayNum])));
return Synbol;
}
private function upgradeSelectedTower(e:MouseEvent = null):void {
var selectedTower:Tower = GameData.instance.selectedTower;
if (selectedTower != null && selectedTower.active) {
selectedTower.upgrade();
}
}
private function sellSelectedTower(e:MouseEvent = null):void {
var selectedTower:Tower = GameData.instance.selectedTower;
if (selectedTower != null && selectedTower.active) {
selectedTower.sell();
}
}
// 引数で与えたタワーのステータス表示に更新する
public function update(tower:Tower):void {
var type:TowerType = tower.type;
var status:TowerStatus = type.getStatus(tower.level);
_level.text = tower.level.toString();
_cost.text = status.cost.toString();
_damage.text = status.damage.toString();
_range.text = status.range.toString();
_firerate.text = status.firerate.toFixed(1);
_levelAdd.text = _damageAdd.text = _rangeAdd.text = _firerateAdd.text = _cost.text = _sell.text = "" ;
//_towerName.text = type.name + " Tower";
_towerName.text = type.name + " ($"+ status.cost.toString()+ ")" ;
//シンボルの表示visible = タイプ関数の真偽【F】
_synbolWalking.visible = type.ground;
_synbolFlying.visible = type.air;
_synbolSlow.visible = (type.slow > 0);
_synbolVenom.visible = (type.venom > 0);
// タワーが選択ボタンのものならボタンを隠して、処理を終える
if (!tower.active) {
_upgradeButton.visible = _sellButton.visible = false;
return;
}
// アップグレード可能か、アップグレード時の上昇値はいくつかを表示に反映させる
_upgradeButton.visible = _sellButton.visible = true;
updateUpgradeButton();
if (type.hasStatus(tower.level + 1)) {
var nextStatus:TowerStatus = type.getStatus(tower.level + 1);
_levelAdd.text = (" → " + nextStatus.level.toString());
_costAdd = nextStatus.cost - status.cost;
//レベルとコスト表示【F】
_cost.text = ( "Lv" + nextStatus.level.toString() + " [" + _costAdd.toString() + "]");
if (nextStatus.damage - status.damage > 0) {
_damageAdd.text = (" → " + nextStatus.damage.toString()); }
if (nextStatus.range - status.range > 0) { _rangeAdd.text = (" → " + nextStatus.range.toString()); }
if (nextStatus.firerate - status.firerate > 0) { _firerateAdd.text = (" → " + nextStatus.firerate.toFixed(1)); }
else if (nextStatus.firerate - status.firerate < 0) { _firerateAdd.text = (" → " + nextStatus.firerate.toFixed(1)); }
}
var _sellValue:int = status.cost * GameData.instance.sellingRatio;
_sell.text = ( "Sell [" + _sellValue.toString() + "]" );
}
public function updateUpgradeButton():void {
var selectedTower:Tower = GameData.instance.selectedTower;
if (selectedTower == null || !selectedTower.active || !selectedTower.type.hasStatus(selectedTower.level + 1)) {
_upgradeButton.enabled = false;
return;
}
var upgradeCost:int = selectedTower.type.getStatus(selectedTower.level + 1).cost - selectedTower.type.getStatus(selectedTower.level).cost;
_upgradeButton.enabled = (GameData.instance.gold >= upgradeCost) ? true : false;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* WaveManager
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.geom.Rectangle;
//public
class WaveManager extends Sprite {
private var _currentWave:int;
private var _waves:Vector.<Wave>;
private var _onScreen:BitmapData;
private var _offScreen:Sprite;
private var _offScreenPosX:int;
private var _nextWaveCount:int;
private var _countDownText:TextField;
private var _countDown:int;
public function finished():Boolean { return _currentWave == _waves.length; }
public function WaveManager(posx:int, posy:int, world:World) {
x = posx;
y = posy;
_waves = Config.getWaves();
_offScreen = new Sprite();
for (var i:int = 0; i < _waves.length; i++) {
var wave:Wave = _waves[i];
wave.x = i * Const.WAVE_WIDTH;
wave.setWorld(world);
_offScreen.addChild(wave);
}
createWaveManagementWindow();
initialize();
}
public function initialize():void {
_currentWave = 0;
_offScreenPosX = 301;
_offScreen.x = _offScreenPosX / 10;
updateOnScreen();
_nextWaveCount = 1;
for (var i:int = 0; i < _waves.length; i++) {
_waves[i].initialize();
}
}
private function updateOnScreen():void {
_onScreen.fillRect(ONSCREEN_RECT, 0x000000);
_onScreen.draw(_offScreen, _offScreen.transform.matrix);
}
private function createWaveManagementWindow():void {
var window:Sprite = addChild(ImageFactory.createWindow(-10, 0, 475, 50)) as Sprite;
_onScreen = new BitmapData(365, 30, false, 0x000000);
var bitmap:Bitmap = window.addChild(new Bitmap(_onScreen)) as Bitmap;
bitmap.x = bitmap.y = 10;
var line:Sprite = window.addChild(new Sprite()) as Sprite;
line.graphics.lineStyle(1, 0xffff00);
line.graphics.moveTo(40, 2);
line.graphics.lineTo(40, 48);
_countDown = 0 ;
addChild(ImageFactory.createSimpleText(19,30, 100, 15, "Send Bonus", 10, 0xffffff));
addChild(_countDownText = ImageFactory.createStatusTextRight(75, 30, 80, 15, _countDown.toString(), 10, 0xffffff));
}
private static const ONSCREEN_RECT:Rectangle = new Rectangle(0, 0, 365, 30);
public function update():void {
_offScreenPosX--;
if (_offScreenPosX % 10 == 0) { _offScreen.x = _offScreenPosX / 10; }
updateOnScreen();
_nextWaveCount--;
_countDown = int(_nextWaveCount / Const.WAVE_INTERVAL * 10) ;
if (_currentWave == _waves.length) {
_countDownText.text = "0" ;
} else { _countDownText.text = "$ " + _countDown.toString() + " × " + (int(_currentWave / 5) +1) ; }
if (_nextWaveCount == 0) {
sendNextWave();
}
for (var i:int = 0; i < _waves.length; i++) {
_waves[i].update();
}
}
public function sendNextWave():void {
// 全てのWaveが送出されていたら何もせずに終了する
if (_currentWave == _waves.length) { return; }
_currentWave++;
GameData.instance.wave = _currentWave;
_waves[_currentWave - 1].send();
// 先送りしていたら、その分をスコアに加算する
GameData.instance.score += int(_nextWaveCount / 10);
// 先送りしていたら、センドボーナスのお金を追加する
_countDown = int(_nextWaveCount / Const.WAVE_INTERVAL * 10) ;
GameData.instance.gold += _countDown * (int((_currentWave - 1)/5) +1);
if((_countDown * (int((_currentWave - 1)/5) +1)) > 0 ) {addChild(new Coin(36,40))};
_offScreenPosX -= _nextWaveCount;
_offScreen.x = _offScreenPosX / 10;
updateOnScreen();
_nextWaveCount = Const.WAVE_INTERVAL;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Wave ウェイブの処理とバーグラフィックなど
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Sprite;
import flash.utils.Dictionary;
import flash.display.GradientType;
//public
class Wave extends Sprite {
private var _world:World;
private var _number:int; // Wave数
private var _enemyType:EnemyType; // 敵のタイプ
private var _enemyHP:int; // 敵のHP
private var _enemyPoint:int; // 敵を倒した時のポイント
private var _enemyMoney:int; // 敵を倒した時の入手金
private var _enemyNum:Vector.<int>; // 出現する敵の数
private var _isActivated:Boolean; // 送出中かどうか
private var _allEnemiesSent:Boolean; // 全ての敵が送出されたかどうか
private var _spawnInterval:int; // 敵の出現間隔
private var _spawnCount:int; // 出現カウント
private var _waitingNum:Vector.<int>; // 待機中の敵の数
public function setWorld(value:World):void { _world = value; }
public function Wave(number:int, type:EnemyType, HP:int, point:int, money:int, numSpawning:Vector.<int>) {
_number = number
_enemyType = type;
_enemyHP = HP;
_enemyPoint = point;
_enemyMoney = money;
_enemyNum = numSpawning;
initialize();
var max:int = 0;
for (var i:int = 0; i < _enemyNum.length; i++) {
if (_enemyNum[i] > max) { max = _enemyNum[i]; }
}
_spawnInterval = int((Const.WAVE_INTERVAL / 4) / max);
_spawnCount = 0;
_waitingNum = new Vector.<int>(_enemyNum.length);
draw();
}
public function initialize():void {
_isActivated = false;
_allEnemiesSent = false;
}
// ウェイブバーを描く (出現する敵の種類によって色を設定)
private function draw():void {
var bodyColor:uint, borderColor:uint;
switch(_enemyType.name) { //bodyColor 数字以外の部分 borderColorは数字などの部分
case "Immune": { bodyColor = 0xccaaee; borderColor = 0x664488; break; }
case "Fast": { bodyColor = 0x99aaff; borderColor = 0x6688dd; break; }
case "Flying": { bodyColor = 0xffdd00; borderColor = 0xddaa00; break; }
case "Swarm": { bodyColor = 0xaaaa88; borderColor = 0x888866; break; }
case "Zombie": { bodyColor = 0x55ddff; borderColor = 0x00aacc; break; }
case "Fade": { bodyColor = 0xcccccc; borderColor = 0x999999; break; }
case "Split": { bodyColor = 0x55cc88; borderColor = 0x053305; break; }
case "Fury": { bodyColor = 0xff3333; borderColor = 0xdd0000; break; }
case "Shell": { bodyColor = 0xaaaa44; borderColor = 0x444422; break; }
case "Fupa": { bodyColor = 0xffccaa; borderColor = 0xccaa77; break; }
case "Ghost": { bodyColor = 0xffeeaa; borderColor = 0xbbbbbb; break; }
case "Detour": { bodyColor = 0xffee22; borderColor = 0xccaa00; break; }
case "Decoyer": { bodyColor = 0xff99bb; borderColor = 0x773399; break; }
case "Wall": { bodyColor = 0xccbbcc; borderColor = 0x443344; break; }
default: { bodyColor = 0x88aa88; borderColor = 0x669966; break; }
}
graphics.lineStyle(1, borderColor);
graphics.beginGradientFill(GradientType.LINEAR, [0x050505 , bodyColor ] , [100, 35] , [20 ,255]);
graphics.drawRect(0.5, 0, Const.WAVE_WIDTH - 1, 20);
graphics.endFill();
addChild(ImageFactory.createStatusText(0, 0, Const.WAVE_WIDTH, 20, _number.toString(), 30, borderColor));
addChild(ImageFactory.createBorderedText(0, 0, Const.WAVE_WIDTH, 20, _enemyType.name, 10, 0xffffff, borderColor));
cacheAsBitmap = true;
}
// 敵の送出を開始する
public function send():void {
_isActivated = true;
_spawnCount = 0;
for (var i:int = 0; i < _enemyNum.length; i++) {
_waitingNum[i] = _enemyNum[i];
}
}
public function update():void {
if (!_isActivated || _allEnemiesSent) { return; }
// カウントを進める
_spawnCount--;
if (_spawnCount > 0) { return; }
_spawnCount = _spawnInterval;
// カウントが0になったら、敵を出現させる
_allEnemiesSent = true;
for (var i:int = 0; i < _waitingNum.length; i++) {
if (_waitingNum[i] > 0) {
_waitingNum[i]--;
_allEnemiesSent = false;
var enemy:Enemy = new Enemy(_world.getStartingPos(i), _enemyType, _enemyHP, _enemyPoint, _enemyMoney, _world , false);
_world.addEnemy(enemy);
}
}
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* GameData
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.events.Event;
import flash.events.EventDispatcher;
//public
class GameData extends EventDispatcher {
private var _wave:int;
private var _score:int;
private var _lives:int;
private var _gold:int;
private var _selectedTower:Tower;
private var _sellingRatio:Number;
public function get wave():int { return _wave; }
public function get score():int { return _score; }
public function get lives():int { return _lives; }
public function get gold():int { return _gold; }
public function get selectedTower():Tower { return _selectedTower; }
public function get sellingRatio():Number { return _sellingRatio; }
public function set wave(value:int):void { _wave = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
public function set score(value:int):void { _score = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
public function set lives(value:int):void { _lives = Math.max(0, value); dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
public function set gold(value:int):void { _gold = value; dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS)); }
public function set selectedTower(value:Tower):void { _selectedTower = value; dispatchEvent(new Event(Const.EVENT_CHANGE_SELECTEDTOWER)); }
public function set sellingRatio(value:Number):void { _sellingRatio = value; }
//----------------------------------------
private static var _instance:GameData = null;
public static function get instance():GameData {
if (GameData._instance == null) { _instance = new GameData(new SingletonEnforcer()); }
return _instance;
}
public function GameData(enforcer:SingletonEnforcer) { initialize(); }
public function initialize():void {
_wave = 0;
_score = 0;
_lives = Config.INITIAL_LIVES;
_gold = Config.INITIAL_GOLD;
_selectedTower = null;
_sellingRatio = 1;
dispatchEvent(new Event(Const.EVENT_CHANGE_GAMESTATUS));
dispatchEvent(new Event(Const.EVENT_CHANGE_SELECTEDTOWER));
}
}
//}
internal class SingletonEnforcer { }
/* ----------------------------------------------------------------------------------------------------------------------
* Const
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class Const {
public static const FRAME_RATE:int = 30; // フレームレート
public static const NODE_SIZE:int = 16; // ノードの大きさ
public static const NODE_COLS:int = 24; // ノードの列数
public static const NODE_ROWS:int = 26; // ノードの行数
public static const TOWER_SIZE:int = 32; // タワーの大きさ
public static const BULLET_SIZE:int = 8; // 弾の大きさ
public static const ENEMY_SIZE:int = 16; // 敵の大きさ
public static const SLOWING_DURATION:int = 5 * Const.FRAME_RATE;
public static const VENOMING_DURATION:int = 1 * Const.FRAME_RATE;
public static const WAVE_INTERVAL:int = 20 * Const.FRAME_RATE;
public static const WAVE_WIDTH:int = int(WAVE_INTERVAL / 10);
public static const CURSOR_OFFSET:int = Const.NODE_SIZE / 2;
public static const EVENT_CHANGE_GAMESTATUS:String = "change_gamestatus";
public static const EVENT_CHANGE_SELECTEDTOWER:String = "change_selectedtower";
//availableFonts["Aqua","Azuki","Cinecaption","Mona","Sazanami","YSHandy","VLGothic","IPAGP","IPAM","UmeUgo","UmePms","Bebas"]
public static const EMBED_FONT:String = "IPAGP";
public static const USE_FONTLOADER:Boolean = true;
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* HotKey
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.Stage;
import flash.events.KeyboardEvent;
//public
class HotKey {
private static var _keymap:Vector.<Function> = new Vector.<Function>(256, true);
private static var _stage:Stage;
public static function setStage(value:Stage):void { HotKey._stage = value; }
public static function enable():void { HotKey._stage.addEventListener(KeyboardEvent.KEY_DOWN, HotKey.onKeyDown); _stage.focus = null; }
public static function disable():void { HotKey._stage.removeEventListener(KeyboardEvent.KEY_DOWN, HotKey.onKeyDown); }
// 押したキーに処理が割り当てられていたら、それを実行する
private static function onKeyDown(e:KeyboardEvent):void {
var command:Function = HotKey._keymap[e.keyCode];
if (command != null) { command(); } // command.execute
_stage.focus = null;
}
// keyCodeに対応するキーに、commandで指定した処理を割り当てる
public static function bind(keyCode:uint, command:Function):void {
HotKey._keymap[keyCode] = command;
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Preloader
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import com.bit101.components.ProgressBar;
import flash.display.DisplayObjectContainer;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.utils.Dictionary;
import net.wonderfl.utils.FontLoader;
//public
class Preloader extends EventDispatcher {
private var _assetsNum:int; // 読み込むアセットの数
private var _loadedNum:int; // 読み込み完了したアセットの数
private var _progressBar:ProgressBar; // プログレスバー
private var _imageLoaders:Dictionary; // 画像のローダを保持する連想配列
private var refImageHolder:Dictionary; // 画像を保持する連想配列の参照
public function Preloader(parentOfProgressBar:DisplayObjectContainer, imagePaths:Dictionary, imageHolder:Dictionary) {
_assetsNum = _loadedNum = 0;
_progressBar = new ProgressBar(parentOfProgressBar, 182, 227);
startLoadingImages(imagePaths, imageHolder);
if (Const.USE_FONTLOADER) { startLoadingFont(); }
_progressBar.maximum = _assetsNum;
}
// 外部画像の読み込みを開始する
private function startLoadingImages(imagePaths:Dictionary, imageHolder:Dictionary):void {
_imageLoaders = new Dictionary();
refImageHolder = imageHolder;
for (var imageName:String in imagePaths) {
_assetsNum++;
var imageLoader:ExternalImageLoader = new ExternalImageLoader();
_imageLoaders[imageName] = imageLoader;
imageLoader.addEventListener(Event.COMPLETE, assetLoaded);
imageLoader.load(imagePaths[imageName]);
}
}
// フォントの読み込みを開始する
private function startLoadingFont():void {
_assetsNum++;
var fontLoader:FontLoader = new FontLoader();
fontLoader.addEventListener(Event.COMPLETE, assetLoaded);
fontLoader.load(Const.EMBED_FONT);
}
// 一つのアセットの読み込みが完了した際に呼ばれるメソッド
private function assetLoaded(e:Event):void {
e.target.removeEventListener(Event.COMPLETE, assetLoaded);
_loadedNum++;
_progressBar.value = _loadedNum;
checkLoadComplete();
}
// 読み込んだアセット数を調べ、全て読み込んでいたら完了イベントを通知する
private function checkLoadComplete():void {
if (_loadedNum == _assetsNum) {
for (var imageName:String in _imageLoaders) {
refImageHolder[imageName] = _imageLoaders[imageName].content;
}
_progressBar.parent.removeChild(_progressBar);
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* ExternalImageLoader
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.BitmapData;
import flash.display.Loader;
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.net.URLRequest;
import flash.system.LoaderContext;
//public
class ExternalImageLoader extends EventDispatcher {
private var _content:BitmapData;
private var _tempA:Loader;
private var _tempB:Loader;
public function get content():BitmapData { return _content; }
public function ExternalImageLoader() {
_content = null; _tempA = new Loader(); _tempB = new Loader();
}
public function load(url:String):void {
_tempA.contentLoaderInfo.addEventListener(Event.INIT, tempALoaded);
_tempA.load(new URLRequest(url), new LoaderContext(true));
}
private function tempALoaded(e:Event):void {
_tempA.contentLoaderInfo.removeEventListener(Event.INIT, tempALoaded);
_content = new BitmapData(int(_tempA.width), int(_tempA.height), true, 0x00ffffff);
_tempB.contentLoaderInfo.addEventListener(Event.INIT, tempBLoaded);
_tempB.loadBytes(_tempA.contentLoaderInfo.bytes);
}
private function tempBLoaded(e:Event):void {
_tempB.contentLoaderInfo.removeEventListener(Event.INIT, tempBLoaded);
_content.draw(_tempB); _tempA.unload(); _tempB.unload();
dispatchEvent(new Event(Event.COMPLETE));
}
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* TileBasedPoint
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
//public
class TileBasedPoint {
private static const TILE_SIZE:int = Const.NODE_SIZE;
private static const TILE_COLS:int = Const.NODE_COLS;
private static const TILE_ROWS:int = Const.NODE_ROWS;
// ワールド座標
private var _worldX:Number;
private var _worldY:Number;
// タイル座標
private var _tileX:int;
private var _tileY:int;
private var _isInvalidWorldPos:Boolean; // ワールド座標値を更新する必要があるかどうか
private var _isInvalidTilePos:Boolean; // タイル座標値を更新する必要があるかどうか
// Creation Method でインスタンスを生成する
public static function createFromWorldPos(x:Number, y:Number):TileBasedPoint { return new TileBasedPoint(true, x, y, 0, 0); }
public static function createFromTilePos(x:int, y:int):TileBasedPoint { return new TileBasedPoint(false, 0, 0, x, y); }
public function TileBasedPoint(isWorldPos:Boolean, worldx:Number, worldy:Number, tilex:int, tiley:int) {
_worldX = worldx;
_worldY = worldy;
_tileX = tilex;
_tileY = tiley;
_isInvalidWorldPos = !isWorldPos;
_isInvalidTilePos = isWorldPos;
}
private function updateWorldPos():void {
_worldX = Math.max(0, Math.min(_tileX * TILE_SIZE, (TILE_COLS - 1) * TILE_SIZE));
_worldY = Math.max(0, Math.min(_tileY * TILE_SIZE, (TILE_ROWS - 1) * TILE_SIZE));
}
private function updateTilePos():void {
_tileX = Math.max(0, Math.min(int(_worldX / TILE_SIZE), TILE_COLS - 1));
_tileY = Math.max(0, Math.min(int(_worldY / TILE_SIZE), TILE_ROWS - 1));
}
// ワールド座標を有効にする
private function validateWorldPos():void {
if (_isInvalidWorldPos) {
updateWorldPos();
_isInvalidWorldPos = false;
}
}
// タイル座標を有効にする
private function validateTilePos():void {
if (_isInvalidTilePos) {
updateTilePos();
_isInvalidTilePos = false;
}
}
public function get x():Number { validateWorldPos(); return _worldX; }
public function get y():Number { validateWorldPos(); return _worldY; }
public function get tileX():int { validateTilePos(); return _tileX; }
public function get tileY():int { validateTilePos(); return _tileY; }
public function set x(value:Number):void { validateWorldPos(); _worldX = value; _isInvalidTilePos = true; }
public function set y(value:Number):void { validateWorldPos(); _worldY = value; _isInvalidTilePos = true; }
public function setWorldPos(x:Number, y:Number):void { validateWorldPos(); _worldX = x; _worldY = y; _isInvalidTilePos = true; }
public function set tileX(value:int):void { validateTilePos(); _tileX = value; _isInvalidWorldPos = true; }
public function set tileY(value:int):void { validateTilePos(); _tileX = value; _isInvalidWorldPos = true; }
public function setTilePos(x:int, y:int):void { validateTilePos(); _tileX = x; _tileY = y; _isInvalidWorldPos = true; }
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* ImageFactory
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Sprite;
import flash.filters.BevelFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.text.AntiAliasType;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
import flash.utils.Dictionary;
import flash.display.Bitmap;
import flash.filters.ColorMatrixFilter;
//public
class ImageFactory {
private static var _images:Dictionary; // 画像を保持する連想配列
public static function getImage(imageName:String):BitmapData {
return ImageFactory._images[imageName];
}
// 外部画像のパスをまとめた配列を取得する
public static function getExternalImagePaths():Dictionary {
var imagePaths:Dictionary = new Dictionary();
imagePaths["World"] = "http://assets.wonderfl.net/images/related_images/2/2c/2c9f/2c9f8923cc3e44db37520f0cbdcda0965a2e3682";
//imagePaths["World"] = "http://assets.wonderfl.net/images/related_images/f/f9/f957/f957053513e0cf8aeb4991f6d7c5ca4f708d2230";
return imagePaths;
}
// (内部で作成できる)画像の読み込みを行う
public static function load():Dictionary {
ImageFactory._images = new Dictionary();
//タワーのグラフィック読み込みを追加【F】
ImageFactory._images["Gun"] = ImageFactory.createGunTower();
ImageFactory._images["Gatling"] = ImageFactory.createGatlingTower();
ImageFactory._images["Venom"] = ImageFactory.createVenomTower();
ImageFactory._images["Cannon"] = ImageFactory.createCannonTower();
ImageFactory._images["Voltex"] = ImageFactory.createVoltexTower();
ImageFactory._images["AntiFly"] = ImageFactory.createAntiFlyTower();
ImageFactory._images["Base"] = ImageFactory.createTowerBase();
ImageFactory._images["Circle"] = ImageFactory.createBase();
ImageFactory._images["Cancel"] = ImageFactory.createCancelMark();
//タワー属性のシンボルイメージ読み込みを追加【F】
ImageFactory._images["groundSynbol"] = ImageFactory.createWalkingSynbol();
ImageFactory._images["airSynbol"] = ImageFactory.createFlyingSynbol();
ImageFactory._images["slowSynbol"] = ImageFactory.createSlowSynbol();
ImageFactory._images["venomSynbol"] = ImageFactory.createVenomSynbol();
ImageFactory._images["stealSynbol"] = ImageFactory.createStealSynbol();
//ステータスのシンボルイメージの読み込みを追加【F】
ImageFactory._images["gradeSynbol"] = ImageFactory.createLevelSynbol();
ImageFactory._images["damageSynbol"] = ImageFactory.createDamageSynbol();
ImageFactory._images["rangeSynbol"] = ImageFactory.createRangeSynbol();
ImageFactory._images["reloadSynbol"] = ImageFactory.createReloadSynbol();
//敵のイメージの読み込み【F】
ImageFactory._images["Normal"] = ImageFactory.createNormalEnemy(0x669966, 0x99cc99);
ImageFactory._images["Fast"] = ImageFactory.createFastEnemy(0x6688dd, 0x99aaff);
ImageFactory._images["Immune"] = ImageFactory.createImmuneEnemy(0x664488, 0xaa88bb);
ImageFactory._images["Flying"] = ImageFactory.createFlyingEnemy(0xddaa00, 0xffdd00);
ImageFactory._images["Swarm"] = ImageFactory.createSwarmEnemy(0x888822, 0xcccc44);
ImageFactory._images["Zombie"] = ImageFactory.createZombieEnemy(0x00aacc, 0x55ddff);
ImageFactory._images["Fade"] = ImageFactory.createFadeEnemy(0x999999, 0xeeeeee);
ImageFactory._images["Split"] = ImageFactory.createSplitEnemy(0x116611, 0x55cc88);
ImageFactory._images["SplitChild"] = ImageFactory.createSplitChildEnemy(0x116611, 0x55cc88);
ImageFactory._images["Fury"] = ImageFactory.createFuryEnemy(0xdd0000, 0xff3333);
ImageFactory._images["Shell"] = ImageFactory.createShellOneEnemy(0x666622, 0x999944);
ImageFactory._images["Shell-2"] = ImageFactory.createShellTwoEnemy(0x666622, 0x999944);
ImageFactory._images["Shell-3"] = ImageFactory.createShellThreeEnemy(0x666622, 0x999944);
ImageFactory._images["Fupa"] = ImageFactory.createFupaEnemy(0xaa9955, 0xffccaa);
ImageFactory._images["FupaChild"] = ImageFactory.createFlyingEnemy(0xddaa22, 0xffdd22);
ImageFactory._images["Ghost"] = ImageFactory.createGhostEnemy(0xbbbbbb, 0xffeeaa);
ImageFactory._images["Detour"] = ImageFactory.createDetourRightEnemy(0xcc8800, 0x444444);
ImageFactory._images["Detour-L"] = ImageFactory.createDetourLeftEnemy(0xcc8800, 0xffffff);
ImageFactory._images["Decoyer"] = ImageFactory.createDecoyerEnemy(0x773399, 0xff99bb);
ImageFactory._images["Decoy-1"] = ImageFactory.createDecoyEnemy(0x773399, 0xff99bb);
ImageFactory._images["Decoy-2"] = ImageFactory.createDecoyEnemy(0x773399, 0xff99bb);
ImageFactory._images["Wall"] = ImageFactory.createWallEnemy(0x443344, 0xccbbcc);
//ImageFactory._images["Bullet_Arrow"] = ImageFactory.createArrowBullet();
ImageFactory._images["Bullet_Gatling"] = ImageFactory.createNormalBullet(2);
ImageFactory._images["Bullet_Cannon"] = ImageFactory.createNormalBullet(3);
//ImageFactory._images["Bullet_Missile"] = ImageFactory.createMissileBullet();
ImageFactory._images["Bullet_Gun"] = ImageFactory.createNormalBullet(2);
ImageFactory._images["Bullet_Voltex"] = ImageFactory.createNormalBullet(1);
ImageFactory._images["Bullet_AntiFly"] = ImageFactory.createArrowBullet();
ImageFactory._images["Coin"] = ImageFactory.createCoin();
return ImageFactory._images;
}
// タワーを設置する土台の画像を作成する
private static function createTowerBase():BitmapData {
var bitmapData:BitmapData = new BitmapData(32, 32,true,0x00ffffff);
var _base:Sprite = new Sprite;
_base.graphics.moveTo(2,1);
_base = ImageFactory.drawingArray(_base,0x888888,0,0x888888,[0,0,2,30,32,32,30,2],[3,27,29,29,27,3,1,1]);
_base.graphics.moveTo(0,27);
_base = ImageFactory.drawingArray(_base,0x888888,0,0x101010,[0,2,30,32,32,30,2,0],[29,32,32,29,27,29,29,27]);
_base.graphics.endFill();
_base.graphics.lineStyle(1,0xd0d0d0,1);
bitmapData.draw(_base);
return bitmapData;
}
// タワー描画時の土台
private static function createBase():BitmapData {
var bitmapData:BitmapData = new BitmapData(32, 32,true,0x00ffffff);
var _base:Sprite = new Sprite;
_base.graphics.beginFill(0xcccccc);
_base.graphics.drawCircle(16, 16, 10);
_base.graphics.endFill();
bitmapData.draw(_base);
return bitmapData;
}
// 各種タワー描画-------------------------------------------------
// ベーシックガン Gun
private static function createGunTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.moveTo(16,14)
sprite = ImageFactory.drawingArray(sprite,_towerColor,0,_towerColor, [18,18,19,19,22,22,20,10,10,20,22,22,16,16], [14,18,18,14,14,12,10,10,22,22,20,18,18,14]);
sprite.graphics.beginFill(_towerColor);
sprite.graphics.drawRect(20,15,10,2);
bitmapData.draw(sprite);
return bitmapData;
}
// ガトリング Gatling
private static function createGatlingTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.moveTo(6, 6);
sprite = ImageFactory.drawingArray (sprite, _towerColor, 0, _towerColor,
[4, 4, 6, 6, 4, 4, 6, 6, 4, 4, 6,14,16,29,29,15,15,17,19,19,17,15,15,29,29,16,14, 6],
[8,11,11,12,14,18,20,21,21,24,26,26,24,24,22,22,21,21,20,12,11,11,10,10, 8, 8, 6, 6]);
sprite.graphics.beginFill(_towerColor);
sprite.graphics.drawEllipse(5,8,10,16);
bitmapData.draw(sprite);
return bitmapData;
}
// ポイズン Venom
private static function createVenomTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.moveTo(15,10)
sprite = ImageFactory.drawingArray (sprite,_towerColor,0,_towerColor, [11,13,13,11,15,19,30,30,19,15], [14,14,18,18,22,17,17,15,15,10]);
sprite.graphics.beginFill(_towerColor);
sprite.graphics.drawCircle(16,9,4);
sprite.graphics.drawCircle(16,23,4);
sprite.graphics.drawCircle(10,13,2);
sprite.graphics.drawCircle(10,19,2);
sprite.graphics.drawCircle(21,16,3);
bitmapData.draw(sprite);
return bitmapData;
}
// キャノン Cannon
private static function createCannonTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.moveTo(7,6);
sprite = ImageFactory.drawingArray (sprite, _towerColor, 0, _towerColor,
[6, 6, 8, 6, 6, 8, 6, 6, 7,17,19,19,16,12,30,30,12,12,19,19,17, 7],
[8,10,10,12,20,22,22,24,26,26,24,22,22,20,20,12,12,10,10, 8, 6, 6]); sprite.graphics.beginFill(_towerColor);
sprite.graphics.drawCircle(14,16,7);
bitmapData.draw(sprite);
return bitmapData;
}
// アンチフライ AntiFly
private static function createAntiFlyTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.moveTo(14,8);
sprite = ImageFactory.drawingArray (sprite,_towerColor,0,_towerColor, [10,12,10,14,24,14], [14,16,18,24,16,8]);
sprite.graphics.lineStyle(1.5,0x000000,1);
sprite.graphics.endFill();
sprite.graphics.moveTo(12,8); sprite.graphics.lineTo(9,13);
sprite.graphics.moveTo(12,24); sprite.graphics.lineTo(9,19);
sprite.graphics.moveTo(28,8);
sprite.graphics.lineTo(22,2);sprite.graphics.lineTo(14,16);
sprite.graphics.lineTo(22,30);sprite.graphics.lineTo(28,24);
bitmapData.draw(sprite);
return bitmapData;
}
// ボルテクス Votex
private static function createVoltexTower():BitmapData{
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
var _towerColor:uint = 0x000000;
sprite = towerCircle(_towerColor);
sprite.graphics.lineStyle(1,0x000000, 1, true);
sprite.graphics.moveTo(12,7); sprite.graphics.lineTo(6,16); sprite.graphics.lineTo(12,25);
sprite.graphics.lineTo(20,25); sprite.graphics.lineTo(26,16); sprite.graphics.lineTo(20,7);
sprite.graphics.lineTo(12,7);
sprite.graphics.lineStyle(0,0x000000, 0, true);
sprite.graphics.beginFill(0x000000);
sprite.graphics.drawCircle(16,16,4);
sprite.graphics.endFill();
sprite.graphics.beginFill(0x000000);
sprite.graphics.moveTo(8,8);
sprite.graphics.lineTo(12,12);sprite.graphics.lineTo(14,10);sprite.graphics.lineTo(11,4);sprite.graphics.lineTo(8,8);
sprite.graphics.moveTo(4,13);
sprite.graphics.lineTo(4,19);sprite.graphics.lineTo(10,18);sprite.graphics.lineTo(10,14);sprite.graphics.lineTo(4,13);
sprite.graphics.moveTo(8,24);
sprite.graphics.lineTo(11,28);sprite.graphics.lineTo(14,22);sprite.graphics.lineTo(12,20);sprite.graphics.lineTo(8,24);
sprite.graphics.moveTo(21,28);
sprite.graphics.lineTo(24,24);sprite.graphics.lineTo(20,20);sprite.graphics.lineTo(18,22);sprite.graphics.lineTo(21,28);
sprite.graphics.moveTo(28,19);
sprite.graphics.lineTo(28,13);sprite.graphics.lineTo(22,14);sprite.graphics.lineTo(22,18);sprite.graphics.lineTo(28,19);
sprite.graphics.moveTo(24,8);
sprite.graphics.lineTo(21,4);sprite.graphics.lineTo(18,10);sprite.graphics.lineTo(20,12);sprite.graphics.lineTo(24,8);
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
//-----------------------------------------------------
//-----------------------------------------------------
// キャンセルマークの画像を作成する
private static function createCancelMark():BitmapData {
var bitmapData:BitmapData = new BitmapData(32, 32, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(4, 0xff0000);
sprite.graphics.drawCircle(16, 16, 12);
sprite.graphics.moveTo(16 + (12 * Math.cos(9 * Math.PI / 8)), 16 + (12 * Math.sin(9 * Math.PI / 8)));
sprite.graphics.lineTo(16 + (12 * Math.cos(Math.PI / 8)), 16 + (12 * Math.sin(Math.PI / 8)));
bitmapData.draw(sprite);
return bitmapData;
}
// ステータスウィンドウ用の画像を作成する【F】
// 靴アイコン:地上の敵を攻撃【F】
private static function createWalkingSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xb0b0b0)
sprite.graphics.moveTo(6,2);
sprite.graphics.lineTo(12,2);
sprite.graphics.lineTo(12,11);
sprite.graphics.lineTo(3,11);
sprite.graphics.curveTo(0,7,6,6);
sprite.graphics.lineTo(6,2);
bitmapData.draw(sprite);
return bitmapData;
}
// 羽アイコン:空中の敵を攻撃【F】
private static function createFlyingSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xb0b0b0)
sprite.graphics.moveTo(8,2);
sprite.graphics.lineTo(11,2);
sprite.graphics.curveTo(15,2.5,8,5);
sprite.graphics.curveTo(12,5.5,6,7);
sprite.graphics.curveTo(10,8,4,9);
sprite.graphics.curveTo(3,9.8,3,12);
sprite.graphics.lineTo(2,11);
sprite.graphics.curveTo(2,2.5,8,2);
bitmapData.draw(sprite);
return bitmapData;
}
// スロウアイコン:減速効果【F】
private static function createSlowSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(1.4, 0xffffff, 1, true);
sprite.graphics.endFill();
sprite.graphics.moveTo(4,1) ;
sprite.graphics.lineTo(2,3) ; sprite.graphics.lineTo(4,5) ; sprite.graphics.lineTo(2,7) ; sprite.graphics.lineTo(4,9) ; sprite.graphics.lineTo(2,11) ;
sprite.graphics.moveTo(7,1) ;
sprite.graphics.lineTo(5,3) ; sprite.graphics.lineTo(7,5) ; sprite.graphics.lineTo(5,7) ; sprite.graphics.lineTo(7,9) ; sprite.graphics.lineTo(5,11) ;
sprite.graphics.moveTo(10,1) ;
sprite.graphics.lineTo(8,3) ; sprite.graphics.lineTo(10,5) ; sprite.graphics.lineTo(8,7) ; sprite.graphics.lineTo(10,9) ; sprite.graphics.lineTo(8,11) ;
bitmapData.draw(sprite);
return bitmapData;
}
// ベノムアイコン:毒液効果【F】
private static function createVenomSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(12,12, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xb0b0b0);
sprite.graphics.moveTo(9,9);
sprite = drawingArray( sprite, 0xb0b0b0, 0, 0xb0b0b0, [7,7,5,5,3], [6,0,0,6,9]);
sprite.graphics.curveTo(0,12,5,12); sprite.graphics.lineTo(7,12); sprite.graphics.curveTo(12,12,9,9);
bitmapData.draw(sprite);
return bitmapData;
}
// スティールアイコン:窃盗効果【F】
private static function createStealSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(12, 12, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xb0b0b0);
sprite.graphics.drawEllipse( 3, 1, 6, 10);
sprite.graphics.endFill();
sprite.graphics.lineStyle(1, 0x000000, 1, true);
sprite.graphics.drawEllipse(4.5, 3, 3, 6);
bitmapData.draw(sprite);
return bitmapData;
}
//レベルアイコン:タワーレベル【F】
private static function createLevelSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xffffff);
sprite.graphics.moveTo(4, 4); sprite.graphics.lineTo(6, 4); sprite.graphics.lineTo(6, 10); sprite.graphics.lineTo(8, 10);
sprite.graphics.lineTo(8, 12); sprite.graphics.lineTo(4, 12); sprite.graphics.lineTo(4, 4);
sprite.graphics.moveTo(8, 6); sprite.graphics.lineTo(9, 6); sprite.graphics.lineTo(10, 10); sprite.graphics.lineTo(11, 6);
sprite.graphics.lineTo(12, 6); sprite.graphics.lineTo(11, 12); sprite.graphics.lineTo(9, 12); sprite.graphics.lineTo(8, 6);
bitmapData.draw(sprite);
return bitmapData;
}
//剣アイコン:攻撃力【F】
private static function createDamageSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(0, 0x000000, 0, true);
sprite.graphics.beginFill(0xffffff);
sprite.graphics.moveTo(4, 11); sprite.graphics.lineTo(10, 4); sprite.graphics.lineTo(12, 4); sprite.graphics.lineTo(12, 6); sprite.graphics.lineTo(5, 12);
sprite.graphics.endFill();sprite.graphics.beginFill(0xffffff);
sprite.graphics.moveTo(4, 7); sprite.graphics.lineTo(5, 6); sprite.graphics.lineTo(10, 11); sprite.graphics.lineTo(9, 12); sprite.graphics.lineTo(4, 7);
bitmapData.draw(sprite);
return bitmapData;
}
//波紋アイコン:攻撃範囲【F】
private static function createRangeSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(2,0xffffff);
sprite.graphics.drawCircle(8,8,4.6);sprite.graphics.drawCircle(8,8,1.8);
bitmapData.draw(sprite);
return bitmapData;
}
//連射アイコン:装填速度【F】
private static function createReloadSynbol():BitmapData{
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(2,0xffffff);
sprite.graphics.moveTo(4,6); sprite.graphics.lineTo(6,8);sprite.graphics.lineTo(4,10);
sprite.graphics.moveTo(7,5); sprite.graphics.lineTo(9,8); sprite.graphics.lineTo(7,11);
sprite.graphics.moveTo(10,4); sprite.graphics.lineTo(12,8); sprite.graphics.lineTo(10,12);
bitmapData.draw(sprite);
return bitmapData;
}
//-----------------------------------------------------
// 敵の画像作成【F】
//-----------------------------------------------------
//Nomal タイプ
private static function createNormalEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite;
sprite.graphics.moveTo(0,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[3.5,7,14] , [8,4,4] , [5.5,9.5,14] , [6,4,8] );
sprite.graphics.moveTo(0,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[3.5,7,14] , [8,4,4] , [5.5,9.5,14] , [6,4,8] );
sprite.graphics.moveTo(15.5,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[15.5,7,3 ,3.5 ,7,14] , [2.5,2.5,8,8,4 ,4 ] , [9.5,5,0 ,5.5,9.5,14] , [2.5 ,5,8,6,4 ,8]);
sprite.graphics.moveTo(15.5,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[15.5,7,3 ,3.5 ,7,14] , [2.5,2.5,8,8,4 ,4 ] , [9.5,5,0 ,5.5,9.5,14] , [2.5 ,5,8,6,4 ,8]);
sprite.graphics.drawCircle(10,8,3);
bitmapData.draw(sprite);
return bitmapData;
}
// Fastタイプ
private static function createFastEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(5,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[8.5,11] , [6,6] , [9.5,11] , [6,8]);
sprite.graphics.moveTo(5,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[8.5,11] , [6,6] , [9.5,11] , [6,8]);
sprite.graphics.moveTo(12,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[12,5.5, ,8.5,11] , [4.5 ,4.5 , ,6 ,6 ] , [8.5 ,0 ,5 ,9.5,11] , [4.5 ,8 ,8 ,6 ,8 ]);
sprite.graphics.moveTo(12,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[12,5.5, ,8.5,11] , [4.5 ,4.5 , ,6 ,6 ] , [8.5 ,0 ,5 ,9.5,11] , [4.5 ,8 ,8 ,6 ,8 ]);
sprite.graphics.moveTo(15 ,8 );
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[15,9,13] , [3.5 ,3 ,3.5 ] , [10 ,8 ,13.5 ] , [3 ,3.5 ,8]);
sprite.graphics.moveTo(15 ,8 );
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[15,9,13] , [3.5 ,3 ,3.5 ] , [10 ,8 ,13.5 ] , [3 ,3.5 ,8]);
bitmapData.draw(sprite);
return bitmapData;
}
// Immuneタイプの敵の画像を作成する【F】
private static function createImmuneEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(4, 8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
sprite.graphics.moveTo(4, 8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
sprite.graphics.moveTo(15,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[12 ,1.5 , ,4 ,10.5] , [0 ,2 , ,5.5 ,4 ] , [4 ,1 ,4 ,5 ,12 ] , [1.5 ,8 ,8 ,4 ,8 ]);
sprite.graphics.moveTo(15,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[12 ,1.5 , ,4 ,10.5] , [0 ,2 , ,5.5 ,4 ] , [4 ,1 ,4 ,5 ,12 ] , [1.5 ,8 ,8 ,4 ,8 ]);
sprite.graphics.moveTo(11,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[10 ,5.5 ] , [6 ,7 ] , [6 ,5.5] , [5 ,8 ]);
sprite.graphics.moveTo(11,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[10 ,5.5 ] , [6 ,7 ] , [6 ,5.5] , [5 ,8 ]);
bitmapData.draw(sprite);
return bitmapData;
}
// Flying タイプの敵の画像を作成する
private static function createFlyingEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(12 ,6 );
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[11 , ,10 ] , [2 , ,3 ] , [6 ,6.5 ,12 ] , [0.5 ,4.5 ,6 ]);
sprite.graphics.moveTo(12,10);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[11 , ,10 ] , [2 , ,3 ] , [6 ,6.5 ,12 ] , [0.5 ,11.5,6]);
sprite.graphics.drawCircle(8.5 ,8 ,3.5)
sprite.graphics.beginFill(_inColor); sprite.graphics.drawCircle(9 ,8 ,3)
sprite.graphics.beginFill(_outColor); sprite.graphics.drawCircle(9.5 ,8 ,2)
bitmapData.draw(sprite);
return bitmapData;
}
// Swarm タイプの敵の画像を作成する
private static function createSwarmEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(0,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[4 ,7 ,12 ] , [8 ,5 ,5 ] , [6 ,9.5 ,14 ] , [7 ,5 ,8 ]);
sprite.graphics.moveTo(0,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[4 ,7 ,12 ] , [8 ,5 ,5 ] , [6 ,9.5 ,14 ] , [7 ,5 ,8 ]);
sprite.graphics.beginFill(_inColor); sprite.graphics.drawCircle(11 ,8 ,2 ); sprite.graphics.drawCircle(8 ,8 ,1 );
bitmapData.draw(sprite);
return bitmapData;
}
// Zombieタイプの敵の画像を作成する
private static function createZombieEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(5,2);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[5, ,8] , [5, ,5] , [5,15,2] , [8,8 ,5]);
sprite.graphics.moveTo(5,14);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 ,
[5, ,8] ,[5, ,5] , [5,15,2] ,[8,8 ,5]);
sprite.graphics.moveTo(2,2);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[8,14,10,14,8 ,2 ,6] , [6,2 , 8,14,10,14,8] );
sprite.graphics.endFill() ;
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawCircle(8,8,3.5);
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(8,8,2);
sprite.graphics.drawCircle(2,2,2);
sprite.graphics.drawCircle(2,14,2);
bitmapData.draw(sprite);
return bitmapData;
}
// Fadeタイプの敵の画像を作成する
private static function createFadeEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(4,8,2.5);
sprite.graphics.drawCircle(12,4,2.5);
sprite.graphics.drawCircle(12,12,2.5);
sprite.graphics.moveTo(2,8);
sprite = drawingCurveArray(sprite ,_outColor ,1 ,_outColor ,0 ,
[2,7,10 ,15,13] , [5,5,1 ,4 ,7 ] ,
[5,9,13,14,13] , [5,3,2 ,6 ,8 ]);
sprite.graphics.moveTo(2,8);
sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,1 ,_outColor ,0 ,
[2,7,10,15,13] , [5,5,1 ,4 ,7 ] ,
[5,9,13,14,13] , [5,3,2 ,6 ,8 ]);
sprite.graphics.endFill();
sprite.graphics.moveTo(7,5); sprite.graphics.lineTo(13,14);
sprite.graphics.moveTo(7,11); sprite.graphics.lineTo(13,2);
bitmapData.draw(sprite);
return bitmapData;
}
// Splitタイプの敵の画像を作成する
private static function createSplitEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawCircle(9,8,6);sprite.graphics.endFill();
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawCircle(5,4,3.5); sprite.graphics.drawCircle(11,5,3);
sprite.graphics.drawCircle(5,12,3.5); sprite.graphics.drawCircle(11,11,3);
sprite.graphics.endFill();
sprite.graphics.moveTo(6,4);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[4,4] , [7,9] , [0,6] , [8,12] );
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(8,8,2);
sprite.graphics.drawCircle(5,4,2.5); sprite.graphics.drawCircle(11,5,2);
sprite.graphics.drawCircle(5,12,2.5); sprite.graphics.drawCircle(11,11,2);
bitmapData.draw(sprite);
return bitmapData;
}
// SplitChildタイプの敵の画像を作成する
private static function createSplitChildEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawCircle(9,8,3.5);sprite.graphics.endFill();
sprite.graphics.moveTo(8,6);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [4,4] , [7,9] , [0,8] , [8,10] );
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(9,8,2);
bitmapData.draw(sprite);
return bitmapData;
}
// Furyタイプの敵の画像を作成する
private static function createFuryEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(14,8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [13,5 ] , [6 ,6 ] , [9 ,0 ] , [6 ,8 ] );
sprite.graphics.endFill();
sprite.graphics.moveTo(15,7);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [15,11 ,10 ,14] , [3 ,0.5,2.5,5 ] , [13,4 ,12 ,15] , [2 ,2 ,4 ,7 ] );
sprite.graphics.endFill();
sprite.graphics.moveTo(12,5.5);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 , [10 ,5.5,8 ] , [3.5,3 ,4] , [8 ,2 ,12 ] , [3.5,6 ,5.5 ] );
sprite.graphics.endFill();
sprite.graphics.moveTo(14,8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [13,5 ] , [6 ,6 ] , [9 ,0 ] , [6 ,8 ] );
sprite.graphics.endFill();
sprite.graphics.moveTo(15,9);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [15,11 ,10 ,14] , [3 ,0.5,2.5,5 ] , [13,4 ,12 ,15] , [2 ,2 ,4 ,7 ] );
sprite.graphics.endFill();
sprite.graphics.moveTo(12,10.5);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_outColor ,1 , [10 ,5.5,8 ] , [3.5,3 ,4] , [8 ,2 ,12 ] , [3.5,6 ,5.5 ] );
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawEllipse(7,7,5,2);
bitmapData.draw(sprite);
return bitmapData;
}
// Shellタイプの敵01-03の画像を作成する
private static function createShellOneEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(8,8,4);
sprite.graphics.endFill();
sprite.graphics.moveTo(15,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[13,11,10,12,10,11,13,15] ,
[4 ,2 ,2 ,8 ,14,14,12,8 ] );
sprite.graphics.moveTo(11,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[9 ,7 ,6 ,8 ,6 ,7 ,9 ,11] ,
[5 ,3 ,3 ,8 ,13,13,11,8 ] );
sprite.graphics.moveTo(7,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] ,
[6 ,4 ,4 ,8 ,12,12,10,8 ] );
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
private static function createShellTwoEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(7,8,3.5);
sprite.graphics.endFill();
sprite.graphics.moveTo(11,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[9 ,7 ,6 ,8 ,6 ,7 ,9 ,11] ,
[5 ,3 ,3 ,8 ,13,13,11,8 ] );
sprite.graphics.moveTo(7,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] ,
[6 ,4 ,4 ,8 ,12,12,10,8 ] );
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
private static function createShellThreeEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(5,8,3);
sprite.graphics.endFill();
sprite.graphics.moveTo(7,8);
sprite = drawingArray(sprite ,0x000000 ,0 ,_outColor ,
[5 ,3 ,2 ,4 ,2 ,3 ,5 ,7 ] ,
[6 ,4 ,4 ,8 ,12,12,10,8 ] );
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
// Fupaタイプの敵の画像を作成する
private static function createFupaEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(6,4);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_outColor ,1 ,
[1,1 ,8 ,15,15,8] , [4,12,12,12,4 ,4] , [1,6 ,10,15,10,6] , [8,12,12,8 ,4 ,4] );
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(11,8,2);
sprite.graphics.moveTo(11,5);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[10,6 ,6 ,8 ] , [5 ,5.5,7.5,6 ] , [8 ,5 ,8 ,11] , [5 ,7.5,7.5,5 ] );
sprite.graphics.moveTo(11,11);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[10,6 ,6 ,8 ] , [5 ,5.5,7.5,6 ] , [8 ,5 ,8 ,11] , [5 ,7.5,7.5,5 ] );
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
// Ghostタイプの敵の画像を作成する
private static function createGhostEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(11,8,4);
sprite.graphics.endFill();
sprite.graphics.lineStyle(1,_outColor,1);
sprite.graphics.drawCircle(10,8,5);
sprite.graphics.moveTo(13,8);
sprite = drawingCurveArray(sprite ,_outColor ,1 ,_outColor ,0 ,
[13,8,3,3] ,
[6 ,3,4,7] ,
[11,1,4,1] ,
[5 ,2,6,8] );
sprite.graphics.moveTo(13,8);
sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,1 ,_outColor ,0 ,
[13,8,3,3] ,
[6 ,3,4,7] ,
[11,1,4,1] ,
[5 ,2,6,8] );
sprite.graphics.endFill();
bitmapData.draw(sprite);
return bitmapData;
}
// Left-Rightタイプの敵の画像を作成する
private static function createDetourRightEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(15,10);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[15,11,8,4 ,5 ,10,15] ,
[7 ,3 ,4,7 ,10,14,12] ,
[13,6 ,9,0 ,7 ,13,15] ,
[5 ,2 ,6,11,12,13,10] );
sprite.graphics.moveTo(14,13);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[13,12,13] ,
[16,15,14] ,
[10,11,14] ,
[16,14,13] );
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(11.5, 10, 2.5);
bitmapData.draw(sprite);
return bitmapData;
}
private static function createDetourLeftEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(15,6);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[15,11,8 ,4 ,5 ,10,15] ,
[9 ,13,12,9 ,6 ,2 ,4 ] ,
[13,6 ,9 ,0 ,7 ,13,15] ,
[11,14,10,5 ,4 ,3 ,6 ] );
sprite.graphics.moveTo(14,3);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[13,12,13] ,
[0 ,1 ,2 ] ,
[10,11,14] ,
[0 ,2 ,3 ] );
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(11.5,6,2.5);
bitmapData.draw(sprite);
return bitmapData;
}
// Decoyerタイプの敵の画像を作成する
private static function createDecoyerEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(15,8);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[15,11,11] ,[6 ,4 ,6 ] ,[8 ,5 ,11] ,[1 ,5 ,8 ] );
sprite.graphics.moveTo(10,8);
sprite = drawingCurveArray(sprite ,_outColor ,0 ,_outColor ,1 ,
[10,5] ,[7 ,8] ,[8 ,0] ,[6 ,8] );
sprite.graphics.moveTo(15,8);
sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,0 ,_outColor ,1 ,
[15,11,11] ,[6 ,4 ,6 ] ,[8 ,5 ,11] ,[1 ,5 ,8 ] );
sprite.graphics.moveTo(10,8);
sprite = drawingCurveArrayMILLOR(sprite ,_outColor ,0 ,_outColor ,1 ,
[10,5] ,[7 ,8] ,[8 ,0] ,[6 ,8] );
sprite.graphics.endFill();
sprite.graphics.beginFill(_inColor);
sprite.graphics.drawCircle(12,8,2);
bitmapData.draw(sprite);
return bitmapData;
}// デコイ画像
private static function createDecoyEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawRect(5,7,6,2);
sprite.graphics.drawCircle(3.5,8,2);
sprite.graphics.drawCircle(12.5,8,2);
bitmapData.draw(sprite);
return bitmapData;
}
// Wallタイプの敵の画像を作成する
private static function createWallEnemy(_outColor:uint, _inColor:uint):BitmapData {
var bitmapData:BitmapData = new BitmapData(16, 16, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.moveTo(2, 8);
sprite = drawingArray(sprite ,_outColor ,0,_outColor ,
[8, 2,2,8,14,14,8 ],[0 ,2,14,16,14,2,0]);
sprite.graphics.endFill();
sprite.graphics.moveTo(3, 8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
sprite.graphics.moveTo(13, 8);
sprite = drawingCurveArray(sprite ,0x000000 ,0 ,_inColor ,1 ,
[12 ,5.5] , [5.5, 4 ] , [11, 4 ] , [4 ,8 ]);
sprite.graphics.moveTo(3, 8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[4 ,10.5] , [5.5, 4 ] , [5, 12] , [4 ,8 ]);
sprite.graphics.moveTo(13, 8);
sprite = drawingCurveArrayMILLOR(sprite ,0x000000 ,0 ,_inColor ,1 ,
[12 ,5.5] , [5.5, 4 ] , [11, 4 ] , [4 ,8 ]);
sprite.graphics.beginFill(_outColor);
sprite.graphics.drawCircle(8,8,2);
bitmapData.draw(sprite);
return bitmapData;
}
//-----------------------------------------------------
// 弾の画像作成【F】
//-----------------------------------------------------
private static function createArrowBullet():BitmapData {
var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.lineStyle(2);
sprite.graphics.moveTo(1, 4);
sprite.graphics.lineTo(7, 4);
bitmapData.draw(sprite);
return bitmapData;
}
// 普通の弾の画像を作成する (引数に弾の半径)
private static function createNormalBullet(radius:int):BitmapData {
var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0x000000);
sprite.graphics.drawCircle(4, 4, radius);
bitmapData.draw(sprite);
return bitmapData;
}
private static function createMissileBullet():BitmapData {
var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0x000000);
sprite.graphics.drawCircle(3, 2, 2);
sprite.graphics.drawCircle(3, 6, 2);
sprite.graphics.drawCircle(5, 4, 2);
bitmapData.draw(sprite);
return bitmapData;
}
// エフェクトのコインの画像を作成する
private static function createCoin():BitmapData {
var bitmapData:BitmapData = new BitmapData(8, 8, true, 0x00ffffff);
var sprite:Sprite = new Sprite();
sprite.graphics.beginFill(0xcccc00);
sprite.graphics.drawEllipse(2, 1, 4, 6);
sprite.graphics.endFill();
sprite.filters = [new BevelFilter(1, 45, 0xffffff, 1, 0x000000, 1, 0, 0)];
bitmapData.draw(sprite);
return bitmapData;
}
//-----------------------------------------------------
// テキストの作成【F】
//-----------------------------------------------------
// 普通のテキストを作成する
public static function createSimpleText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER);
}
// 縁取り付きのテキストを作成する
public static function createBorderedText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, borderColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER, false, true, borderColor);
}
// 縁取り付き左揃えのテキストを作成する【F】
public static function createBorderedTextLEFT(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, borderColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.LEFT, false, true, borderColor);
}
// スコア表示用のテキストを作成する
public static function createScoreText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.RIGHT, true);
}
// タワーのステータス表示用テキストを作成する
public static function createStatusText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.CENTER, true);
}
// タワーのステータス表示用テキスト右揃えを作成する
public static function createStatusTextRight(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, textColor, TextFieldAutoSize.RIGHT, true);
}
private static function createText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int, textColor:uint, autoSize:String, bold:Boolean = false, border:Boolean = false, borderColor:uint = 0x000000, embed:Boolean = false):TextField {
var textField:TextField = new TextField();
if (embed) {
textField.embedFonts = true;
textField.antiAliasType = AntiAliasType.ADVANCED;
}
var font:String = embed ? Const.EMBED_FONT : "Arial";
textField.defaultTextFormat = new TextFormat(font, fontSize, null, bold);
textField.text = text;
textField.x = posx;
textField.y = posy + Math.ceil((height - (textField.textHeight + 4)) / 2);
textField.width = Math.max(width, textField.textWidth + 4);
textField.height = textField.textHeight + 4;
textField.textColor = textColor;
if (border) { textField.filters = [new GlowFilter(borderColor, 1, 4, 4)]; }
textField.autoSize = autoSize;
textField.mouseEnabled = textField.selectable = false;
return textField;
}
// 説明用のテキストを作成する
public static function createInstructionText(posx:int, posy:int, width:int, height:int, text:String, fontSize:int):TextField {
return ImageFactory.createText(posx, posy, width, height, text, fontSize, 0xffffff, TextFieldAutoSize.LEFT, false, false, 0x000000, Const.USE_FONTLOADER);
}
// ウインドウを作成する
public static function createWindow(posx:int, posy:int, width:int, height:int):Sprite {
var sprite:Sprite = new Sprite();
sprite.x = posx;
sprite.y = posy;
sprite.mouseEnabled = false;
var matrix:Matrix = new Matrix();
matrix.createGradientBox(width, height, Math.PI / 2);
sprite.graphics.lineStyle(1);
sprite.graphics.lineGradientStyle(GradientType.LINEAR, [0xf0f0f0, 0x808080], [1, 1], [0, 255], matrix);
sprite.graphics.beginGradientFill(GradientType.LINEAR, [0x303030, 0x000000], [1, 1], [0, 255], matrix);
sprite.graphics.drawRect(1, 1, width - 2, height - 2);
sprite.graphics.endFill();
return sprite;
}
//描画サポートファンクション【F】-----------------------------------
//線を描画用のファンクション引数は(スプライト、線色、線のアルファ、塗り色、x座標アレイ、y座標アレイ)
private static function drawingArray(drawn:Sprite,lineColor:uint,alpha:int,bodyColor:uint,xArray:Array,yArray:Array):Sprite {
drawn.graphics.lineStyle(1,lineColor,alpha,true);
drawn.graphics.beginFill(bodyColor);
if(xArray.length == yArray.length){
var len:int = xArray.length;
for ( var i:int=0; i<len; i++ ){drawn.graphics.lineTo(xArray[i],yArray[i])} ;
}
return drawn;
}
//タワー画像の下に敷く円 引数は(線の色)
private static function towerCircle(lineColor:uint):Sprite{
var _cy:Sprite = new Sprite;
_cy.graphics.lineStyle(1,lineColor,1,true);
_cy.graphics.drawCircle(16,16,10);
return _cy;
}
//カーブ用の描画サポート、アーカーポイントの座標がnullのときはlineToする
//引数は(スプライト、線色、線のアルファ、塗り色、塗りのアルファ、アーカーx座標アレイ、アーカーy座標アレイ、 描画x座標アレイ、 描画y座標アレイ)
private static function drawingCurveArray(drawn:Sprite, lineColor:uint, lineAlpha:Number, bodyColor:uint, bodyAlpha:Number , AxArray:Array, AyArray:Array ,PxArray:Array, PyArray:Array):Sprite{
drawn.graphics.lineStyle(1 ,lineColor, lineAlpha, true);
drawn.graphics.beginFill(bodyColor ,bodyAlpha );
if(AxArray.length == AyArray.length && PxArray.length == PyArray.length && AxArray.length == PxArray.length){
var len:int = AxArray.length;
for ( var i:int=0; i<len; i++ ){
if ( AxArray[i] == null && AyArray[i] == null) {drawn.graphics.lineTo(PxArray[i], PyArray[i]); continue
} else { drawn.graphics.curveTo(AxArray[i], AyArray[i] , PxArray[i], PyArray[i] ); continue ;}
}
}
return drawn;
}
// 敵を作成する専用描画ファンクション
// カーブを上下に反射して描画(縦16ピクセル用)
private static function drawingCurveArrayMILLOR(drawn:Sprite, lineColor:uint, lineAlpha:Number, bodyColor:uint, bodyAlpha:Number , AxArray:Array, AyArray:Array ,PxArray:Array, PyArray:Array):Sprite{
drawn.graphics.lineStyle(1 ,lineColor, lineAlpha, true);
drawn.graphics.beginFill(bodyColor ,bodyAlpha );
if(AxArray.length == AyArray.length && PxArray.length == PyArray.length && AxArray.length == PxArray.length){
var len:int = AxArray.length;
for ( var i:int=0; i<len; i++ ){
if ( AxArray[i] == null && AyArray[i] == null) {drawn.graphics.lineTo(PxArray[i], PyArray[i]); continue
} else { drawn.graphics.curveTo(AxArray[i], 16 - AyArray[i] , PxArray[i], 16 - PyArray[i] ); continue ;}
}
}
return drawn;
}
//-----------------------------------
}
//}
/* ----------------------------------------------------------------------------------------------------------------------
* Config
* -----------------------------------------------------------------------------------------------------------------------
*/
//package {
import flash.utils.Dictionary;
//public
class Config {
public static const INITIAL_LIVES:int = 10;
public static const INITIAL_GOLD:int = 200;
//横Node0-23 縦Node0-25
public static const NODE_TYPE:Array = [
[1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2],
[1,1,1,1,2,2,2,2,2,2,2,2,2,2,1,1,1,1,2,2,2,2,2,2],
[1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,3,3,3,3,0,0,0,0,0,0,0,0,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,0,0,2,2,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];
private static const XML_DATA:XML =
<root>
<starts>
<start x="8" y="0" width="4" flying="0" />
<start x="21" y="0" width="2" flying="0" />
<start x="2" y="0" width="1" flying="1" />
</starts>
<goals>
<goal x="10" y="20" /><goal x="11" y="20" />
<goal x="10" y="21" /><goal x="11" y="21" />
</goals>
<tower>
<type name="Gun" towerbase="0" ground="1" air="1" slow="0" splash="0" venom="0">
<status level="1" cost="8" damage="10" range="60" firerate="1.6" />
<status level="2" cost="16" damage="20" range="65" firerate="1.8" />
<status level="3" cost="32" damage="40" range="70" firerate="2.0" />
<status level="4" cost="64" damage="80" range="80" firerate="2.2" />
<status level="5" cost="192" damage="300" range="180" firerate="1.0" />
</type>
<type name="Gatling" towerbase="0" ground="1" air="1" slow="0" splash="0" venom="0">
<status level="1" cost="20" damage="5" range="55" firerate="4.0" />
<status level="2" cost="35" damage="9" range="60" firerate="4.5" />
<status level="3" cost="95" damage="22" range="65" firerate="5.0" />
<status level="4" cost="210" damage="50" range="70" firerate="5.5" />
<status level="5" cost="800" damage="166" range="80" firerate="9.9" />
</type>
<type name="Cannon" towerbase="0" ground="1" air="0" slow="0" splash="24" venom="0">
<status level="1" cost="25" damage="15" range="80" firerate="0.9" />
<status level="2" cost="50" damage="40" range="88" firerate="1.0" />
<status level="3" cost="120" damage="120" range="96" firerate="1.1" />
<status level="4" cost="280" damage="350" range="104" firerate="1.2" />
<status level="5" cost="940" damage="980" range="126" firerate="1.6" />
</type>
<type name="Venom" towerbase="0" ground="1" air="0" slow="0" splash="0" venom="3">
<status level="1" cost="30" damage="5" range="32" firerate="0.5" />
<status level="2" cost="70" damage="35" range="34" firerate="0.6" />
<status level="3" cost="150" damage="80" range="36" firerate="0.8" />
<status level="4" cost="320" damage="200" range="38" firerate="1.2" />
<status level="5" cost="1050" damage="750" range="45" firerate="1.6" />
</type>
<type name="Voltex" towerbase="0" ground="1" air="1" slow="25" splash="42" venom="0">
<status level="1" cost="70" damage="20" range="42" firerate="0.6" />
<status level="2" cost="130" damage="50" range="42" firerate="0.6" />
<status level="3" cost="250" damage="120" range="54" firerate="0.8" />
<status level="4" cost="490" damage="300" range="54" firerate="0.8" />
<status level="5" cost="990" damage="690" range="66" firerate="1.0" />
</type>
<type name="AntiFly" towerbase="0" ground="0" air="1" slow="0" splash="1" venom="0">
<status level="1" cost="100" damage="135" range="100" firerate="1.1" />
<status level="2" cost="250" damage="255" range="104" firerate="1.3" />
<status level="3" cost="510" damage="510" range="108" firerate="1.5" />
<status level="4" cost="990" damage="990" range="112" firerate="1.7" />
<status level="5" cost="2000" damage="2500" range="120" firerate="2.0" />
</type>
<type name="Base" towerbase="1" ground="0" air="0" slow="0" splash="0" venom="0">
<status level="1" cost="5" damage="0" range="0" firerate="0" />
</type>
</tower>
<enemy>
// flying[0/1] immunity[0/1] regeneration[回復量(MaxHPの千分率/フレーム)] fade[時間量] born[0/1] accelerate[0/1]
<type name="Normal" speed="1.4" MinSpeed="1.3" MaxSpeed="1.5" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="0"/>
<type name="Immune" speed="0.8" MinSpeed="0.7" MaxSpeed="0.9" flying="0" immunity="1" regeneration="0" fade="0" born="0" accelerate="0"/>
<type name="Fast" speed="2.8" MinSpeed="2.6" MaxSpeed="3.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="0"/>
<type name="Flying" speed="1.4" MinSpeed="1.3" MaxSpeed="1.5" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="0" />
<type name="Swarm" speed="1.8" MinSpeed="1.5" MaxSpeed="2.1" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Zombie" speed="1.1" MinSpeed="1.0" MaxSpeed="1.2" flying="0" immunity="0" regeneration="10" fade="0" born="0" accelerate="0" />
<type name="Fade" speed="1.6" MinSpeed="1.5" MaxSpeed="1.7" flying="0" immunity="0" regeneration="0" fade="80" born="0" accelerate="0" />
<type name="Split" speed="1.1" MinSpeed="1.0" MaxSpeed="1.2" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
<type name="SplitChild" speed="1.8" MinSpeed="1.6" MaxSpeed="2.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Fury" speed="1.6" MinSpeed="1.3" MaxSpeed="8.0" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Fupa" speed="1.5" MinSpeed="1.3" MaxSpeed="1.7" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
<type name="FupaChild" speed="0.8" MinSpeed="0.7" MaxSpeed="0.9" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="0" />
<type name="Ghost" speed="1.3" MinSpeed="1.2" MaxSpeed="1.4" flying="1" immunity="0" regeneration="0" fade="40" born="0" accelerate="0" />
<type name="Shell" speed="3.8" MinSpeed="1.3" MaxSpeed="4.2" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
<type name="Shell-2" speed="4.4" MinSpeed="1.4" MaxSpeed="4.6" flying="0" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
<type name="Shell-3" speed="5.4" MinSpeed="1.6" MaxSpeed="5.4" flying="0" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Detour" speed="2.0" MinSpeed="0.7" MaxSpeed="2.3" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
<type name="Detour-L" speed="2.0" MinSpeed="0.7" MaxSpeed="2.3" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Decoyer" speed="1.6" MinSpeed="1.3" MaxSpeed="1.6" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="0" />
<type name="Decoy-1" speed="6.2" MinSpeed="0" MaxSpeed="6.2" flying="1" immunity="0" regeneration="0" fade="0" born="1" accelerate="1" />
<type name="Decoy-2" speed="6.2" MinSpeed="0" MaxSpeed="6.2" flying="1" immunity="0" regeneration="0" fade="0" born="0" accelerate="1" />
<type name="Wall" speed="0.8" MinSpeed="0.6" MaxSpeed="1.0" flying="0" immunity="1" regeneration="2" fade="0" born="0" accelerate="0" />
</enemy>
<bornAbility>
//親名[string]、子名[string]、子HP割合[Number]、子得点割合[Number]、1回産数[int]、限度産量[int]、インターバル[int]、出産被ダメ%[0~1]、死亡出産[0/1]、お金相続[0/1]、出産後の自分除去[0/1]
<parent name="Split" childrenName="SplitChild" childrenHP="0.2" childrenPoint="0.2" amount="4" limit="4" intervalBorn="0" HPrateBorn="0" deadBorn="1" descent="1" selfRemove="1"/>
<parent name="Fupa" childrenName="FupaChild" childrenHP="0.5" childrenPoint="0.5" amount="1" limit="1" intervalBorn="0" HPrateBorn="0" deadBorn="1" descent="1" selfRemove="1"/>
<parent name="Shell" childrenName="Shell-2" childrenHP="0.6" childrenPoint="1" amount="1" limit="1" intervalBorn="0" HPrateBorn="0.6" deadBorn="0" descent="1" selfRemove="1"/>
<parent name="Shell-2" childrenName="Shell-3" childrenHP="0.5" childrenPoint="1" amount="1" limit="1" intervalBorn="0" HPrateBorn="0.5" deadBorn="0" descent="1" selfRemove="1"/>
<parent name="Detour" childrenName="Detour-L" childrenHP="1" childrenPoint="1" amount="1" limit="1" intervalBorn="1" HPrateBorn="0" deadBorn="0" descent="1" selfRemove="0"/>
<parent name="Decoyer" childrenName="Decoy-1" childrenHP="0.01" childrenPoint="0.01" amount="1" limit="40" intervalBorn="45" HPrateBorn="0" deadBorn="0" descent="0" selfRemove="0"/>
<parent name="Decoy-1" childrenName="Decoy-2" childrenHP="1" childrenPoint="1" amount="1" limit="1" intervalBorn="1" HPrateBorn="0" deadBorn="0" descent="0" selfRemove="0"/>
</bornAbility>
<accelerateAbility>
//能力者名[string]、加算変化[Number]、積変化[Number]、飛行角度[int(degree)],サイン周期変化[Number]、インターバル[int]、加速ダメ%[0~1]、加速被ダメ割合[Number]
<runner name="Swarm" AddPoint="0" RatePoint="1" Angle="0" sineSlip="60" intervalRun="0" HPrateRun="0" damageRun="0"/>
<runner name="SplitChild" AddPoint="0" RatePoint="1" Angle="0" sineSlip="90" intervalRun="0" HPrateRun="0" damageRun="0"/>
<runner name="Fury" AddPoint="0.15" RatePoint="1" Angle="0" sineSlip="0" intervalRun="0" HPrateRun="0" damageRun="1"/>
<runner name="Shell" AddPoint="-0.2" RatePoint="1" Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
<runner name="Shell-2" AddPoint="-0.2" RatePoint="1" Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
<runner name="Shell-3" AddPoint="-0.2" RatePoint="1" Angle="0" sineSlip="0" intervalRun="2" HPrateRun="0" damageRun="0"/>
<runner name="Detour" AddPoint="0" RatePoint="0.99" Angle="305" sineSlip="0" intervalRun="3" HPrateRun="0" damageRun="0"/>
<runner name="Detour-L" AddPoint="0" RatePoint="0.99" Angle="55" sineSlip="0" intervalRun="3" HPrateRun="0" damageRun="0"/>
<runner name="Decoyer" AddPoint="0" RatePoint="1" Angle="0" sineSlip="60" intervalRun="2" HPrateRun="0" damageRun="0"/>
<runner name="Decoy-1" AddPoint="0" RatePoint="0.9" Angle="90" sineSlip="0" intervalRun="1" HPrateRun="0" damageRun="0"/>
<runner name="Decoy-2" AddPoint="0" RatePoint="0.9" Angle="270" sineSlip="0" intervalRun="1" HPrateRun="0" damageRun="0"/>
</accelerateAbility>
<waves>
<wave type="Normal" HP="20" point="8" money="1" ><spawn num="10" /><spawn num="0" /><spawn num="0" /></wave>
<wave type="Normal" HP="25" point="8" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Normal" HP="30" point="8" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Swarm" HP="8" point="1" money="1" ><spawn num="20" /><spawn num="20" /><spawn num="0" /></wave>
<wave type="Shell" HP="90" point="8" money="2" ><spawn num="5" /><spawn num="5" /><spawn num="0" /></wave>
<wave type="Normal" HP="50" point="8" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fade" HP="70" point="8" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fast" HP="80" point="8" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Flying" HP="70" point="10" money="2" ><spawn num="0" /><spawn num="0" /><spawn num="15" /></wave>
<wave type="Zombie" HP="300" point="50" money="20" ><spawn num="2" /><spawn num="2" /><spawn num="0" /></wave>
<wave type="Split" HP="70" point="5" money="1" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Normal" HP="110" point="10" money="2" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Immune" HP="160" point="10" money="2" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Shell" HP="140" point="10" money="2" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Flying" HP="120" point="12" money="2" ><spawn num="0" /><spawn num="0" /><spawn num="15" /></wave>
<wave type="Zombie" HP="180" point="14" money="3" ><spawn num="6" /><spawn num="6" /><spawn num="0" /></wave>
<wave type="Normal" HP="170" point="12" money="2" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fury" HP="1000" point="60" money="25" ><spawn num="2" /><spawn num="2" /><spawn num="0" /></wave>
<wave type="Flying" HP="150" point="15" money="4" ><spawn num="4" /><spawn num="4" /><spawn num="4" /></wave>
<wave type="Immune" HP="1600" point="62" money="30" ><spawn num="3" /><spawn num="3" /><spawn num="0" /></wave>
<wave type="Normal" HP="240" point="12" money="3" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fast" HP="260" point="12" money="3" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fade" HP="400" point="12" money="3" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fupa" HP="800" point="30" money="18"><spawn num="4" /><spawn num="4" /><spawn num="0" /></wave>
<wave type="Normal" HP="350" point="14" money="4" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Immune" HP="400" point="14" money="4" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Swarm" HP="100" point="4" money="1" ><spawn num="35" /><spawn num="35" /><spawn num="0" /></wave>
<wave type="Normal" HP="500" point="14" money="4" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Ghost" HP="600" point="18" money="8" ><spawn num="0" /><spawn num="5" /><spawn num="5" /></wave>
<wave type="Split" HP="610" point="8" money="2" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Flying" HP="480" point="14" money="4" ><spawn num="0" /><spawn num="0" /><spawn num="20" /></wave>
<wave type="Fast" HP="4000" point="150" money="80" ><spawn num="1" /><spawn num="1" /><spawn num="0" /></wave>
<wave type="Normal" HP="650" point="15" money="5" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fupa" HP="750" point="15" money="5" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Immune" HP="900" point="15" money="5" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Flying" HP="800" point="15" money="5" ><spawn num="6" /><spawn num="6" /><spawn num="6" /></wave>
<wave type="Normal" HP="1000" point="15" money="5" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Immune" HP="1800" point="30" money="10" ><spawn num="5" /><spawn num="5" /><spawn num="0" /></wave>
<wave type="Fast" HP="1200" point="15" money="6" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Fade" HP="2000" point="20" money="8" ><spawn num="20" /><spawn num="20" /><spawn num="0" /></wave>
<wave type="Swarm" HP="550" point="5" money="2" ><spawn num="45" /><spawn num="45" /><spawn num="0" /></wave>
<wave type="Fast" HP="1500" point="15" money="10" ><spawn num="0" /><spawn num="20" /><spawn num="0" /></wave>
<wave type="Shell" HP="3800" point="15" money="12" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Immune" HP="7000" point="15" money="16" ><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Detour" HP="1500" point="15" money="20" ><spawn num="10" /><spawn num="0" /><spawn num="0" /></wave>
<wave type="Wall" HP="9500" point="15" money="48" ><spawn num="4" /><spawn num="4" /><spawn num="0" /></wave>
<wave type="Fury" HP="5300" point="50" money="52" ><spawn num="5" /><spawn num="5" /><spawn num="0" /></wave>
<wave type="Fupa" HP="4800" point="20" money="35"><spawn num="10" /><spawn num="10" /><spawn num="0" /></wave>
<wave type="Split" HP="20000"point="200" money="40"><spawn num="3" /><spawn num="3" /><spawn num="0" /></wave>
<wave type="Decoyer" HP="12000"point="250" money="100"><spawn num="2" /><spawn num="2" /><spawn num="2" /></wave>
</waves>
</root>;
// スタート地点の配列を返す
public static function getStarts():Vector.<Start> {
var value:Vector.<Start> = new Vector.<Start>();
for each(var s:XML in Config.XML_DATA.starts.*) {
value.push(new Start(int(s.@x), int(s.@y), int(s.@width), Boolean(int(s.@flying))));
}
return value;
}
// ゴールの配列を返す
public static function getGoals():Vector.<Goal> {
var value:Vector.<Goal> = new Vector.<Goal>();
for each(var g:XML in Config.XML_DATA.goals.*) {
value.push(new Goal(int(g.@x), int(g.@y)));
}
return value;
}
//-------------
// タワーの種類の配列を返す
public static function getTowerType():Vector.<TowerType> {
var value:Vector.<TowerType> = new Vector.<TowerType>();
for each(var t:XML in Config.XML_DATA.tower.*) {
value.push(new TowerType(t.@name, Boolean(int(t.@towerbase)),Boolean(int(t.@ground)), Boolean(int(t.@air)), int(t.@slow), int(t.@splash) , int(t.@venom)));
}
return value;
}
// 引数で指定した種類の、ステータスの配列を返す
public static function getTowerStatus(towerTypeName:String):Vector.<TowerStatus> {
var value:Vector.<TowerStatus> = new Vector.<TowerStatus>();
for each(var s:XML in Config.XML_DATA.tower.*.(@name == towerTypeName).*) {
value.push(new TowerStatus(int(s.@level), int(s.@cost), int(s.@damage), int(s.@range), Number(s.@firerate)));
}
//value.sortOn("level", Array.NUMERIC);
return value;
}
//-------------
// 敵の種類の連想配列を返す
public static function getEnemyType():Dictionary {
var value:Dictionary = new Dictionary();
for each(var e:XML in Config.XML_DATA.enemy.*) {
var typeName:String = e.@name;
value[typeName] = new EnemyType(typeName, Number(e.@speed), Number(e.@MinSpeed), Number(e.@MaxSpeed),Boolean(int(e.@flying)), Boolean(int(e.@immunity)),int(e.@regeneration),int(e.@fade),Boolean(int(e.@born)),Boolean(int(e.@accelerate)) ) ;
}
return value;
}
// 出産能力の連想配列を返す
public static function getBornAbility():Dictionary {
var value:Dictionary = new Dictionary();
for each(var b:XML in Config.XML_DATA.bornAbility.*) {
var parentName:String = b.@name;
value[parentName] = new BornAbility( parentName, String(b.@childrenName), Number(b.@childrenHP), Number(b.@childrenPoint), int(b.@amount), int(b.@limit), int(b.@intervalBorn), Number(b.@HPrateBorn), Boolean(int(b.@deadBorn)), Boolean(int(b.@descent)), Boolean(int(b.@selfRemove)) );
}
return value;
}
// 加速能力の連想配列を返す
public static function getAccelerateAbility():Dictionary {
var value:Dictionary = new Dictionary();
for each(var a:XML in Config.XML_DATA.accelerateAbility.*) {
var runnerName:String = a.@name ;
value[runnerName] = new AccelerateAbility( runnerName, Number(a.@AddPoint), Number(a.@RatePoint), Number(a.@Angle), int(a.@sineSlip), int(a.@intervalRun), Number(a.@HPrateRun), Number(a.@damageRun));
}
return value;
}
//-------------
// ウェーブの配列を返す
public static function getWaves():Vector.<Wave> {
var waveNumber:int = 1;
var value:Vector.<Wave> = new Vector.<Wave>();
for each(var w:XML in Config.XML_DATA.waves.*) {
var spawn:Vector.<int> = new Vector.<int>();
for each(var s:XML in w.*) { spawn.push(int(s.@num)); }
value.push(new Wave(waveNumber, EnemyType.getType(String(w.@type)), int(w.@HP), int(w.@point), int(w.@money), spawn));
waveNumber++;
}
return value;
}
}
//}