Colin Moock

Unionプラットフォームを用いたたくさんの作品を見れたことは、クリエーターとしての何よりの喜びです。このコンテストを通じて、たくさんの素晴らしい作品に出合えたことを、光栄に思います。フラッシュコミュニティーで良く知られたプロジェクト、PaperVisionや、ToneMatrixとTenorionなどの実験的なインターフェースとUnionの組み合わせは、特に刺激的でした。wonderflは知識を共有できる本当に素晴らしい場だと思います。CHECKMATEに投稿された皆さんの作品から、Unionチームの今後の開発におけるたくさんのインスピレーションをもらいました!
たくさんの美味しそうなラーメンの投稿を見たおかげで、お腹が減ってきました。今からラーメンを食べに行きます。全ての参加者の皆さん、wonderflな作品の数々、本当にありがとうございました!

As the creator of the Union development platform, I can think of nothing more rewarding than seeing what people make. I was honoured to see so many fantastic entries for this contest, and was particularly excited to see Union combined with other well-known Flash community projects, such as Papervision, and other experimental interfaces, such as ToneMatrix and Tenorion. wonderfl is such a great place for sharing. The CheckMate entries have given the Union team even more inspiration to continue building Union!
Now I must eat because I am now starving from looking at all the delicious ramen entries!! To all contestants: thank you so much for your wonderfl work!

Amateur

Queenalumican_net

  1. /* It's Show Time !
  2. * Make a music & Let's Scratch ramens !
  3. *
  4. * ・具をトッピングしたり、どんぶりをスクラッチしたり、レバーをいじったりして遊びながら、
  5. *  おいしいラーメン (音楽) を作ってください。
  6. *
  7. * ・「Shiftキー + 既に置いてある具材をドラッグ」 で置き直せます。
  8. *
  9. * ・トッピングした音は自動でビートに吸着するので、
  10. *  適当に置いてもそれなりに聴けると思います。
  11. *
  12. * 一部に propan_mode さん(http://propanmode.net/)が配布されている効果音と、
  13. * 音声読み上げソフト SofTalk (http://cncc.hp.infoseek.co.jp/)を使わせていただいています、多謝。
  14. *
  15. * コードの汚さはおいしさに反比例しています。
  16. * さあレッツラ ラーメン!
  17. *
  18. * @author alumican.net
  19. * @link http://alumican.net/
  20. *
  21. *****************************************
  22. *
  23. * Draw a Tasty Ramen !
  24. *
  25. * You can edit and modify every piece of this code.
  26. * Load more pictures of GU (ingredients of ramen)
  27. * from flickr or draw one by yourself.
  28. * Make it look tasty.
  29. *
  30. */
  31. package
  32. {
  33. import flash.display.*;
  34. import org.libspark.thread.*;
  35. import com.flashdynamix.utils.SWFProfiler;
  36. public class FlashTest extends Sprite
  37. {
  38. public function FlashTest():void
  39. {
  40. //キャプチャ制御
  41. Wonderfl.disable_capture();
  42. // Wonderfl.capture_delay(30);
  43. //ステージ初期化
  44. stage.scaleMode = StageScaleMode.NO_SCALE;
  45. stage.align = StageAlign.TOP_LEFT;
  46. stage.frameRate = 60;
  47. //スレッドの開始
  48. Thread.initialize(new EnterFrameThreadExecutor());
  49. new MainThread(this).start();
  50. //プロファイラの表示
  51. SWFProfiler.init(this);
  52. }
  53. }
  54. }
  55. import flash.display.*;
  56. import flash.errors.*;
  57. import flash.events.*;
  58. import flash.geom.*;
  59. import flash.media.*;
  60. import flash.net.*;
  61. import flash.system.*;
  62. import flash.text.*;
  63. import flash.ui.*;
  64. import flash.utils.*;
  65. import org.libspark.betweenas3.*;
  66. import org.libspark.betweenas3.easing.*;
  67. import org.libspark.betweenas3.tweens.*;
  68. import org.libspark.thread.*;
  69. import org.libspark.thread.errors.*;
  70. import org.libspark.thread.threads.display.*;
  71. import org.libspark.thread.threads.media.*;
  72. import org.libspark.thread.threads.net.*;
  73. import org.libspark.thread.utils.*;
  74. //------------------------------------------------------------------------------------------------------------------------------------------------------
  75. /** MainThread
  76. * メインスレッド
  77. */
  78. internal class MainThread extends Thread
  79. {
  80. //----------------------------------------
  81. //CONSTANTS
  82. //----------------------------------------
  83. //----------------------------------------
  84. //VARIABLES
  85. //----------------------------------------
  86. /**
  87. * stageの参照
  88. */
  89. public var stage:Stage;
  90. /**
  91. * ベースSprite
  92. */
  93. private var _base:Sprite;
  94. /**
  95. * リソース管理クラス
  96. */
  97. private var _resource:Resource;
  98. /**
  99. * コンポーザークラス
  100. */
  101. private var _composer:Composer;
  102. //----------------------------------------
  103. //METHODS
  104. //----------------------------------------
  105. public function MainThread(base:Sprite):void
  106. {
  107. this.stage = base.stage;
  108. _base = base;
  109. //デバッガの初期化
  110. Debugger.initialize(_base);
  111. }
  112. /**
  113. * スレッドの実行関数
  114. */
  115. override protected function run():void
  116. {
  117. Debugger.log("", "now loading...");
  118. //外部リソースを読み込む
  119. _resource = new Resource();
  120. _resource.start();
  121. _resource.join();
  122. next(_loadResourceComplete);
  123. }
  124. /**
  125. * 外部リソースの読み込み完了ハンドラ
  126. */
  127. private function _loadResourceComplete():void
  128. {
  129. Debugger.log("", "initializing...");
  130. _composer = new Composer(_base, _resource);
  131. _composer.start();
  132. _composer.join();
  133. next(null);
  134. }
  135. }
  136. //------------------------------------------------------------------------------------------------------------------------------------------------------
  137. /** Composer
  138. * コンポーザー
  139. */
  140. internal class Composer extends Thread
  141. {
  142. //----------------------------------------
  143. //CONSTANTS
  144. //----------------------------------------
  145. /**
  146. * ステージサイズ
  147. */
  148. private const W:uint = 465;
  149. private const H:uint = 465;
  150. //----------------------------------------
  151. //VARIABLES
  152. //----------------------------------------
  153. /**
  154. * stageの参照
  155. */
  156. public var stage:Stage;
  157. /**
  158. * ベースSprite
  159. */
  160. public function get base():Sprite { return _base; }
  161. private var _base:Sprite;
  162. /**
  163. * リソース管理クラス
  164. */
  165. private var _resource:Resource;
  166. /**
  167. * ターンテーブル
  168. */
  169. private var _tables:Array;
  170. /**
  171. * ターンテーブルの数
  172. */
  173. private var _tableCount:uint;
  174. /**
  175. * ピッチコントローラ
  176. */
  177. private var _pitchController:PitchController;
  178. /**
  179. * 音符アタッチャー
  180. */
  181. private var _noteAttacher:NoteAttacher;
  182. /**
  183. * カーソル
  184. */
  185. private var _cursor:Cursor;
  186. //----------------------------------------
  187. //METHODS
  188. //----------------------------------------
  189. public function Composer(base:Sprite, resource:Resource):void
  190. {
  191. this.stage = base.stage;
  192. _base = base;
  193. _resource = resource;
  194. }
  195. /**
  196. * スレッドの実行関数
  197. */
  198. override protected function run():void
  199. {
  200. Debugger.log("", "run");
  201. _setupTables();
  202. _setupPitchController();
  203. _setupNoteAttacher();
  204. _setupCursor();
  205. //再生開始
  206. play();
  207. }
  208. /**
  209. * ターンテーブルを配置する
  210. */
  211. private function _setupTables():void
  212. {
  213. _tableCount = 2;
  214. _tables = new Array(_tableCount);
  215. var table:Turntable;
  216. for (var i:uint = 0; i < _tableCount; ++i)
  217. {
  218. table = new Turntable(_resource, this, i);
  219. table.x = W / 4 * (i * 2 + 1);
  220. table.y = H / 2 - 30;
  221. _base.addChild(table);
  222. //配列に格納する
  223. _tables[i] = table;
  224. }
  225. }
  226. /**
  227. * ピッチコントローラの配置
  228. */
  229. private function _setupPitchController():void
  230. {
  231. _pitchController = new PitchController(_resource, this);
  232. _pitchController.x = 30;
  233. _pitchController.y = 40;
  234. _base.addChild(_pitchController);
  235. }
  236. /**
  237. * アタッチャーの配置
  238. */
  239. private function _setupNoteAttacher():void
  240. {
  241. _noteAttacher = new NoteAttacher(_resource, this);
  242. _base.addChild(_noteAttacher);
  243. _noteAttacher.x = (W - _noteAttacher.width) / 2;
  244. _noteAttacher.y = H - 70;
  245. }
  246. /**
  247. *マウストレーラーの配置
  248. */
  249. private function _setupCursor():void
  250. {
  251. _cursor = new Cursor(_resource, this);
  252. _base.addChild(_cursor);
  253. }
  254. /**
  255. * 再生開始
  256. */
  257. public function play():void
  258. {
  259. Debugger.log("");
  260. var table:Turntable;
  261. for (var i:uint = 0; i < _tableCount; ++i)
  262. {
  263. table = _tables[i];
  264. table.play();
  265. }
  266. }
  267. /**
  268. * ピッチコントローラからの再生ピッチの変更通知
  269. */
  270. public function notifyPitchControllerUpdate(pitch:Number):void
  271. {
  272. var table:Turntable;
  273. for (var i:uint = 0; i < _tableCount; ++i)
  274. {
  275. table = _tables[i];
  276. table.defaultPitch = pitch;
  277. }
  278. }
  279. /**
  280. * 音を合成する(xy座標)
  281. */
  282. public function synthSoundOnXY(bytes:Array, x:Number, y:Number, object:DisplayObject, mode:String):Array
  283. {
  284. var gp:Point = _noteAttacher.localToGlobal( new Point(x, y) );
  285. var table:Turntable, p:Point;
  286. var result:Array = new Array();
  287. for (var i:uint = 0; i < _tableCount; ++i)
  288. {
  289. table = _tables[i];
  290. p = table.getPolarFromXY( table.globalToLocal( gp.clone() ) );
  291. if (p.x <= 1)
  292. {
  293. (mode == "add") ? table.addFilling(object, p.x, p.y) : table.removeFilling(object);
  294. result.push(
  295. {
  296. discID : i,
  297. position : table.synthSoundUsingAngle(bytes[i], p.y, mode),
  298. distance : p.x,
  299. angle : p.y
  300. }
  301. );
  302. }
  303. }
  304. return result;
  305. }
  306. /**
  307. * 音を合成する(バイト番号)
  308. */
  309. public function synthSoundOnPosition(bytes:Array, discID:uint, position:uint, mode:String):void
  310. {
  311. Turntable(_tables[discID]).synthSoundUsingPosition(bytes[discID], position, mode);
  312. }
  313. }
  314. //------------------------------------------------------------------------------------------------------------------------------------------------------
  315. /** Turntable
  316. * ターンテーブル
  317. */
  318. internal class Turntable extends Sprite
  319. {
  320. //----------------------------------------
  321. //CONSTANTS
  322. /**
  323. * ピッチ可変再生のためのバッファ長
  324. */
  325. private const SOUND_BUFFER_LENGHT:uint = 2048;
  326. /**
  327. * サンプリングレート(KHz)
  328. */
  329. private const SOUND_SAMPLING_RATE:Number = 44.1;
  330. /**
  331. * π
  332. */
  333. private const PI:Number = Math.PI;
  334. private const PI2:Number = Math.PI * 2;
  335. //----------------------------------------
  336. //VARIABLES
  337. /**
  338. * リソース管理クラス
  339. */
  340. private var _resource:Resource;
  341. /**
  342. * コンポーザー
  343. */
  344. private var _composer:Composer;
  345. /**
  346. * ディスクID
  347. */
  348. private var _discID:uint;
  349. /**
  350. * メイントラック
  351. */
  352. private var _track:Sound;
  353. /**
  354. * 再生ピッチ
  355. */
  356. public function get pitch():Number { return _pitch; }
  357. public function set pitch(value:Number):void { _pitch = value; }
  358. private var _pitch:Number;
  359. /**
  360. * デフォルトの再生ピッチ
  361. */
  362. public function get defaultPitch():Number { return _defaultPitch; }
  363. public function set defaultPitch(value:Number):void { _defaultPitch = value; }
  364. private var _defaultPitch:Number;
  365. /**
  366. * メイントラックのByteデータ
  367. */
  368. private var _trackBytes:ByteArray;
  369. /**
  370. * メイントラックのByteデータ(合成前)
  371. */
  372. private var _trackBytesOriginal:ByteArray;
  373. //メイントラックの再生位置
  374. private var _trackPosition:Number;
  375. //メイントラックの総バイト数
  376. private var _trackBytesTotal:Number;
  377. //動的生成Sound
  378. private var _dynamicSound:Sound;
  379. //動的生成SoundChannel
  380. private var _dynamicSoundChannel:SoundChannel;
  381. /**
  382. * 再生中の場合はtrue
  383. */
  384. public function get isPlaying():Boolean { return _dynamicSoundChannel != null; }
  385. /**
  386. * disc用Sprite
  387. */
  388. private var _disc:Sprite;
  389. /**
  390. * どんぶり用Sprite
  391. */
  392. private var _bowl:Bitmap;
  393. /**
  394. * 具材用Sprite
  395. */
  396. private var _filling:Sprite;
  397. /**
  398. * ボタン領域
  399. */
  400. private var _area:Sprite;
  401. /**
  402. * スクラッチ中ならばtrue
  403. */
  404. public function get isScratching():Boolean { return _isScratching; }
  405. private var _isScratching:Boolean;
  406. /**
  407. * スクラッチ速度
  408. */
  409. public function get scratchVelocity():Number { return _scratchVelocity; }
  410. private var _scratchVelocity:Number;
  411. //スクラッチの角度
  412. private var _newScratchAngle:Number;
  413. private var _oldScratchAngle:Number;
  414. //----------------------------------------
  415. //METHODS
  416. /**
  417. * コンストラクタ
  418. */
  419. public function Turntable(resource:Resource, composer:Composer, discID:uint):void
  420. {
  421. _resource = resource;
  422. _composer = composer;
  423. _discID = discID;
  424. addEventListener(Event.ADDED_TO_STAGE, _initialize);
  425. addEventListener(Event.REMOVED_FROM_STAGE, _finalize);
  426. }
  427. /**
  428. * 初期化関数
  429. */
  430. private function _initialize(e:Event):void
  431. {
  432. _initializeImages();
  433. _initializeSounds();
  434. }
  435. /**
  436. * 画像の初期化
  437. */
  438. private function _initializeImages():void
  439. {
  440. //----------------------------------------
  441. //ディスク
  442. _disc = new Sprite();
  443. addChild(_disc);
  444. //----------------------------------------
  445. //どんぶり画像
  446. _bowl = _resource.bowlBmps(0);
  447. _bowl.x = -_bowl.width / 2;
  448. _bowl.y = -_bowl.height / 2;
  449. _bowl.smoothing = true;
  450. _disc.addChild(_bowl);
  451. //----------------------------------------
  452. //ボタン領域
  453. _area = new Sprite();
  454. var g:Graphics = _area.graphics;
  455. g.beginFill(0x0, 0);
  456. g.drawCircle(0, 0, _bowl.width / 2);
  457. g.endFill();
  458. _area.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
  459. _area.buttonMode = true;
  460. _disc.addChild(_area);
  461. //----------------------------------------
  462. //具材
  463. _filling = new Sprite();
  464. _disc.addChild(_filling);
  465. _filling.mouseEnabled = false;
  466. _filling.mouseChildren = false;
  467. stage.addEventListener(KeyboardEvent.KEY_DOWN, _keyDownHandler);
  468. stage.addEventListener(KeyboardEvent.KEY_UP , _keyUpHandler);
  469. }
  470. /**
  471. * 音の初期化
  472. */
  473. private function _initializeSounds():void
  474. {
  475. //----------------------------------------
  476. //ベーストラック
  477. _track = _resource.trackSounds(_discID);
  478. _trackBytes = new ByteArray();
  479. //Soundオブジェクトから生データ(ByteArray)を抽出する
  480. _track.extract(_trackBytes, _track.length * SOUND_SAMPLING_RATE * 8, 0);
  481. //Sound再生ヘッダを先頭へ移動する
  482. _trackPosition = 0;
  483. //Soundのバイト数を取得する
  484. _trackBytesTotal = _trackBytes.length;
  485. //3倍にする(読み取り領域がはみ出たときのため)
  486. var single:ByteArray = new ByteArray();
  487. single.writeBytes(_trackBytes, 0, _trackBytes.length);
  488. _trackBytes.writeBytes(single);
  489. _trackBytes.writeBytes(single);
  490. //復元用に保存する
  491. _trackBytesOriginal = new ByteArray();
  492. _trackBytes.position = 0;
  493. _trackBytes.readBytes(_trackBytesOriginal, 0, _trackBytes.length);
  494. //動的音生成のSoundを生成する
  495. _dynamicSound = new Sound();
  496. _dynamicSound.addEventListener(SampleDataEvent.SAMPLE_DATA, _onSoundSampleDataHandler);
  497. //デフォルトの再生ピッチ
  498. _defaultPitch = 1.0;
  499. //再生ピッチ
  500. _pitch = 1.0;
  501. //スクラッチ状況の初期化
  502. _isScratching = false;
  503. _newScratchAngle = Math.atan2(mouseY, mouseX);
  504. _oldScratchAngle = _newScratchAngle;
  505. _scratchVelocity = 0;
  506. }
  507. /**
  508. * 終了関数
  509. */
  510. private function _finalize(e:Event):void
  511. {
  512. _finalizeImages();
  513. _finalizeSounds();
  514. }
  515. /**
  516. * 画像の終了処理
  517. */
  518. private function _finalizeImages():void
  519. {
  520. }
  521. /**
  522. * 音の終了処理
  523. */
  524. private function _finalizeSounds():void
  525. {
  526. }
  527. /**
  528. * 再生を開始する
  529. */
  530. public function play():void
  531. {
  532. if (isPlaying) return;
  533. //ピッチ計測開始
  534. addEventListener(Event.ENTER_FRAME, _updatePitch);
  535. //再生開始
  536. _dynamicSoundChannel = _dynamicSound.play();
  537. }
  538. /**
  539. * 再生を停止する
  540. */
  541. public function stop():void
  542. {
  543. if (!isPlaying) return;
  544. //ピッチ計測停止
  545. removeEventListener(Event.ENTER_FRAME, _updatePitch);
  546. //再生停止
  547. _dynamicSoundChannel.stop();
  548. _dynamicSoundChannel = null;
  549. }
  550. /**
  551. * 再生ピッチ調整
  552. */
  553. private function _updatePitch(e:Event):void
  554. {
  555. _oldScratchAngle = _newScratchAngle;
  556. _newScratchAngle = Math.atan2(mouseY, mouseX);
  557. var targetPitch:Number;
  558. if (_isScratching)
  559. {
  560. var targetVelocity:Number = _newScratchAngle - _oldScratchAngle;
  561. if (targetVelocity < 0 ) targetVelocity += PI2;
  562. if (targetVelocity > PI) targetVelocity -= PI2;
  563. targetVelocity *= 50;
  564. _scratchVelocity += (targetVelocity - _scratchVelocity) * 0.5;
  565. targetPitch = _scratchVelocity;
  566. }
  567. else
  568. {
  569. _scratchVelocity += (0 - _scratchVelocity) * 0.1;
  570. targetPitch = _defaultPitch + _scratchVelocity;
  571. }
  572. _pitch += (targetPitch - _pitch) * 0.1;
  573. }
  574. /**
  575. * マウスダウンハンドラ
  576. */
  577. private function _mouseDownHandler(e:MouseEvent):void
  578. {
  579. _isScratching = true;
  580. stage.addEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
  581. }
  582. /**
  583. * マウスアップハンドラ
  584. */
  585. private function _mouseUpHandler(e:MouseEvent):void
  586. {
  587. _isScratching = false;
  588. stage.removeEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
  589. }
  590. /**
  591. * サウンドのサンプルデータハンドラ
  592. */
  593. private function _onSoundSampleDataHandler(e:SampleDataEvent):void
  594. {
  595. //ピッチを0.5の倍数に調整する
  596. var normPitch:Number = Math.round(_pitch * 2) / 2;
  597. for (var i:uint = 0; i < SOUND_BUFFER_LENGHT; ++i)
  598. {
  599. //ByteArrayの読み取りヘッダを移動する
  600. _trackPosition += normPitch * 8;
  601. //ループ処理
  602. if (_trackPosition > _trackBytesTotal - 8) _trackPosition -= _trackBytesTotal;
  603. else if (_trackPosition < 7 ) _trackPosition += _trackBytesTotal;
  604. //読み込みヘッダの移動(1トラック分オフセット)
  605. _trackBytes.position = _trackBytesTotal + _trackPosition;
  606. //ByteArrayの読み込みと書き込み
  607. e.data.writeFloat( _trackBytes.readFloat() / 2 );
  608. e.data.writeFloat( _trackBytes.readFloat() / 2 );
  609. }
  610. //ディスクの回転
  611. _disc.rotation = 360 * _trackPosition / _trackBytesTotal;
  612. }
  613. /**
  614. * トラックをSound合成前の状態に復元する
  615. */
  616. public function resetTrack():void
  617. {
  618. //トラックの復元
  619. _trackBytesOriginal.readBytes(_trackBytes, 0, _trackBytesOriginal.length);
  620. _trackBytesOriginal.position = 0;
  621. }
  622. /**
  623. * Soundを合成する
  624. */
  625. public function synthSoundUsingPosition(bytes:ByteArray, position:uint, mode:String):uint
  626. {
  627. var len:uint = bytes.length;
  628. var last:uint = position + _trackBytesTotal + len;
  629. var dst:Number;
  630. //ブレンドモード
  631. var op:Number = (mode == "add") ? 1 :
  632. (mode == "sub") ? -1 : 0;
  633. bytes.position = 0;
  634. for (var i:uint = position + _trackBytesTotal; i < last; i += 4)
  635. {
  636. //合成(あとでちゃんと調べる)
  637. _trackBytes.position = i;
  638. dst = _trackBytes.readFloat() + op * bytes.readFloat() * 2;
  639. //中心の波形に書き込む
  640. _trackBytes.position = i;
  641. _trackBytes.writeFloat(dst);
  642. //前の波形に書き込む
  643. _trackBytes.position = i - _trackBytesTotal;
  644. _trackBytes.writeFloat(dst);
  645. //後ろの波形に書き込む
  646. if (i + len < _trackBytesTotal * 2)
  647. {
  648. _trackBytes.position = i + _trackBytesTotal;
  649. _trackBytes.writeFloat(dst);
  650. }
  651. }
  652. bytes.position = 0;
  653. return position;
  654. }
  655. /**
  656. * 任意のdisc角度にSoundを合成する
  657. */
  658. public function synthSoundUsingAngle(bytes:ByteArray, angle:Number, mode:String):uint
  659. {
  660. //なんか音が遅れるんですけど
  661. var adjust:Number = (_discID == 0) ? -0.10 : -0.05;
  662. //真上で鳴らす
  663. var ratio:Number = 0.75 - angle / PI2 + adjust;
  664. ratio %= 1;
  665. if (ratio < 0) ratio += 1;
  666. //var position:Number = _trackBytesTotal * ratio;
  667. //position = Math.round(position / 8) * 8;
  668. //ビートに乗せる
  669. var position:Number = _trackBytesTotal * ratio;
  670. var unit:int = 2 * SOUND_SAMPLING_RATE * 1000;
  671. position = Math.round(position / unit) * unit;
  672. synthSoundUsingPosition(bytes, position, mode);
  673. return position;
  674. }
  675. /**
  676. * disc中心を基準点とするxy座標から、discの回転を考慮した極座標を取得する
  677. * x : 角度[0, 2pi]
  678. * y : 中心からの距離[0, +inf](1で円周上)
  679. */
  680. public function getPolarFromXY(p:Point):Point
  681. {
  682. var x:Number = p.x;
  683. var y:Number = p.y;
  684. var dist:Number = Math.sqrt(x * x + y * y) / (_area.width / 2);
  685. var angle:Number = Math.atan2(y, x) - PI2 * _trackPosition / _trackBytesTotal;
  686. if (angle < 0 ) angle += PI2;
  687. if (angle > PI2) angle -= PI2;
  688. return new Point(dist, angle);
  689. }
  690. /**
  691. * 具材のDisplayObjectを追加する
  692. */
  693. public function addFilling(object:DisplayObject, dist:Number = 0, angle:Number = 0):DisplayObject
  694. {
  695. dist *= _area.width / 2;
  696. object.x = dist * Math.cos(angle);
  697. object.y = dist * Math.sin(angle);
  698. object.rotation -= _disc.rotation;
  699. return _filling.addChild(object);
  700. }
  701. /**
  702. * 具材のDisplayObjectを削除する
  703. */
  704. public function removeFilling(object:DisplayObject):DisplayObject
  705. {
  706. var angle:Number = _disc.rotation + Math.atan2(object.y, object.x) * 180 / PI;
  707. object.rotation += angle;
  708. return (_filling.contains(object)) ? _filling.removeChild(object) : null;
  709. }
  710. /**
  711. * 全ての具材のDisplayObjectを削除する
  712. */
  713. public function removeAllFilling():Array
  714. {
  715. var removed:Array = new Array();
  716. for (var i:uint = _filling.numChildren - 1; i >= 0; --i)
  717. {
  718. removed.push( _filling.removeChildAt(i) );
  719. }
  720. return removed;
  721. }
  722. /**
  723. * キープレスハンドラ
  724. */
  725. private function _keyDownHandler(e:KeyboardEvent):void
  726. {
  727. if (e.keyCode == 16)
  728. {
  729. _filling.mouseEnabled = true;
  730. _filling.mouseChildren = true;
  731. }
  732. }
  733. /**
  734. * キーアップハンドラ
  735. */
  736. private function _keyUpHandler(e:KeyboardEvent):void
  737. {
  738. if (e.keyCode == 16)
  739. {
  740. _filling.mouseEnabled = false;
  741. _filling.mouseChildren = false;
  742. }
  743. }
  744. }
  745. //------------------------------------------------------------------------------------------------------------------------------------------------------
  746. /** NoteAttacher
  747. * 音の合成UI
  748. */
  749. internal class NoteAttacher extends Sprite
  750. {
  751. //----------------------------------------
  752. //CONSTANTS
  753. /**
  754. * サンプリングレート(KHz)
  755. */
  756. private const SOUND_SAMPLING_RATE:Number = 44.1;
  757. //----------------------------------------
  758. //VARIABLES
  759. /**
  760. * リソース管理クラス
  761. */
  762. private var _resource:Resource;
  763. /**
  764. * コンポーザー
  765. */
  766. private var _composer:Composer;
  767. /**
  768. * 合成音のドラッグ元DisplayObject配列
  769. */
  770. private var _noteObjects:Array;
  771. /**
  772. * 合成音数
  773. */
  774. private var _noteCount:uint;
  775. /**
  776. * ドラッグ中のDisplayObject
  777. */
  778. private var _draggingObject:MovieClip;
  779. /**
  780. * 合成音のバイト列
  781. */
  782. private var _noteBytes:Array;
  783. /**
  784. * 具材名再生用SoundChannel
  785. */
  786. private var _fillingSoundChannel:SoundChannel;
  787. //----------------------------------------
  788. //METHODS
  789. /**
  790. * コンストラクタ
  791. */
  792. public function NoteAttacher(resource:Resource, composer:Composer):void
  793. {
  794. _resource = resource;
  795. _composer = composer;
  796. addEventListener(Event.ADDED_TO_STAGE, _initialize);
  797. addEventListener(Event.REMOVED_FROM_STAGE, _finalize);
  798. }
  799. /**
  800. * 初期化関数
  801. */
  802. private function _initialize(e:Event):void
  803. {
  804. //コピー元を生成する
  805. _noteCount = _resource.noteCount;
  806. _noteObjects = new Array(_noteCount);
  807. _noteBytes = new Array(_noteCount);
  808. var p:Number = 0;
  809. for (var i:uint = 0; i < _noteCount; ++i)
  810. {
  811. //----------------------------------------
  812. //ドラッグ用のDisplayObject
  813. var bmp:Bitmap = _resource.fillingBmps(i);
  814. bmp.x = -bmp.width / 2;
  815. bmp.y = -bmp.height / 2;
  816. bmp.smoothing = true;
  817. p += (i == 0) ? bmp.width / 2 : bmp.width / 2 + 10;
  818. var object:MovieClip = new MovieClip();
  819. object.addChild(bmp);
  820. object.initX = object.x = p;
  821. object.initY = object.y = 0;
  822. object.id = i;
  823. object.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
  824. object.buttonMode = true;
  825. addChild(object);
  826. p += bmp.width / 2;
  827. _noteObjects[i] = object;
  828. //----------------------------------------
  829. //Soundオブジェクトから生データ(ByteArray)を抽出する
  830. _noteBytes[i] = new Array(2);
  831. for (var j:uint = 0; j < 2; ++j)
  832. {
  833. var note:Sound = _resource.noteSounds(j, i);
  834. var ba:ByteArray = new ByteArray();
  835. note.extract(ba, note.length * SOUND_SAMPLING_RATE * 8);
  836. _noteBytes[i][j] = ba;
  837. }
  838. }
  839. }
  840. /**
  841. * 終了関数
  842. */
  843. private function _finalize(e:Event):void
  844. {
  845. }
  846. /**
  847. * コピー元DisplayObjectのマウスダウンハンドラ
  848. */
  849. private function _mouseDownHandler(e:MouseEvent):void
  850. {
  851. var o:MovieClip = _draggingObject = MovieClip(e.currentTarget);
  852. o.startDrag(false, null);
  853. o.x = mouseX;
  854. o.y = mouseY;
  855. //具材名を再生する
  856. if (_fillingSoundChannel != null) _fillingSoundChannel.stop();
  857. _fillingSoundChannel = _resource.fillingSounds(o.id).play();
  858. stage.addEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
  859. }
  860. /**
  861. * コピー元DisplayObjectのマウスアップハンドラ
  862. */
  863. private function _mouseUpHandler(e:MouseEvent):void
  864. {
  865. var o:MovieClip = _draggingObject;
  866. var id:uint = o.id;
  867. //ドラッグ停止
  868. o.stopDrag();
  869. //具材の生成
  870. var bmp:Bitmap = _resource.fillingBmps(id);
  871. bmp.x = -bmp.width / 2;
  872. bmp.y = -bmp.height / 2;
  873. var filling:MovieClip = new MovieClip();
  874. filling.id = id;
  875. filling.addEventListener(MouseEvent.MOUSE_DOWN, _fillingMouseDownHandler);
  876. filling.addChild(bmp);
  877. //合成
  878. var result:Array = _composer.synthSoundOnXY(_noteBytes[id], o.x, o.y, filling, "add");
  879. if (result.length > 0)
  880. {
  881. filling.discID = result[0].discID;
  882. filling.position = result[0].position;
  883. //_resource.noteSounds(id).play();
  884. //元の座標に戻す
  885. o.x = o.initX;
  886. o.y = o.initY;
  887. o.scaleX = o.scaleY = 0;
  888. BetweenAS3.tween(o, { scaleX:1, scaleY:1 }, null, 0.5, Bounce.easeOut).play();
  889. }
  890. else
  891. {
  892. //元の座標に戻す
  893. BetweenAS3.tween(o, { x:o.initX, y:o.initY, scaleX:1, scaleY:1 }, null, 0.5, Quart.easeOut).play();
  894. }
  895. stage.removeEventListener(MouseEvent.MOUSE_UP, _mouseUpHandler);
  896. _draggingObject = null;
  897. }
  898. /**
  899. * 配置済み具材のマウスダウンハンドラ
  900. */
  901. private function _fillingMouseDownHandler(e:MouseEvent):void
  902. {
  903. var o:MovieClip = _draggingObject = MovieClip(e.currentTarget);
  904. var id:uint = o.id;
  905. //音を取る
  906. _composer.synthSoundOnPosition(_noteBytes[id], o.discID, o.position, "sub");
  907. //ドラッグ開始
  908. addChild(o);
  909. o.startDrag(false, null);
  910. o.x = mouseX;
  911. o.y = mouseY;
  912. //具材名を再生する
  913. if (_fillingSoundChannel != null) _fillingSoundChannel.stop();
  914. _fillingSoundChannel = _resource.fillingSounds(o.id).play();
  915. stage.addEventListener(MouseEvent.MOUSE_UP, _fillingMouseUpHandler);
  916. }
  917. /**
  918. * 配置済み具材のマウスアップハンドラ
  919. */
  920. private function _fillingMouseUpHandler(e:MouseEvent):void
  921. {
  922. var o:MovieClip = _draggingObject;
  923. var id:uint = o.id;
  924. //ドラッグ終了
  925. o.stopDrag();
  926. //音の合成
  927. var result:Array = _composer.synthSoundOnXY(_noteBytes[id], o.x, o.y, o, "add");
  928. if (result.length > 0)
  929. {
  930. //再着地成功
  931. o.discID = result[0].discID;
  932. o.position = result[0].position;
  933. o.distance = result[0].distance;
  934. o.angle = result[0].angle;
  935. }
  936. else
  937. {
  938. //再着地失敗
  939. BetweenAS3.serial(
  940. BetweenAS3.tween(o, { scaleX:0, scaleY:0 }, null, 0.5, Quart.easeOut),
  941. BetweenAS3.func(function():void { removeChild(o); } )
  942. ).play();
  943. o.removeEventListener(MouseEvent.MOUSE_DOWN, _fillingMouseDownHandler);
  944. }
  945. stage.removeEventListener(MouseEvent.MOUSE_UP, _fillingMouseUpHandler);
  946. _draggingObject = null;
  947. }
  948. }
  949. //------------------------------------------------------------------------------------------------------------------------------------------------------
  950. /** PitchController
  951. * ピッチコントローラ
  952. */
  953. internal class PitchController extends Sprite
  954. {
  955. //----------------------------------------
  956. //CONSTANTS
  957. //----------------------------------------
  958. //VARIABLES
  959. /**
  960. * リソース管理クラス
  961. */
  962. private var _resource:Resource;
  963. /**
  964. * コンポーザー
  965. */
  966. private var _composer:Composer;
  967. /**
  968. * スライダーオブジェクト
  969. */
  970. private var _slider:Sprite;
  971. /**
  972. * ベースオブジェクト
  973. */
  974. private var _base:Sprite;
  975. /**
  976. * スライダーが示す再生ピッチ
  977. */
  978. private var _pitch:Number;
  979. /**
  980. * スライダーのデフォルト座標
  981. */
  982. private var _defaultSliderPosition:Number;
  983. //----------------------------------------
  984. //METHODS
  985. /**
  986. * コンストラクタ
  987. */
  988. public function PitchController(resource:Resource, composer:Composer):void
  989. {
  990. _resource = resource;
  991. _composer = composer;
  992. addEventListener(Event.ADDED_TO_STAGE, _initialize);
  993. addEventListener(Event.REMOVED_FROM_STAGE, _finalize);
  994. }
  995. /**
  996. * 初期化関数
  997. */
  998. private function _initialize(e:Event):void
  999. {
  1000. //----------------------------------------
  1001. //ベースの生成
  1002. _base = new Sprite();
  1003. var g:Graphics = _base.graphics;
  1004. g.beginFill(0xeeeeee);
  1005. g.drawRoundRect(0, 0, 400, 3, 3);
  1006. g.endFill();
  1007. addChild(_base);
  1008. _defaultSliderPosition = _base.x + _base.width / 2;
  1009. //----------------------------------------
  1010. //スライダーの生成
  1011. _slider = new Sprite();
  1012. var bmp:Bitmap = _resource.fillingBmps(5);
  1013. bmp.x = -bmp.width / 2;
  1014. bmp.y = -bmp.height / 2;
  1015. bmp.smoothing = true;
  1016. _slider.addChild(bmp);
  1017. _slider.x = _defaultSliderPosition;
  1018. _slider.addEventListener(MouseEvent.MOUSE_DOWN, _sliderMouseDownHandler);
  1019. _slider.buttonMode = true;
  1020. _slider.doubleClickEnabled = true;
  1021. addChild(_slider);
  1022. _calcPitch();
  1023. addEventListener(Event.ENTER_FRAME, _updateRotation);
  1024. }
  1025. /**
  1026. * 終了関数
  1027. */
  1028. private function _finalize(e:Event):void
  1029. {
  1030. removeEventListener(Event.ENTER_FRAME, _updateRotation);
  1031. }
  1032. /**
  1033. * スライダーの座標から計算されたピッチを通知する
  1034. */
  1035. private function _calcPitch():void
  1036. {
  1037. //再生ピッチ計算(真ん中が1)
  1038. _pitch = (_slider.x / (_base.x + _base.width)) * 10 - 4;
  1039. if (_pitch < 0.5) _pitch -= 1.0;
  1040. }
  1041. /**
  1042. * スライダーのマウスダウンハンドラ
  1043. */
  1044. private function _sliderMouseDownHandler(e:MouseEvent):void
  1045. {
  1046. //ドラッグ開始
  1047. _slider.startDrag(false, new Rectangle(_base.x, _base.height / 2, _base.width, 0));
  1048. stage.addEventListener(MouseEvent.MOUSE_MOVE, _sliderMouseMoveHandler);
  1049. stage.addEventListener(MouseEvent.MOUSE_UP, _sliderMouseUpHandler);
  1050. removeEventListener(Event.ENTER_FRAME, _updateAutoBackHandler);
  1051. }
  1052. /**
  1053. * スライダーのマウスアップハンドラ
  1054. */
  1055. private function _sliderMouseUpHandler(e:MouseEvent):void
  1056. {
  1057. //ドラッグ停止
  1058. _slider.stopDrag();
  1059. stage.removeEventListener(MouseEvent.MOUSE_MOVE, _sliderMouseMoveHandler);
  1060. stage.removeEventListener(MouseEvent.MOUSE_UP, _sliderMouseUpHandler);
  1061. addEventListener(Event.ENTER_FRAME, _updateAutoBackHandler);
  1062. }
  1063. /**
  1064. * スライダーのドラッグハンドラ
  1065. */
  1066. private function _sliderMouseMoveHandler(e:MouseEvent):void
  1067. {
  1068. _calcPitch();
  1069. _composer.notifyPitchControllerUpdate(_pitch);
  1070. }
  1071. /**
  1072. * マウスを話したときに自動で戻る
  1073. */
  1074. private function _updateAutoBackHandler(e:Event):void
  1075. {
  1076. var d:Number = _defaultSliderPosition - _slider.x;
  1077. var a:Number = (d > 0) ? d : -d;
  1078. if (a < 1.0)
  1079. {
  1080. _slider.x = _defaultSliderPosition;
  1081. removeEventListener(Event.ENTER_FRAME, _updateAutoBackHandler);
  1082. }
  1083. else
  1084. {
  1085. _slider.x += d * 0.1;
  1086. }
  1087. _calcPitch();
  1088. _composer.notifyPitchControllerUpdate(_pitch);
  1089. }
  1090. /**
  1091. * ぐるぐる回しとく
  1092. */
  1093. private function _updateRotation(e:Event):void
  1094. {
  1095. _slider.rotation += _pitch * 5;
  1096. }
  1097. }
  1098. //------------------------------------------------------------------------------------------------------------------------------------------------------
  1099. /** Cursor
  1100. * カーソル
  1101. */
  1102. internal class Cursor extends Sprite
  1103. {
  1104. //----------------------------------------
  1105. //CONSTANTS
  1106. //----------------------------------------
  1107. //VARIABLES
  1108. /**
  1109. * リソース管理クラス
  1110. */
  1111. private var _resource:Resource;
  1112. /**
  1113. * コンポーザー
  1114. */
  1115. private var _composer:Composer;
  1116. /**
  1117. * マウストレーラー
  1118. */
  1119. private var _cursor:Sprite;
  1120. /**
  1121. * 通常時カーソル
  1122. */
  1123. private var _upBmp:Bitmap;
  1124. /**
  1125. * マウスダウン時カーソル
  1126. */
  1127. private var _downBmp:Bitmap;
  1128. //----------------------------------------
  1129. //METHODS
  1130. /**
  1131. * コンストラクタ
  1132. */
  1133. public function Cursor(resource:Resource, composer:Composer):void
  1134. {
  1135. _resource = resource;
  1136. _composer = composer;
  1137. addEventListener(Event.ADDED_TO_STAGE, _initialize);
  1138. addEventListener(Event.REMOVED_FROM_STAGE, _finalize);
  1139. }
  1140. /**
  1141. * 初期化関数
  1142. */
  1143. private function _initialize(e:Event):void
  1144. {
  1145. //カーソル画像の取得
  1146. _upBmp = _resource.cursorBmps(0);
  1147. _upBmp.smoothing = true;
  1148. _downBmp = _resource.cursorBmps(1);
  1149. _downBmp.smoothing = true;
  1150. _downBmp.visible = false;
  1151. //マウストレーラーの生成
  1152. _cursor = new Sprite();
  1153. _cursor.mouseEnabled = false;
  1154. _cursor.mouseChildren = false;
  1155. _cursor.addChild(_upBmp);
  1156. _cursor.addChild(_downBmp);
  1157. addChild(_cursor);
  1158. Mouse.hide();
  1159. var context:ContextMenu = new ContextMenu();
  1160. context.addEventListener(ContextMenuEvent.MENU_SELECT, _contectMenuSelectHandler);
  1161. _composer.base.contextMenu = context;
  1162. stage.addEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
  1163. stage.addEventListener(MouseEvent.MOUSE_UP , _mouseUpHandler);
  1164. stage.addEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
  1165. }
  1166. /**
  1167. * 終了関数
  1168. */
  1169. private function _finalize(e:Event):void
  1170. {
  1171. _cursor.removeChild(_upBmp);
  1172. _cursor.removeChild(_downBmp);
  1173. stage.removeEventListener(MouseEvent.MOUSE_DOWN, _mouseDownHandler);
  1174. stage.removeEventListener(MouseEvent.MOUSE_UP , _mouseUpHandler);
  1175. stage.removeEventListener(MouseEvent.MOUSE_MOVE, _mouseMoveHandler);
  1176. _upBmp = null;
  1177. _downBmp = null;
  1178. _cursor = null;
  1179. }
  1180. /**
  1181. * マウスダウンハンドラ
  1182. */
  1183. private function _mouseDownHandler(e:MouseEvent):void
  1184. {
  1185. _upBmp.visible = false;
  1186. _downBmp.visible = true;
  1187. }
  1188. /**
  1189. * マウスアップハンドラ
  1190. */
  1191. private function _mouseUpHandler(e:MouseEvent):void
  1192. {
  1193. _upBmp.visible = true;
  1194. _downBmp.visible = false;
  1195. }
  1196. /**
  1197. * マウス移動ハンドラ
  1198. */
  1199. private function _mouseMoveHandler(e:MouseEvent):void
  1200. {
  1201. _cursor.x = mouseX;
  1202. _cursor.y = mouseY;
  1203. }
  1204. /**
  1205. * 右クリックメニュー表示時にマウスカーソルを隠す
  1206. * @param e
  1207. */
  1208. private function _contectMenuSelectHandler(e:ContextMenuEvent):void
  1209. {
  1210. Mouse.hide();
  1211. }
  1212. }
  1213. //------------------------------------------------------------------------------------------------------------------------------------------------------
  1214. /** Resource
  1215. * リソース管理クラス
  1216. */
  1217. internal class Resource extends Thread
  1218. {
  1219. //----------------------------------------
  1220. //CONSTANTS
  1221. private const BASE_URL:String = "http://lab.alumican.net/wonderfl/ramen_beats_box/";
  1222. // private const BASE_URL:String = "assets/";
  1223. /**
  1224. * 画像URL配列
  1225. */
  1226. private const IMAGE_URLS:Array = [
  1227. BASE_URL + "imgs/ramen.png", /* ラーメン */
  1228. BASE_URL + "imgs/cursor_up.png", /* 箸(開) */
  1229. BASE_URL + "imgs/cursor_down.png", /* 箸(閉) */
  1230. BASE_URL + "imgs/kakuni.png", /* 角煮 */
  1231. BASE_URL + "imgs/chashu.png", /* チャーシュー */
  1232. BASE_URL + "imgs/menma.png", /* メンマ */
  1233. BASE_URL + "imgs/nitamago.png", /* 煮卵 */
  1234. BASE_URL + "imgs/mame.png", /* 豆 */
  1235. BASE_URL + "imgs/naruto.png" /* ナルト */
  1236. ];
  1237. /**
  1238. * 音URL配列
  1239. */
  1240. private const SOUND_URLS:Array = [
  1241. BASE_URL + "sounds/bit235_etc02.mp3", /* ギタートラック */
  1242. BASE_URL + "sounds/bit243_bass01.mp3", /* ベーストラック */
  1243. // BASE_URL + "sounds/bit243_drum02.mp3", /* ドラムトラック */
  1244. //disc1
  1245. BASE_URL + "sounds/note_0.mp3",
  1246. BASE_URL + "sounds/note_1.mp3",
  1247. BASE_URL + "sounds/note_2.mp3",
  1248. BASE_URL + "sounds/note_3.mp3",
  1249. BASE_URL + "sounds/note_4.mp3",
  1250. BASE_URL + "sounds/note_5.mp3",
  1251. //disc2
  1252. BASE_URL + "sounds/kick_004.mp3",
  1253. BASE_URL + "sounds/kick_009.mp3",
  1254. BASE_URL + "sounds/snare_010.mp3",
  1255. BASE_URL + "sounds/snare_019.mp3",
  1256. BASE_URL + "sounds/voice_hey_omachi.mp3",
  1257. BASE_URL + "sounds/voice_wow_oisii.mp3",
  1258. //filling name
  1259. BASE_URL + "sounds/voice_kakuni.mp3",
  1260. BASE_URL + "sounds/voice_chashu.mp3",
  1261. BASE_URL + "sounds/voice_menma.mp3",
  1262. BASE_URL + "sounds/voice_nitamago.mp3",
  1263. BASE_URL + "sounds/voice_mame.mp3",
  1264. BASE_URL + "sounds/voice_naruto.mp3"
  1265. ];
  1266. /**
  1267. * ラーメンドンブリの数
  1268. */
  1269. public const bowlCount:uint = 1;
  1270. /**
  1271. * カーソル用Bitmapの数
  1272. */
  1273. public const cursorCount:uint = 2;
  1274. /**
  1275. * ラーメン具材の数
  1276. */
  1277. public const fillingCount:uint = IMAGE_URLS.length - bowlCount - 2;
  1278. /**
  1279. * ベーストラックの数
  1280. */
  1281. public const trackCount:uint = 2;
  1282. /**
  1283. * サウンドエフェクトの数
  1284. */
  1285. public const noteCount:uint = fillingCount;
  1286. /**
  1287. * サウンドエフェクトのサブセット数
  1288. */
  1289. public const noteSubsetCount:uint = 2;
  1290. //----------------------------------------
  1291. //VARIABLES
  1292. /**
  1293. * 読み込んだ画像データ配列
  1294. */
  1295. public function bmps(index:uint):Bitmap { return new Bitmap(Bitmap(_bmps[index]).bitmapData.clone(), "auto", true); }
  1296. private var _bmps:Array;
  1297. /**
  1298. * 読み込んだ音データ配列
  1299. */
  1300. public function sounds(index:uint):Sound { return _sounds[index]; }
  1301. private var _sounds:Array;
  1302. /**
  1303. * ラーメンドンブリのBitmap
  1304. */
  1305. public function bowlBmps(index:uint):Bitmap { return bmps(index); }
  1306. /**
  1307. * カーソル用のBitmap
  1308. */
  1309. public function cursorBmps(index:uint):Bitmap { return bmps(index + bowlCount); }
  1310. /**
  1311. * ラーメン具材のBitmap
  1312. */
  1313. public function fillingBmps(index:uint):Bitmap { return bmps(index + bowlCount + cursorCount); }
  1314. /**
  1315. * ベーストラックのSound
  1316. */
  1317. public function trackSounds(index:uint):Sound { return sounds(index); }
  1318. /**
  1319. * 合成用のSound
  1320. */
  1321. public function noteSounds(subset:uint, index:uint):Sound { return sounds(index + trackCount + subset * noteCount); }
  1322. /**
  1323. * 具材名のSound
  1324. */
  1325. public function fillingSounds(index:uint):Sound { return sounds(index + trackCount + noteSubsetCount * noteCount); }
  1326. //----------------------------------------
  1327. //METHODS
  1328. /**
  1329. * コンストラクタ
  1330. */
  1331. public function Resource():void
  1332. {
  1333. }
  1334. /**
  1335. * スレッドの実行関数
  1336. */
  1337. override protected function run():void
  1338. {
  1339. //素材の読み込み開始
  1340. _loadImages();
  1341. }
  1342. /**
  1343. * 画像の読み込みを開始する
  1344. */
  1345. private function _loadImages():void
  1346. {
  1347. Debugger.log("", "loading images...");
  1348. _loadDatas(IMAGE_URLS, "img", _onImagesLoadComplete);
  1349. }
  1350. /**
  1351. * 音の読み込みを開始する
  1352. */
  1353. private function _loadSounds():void
  1354. {
  1355. Debugger.log("", "loading sounds...");
  1356. _loadDatas(SOUND_URLS, "sound", _onSoundsLoadComplete);
  1357. }
  1358. /**
  1359. * 画像の読み込み完了ハンドラ
  1360. */
  1361. private function _onImagesLoadComplete(container:Array, type:String):void
  1362. {
  1363. //読み込んだ画像配列
  1364. _bmps = container;
  1365. //音の読み込みを開始する
  1366. _loadSounds();
  1367. }
  1368. /**
  1369. * 音の読み込み完了ハンドラ
  1370. */
  1371. private function _onSoundsLoadComplete(container:Array, type:String):void
  1372. {
  1373. //読み込んだ音配列
  1374. _sounds = container;
  1375. }
  1376. /**
  1377. * URL配列で与えられたデータを読み込む汎用メソッド
  1378. */
  1379. private function _loadDatas(urls:Array, type:String, onComplete:Function = null, onError:Function = null):void
  1380. {
  1381. //読み込んだデータを格納する配列
  1382. var container:Array = new Array();
  1383. //読み込み開始
  1384. var loaders:ParallelExecutor = new ParallelExecutor();
  1385. for (var i:uint = 0; i < urls.length; ++i)
  1386. {
  1387. var thread:Thread = (type == "text" ) ? new URLLoaderThread( new URLRequest(urls[i]) ) :
  1388. (type == "sound") ? new SoundLoaderThread( new URLRequest(urls[i]) ) :
  1389. new LoaderThread( new URLRequest(urls[i]), new LoaderContext(true) ) ;
  1390. loaders.addThread(thread);
  1391. }
  1392. loaders.start();
  1393. loaders.join();
  1394. //読み込み完了ハンドラ
  1395. function onLoadComplete():void
  1396. {
  1397. //読み込んだデータを配列に格納する
  1398. for (var i:uint = 0; i < urls.length; ++i)
  1399. {
  1400. var data:* = (type == "text" ) ? URLLoaderThread( loaders.getThreadAt(i) ).loader.data :
  1401. (type == "sound") ? SoundLoaderThread( loaders.getThreadAt(i) ).sound :
  1402. LoaderThread( loaders.getThreadAt(i) ).loader.content ;
  1403. container.push(data);
  1404. }
  1405. //コールバック関数の呼び出し
  1406. if (onComplete != null) onComplete(container, type);
  1407. }
  1408. //読み込みエラーハンドラ
  1409. function onLoadError(e:Error, t:Thread):void
  1410. {
  1411. var url:String = (type == "text" ) ? URLLoaderThread(t).request.url :
  1412. (type == "sound") ? SoundLoaderThread(t).request.url :
  1413. LoaderThread(t).request.url ;
  1414. trace("error : _loadDatas, url = " + url + ", type = " + type);
  1415. //コールバック関数の呼び出し
  1416. (onError != null) ? onError() : next(null);
  1417. }
  1418. //ハンドラの登録
  1419. next(onLoadComplete);
  1420. error(IOError, onLoadComplete);
  1421. error(SecurityError, onLoadError);
  1422. }
  1423. /**
  1424. * ディープコピーを生成する
  1425. */
  1426. static public function clone(src:*):*
  1427. {
  1428. var ba:ByteArray = new ByteArray();
  1429. ba.writeObject(src);
  1430. ba.position = 0;
  1431. return ba.readObject();
  1432. }
  1433. }
  1434. //------------------------------------------------------------------------------------------------------------------------------------------------------
  1435. /** Debugger
  1436. * デバッグ用クラス
  1437. */
  1438. internal class Debugger
  1439. {
  1440. //----------------------------------------
  1441. //CONSTANTS
  1442. //----------------------------------------
  1443. //VARIABLES
  1444. /**
  1445. * ログ出力用TextField
  1446. */
  1447. static private var _field:TextField;
  1448. //----------------------------------------
  1449. //METHODS
  1450. /**
  1451. * コンストラクタ
  1452. */
  1453. public function Debugger():void
  1454. {
  1455. }
  1456. /**
  1457. * 初期化関数
  1458. */
  1459. static public function initialize(base:Sprite):void
  1460. {
  1461. _field = base.addChild(new TextField()) as TextField;
  1462. _field.width = 465;
  1463. _field.height = 465;
  1464. _field.selectable = false;
  1465. _field.mouseEnabled = false;
  1466. }
  1467. /**
  1468. * ログ出力
  1469. */
  1470. static public function log(...args):void
  1471. {
  1472. var argn:uint = args.length;
  1473. for (var i:uint = 0; i < argn; ++i)
  1474. {
  1475. if (args[i] == "")
  1476. {
  1477. _field.text = "";
  1478. continue;
  1479. }
  1480. _field.appendText(String(args[i]) + "\n");
  1481. }
  1482. }
  1483. }
flash swf thumbnail play
出題者からのコメント
面白い!ラーメンとビートという、私の好みのものが組み合わさっています。大好きです。とてもクリエイティブで、完成度も十分です。
Comments from King
笑う!! I love it! Beats and ramen! Two of my favourite things in the world combined together! Very creative and satisfying.

Bishopiong

  1. // forked from checkmate's colin challenge for amateurs
  2. /*
  3. extreme drawing !!
  4. Shoyu Tonkotsu (pork and soy sauce) Ramen, Enjoy! :)
  5. ラーメン"書き"あげた
  6. へいおまち煮卵チャーシュー全部いり
  7. */
  8. /*
  9. *
  10. * Draw a Tasty Ramen !
  11. *
  12. * You can edit and modify every piece of this code.
  13. * Load more pictures of GU (ingredients of ramen)
  14. * from flickr or draw one by yourself.
  15. * Make it look tasty.
  16. *
  17. */
  18. package{
  19. import flash.display.Sprite;
  20. [SWF(width="460", height="460", backgroundColor="0xFFFFFF", frameRate="15")];
  21. public class FlashTest extends Sprite{
  22. import flash.display.Bitmap;
  23. import flash.display.BitmapData;
  24. import flash.display.Graphics;
  25. import flash.display.GradientType;
  26. import flash.display.SpreadMethod;
  27. import flash.display.LineScaleMode;
  28. import flash.display.CapsStyle
  29. import flash.display.JointStyle;
  30. import flash.events.Event;
  31. import flash.geom.Point;
  32. import flash.geom.Matrix;
  33. import flash.geom.ColorTransform
  34. import flash.filters.BlurFilter;
  35. import flash.filters.BevelFilter;
  36. import flash.filters.GlowFilter;
  37. import flash.display.BlendMode;
  38. import flash.display.Stage;
  39. import flash.display.StageAlign;
  40. import flash.display.StageScaleMode;
  41. private var cvSt:Bitmap;
  42. private var bmSt:BitmapData;
  43. private var cvStF:Bitmap;
  44. private var bmStF:BitmapData;
  45. private var maskR:BitmapData;
  46. private var maskSt:Sprite;
  47. private var _spRamenBg:Sprite;
  48. private var _spRamenBgEff:Sprite;
  49. private var _spRamen:Sprite;
  50. private var aryOffset:Array = new Array();
  51. private var aryOffsetSP:Array = new Array();
  52. private var aryGC:Array;
  53. private var aryGA:Array;
  54. private var aryGR:Array;
  55. private var matG:Matrix;
  56. private var bvlDish:BevelFilter;
  57. private var bvlTopper:BevelFilter;
  58. private var bvlTopperInner:BevelFilter;
  59. public function FlashTest(){
  60. init();
  61. }
  62. private function init():void{
  63. stage.scaleMode=StageScaleMode.NO_SCALE;
  64. stage.align=StageAlign.TOP_LEFT;
  65. bvlDish = new BevelFilter(4, -45, 0xffffff,1, 0x000000,1
  66. ,16, 16, 0.5
  67. ,1, "inner", false);
  68. bvlTopper = new BevelFilter(4, 45, 0xffffff,1, 0x000000,1
  69. ,4, 4, 0.5
  70. ,1, "outer", false);
  71. bvlTopperInner = new BevelFilter(4, 15, 0xffffff,1, 0x000000,0
  72. ,16, 16, 1
  73. ,1, "inner", false);
  74. // draw
  75. _spRamenBg = makeRamenBg();
  76. addChild(_spRamenBg);
  77. initSteam();
  78. _spRamenBgEff = makeRamenBgEff();
  79. addChild(_spRamenBgEff);
  80. _spRamen= makeRamen();
  81. addChild(_spRamen);
  82. initSteamFront();
  83. // Act
  84. addEventListener(Event.ENTER_FRAME, actSteam);
  85. }
  86. // ------------------------------------
  87. // Ramen(background)
  88. private function makeRamenBg():Sprite
  89. {
  90. var retVal:Sprite = new Sprite();
  91. // dish
  92. var _d1Dish:Sprite = mADish();
  93. // soup
  94. var _d1Soup:Sprite = mASoup();
  95. retVal.addChild(_d1Dish);
  96. retVal.addChild(_d1Soup);
  97. return retVal;
  98. }
  99. private function makeRamenBgEff():Sprite
  100. {
  101. var retVal:Sprite = new Sprite();
  102. // nori
  103. var _d2Nori:Sprite = mBNori();
  104. // shade
  105. var _d2Shade1:Sprite = mBShade1();
  106. // dish
  107. var _d2Dish1:Sprite = mBDish1();
  108. retVal.addChild(_d2Nori);
  109. retVal.addChild(_d2Dish1);
  110. retVal.addChild(_d2Shade1);
  111. return retVal;
  112. }
  113. // ------------------------------------
  114. // Steam
  115. private function initSteam():void
  116. {
  117. bmSt = new BitmapData(470, 220, true, 0xffffff);
  118. cvSt = new Bitmap(bmSt);
  119. cvSt.x += 20;
  120. cvSt.y += 80;
  121. addChild(cvSt);
  122. maskR = new BitmapData(470, 470, true, 0x000000);
  123. maskSt = new Sprite();
  124. maskSt.y += 30;
  125. aryGC = [0xffffff, 0xffffff, 0xffffff];
  126. aryGA = [0.2, 0.2, 1];
  127. aryGR = [0, 0x11, 0xcc];
  128. matG = new Matrix();
  129. matG.createGradientBox(550, 330, 90, 0,0);
  130. with(maskSt.graphics){
  131. beginGradientFill(GradientType.RADIAL, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  132. drawCircle(232.5, 250, 335);
  133. endFill();
  134. }
  135. maskR.draw(maskSt);
  136. maskR.draw(bmSt);
  137. addChild(new Bitmap(maskR));
  138. cvSt.blendMode = BlendMode.SCREEN;
  139. aryOffsetSP = [0.5, 3];
  140. aryOffset = [new Point(), new Point()];
  141. }
  142. private function initSteamFront():void
  143. {
  144. var maskStF:Sprite = new Sprite();
  145. with(maskStF.graphics){
  146. beginFill(0x000000,1);
  147. drawCircle(232.5, 295, 225);
  148. endFill();
  149. }
  150. maskStF.scaleY=0.58;
  151. cvStF = new Bitmap(bmSt);
  152. cvStF.x = 18;
  153. cvStF.y = 78;
  154. cvStF.blendMode = BlendMode.OVERLAY;
  155. cvStF.alpha=0.7;
  156. cvStF.mask = maskStF;
  157. addChild(maskStF);
  158. addChild(cvStF);
  159. }
  160. private function actSteam(e:Event):void
  161. {
  162. aryOffset[0].x += aryOffsetSP[0];
  163. aryOffset[1].y += aryOffsetSP[1];
  164. bmSt.perlinNoise(30, 30, 2, 2, false, true, 1, true, aryOffset);
  165. bmSt.draw(cvSt);
  166. bmSt.draw(cvStF);
  167. }
  168. // ------------------------------------
  169. // Ramen(Main)
  170. private function makeRamen():Sprite
  171. {
  172. var retVal:Sprite = new Sprite();
  173. // garlic chips
  174. var _d2Chips:Sprite = mBChips();
  175. // soup
  176. var _d2Soup:Sprite = mBSoup1();
  177. var _d2SoupOil:Sprite = mBSoup2();
  178. var _d2SoupGlow:Sprite = mBSoupGlow();
  179. // Txt
  180. var _d2Txt:Sprite = mBTxt();
  181. var _d2TxtCM:Sprite = mBTxtCM();
  182. // noodle
  183. var _d2Noodle:Sprite = mBNoodle();
  184. // cloud ear
  185. var _d2Kikurage:Sprite = mBKikurage();
  186. // char siu
  187. var _d2Charsiu:Sprite = mBCharsiu();
  188. // egg
  189. var _d2Egg:Sprite = mBEgg();
  190. // leek
  191. var _d2Negi:Sprite = mBNegi();
  192. // dish
  193. var _d2Dish2:Sprite = mBDish2();
  194. var _d2Dish3:Sprite = mBDish3();
  195. retVal.cacheAsBitmap = true;
  196. retVal.addChild(_d2SoupGlow);
  197. retVal.addChild(_d2Txt);
  198. retVal.addChild(_d2Noodle);
  199. retVal.addChild(_d2Chips);
  200. retVal.addChild(_d2Charsiu);
  201. retVal.addChild(_d2Soup);
  202. retVal.addChild(_d2TxtCM);
  203. retVal.addChild(_d2Kikurage);
  204. retVal.addChild(_d2SoupOil);
  205. retVal.addChild(_d2Negi);
  206. retVal.addChild(_d2Egg);
  207. retVal.addChild(_d2Dish2);
  208. retVal.addChild(_d2Dish3);
  209. return retVal;
  210. }
  211. // ------------------------------------
  212. // pieces
  213. private function mADish():Sprite
  214. {
  215. var retVal:Sprite = new Sprite();
  216. with(retVal.graphics){
  217. beginFill(0x990000, 1);
  218. moveTo(8, 190);
  219. curveTo(50,96 , 200,88);
  220. curveTo(232.5,85 , 265,88);
  221. curveTo(415,100 , 457,190);
  222. lineTo(445, 330);
  223. lineTo(20, 330);
  224. endFill();
  225. }
  226. return retVal;
  227. }
  228. private function mASoup():Sprite
  229. {
  230. var retVal:Sprite = new Sprite();
  231. aryGC = [0xff6600, 0xffff99];
  232. aryGA = [1, 1];
  233. aryGR = [0, 0xee];
  234. matG = new Matrix();
  235. matG.createGradientBox(470, 330, 0, 0,0);
  236. with(retVal.graphics){
  237. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  238. drawCircle(230, 430, 200);
  239. endFill();
  240. }
  241. retVal.scaleY= 0.5;
  242. return retVal;
  243. }
  244. // ------------------------------------
  245. private function mBChips():Sprite
  246. {
  247. var retVal:Sprite = new Sprite();
  248. for(var i:int=0; i<500; i++){
  249. var pD2:Sprite = new pChip();
  250. pD2.x = 30+ Math.round(Math.random()*400);
  251. pD2.y = 130+ Math.round(Math.random()*200);
  252. pD2.alpha -= Math.round(pD2.y-130)/200;
  253. retVal.addChild(pD2);
  254. }
  255. var maskD2E:Sprite = new Sprite();
  256. with(maskD2E.graphics){
  257. beginFill(0x000000,1);
  258. drawCircle(230, 430, 205);
  259. endFill();
  260. }
  261. maskD2E.scaleY= 0.52;
  262. retVal.mask = maskD2E;
  263. return retVal;
  264. }
  265. private function mBNori():Sprite
  266. {
  267. var retVal:Sprite = new Sprite();
  268. var _d2Nori1:Sprite = new Sprite();
  269. var _d2Nori2:Sprite = new Sprite();
  270. aryGC = [0x110000, 0xffa033];
  271. aryGA = [1, 1];
  272. aryGR = [0, 0x99];
  273. matG = new Matrix();
  274. matG.createGradientBox(200, 200, Math.PI/4*3, 0,0);
  275. with(_d2Nori1.graphics){
  276. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 0.7);
  277. moveTo(270, 30);
  278. curveTo(320,30, 340, 24);
  279. curveTo(340,170, 320,200);
  280. lineTo(250,190);
  281. curveTo(270,150, 270,30);
  282. endFill();
  283. }
  284. aryGC = [0x221111, 0xffaa3a];
  285. with(_d2Nori2.graphics){
  286. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 0.7);
  287. moveTo(330, 45);
  288. curveTo(380,60, 400, 60);
  289. curveTo(395,170, 355,230);
  290. lineTo(300,205);
  291. curveTo(330,150, 330,45);
  292. endFill();
  293. }
  294. var _d2BNori:BitmapData= new BitmapData(200,250,true,0x000000);
  295. _d2BNori.noise(Math.round(Math.random()*100), 0, 40, 1);
  296. var _d2PNori1:Bitmap= new Bitmap(_d2BNori);
  297. var _d2PNori2:Bitmap= new Bitmap(_d2BNori);
  298. _d2PNori1.x= _d2PNori2.x= 250;
  299. _d2PNori1.y= _d2PNori2.y= 0;
  300. _d2PNori1.blendMode= BlendMode.SCREEN;
  301. _d2PNori2.blendMode= BlendMode.SCREEN;
  302. _d2Nori1.blendMode = BlendMode.INVERT;
  303. _d2Nori1.blendMode = BlendMode.INVERT;
  304. retVal.addChild(_d2Nori1);
  305. retVal.addChild(_d2Nori2);
  306. retVal.addChild(_d2PNori1);
  307. retVal.addChild(_d2PNori2);
  308. return retVal;
  309. }
  310. private function mBTxt():Sprite
  311. {
  312. var retVal:Sprite = new Sprite();
  313. var pTxtC1:Sprite = new Sprite();
  314. var pTxtC2:Sprite = new Sprite();
  315. var pTxtC3:Sprite = new Sprite();
  316. with(pTxtC1.graphics){
  317. lineStyle(3, 0xfff6f6, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE, JointStyle.MITER, 3);
  318. moveTo(0,10);
  319. lineTo(0,6);
  320. curveTo(1,1, 6,0);
  321. lineTo(32,0);
  322. }
  323. with(pTxtC2.graphics){
  324. lineStyle(3, 0xfff6f6, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE, JointStyle.MITER, 3);
  325. moveTo(0,0);
  326. lineTo(0,10);
  327. }
  328. with(pTxtC3.graphics){
  329. lineStyle(3, 0xfff6f6, 1, false, LineScaleMode.NONE, CapsStyle.SQUARE, JointStyle.MITER, 3);
  330. moveTo(0,0);
  331. lineTo(32,0);
  332. }
  333. retVal.addChild(pTxtC1);
  334. retVal.addChild(pTxtC2);
  335. retVal.addChild(pTxtC3);
  336. pTxtC2.x = 8;
  337. pTxtC3.x = 1;
  338. pTxtC3.y = 16;
  339. retVal.x = 355;
  340. retVal.y = 80;
  341. retVal.scaleX = -1;
  342. retVal.rotation = -80;
  343. retVal.alpha = 0.95;
  344. retVal.blendMode = BlendMode.LAYER;
  345. var blurNoriTxt:BlurFilter = new BlurFilter(2,0);
  346. retVal.filters= [blurNoriTxt];
  347. return retVal;
  348. }
  349. private function mBTxtCM():Sprite
  350. {
  351. var retVal:Sprite = new Sprite();
  352. var pTxtC:Sprite = new Sprite();
  353. var pTxtH:Sprite = new Sprite();
  354. var pTxtE:Sprite = new Sprite();
  355. var pTxtC2:Sprite = new Sprite();
  356. var pTxtK:Sprite = new Sprite();
  357. var pTxtM:Sprite = new Sprite();
  358. var pTxtA:Sprite = new Sprite();
  359. var pTxtT:Sprite = new Sprite();
  360. var pTxtE2:Sprite = new Sprite();
  361. var lSize:uint = 3;
  362. var lColor:Number = 0x404040;
  363. var lSScale:* = LineScaleMode.NORMAL;
  364. var lSCaps:* = LineScaleMode.NONE;
  365. var lSJoint:* = LineScaleMode.NONE;
  366. with(pTxtC.graphics){
  367. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  368. moveTo(9,7);
  369. lineTo(6,0);
  370. lineTo(0,5);
  371. lineTo(9,25);
  372. lineTo(14,19);
  373. lineTo(11,13);
  374. }
  375. with(pTxtH.graphics){
  376. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  377. moveTo(0,5);
  378. lineTo(10,28);
  379. moveTo(5,18);
  380. lineTo(11,12);
  381. moveTo(6,0);
  382. lineTo(16,22);
  383. }
  384. with(pTxtE.graphics){
  385. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  386. moveTo(7,0);
  387. lineTo(0,4);
  388. lineTo(8,23);
  389. lineTo(15,19);
  390. moveTo(4,15);
  391. lineTo(9,11);
  392. }
  393. with(pTxtC2.graphics){
  394. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  395. moveTo(12,8);
  396. lineTo(9,0);
  397. lineTo(2,3);
  398. lineTo(10,22);
  399. lineTo(16,19);
  400. lineTo(13.2,12.5);
  401. }
  402. with(pTxtK.graphics){
  403. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  404. moveTo(0,2);
  405. lineTo(8,25);
  406. moveTo(8,0);
  407. lineTo(5,13);
  408. lineTo(15,22);
  409. }
  410. with(pTxtM.graphics){
  411. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  412. moveTo(16.5,22);
  413. lineTo(10.5,0);
  414. lineTo(9,12);
  415. lineTo(1,3);
  416. lineTo(8,24);
  417. }
  418. with(pTxtA.graphics){
  419. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  420. moveTo(13,19);
  421. lineTo(2,0);
  422. lineTo(3,23);
  423. moveTo(1,14);
  424. lineTo(8,13);
  425. }
  426. with(pTxtT.graphics){
  427. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  428. moveTo(0,3);
  429. lineTo(12,0);
  430. moveTo(6,1);
  431. lineTo(11,21);
  432. }
  433. with(pTxtE2.graphics){
  434. lineStyle(lSize, lColor, 1, false, lSScale, lSCaps, lSJoint);
  435. moveTo(7,0);
  436. lineTo(0,1);
  437. lineTo(4,21);
  438. lineTo(13,19);
  439. moveTo(3,11);
  440. lineTo(8,10);
  441. }
  442. retVal.addChild(pTxtC);
  443. retVal.addChild(pTxtH);
  444. retVal.addChild(pTxtE);
  445. retVal.addChild(pTxtC2);
  446. retVal.addChild(pTxtK);
  447. retVal.addChild(pTxtM);
  448. retVal.addChild(pTxtA);
  449. retVal.addChild(pTxtT);
  450. retVal.addChild(pTxtE2);
  451. pTxtC.x = 0;
  452. pTxtC.y = 36;
  453. pTxtH.x = 10;
  454. pTxtH.y = 27;
  455. pTxtE.x = 22;
  456. pTxtE.y = 22;
  457. pTxtC2.x = 30;
  458. pTxtC2.y = 18;
  459. pTxtK.x = 43.5;
  460. pTxtK.y = 12;
  461. pTxtM.x = 54;
  462. pTxtM.y = 8;
  463. pTxtA.x = 71;
  464. pTxtA.y = 6;
  465. pTxtT.x = 79;
  466. pTxtT.y = 2;
  467. pTxtE2.x = 94;
  468. pTxtE2.y = 0;
  469. retVal.scaleX = 1.25;
  470. retVal.scaleY = 1.1;
  471. retVal.x = 55;
  472. retVal.y = 103;
  473. retVal.blendMode= BlendMode.OVERLAY;
  474. return retVal;
  475. }
  476. private function mBNoodle():Sprite
  477. {
  478. var retVal:Sprite = new Sprite();
  479. var bdNoodle:BitmapData = new BitmapData(440,220);
  480. var _dNoodle:Sprite = new Sprite();
  481. bdNoodle.perlinNoise(160, 10, 2, 2, false, false, 1, true);
  482. var iSp:uint = 10;
  483. var iAmp:uint = 120;
  484. var iCnt:uint = 1;
  485. var iP:uint = 0;
  486. var tP:uint = 0;
  487. var matNoodle:Matrix = new Matrix(1,0,0,1,0,0);
  488. iP+=iSp;
  489. for(var i:int=0; i<=440; i++){
  490. tP += iCnt;
  491. matNoodle.tx = Math.sin(tP*Math.PI/180) * iAmp;
  492. with(_dNoodle.graphics){
  493. beginBitmapFill(bdNoodle, matNoodle);
  494. moveTo(i, 0);
  495. lineTo(i+1, 0);
  496. lineTo(i+1, 220);
  497. lineTo(i, 220);
  498. endFill();
  499. }
  500. }
  501. bdNoodle = null;
  502. var clNoodle:ColorTransform= new ColorTransform(1,1,1,1, 200,200,30,0);
  503. _dNoodle.transform.colorTransform= clNoodle;
  504. _dNoodle.alpha=0.8;
  505. var maskNoodle:Sprite = new Sprite();
  506. with(maskNoodle.graphics){
  507. beginFill(0x000000,1);
  508. drawCircle(232.5, 430, 205);
  509. endFill();
  510. }
  511. maskNoodle.scaleY = 0.52;
  512. _dNoodle.mask = maskNoodle;
  513. var flNoodle:Sprite = new Sprite();
  514. aryGC = [0x000000, 0x000000];
  515. aryGA = [1, 0];
  516. aryGR = [0xbb, 0xee];
  517. matG = new Matrix();
  518. matG.createGradientBox(410, 410, 0, 0,0);
  519. with(flNoodle.graphics){
  520. beginGradientFill(GradientType.RADIAL, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 0);
  521. drawCircle(231, 225, 205);
  522. endFill();
  523. }
  524. flNoodle.y = 105;
  525. flNoodle.scaleY = 0.52;
  526. retVal.addChild(_dNoodle);
  527. retVal.addChild(flNoodle);
  528. retVal.addChild(maskNoodle);
  529. _dNoodle.blendMode = BlendMode.LAYER;
  530. flNoodle.blendMode = BlendMode.ALPHA;
  531. _dNoodle.x = 40;
  532. _dNoodle.y = 15;
  533. _dNoodle.rotation=18;
  534. var blurNoodle:BlurFilter= new BlurFilter(2,2);
  535. _dNoodle.filters= [blurNoodle];
  536. return retVal;
  537. }
  538. private function mBKikurage():Sprite
  539. {
  540. var retVal:Sprite = new Sprite();
  541. for(var i:int=0; i<80; i++){
  542. var pD:Sprite = new pKikurage();
  543. pD.x= Math.round(Math.random()*120);
  544. pD.y= i+ Math.round(Math.random()*60);
  545. retVal.addChild(pD);
  546. }
  547. retVal.scaleY= 0.6;
  548. retVal.x = 80;
  549. retVal.y = 150;
  550. retVal.filters= [bvlTopper];
  551. return retVal;
  552. }
  553. private function mBCharsiu():Sprite
  554. {
  555. var retVal:Sprite = new Sprite();
  556. var pNum:uint = 3;
  557. aryGC = [0xbb9999,0xddb9b9, 0x990000, 0xffffff];
  558. aryGA = [1, 1, 1, 0.8];
  559. aryGR = [0, 0x11, 0x22, 0x99];
  560. matG = new Matrix();
  561. matG.createGradientBox(100, 100, 0, 0,0);
  562. var blurC:BlurFilter = new BlurFilter(4,4);
  563. var bvlC:BevelFilter = new BevelFilter(4, 70, 0xffffff,0, 0x996666,1,8, 8, 1 ,1, "outer", false);
  564. var aryRC:Array = [2,0,1]
  565. var rc:uint = 0;
  566. for(var i:int=0; i
  567. var pS1:Sprite = new Sprite();
  568. var pS2:Sprite = new Sprite();
  569. rc = aryRC[i];
  570. with(pS1.graphics){
  571. beginFill(0xeecccc, 1);
  572. switch(rc){
  573. case 0:
  574. moveTo(40,0);
  575. curveTo(80,0, 80,35);
  576. curveTo(80,80, 30,80);
  577. curveTo(0,80, 0,45);
  578. curveTo(10,15, 40,0);
  579. endFill();
  580. break;
  581. case 1:
  582. moveTo(45,0);
  583. curveTo(78,10, 80,50);
  584. curveTo(80,70, 60,70);
  585. curveTo(65,100, 50,100);
  586. curveTo(0,100, 0,70);
  587. curveTo(0,25, 10,25);
  588. curveTo(10,10, 45,0);
  589. endFill();
  590. break;
  591. case 2:
  592. moveTo(40,0);
  593. curveTo(50,0, 50,14);
  594. curveTo(35,45, 35,80);
  595. curveTo(37,90, 12,90);
  596. curveTo(0,90, 0,65);
  597. curveTo(10,25, 40,0);
  598. endFill();
  599. break;
  600. }
  601. }
  602. with(pS2.graphics){
  603. beginGradientFill(GradientType.RADIAL, aryGC, aryGA, aryGR, matG, SpreadMethod.REFLECT, "rgb", 0);
  604. switch(rc){
  605. case 0:
  606. moveTo(10,15);
  607. curveTo(20,25, 40,20);
  608. curveTo(50,0, 65,15);
  609. curveTo(75,15, 75,40);
  610. curveTo(75,65, 40,65);
  611. curveTo(-5,65, 5,35);
  612. curveTo(5,5, 10,15);
  613. break;
  614. case 1:
  615. moveTo(40,0);
  616. curveTo(70,0, 70,45);
  617. curveTo(60,35, 50,80);
  618. curveTo(50,90, 20,80);
  619. curveTo(0,50, 10,30);
  620. curveTo(0,0, 40,0);
  621. break;
  622. case 2:
  623. moveTo(32,0);
  624. curveTo(36,0, 36,10);
  625. curveTo(35,15, 22,15);
  626. curveTo(16,35, 16,48);
  627. curveTo(20,70, 15,80);
  628. break;
  629. }
  630. }
  631. pS2.x += 7;
  632. pS2.y += 7;
  633. pS2.filters= [blurC];
  634. pS2.blendMode = BlendMode.OVERLAY;
  635. pS1.addChild(pS2);
  636. pS1.rotation = i*10;
  637. pS1.x -= i*5;
  638. switch(rc){
  639. case 0:
  640. pS1.y -= 10;
  641. break;
  642. case 1:
  643. break;
  644. case 2:
  645. pS1.rotation += 170;
  646. pS1.x += 110;
  647. pS1.y += 90;
  648. break;
  649. }
  650. var glowC:GlowFilter= new GlowFilter(0x660000,0.5,16,16,2,2,true,false);
  651. pS1.filters = [glowC,bvlC];
  652. retVal.addChild(pS1);
  653. }
  654. retVal.scaleX = 1.6;
  655. retVal.scaleY = 1.1;
  656. retVal.rotation = 20;
  657. retVal.x = 285;
  658. retVal.y = 127;
  659. return retVal;
  660. }
  661. private function mBEgg():Sprite
  662. {
  663. var retVal:Sprite = new Sprite();
  664. var pEgg1:Sprite = new Sprite();
  665. var pEgg1C1:Sprite = new Sprite();
  666. var pEgg2:Sprite = new Sprite();
  667. var pEgg2C1:Sprite = new Sprite();
  668. aryGC = [0xffeecc, 0xff9900];
  669. aryGA = [1, 0.6];
  670. aryGR = [0xaa, 0xff];
  671. matG = new Matrix();
  672. matG.createGradientBox(90, 120, Math.PI/2, 0,0);
  673. with(pEgg1.graphics){
  674. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  675. moveTo(60,0);
  676. curveTo(90,20, 90,60);
  677. curveTo(84,120, 30,120);
  678. curveTo(0,120, 0,100);
  679. curveTo(0,60, 10,40);
  680. curveTo(20,0, 60,0);
  681. endFill();
  682. }
  683. matG = new Matrix();
  684. matG.createGradientBox(80, 140, Math.PI/2, 0,0);
  685. with(pEgg2.graphics){
  686. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  687. moveTo(40,0);
  688. curveTo(80,15, 80,70);
  689. curveTo(80,140, 50,140);
  690. curveTo(0,140, 0,80);
  691. curveTo(0,35, 15,15);
  692. curveTo(25,0, 40,0);
  693. endFill();
  694. }
  695. aryGC = [0xffff66, 0xff6600];
  696. aryGA = [1, 1];
  697. aryGR = [0, 0xff];
  698. matG = new Matrix();
  699. matG.createGradientBox(50, 50, 0, 0,0);
  700. with(pEgg1C1.graphics){
  701. beginGradientFill(GradientType.RADIAL, aryGC, aryGA, aryGR, matG, SpreadMethod.REFLECT, "rgb", 0);
  702. moveTo(50, 0);
  703. curveTo(70,0, 70,20);
  704. curveTo(65,80, 35,85);
  705. curveTo(0,85, 0,65);
  706. curveTo(-5,-5, 50,0);
  707. endFill();
  708. }
  709. with(pEgg2C1.graphics){
  710. beginGradientFill(GradientType.RADIAL, aryGC, aryGA, aryGR, matG, SpreadMethod.REFLECT, "rgb", 0);
  711. moveTo(30, 0);
  712. curveTo(60,0, 60,45);
  713. curveTo(60,90, 35,90);
  714. curveTo(0,85, 0,40);
  715. curveTo(0,0, 30,0);
  716. endFill();
  717. }
  718. pEgg1C1.x = 7;
  719. pEgg1C1.y = 20;
  720. pEgg1.addChild(pEgg1C1);
  721. pEgg2C1.x = 10;
  722. pEgg2C1.y = 24;
  723. pEgg2.addChild(pEgg2C1);
  724. pEgg1C1.filters= [bvlTopperInner];
  725. pEgg2C1.filters= [bvlTopperInner];
  726. pEgg2.x = 88;
  727. pEgg2.y = 20;
  728. retVal.addChild(pEgg1);
  729. retVal.addChild(pEgg2);
  730. retVal.scaleY = 0.6;
  731. retVal.x = 50;
  732. retVal.y = 215;
  733. var blurEgg:BlurFilter= new BlurFilter(2,2);
  734. var bvlEgg:BevelFilter= new BevelFilter(4, 45, 0xffffff,0, 0x000000,1 ,4, 4, 0.5 ,1, "outer", false);
  735. retVal.filters= [blurEgg, bvlEgg];
  736. return retVal;
  737. }
  738. private function mBNegi():Sprite
  739. {
  740. var retVal:Sprite = new Sprite();
  741. var ir:uint;
  742. var im:uint= 200;
  743. for(var i:int=0; i
  744. var pDG:Sprite = new pNegi();
  745. ir = Math.round(Math.random()*90);
  746. pDG.x = 120+ Math.round(Math.random()*160);
  747. pDG.y = 160 + (Math.abs(200-pDG.x)/2) + ir;
  748. pDG.x += (pDG.y<205) ? ir/2: -(ir/2);
  749. pDG.alpha-= ir/90;
  750. retVal.addChild(pDG);
  751. }
  752. retVal.alpha=0.8;
  753. retVal.scaleY=0.7;
  754. retVal.filters = [bvlTopper];
  755. return retVal;
  756. }
  757. private function mBSoup1():Sprite
  758. {
  759. var retVal:Sprite= new Sprite();
  760. aryGC = [0xffffff, 0xff9900];
  761. aryGA = [0.1, 0.4];
  762. aryGR = [0x66, 0xff];
  763. matG = new Matrix();
  764. matG.createGradientBox(470, 330, Math.PI/2, 0,0);
  765. with(retVal.graphics){
  766. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  767. drawCircle(230, 430, 205);
  768. endFill();
  769. }
  770. retVal.scaleY = 0.52;
  771. var blurSoup:BlurFilter= new BlurFilter(2,2);
  772. retVal.filters = [blurSoup];
  773. return retVal;
  774. }
  775. private function mBSoup2():Sprite
  776. {
  777. var retVal:Sprite = new Sprite();
  778. var _d2Soup2a:Sprite = new Sprite();
  779. var _d2Soup2b:Sprite = new Sprite();
  780. var _d2Soup2c:Sprite = new Sprite();
  781. with(_d2Soup2a.graphics){
  782. beginFill(0xffffff,0.7);
  783. moveTo(160,125);
  784. curveTo(0,160, 40,260);
  785. curveTo(30,180, 160,125);
  786. }
  787. retVal.addChild(_d2Soup2a);
  788. with(_d2Soup2b.graphics){
  789. beginFill(0xffffff,0.7);
  790. moveTo(380,155);
  791. curveTo(470,210, 400,280);
  792. curveTo(360,300, 250,300);
  793. curveTo(350,290, 400,240);
  794. curveTo(430,180, 380,155);
  795. }
  796. retVal.addChild(_d2Soup2b);
  797. with(_d2Soup2c.graphics){
  798. beginFill(0xffffff, 0.4);
  799. moveTo(100,0);
  800. curveTo(90,5, 110,5);
  801. curveTo(140,-2, 180,0);
  802. curveTo(220,0, 220,40);
  803. curveTo(220,75, 110,75);
  804. curveTo(0,75, 0,48);
  805. curveTo(5,10, 40,0);
  806. curveTo(80,-5, 160,0);
  807. }
  808. _d2Soup2c.x = 150;
  809. _d2Soup2c.y = 200;
  810. retVal.addChild(_d2Soup2c);
  811. var blurSoup:BlurFilter = new BlurFilter(8,8);
  812. var blurSoup2:BlurFilter = new BlurFilter(16,16);
  813. _d2Soup2a.filters= [blurSoup];
  814. _d2Soup2b.filters= [blurSoup];
  815. _d2Soup2c.filters= [blurSoup2];
  816. return retVal;
  817. }
  818. private function mBSoupGlow():Sprite
  819. {
  820. var retVal:Sprite = mASoup();
  821. var bvlSoup:BevelFilter= new BevelFilter(4,135,0xffffff,1,0xcc6600,1,16,16,1,1,"inner",false);
  822. retVal.filters = [bvlSoup];
  823. retVal.blendMode = BlendMode.ADD;
  824. return retVal;
  825. }
  826. private function mBDish1():Sprite
  827. {
  828. var retVal:Sprite = new Sprite();
  829. aryGC = [0x000000, 0xcc6600];
  830. aryGA = [0.3, 0.3];
  831. aryGR = [0x11, 0xff];
  832. matG = new Matrix();
  833. matG.createGradientBox(400, 280, 0, 0, 0);
  834. with(retVal.graphics){
  835. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  836. moveTo(28, 154);
  837. curveTo(88,85, 232.5,85);
  838. curveTo(377,95, 437,154);
  839. curveTo(377,86, 232.5,86);
  840. curveTo(88,95, 28,154);
  841. }
  842. retVal.blendMode= BlendMode.DARKEN;
  843. return retVal;
  844. }
  845. private function mBDish2():Sprite
  846. {
  847. var retVal:Sprite = new Sprite();
  848. aryGC = [0xa05000, 0x000000];
  849. aryGA = [1, 1];
  850. aryGR = [0, 0xff];
  851. matG = new Matrix();
  852. matG.createGradientBox(450, 450, Math.PI/4, 0,0);
  853. with(retVal.graphics){
  854. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  855. moveTo(150, 337);
  856. curveTo(140,350, 135,378);
  857. curveTo(150,410, 232.5,414);
  858. curveTo(315,410, 330,378);
  859. curveTo(325,350, 315,337);
  860. endFill();
  861. }
  862. retVal.filters= [bvlDish];
  863. return retVal;
  864. }
  865. private function mBDish3():Sprite
  866. {
  867. var retVal:Sprite = new Sprite();
  868. aryGC = [0xcc6600, 0x000000];
  869. aryGA = [1, 1];
  870. aryGR = [0, 0xff];
  871. matG = new Matrix();
  872. matG.createGradientBox(450, 450, Math.PI/4, 0,0);
  873. with(retVal.graphics){
  874. beginGradientFill(GradientType.LINEAR, aryGC, aryGA, aryGR, matG, SpreadMethod.PAD, "rgb", 1);
  875. moveTo(17, 170);
  876. curveTo(6,185, 8,207);
  877. curveTo(8,220, 17,240);
  878. curveTo(80,335, 182,377);
  879. curveTo(232.5,390, 283,377);
  880. curveTo(385,335, 448,240);
  881. curveTo(457,220, 457,207);
  882. curveTo(459,185, 448,170);
  883. curveTo(459,185, 454,204);
  884. curveTo(445,270, 320,295);
  885. curveTo(232.5,312, 145,295);
  886. curveTo(20,270, 11,204);
  887. curveTo(10,190, 17,170);
  888. endFill();
  889. }
  890. retVal.filters= [bvlDish];
  891. return retVal;
  892. }
  893. private function mBShade1():Sprite
  894. {
  895. var retVal:Sprite = new Sprite();
  896. var _pW:Sprite = new Sprite();
  897. var _pShade:Sprite = new Sprite();
  898. with(_pW.graphics){
  899. beginFill(0xcc6600,1);
  900. drawCircle(232, 400, 225);
  901. endFill();
  902. }
  903. _pW.scaleY= 0.5;
  904. with(_pShade.graphics){
  905. beginFill(0x000000,0.3);
  906. moveTo(135,378);
  907. curveTo(150,450, 330,420);
  908. curveTo(480,350, 540,310);
  909. curveTo(520,160, 350,120);
  910. endFill();
  911. }
  912. retVal.blendMode = BlendMode.LAYER;
  913. _pW.blendMode = BlendMode.ERASE;
  914. var blurShade:BlurFilter= new BlurFilter(32,32);
  915. _pShade.filters= [blurShade];
  916. retVal.addChild(_pShade);
  917. retVal.addChild(_pW);
  918. return retVal;
  919. }
  920. }
  921. }
  922. import flash.display.Sprite;
  923. import flash.display.LineScaleMode;
  924. import flash.display.CapsStyle
  925. import flash.display.JointStyle;
  926. // Chip
  927. class pChip extends Sprite
  928. {
  929. public function pChip():void
  930. {
  931. var t1:uint = Math.round(Math.random()*3);
  932. var t2:uint = Math.round(Math.random()*3);
  933. var t3:uint = Math.round(Math.random()*3);
  934. with(graphics){
  935. beginFill(0x330000,1);
  936. moveTo(0, 0);
  937. lineTo(t1, 0);
  938. lineTo(t1, t2);
  939. lineTo(t3, t2);
  940. endFill();
  941. }
  942. rotation = Math.round(Math.random()*360);
  943. }
  944. }
  945. // leek
  946. class pNegi extends Sprite
  947. {
  948. public function pNegi():void
  949. {
  950. var aryC:Array = [0x009900, 0x009900, 0x00cc33, 0x00cc33, 0x00ff66];
  951. var t1:uint = Math.round(Math.random()*(aryC.length-1));
  952. var t1b:uint = Math.round(Math.random()*(aryC.length-1));
  953. var r1:uint = 3+Math.round(Math.random()*7);
  954. var t2:uint = Math.round(Math.random()*(aryC.length-1));
  955. var t2b:uint = Math.round(Math.random()*(aryC.length-1));
  956. var r2:uint = 2+Math.round(Math.random()*6);
  957. var p1:Sprite = drawP(aryC[t1], r1);
  958. var p1b:Sprite = drawP(aryC[t1], r1-2);
  959. var p2:Sprite = drawP(aryC[t2], r2);
  960. var p2b:Sprite = drawP(aryC[t2], r2-1);
  961. p1b.x += (p1.width-p1b.width)/2;
  962. p1b.y += (p1.height-p1b.height)/2;
  963. p1.addChild(p1b);
  964. p2b.x += (p2.width-p2b.width)/2;
  965. p2b.y += (p2.height-p2b.height)/2;
  966. p2.addChild(p2b);
  967. p2.x+= Math.round(Math.random()*(p1.width-p2.width));
  968. p2.y+= Math.round(Math.random()*(p1.height-p2.height));
  969. addChild(p1);
  970. addChild(p2);
  971. rotation = Math.round(Math.random()*360);
  972. }
  973. private function drawP(c:Number, r:uint):Sprite
  974. {
  975. var retVal:Sprite = new Sprite();
  976. with(retVal.graphics){
  977. beginFill(c, 1);
  978. drawCircle(0,0, r);
  979. endFill();
  980. }
  981. return retVal;
  982. }
  983. }
  984. // cloud ear
  985. class pKikurage extends Sprite
  986. {
  987. public function pKikurage():void
  988. {
  989. var pS:uint = Math.round(Math.random()*1);
  990. var pT:uint = 3+Math.round(Math.random()*3);
  991. var s1x:uint = 1 +Math.round(Math.random()*5);
  992. var s1y:uint = 1 +Math.round(Math.random()*5);
  993. var p1x:uint = 2 +Math.round(Math.random()*10);
  994. var p1y:uint = 2 +Math.round(Math.random()*10);
  995. var s2x:uint = 1 +Math.round(Math.random()*5);
  996. var s2y:uint = 1 +Math.round(Math.random()*5);
  997. var p2x:uint = 2 +Math.round(Math.random()*10);
  998. var p2y:uint = 2 +Math.round(Math.random()*10);
  999. var aryC:Array = [0x333333, 0x444444, 0x555555, 0x666666];
  1000. var iC:uint = Math.round(Math.random()*(aryC.length-1));
  1001. with(graphics){
  1002. lineStyle(pT, aryC[iC], 1, false, LineScaleMode.NONE, CapsStyle.SQUARE, JointStyle.MITER, 3);
  1003. moveTo(0,0);
  1004. curveTo(s1x,s1y, p1x,p2x);
  1005. curveTo(p1x+s2x,p1y+s2y, p1x+p2x,p1y+p2y);
  1006. endFill();
  1007. }
  1008. rotation = Math.round(Math.random()*360);
  1009. if(pS==0) scaleX = -1;
  1010. }
  1011. }
flash swf thumbnail play
出題者からのコメント
細部への作り込みが素晴らしい!おいしそう!
zahirさんもまた、作り込みが素晴らしかった挑戦者です。
Okasukeさんの、麺がスープに泳ぐエフェクトの描き込みも素晴らしいです。
Comments from King
Such wonderful attention to detail. おいしそう!!!!
Honourable mention to another extreme drawing contestant, zahir.
And also honourable mention to Okasuke for the great animated liquid effect on the noodles!

Knightk3lab

  1. // forked from checkmate's colin challenge for amateurs
  2. /*
  3.  * 
  4.  * Draw a Tasty Ramen !
  5.  * 
  6.  * You can edit and modify every piece of this code.
  7.  * Load more pictures of GU (ingredients of ramen)
  8.  * from flickr or draw one by yourself.
  9.  * Make it look tasty.
  10.  *
  11.  */
  12. package 
  13. {
  14.     import flash.display.Sprite;
  15.     import flash.events.Event;
  16.     import org.papervision3d.materials.BitmapFileMaterial;
  17.     import org.papervision3d.objects.parsers.Collada;
  18.     import org.papervision3d.view.BasicView;
  19.     import org.papervision3d.materials.utils.MaterialsList;
  20.     [SWF(width="465", height="465", frameRate="50", backgroundColor="0x000000")]
  21.     public class Main extends BasicView{
  22.         private var collada:Collada;
  23.         public function Main():void {
  24.             super(00truefalse);
  25.             init();
  26.         }
  27.         private function init():void {
  28.             var ramen:BitmapFileMaterial = new BitmapFileMaterial("http://www.k3lab.com/wonderfl/ramen/test.jpg");
  29.             ramen.doubleSided = false;
  30.             var plane:BitmapFileMaterial = new BitmapFileMaterial("http://www.k3lab.com/wonderfl/ramen/plane01completemap.jpg");
  31.             plane.doubleSided = false;
  32.             camera.y = 30000;
  33.             camera.z = 10000;
  34.             var materialsList:MaterialsList = new MaterialsList();
  35.             materialsList.addMaterial( ramen, "baked_mymaterial" );
  36.             materialsList.addMaterial( plane, "baked_02_-_Default" );
  37.             collada = new Collada("http://www.k3lab.com/wonderfl/ramen/test2.dae", materialsList, .11);
  38.             scene.addChild(collada);
  39.             startRendering();     
  40.         }
  41.         override protected function onRenderTick(event:Event = null):void { 
  42.             collada.yaw(1); 
  43.             camera.y += ((2000 - mouseY*2) - camera.y) / 12
  44.             camera.z+=((1600 - mouseY) - camera.z) / 22
  45.             super.onRenderTick(event); 
  46.         }
  47.     }
  48. }
flash swf thumbnail play
出題者からのコメント
3Dのラーメン!これはかっこいい。次はいっそ、ラーメン屋さんを作ってね!
Comments from King
3D-Ramen?? Awesome! 次はラーメン屋さんを作ってね!

ad

Professional

Queenkeno42

  1. // forked from checkmate's colin challenge for professionals
  2. /**
  3. * Create a Flash app using Union Platform,
  4. * where you can collaborate with more than 4 people online.
  5. *
  6. * UnionRamen is an example app,
  7. * you can write code based on this, or build from scratch.
  8. *
  9. * UnionRamen is a multiuser bowl of ramen built on the Union Platform.
  10. * Press the 'n' key to add naruto to the bowl.
  11. * For Union Platform documentation, see www.unionplatform.com.
  12. *
  13. * @author Colin Moock
  14. * @date July 2009
  15. * @location Toronto, Canada
  16. */
  17. /**
  18. * ■ TypeShoot ver 1.1.0.20090824.1
  19. *
  20. * これはタイピングゲームです。
  21. * ワードを打つとミサイルを発射し、敵陣営に到達すると敵のダメージとなります。
  22. * 一定量のダメージを与えると勝利となります。
  23. *
  24. * 敵が発射したミサイルはワードを打って撃墜できます。
  25. * 自陣を守って敵陣を落としましょう!
  26. *
  27. * 日本語ワードを入力するときは、ローマ字表現を英字で打ち込んでください。
  28. * かな入力は未対応です・・。
  29. *
  30. * 攻撃ワードは、ゲーム中に現れるワードは全て受け付けますが、
  31. * 入力窓のすぐ上にあるワードを打つとダメージが2倍のミサイルになります。
  32. * また、アタックコンボボーナスの対象となります。
  33. *
  34. * 攻撃・防御をミスタイプなしで連続して行うと、コンボ数がカウントされます。
  35. * 一定値に達すると、攻撃・防御の際にボーナス攻撃が発生します。
  36. * 攻撃コンボ→ダブルアタック:一定確率で2発同時に発射します。
  37. * 防御コンボ→オートリフレクション:撃墜したワードを一定確率でそのまま打ち返します。
  38. *
  39. * ■ 戦闘中のショートカットキー
  40. * F1 チャット入力
  41. * TAB 防御対象の切り替え
  42. * ESC 防御入力中のワードの取り消し・防御対象の取り消し
  43. * ←→ 防御中の自機を左右に移動
  44. * ↑ 攻撃モードに切り替え
  45. * ↓ 防御モードに切り替え
  46. *
  47. * ■ SETTINGS画面の説明
  48. * YOUR NAMEの入力欄で名前を変更できます。空欄は受け付けません。
  49. *
  50. * ATTACK LANGUAGEで攻撃ワード候補がどの言語で現れるかを選択できます。
  51. * 防御ワードは敵が打ったものがそのまま出てくるので、ここでは制御できません。
  52. *
  53. * COLOR SETTINGで自機の色を変えられます。
  54. * ゲーム回数を重ねると選択できる色が増えます。最大20色です。
  55. *
  56. * チャット画面でユーザー名の横に表示されるかっこ内の数字は、
  57. * それぞれ攻撃時/防御時のそのプレイヤーの最大毎秒タイプ数です。
  58. * チームを選択する際におおまかな目安として利用してください。
  59. *
  60. * VS COMを押すとコンピュータと対戦できます。
  61. * 勝敗に応じてコンピュータのレベルが変わります。
  62. *
  63. * ■ ■ ■ あなたがこのゲームを楽しめますように!
  64. *
  65. * 制作 Kenichi UENO (Keno)
  66. * 音素材 Yoichi KANEKO / ザ・マッチメイカァズ2nd 【フリー効果音素材】
  67. * テストプレイやアドバイスなど LOGOSWARE PDGの皆さん / 某黒猫の皆さん / Nyafu
  68. *
  69. * 遊んでくれた人 YOU!
  70. */
  71. package
  72. {
  73. import flash.display.Sprite;
  74. import flash.display.StageAlign;
  75. import flash.display.StageScaleMode;
  76. import flash.events.Event;
  77. import flash.events.IOErrorEvent;
  78. import flash.events.ProgressEvent;
  79. import net.user1.logger.Logger;
  80. import net.user1.reactor.Reactor;
  81. import net.user1.reactor.ReactorEvent;
  82. import net.user1.reactor.Room;
  83. import net.user1.reactor.XMLSocketConnection;
  84. import net.user1.utils.LocalData;
  85. [SWF(width = "465", height = "465", backgroundColor = "0", fps = "30")]
  86. public class Missiles extends Sprite
  87. {
  88. protected var reactor:Reactor = new Reactor();
  89. protected var gameController:GameController;
  90. protected var enterUI:EnterUI = new EnterUI();
  91. protected var infoUI:InfoUI = new InfoUI();
  92. protected var gameStage:GameStage = new GameStage();
  93. protected var nowProgress:Number = 0;
  94. public function Missiles()
  95. {
  96. SoundManager.initChecker.addEventListener(ProgressEvent.PROGRESS, onProgress);
  97. SoundManager.init();
  98. Score.initScore();
  99. Score.lastLevel = Score.getLevel();
  100. Roma.init();
  101. this.graphics.lineStyle(2, 0x00FF00);
  102. this.graphics.moveTo(0, 230);
  103. this.addEventListener(Event.ENTER_FRAME, onProgress);
  104. connect();
  105. }
  106. // サウンドのロードエフェクト + ついでにunion接続
  107. private function onProgress(e:Event):void {
  108. nowProgress = nowProgress + 0.25 * (((SoundManager.count + (reactor.isConnected()?1:0)) / (SoundManager.countMax+1)) - nowProgress);
  109. this.graphics.lineTo(Constants.STAGE_WIDTH * nowProgress, 230);
  110. if ( nowProgress >= 0.99 ) {
  111. this.alpha *= 0.75;
  112. if ( this.alpha < 0.05 ) {
  113. this.removeEventListener(Event.ENTER_FRAME, onProgress);
  114. this.graphics.clear();
  115. this.alpha = 1.0;
  116. // start();
  117. gameStart();
  118. }
  119. }
  120. }
  121. // 入室画面表示
  122. private function start():void{
  123. this.addChild( enterUI ); // 名前いれないほうが入りやすいかなあ
  124. enterUI.x = 0.5 * (Constants.STAGE_WIDTH - enterUI.width);
  125. enterUI.y = 0.5 * (Constants.STAGE_HEIGHT - enterUI.height);
  126. enterUI.addEventListener("enter", onEnter);
  127. }
  128. protected function onEnter(e:Event):void {
  129. enterUI.removeEventListener("enter", onEnter);
  130. gameStart();
  131. }
  132. protected function connect():void{
  133. reactor.connect("tryunion.com", 9100);
  134. }
  135. protected function gameStart():void {
  136. trace( reactor.getServer().getVersion(), reactor.getServer().getUPCVersion() );
  137. reactor.getLog().setLevel(Logger.FATAL);
  138. ServerClockUtil.init( reactor.getServer() );
  139. // this.removeChild( enterUI );
  140. this.addChild( gameStage );
  141. this.addChild( infoUI );
  142. infoUI.x = infoUI.y = 30;
  143. infoUI.visible = false;
  144. gameController = new GameController(reactor, infoUI, gameStage); // 選択画面とゲーム画面をコントロール
  145. gameController.startInfo();
  146. }
  147. }
  148. }
  149. import flash.display.Bitmap;
  150. import flash.display.BitmapData;
  151. import flash.filters.BitmapFilter;
  152. import flash.filters.BlurFilter;
  153. import flash.filters.GlowFilter;
  154. import flash.geom.Rectangle;
  155. import flash.net.navigateToURL;
  156. import flash.system.IME;
  157. import flash.system.IMEConversionMode;
  158. import flash.system.Capabilities;
  159. import flash.display.DisplayObject;
  160. import flash.display.DisplayObjectContainer;
  161. import flash.display.SpreadMethod;
  162. import flash.display.Sprite;
  163. import flash.display.Stage;
  164. import flash.events.Event;
  165. import flash.events.EventDispatcher;
  166. import flash.events.KeyboardEvent;
  167. import flash.events.MouseEvent;
  168. import flash.events.ProgressEvent;
  169. import flash.events.TextEvent;
  170. import flash.events.TimerEvent;
  171. import flash.filters.ColorMatrixFilter;
  172. import flash.geom.ColorTransform;
  173. import flash.geom.Matrix;
  174. import flash.geom.Point;
  175. import flash.media.Sound;
  176. import flash.media.SoundChannel;
  177. import flash.media.SoundTransform;
  178. import flash.net.URLRequest;
  179. import flash.system.System;
  180. import flash.text.engine.FontDescription;
  181. import flash.text.Font;
  182. import flash.text.TextField;
  183. import flash.text.TextFormat;
  184. import flash.ui.Keyboard;
  185. import flash.ui.Mouse;
  186. import flash.utils.ByteArray;
  187. import flash.utils.Dictionary;
  188. import flash.utils.escapeMultiByte;
  189. import flash.utils.getTimer;
  190. import flash.utils.Timer;
  191. import net.user1.reactor.Client;
  192. import net.user1.reactor.CustomClient;
  193. import net.user1.reactor.filters.AttributeComparison;
  194. import net.user1.reactor.filters.AttributeFilter;
  195. import net.user1.reactor.filters.CompareType;
  196. import net.user1.reactor.filters.Filter;
  197. import net.user1.reactor.filters.IFilter;
  198. import net.user1.reactor.IClient;
  199. import net.user1.reactor.MessageListener;
  200. import net.user1.reactor.RoomEvent;
  201. import net.user1.reactor.Server;
  202. import net.user1.reactor.ServerEvent;
  203. import net.user1.utils.LocalData;
  204. import net.user1.reactor.Room;
  205. import net.user1.reactor.Reactor;
  206. import net.user1.utils.UDictionary;
  207. // 背景エフェクト
  208. class BackGround extends Bitmap {
  209. protected var bd:BitmapData = new BitmapData(465, 300, true, 0x0);
  210. protected var p:Point = new Point();
  211. protected var filter:BitmapFilter = new BlurFilter();
  212. public var sprite:Sprite;
  213. public function BackGround(sprite:Sprite) {
  214. this.sprite = sprite;
  215. this.bitmapData = bd;
  216. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  217. }
  218. protected function onEnterFrame(e:Event):void {
  219. bd.draw(sprite);
  220. bd.applyFilter(bd, bd.rect, p, filter);
  221. }
  222. public function setFilter(type:int):void {
  223. switch(type) {
  224. case 0:
  225. filter = new ColorMatrixFilter([0.98, 0, 0, 0, 0, 0, 0.98, 0, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 0, 0.98, 0]);
  226. break;
  227. case 1:
  228. filter = new BlurFilter(10, 2, 2);
  229. break;
  230. }
  231. }
  232. }
  233. class EffectSprite extends Sprite {
  234. public function EffectSprite() {
  235. this.mouseEnabled = this.mouseChildren = false;
  236. }
  237. public function missileDestroy(p:Point):void {
  238. var am:AttackMotion = new AttackMotion();
  239. this.addChild( am );
  240. am.x = p.x;
  241. am.y = p.y;
  242. for ( var i:int = 0; i < 5; i++ ){
  243. var yakochu:Yakochu = new Yakochu();
  244. this.addChild( yakochu );
  245. yakochu.x = p.x;
  246. yakochu.y = p.y;
  247. }
  248. }
  249. }
  250. class Yakochu extends Sprite {
  251. private var vx:Number = Math.random() * 2.0 - 1;
  252. private var vy:Number = Math.random() * 2.0 - 1;
  253. private var ax:Number = Math.random() * 0.5 - 0.25;
  254. private var ay:Number = Math.random() * 0.5 - 0.25;
  255. public function Yakochu():void {
  256. graphics.beginFill(Math.random() * 0xFFFFFF | 0xAAAAAA, 0.5);
  257. graphics.drawCircle(0, 0, Math.random() * 2);
  258. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  259. this.alpha = 6;
  260. }
  261. protected function onEnterFrame(e:Event):void {
  262. vx += ax; vy += ay;
  263. this.x += vx;
  264. this.y += vy;
  265. this.alpha *= 0.94;
  266. if ( this.alpha < 0.1 ) {
  267. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  268. if ( this.parent != null ) this.parent.removeChild( this );
  269. }
  270. }
  271. }
  272. // 攻撃用ワード表示
  273. class AttackQuestion extends Sprite {
  274. protected var tf:TextField = new TextField();
  275. protected var word:String = "";
  276. protected var jWord:Array;
  277. public var isJapanese:Boolean;
  278. protected var missile:Sprite = new Sprite();
  279. protected var angle:Number = 0;
  280. public function AttackQuestion() {
  281. missile.graphics.lineStyle(0, 0x00FF00);
  282. missile.graphics.moveTo(15, 0);
  283. missile.graphics.lineTo(0, 5);
  284. missile.graphics.lineTo(0, -5);
  285. missile.graphics.lineTo(15, 0);
  286. tf.defaultTextFormat = new TextFormat(TextFieldUtil.getFont(), 14, 0xFFFFFF);
  287. tf.autoSize = "left";
  288. this.addChild( missile );
  289. this.addChild( tf );
  290. tf.x = 17;
  291. tf.y = -11;
  292. do {
  293. isJapanese = Score.isJapanese();
  294. if ( isJapanese ) {
  295. jWord = Words.getJRandom();
  296. //word = jWord[0]; // 漢字
  297. word = jWord[1]; // ひらがな
  298. //word = Roma.getRomaToType(jWord[1]).toLowerCase(); // ローマ字
  299. } else {
  300. word = Words.getRandom();
  301. }
  302. tf.text = HandicapUtil.getHandicapWord(word);
  303. } while( tf.text.length > 26 ) // 最大26文字
  304. this.mouseChildren = false;
  305. }
  306. // 現在有効なワードを明るくする
  307. public function setBright():void {
  308. missile.graphics.beginFill(0x88FF88);
  309. missile.graphics.moveTo(15, 0);
  310. missile.graphics.lineTo(0, 5);
  311. missile.graphics.lineTo(0, -5);
  312. missile.graphics.lineTo(15, 0);
  313. this.addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
  314. }
  315. protected function onEnterFrame(e:Event):void {
  316. angle+=8.5;
  317. missile.rotationX = angle;
  318. }
  319. // このワードのストリング値を返す
  320. public function getText():String {
  321. return word;
  322. }
  323. }
  324. // 攻撃用ユーザーインターフェース
  325. class AttackUI extends Sprite {
  326. protected var input:TextField = new TextField();
  327. protected var questionNum:int = 3;
  328. protected var questionList:Array = [];
  329. public function AttackUI() {
  330. TextFieldUtil.setupBorder(input);
  331. input.width = 210;
  332. input.height = 20;
  333. input.type = "input";
  334. input.y = 42;
  335. this.addChild( input );
  336. input.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  337. input.addEventListener( KeyboardEvent.KEY_UP, onKeyUp );
  338. }
  339. protected var addToType:int = 0;
  340. public function setup():void {
  341. for ( var i:int = 0; i < questionNum; i++ ) {
  342. questionList.push(new AttackQuestion());
  343. }
  344. for ( i = 0; i < questionNum; i++ ) {
  345. addChild( questionList[i] );
  346. }
  347. for ( i = 1; i < questionNum; i++ ) {
  348. questionList[i].y = questionList[i-1].y -13;
  349. }
  350. questionList[0].setBright();
  351. setFocus();
  352. this.addEventListener( Event.ENTER_FRAME, onEnterFrame);
  353. }
  354. public function reset():void {
  355. this.removeEventListener( Event.ENTER_FRAME, onEnterFrame);
  356. while ( questionList.length ) {
  357. removeChild(questionList[questionList.length-1]);
  358. questionList.pop();
  359. }
  360. input.text = "";
  361. addToType = 0;
  362. }
  363. // 入力部分にフォーカスをあてる
  364. public function setFocus():void {
  365. if ( this.stage != null ) {
  366. stage.focus = input;
  367. if ( Capabilities.hasIME ) {
  368. try {
  369. IME.enabled = false;
  370. } catch(e:*){}
  371. }
  372. }
  373. }
  374. //
  375. protected function onEnterFrame(e: Event):void {
  376. if ( questionList[0].y < 28 ) {
  377. for ( var i:int = 0; i < questionNum; i++ )
  378. questionList[i].y ++;
  379. }
  380. }
  381. protected var beforeIMEText:String = "";
  382. protected function onKeyUp(e:KeyboardEvent):void {
  383. if ( beforeIMEText != "" ) input.text = beforeIMEText;
  384. if ( textClear ) {
  385. input.text = "";
  386. textClear = false;
  387. }
  388. }
  389. protected var textClear:Boolean = false;
  390. protected function onKeyDown(e:KeyboardEvent):void {
  391. if ( e.keyCode == 229 ) {
  392. if ( Capabilities.hasIME ) {
  393. try {
  394. IME.enabled = false;
  395. } catch(e:*){}
  396. }
  397. beforeIMEText = input.text;
  398. return;
  399. } else {
  400. beforeIMEText = "";
  401. }
  402. if ( e.keyCode == Constants.CHAT_KEY ) return;
  403. if ( e.keyCode == Keyboard.DOWN || e.keyCode == Keyboard.UP ) return;
  404. if ( e.keyCode == Keyboard.ENTER || e.keyCode == Keyboard.SPACE ) {
  405. var word:String = HandicapUtil.getUnHandicapWord(input.text);
  406. var power:Number = 0;
  407. if ( input.text.length <= addToType ) {
  408. // 選択状態のお方でいらっしゃいますか
  409. if ( questionList[0].isJapanese ) {
  410. var jword:String = Roma.getHiragana(word); // ひらがなモード用
  411. if ( questionList[0].getText() == jword ) word = jword;
  412. }
  413. if ( questionList[0].getText() == word ) { // 選択ワードと一致しました
  414. power = 1;
  415. removeChild( questionList[0] );
  416. questionList.shift();
  417. questionList[0].setBright();
  418. var aq:AttackQuestion = new AttackQuestion();
  419. aq.y = questionList[questionNum-2].y - 13;
  420. questionList.push( aq );
  421. addChild(aq);
  422. if ( input.text.length == addToType ) {
  423. Score.attackCombo++;
  424. if ( Score.attackCombo == Constants.ATTACK_COMBO_START ) {
  425. dispatchEvent(new GameEvent(GameEvent.ATTACK_COMBO_START, true));
  426. SoundManager.ComboSound.play();
  427. }
  428. }
  429. } else {
  430. if ( Words.isExist( word ) ) {
  431. power = 0.5;
  432. } else if ( Words.isJExist( word ) ) {
  433. word = Roma.getHiragana( word );
  434. power = 0.5;
  435. }
  436. }
  437. if ( (power == 0) || (input.text.length != addToType) ) {
  438. if ( Score.attackCombo >= Constants.ATTACK_COMBO_START ) {
  439. dispatchEvent(new GameEvent(GameEvent.ATTACK_COMBO_END, true));
  440. }
  441. Score.attackCombo = 0;
  442. }
  443. if ( power > 0 ) {
  444. Score.correct += input.text.length;
  445. Score.type += addToType;
  446. addToType = 0;
  447. dispatchEvent(new GameEvent(GameEvent.ATTACK, true, false, word + "-" + power));
  448. if ( Score.getAttackBonusRate() > (Math.random() * 100) )
  449. dispatchEvent(new GameEvent(GameEvent.ATTACK_DOUBLE, true, false, word + "-" + power));
  450. }
  451. }
  452. // input.text = "";
  453. textClear = true;
  454. } else {
  455. if ( e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT ) {
  456. e.stopPropagation();
  457. }
  458. addToType++;
  459. }
  460. }
  461. }
  462. class HandicapUtil {
  463. public static function getUnHandicapWord(text:String):String {
  464. return text;
  465. /* var temp:Array = text.split(" ");
  466. var flg:Boolean = true;
  467. for ( var i:int = 1; i < temp.length; i++ ) {
  468. flg = flg && (temp[0] == temp[i]);
  469. }
  470. if ( flg && (Score.handicap == temp.length) ) {
  471. return temp[0];
  472. } else {
  473. return "";
  474. }
  475. */
  476. }
  477. public static function getHandicapWord(text:String):String {
  478. return text;
  479. /*
  480. var ret:String = text;
  481. for ( var i:int = 1; i < Score.handicap; i++ ) {
  482. ret += " " + text;
  483. }
  484. return ret;
  485. */
  486. }
  487. }
  488. class DefenceUI extends Sprite {
  489. protected var words1:TextField = new TextField();
  490. public function DefenceUI() {
  491. this.addChild( words1 );
  492. }
  493. public function reset():void {
  494. //
  495. }
  496. public function set1stText(str:String):void {
  497. // words1.text = str;
  498. }
  499. public function set enable(value:Boolean):void {
  500. if( value ){
  501. this.stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  502. }else {
  503. if( this.stage != null )
  504. this.stage.removeEventListener( KeyboardEvent.KEY_DOWN, onKeyDown );
  505. }
  506. }
  507. protected function onKeyDown(e:KeyboardEvent):void {
  508. dispatchEvent(new GameEvent(GameEvent.DEFENCE_TYPE, true, false, String(e.charCode)));
  509. }
  510. }
  511. class ScoreUI extends Sprite {
  512. protected var baseTF:TextField = new TextField();
  513. protected var scoreTF:TextField = new TextField();
  514. public function ScoreUI() {
  515. baseTF.defaultTextFormat = new TextFormat(TextFieldUtil.getFont(), null, 0xFFFFFF, false, null, null, null, null, null, null, null, null, 2);
  516. scoreTF.autoSize = "right";
  517. scoreTF.defaultTextFormat = new TextFormat(TextFieldUtil.getFont(), null, 0xFFFFFF, false, null, null, null, null, "right", null, null, null, 2);
  518. baseTF.autoSize = "left";
  519. var timer:Timer = new Timer( 1000 );
  520. timer.start();
  521. timer.addEventListener(TimerEvent.TIMER, onTimer);
  522. updateScore();
  523. baseTF.text = "タイプ数:\n攻撃コンボ:\n防御コンボ:\nスコア:\nボーナス:";
  524. this.addChild( baseTF );
  525. this.addChild( scoreTF );
  526. }
  527. protected function onTimer(e:TimerEvent):void {
  528. updateScore();
  529. }
  530. protected function updateScore():void{
  531. var typeStr:String = String(Score.type);
  532. if ( Score.type > 0 ) typeStr += ( "(" + int(100*Score.correct / Score.type) + "%)");
  533. scoreTF.text = typeStr + "\n" + int(Score.attackCombo) + "\n" + int(Score.defenceCombo) + "\n" + int(Score.score) + "\n";
  534. if ( Score.attackCombo < Constants.ATTACK_COMBO_START && Score.defenceCombo < Constants.DEFENCE_COMBO_START ) {
  535. scoreTF.appendText( "なし" );
  536. } else {
  537. if ( Score.attackCombo >= Constants.ATTACK_COMBO_START ) {
  538. scoreTF.appendText( "[DA "+ Score.getAttackBonusRate() +"%]" );
  539. }
  540. if ( Score.defenceCombo >= Constants.DEFENCE_COMBO_START ) {
  541. scoreTF.appendText( "[AR "+ Score.getDefenceBonusRate() +"%]" );
  542. }
  543. }
  544. scoreTF.x = 130 - scoreTF.width;
  545. }
  546. }
  547. class OperationUI extends Sprite {
  548. protected var attackerBtn:Button = new Button(90, 25, "攻撃モード");
  549. protected var defenderBtn:Button = new Button(90, 25, "防御モード");
  550. protected var attackUI:AttackUI = new AttackUI();
  551. protected var defenceUI:DefenceUI = new DefenceUI();
  552. protected var scoreUI:ScoreUI = new ScoreUI();
  553. protected var playMode:String;
  554. public function OperationUI() {
  555. this.addChild( attackerBtn );
  556. this.addChild( defenderBtn );
  557. this.addChild( attackUI );
  558. this.addChild( defenceUI );
  559. this.addChild( scoreUI );
  560. attackUI.visible = defenceUI.visible = defenceUI.enable = false;
  561. attackerBtn.x = 10;
  562. attackerBtn.y = 15;
  563. defenderBtn.x = 10;
  564. defenderBtn.y = 50;
  565. attackUI.x = 110;
  566. attackUI.y = 15;
  567. defenceUI.x = 110;
  568. defenceUI.y = 15;
  569. scoreUI.x = 330;
  570. scoreUI.y = 10;
  571. attackerBtn.addEventListener(MouseEvent.CLICK, onAttackerClick);
  572. defenderBtn.addEventListener(MouseEvent.CLICK, onDefenderClick);
  573. }
  574. public function setDefenceText(texts:Array):void {
  575. defenceUI.set1stText(texts[0]);
  576. }
  577. public function getPlayMode():String {
  578. return playMode;
  579. }
  580. public function setup():void {
  581. attackUI.setup();
  582. }
  583. public function reset():void {
  584. attackUI.reset();
  585. defenceUI.reset();
  586. }
  587. protected function tempDisabled():void {
  588. this.mouseChildren = false;
  589. }
  590. public function switchMode():void {
  591. if ( playMode == Constants.PLAY_MODE_ATTACKER ) {
  592. SoundManager.ClickSound.play();
  593. dispatchEvent( new GameEvent(GameEvent.MODE_DEFENCE, true) );
  594. } else if ( playMode == Constants.PLAY_MODE_DEFENDER ) {
  595. SoundManager.ClickSound.play();
  596. dispatchEvent( new GameEvent(GameEvent.MODE_ATTACK, true) );
  597. }
  598. }
  599. // 基本的にmessage経由で呼び出す
  600. public function setMode(playMode:String):void {
  601. this.playMode = playMode;
  602. if ( playMode == Constants.PLAY_MODE_ATTACKER ) {
  603. attackerBtn.selected = true;
  604. defenderBtn.selected = false;
  605. attackUI.visible = true;
  606. defenceUI.visible = false;
  607. defenceUI.enable = false;
  608. setFocus();
  609. } else if ( playMode == Constants.PLAY_MODE_DEFENDER ) {
  610. attackerBtn.selected = false;
  611. defenderBtn.selected = true;
  612. attackUI.visible = false;
  613. defenceUI.visible = true;
  614. defenceUI.enable = true;
  615. } else if ( playMode == "" ) {
  616. attackerBtn.selected = false;
  617. defenderBtn.selected = false;
  618. attackUI.visible = false;
  619. defenceUI.visible = false;
  620. defenceUI.enable = false;
  621. }
  622. }
  623. public function setFocus():void {
  624. attackUI.setFocus();
  625. }
  626. protected function onAttackerClick(e:MouseEvent):void {
  627. if( !attackerBtn.selected ){
  628. attackerBtn.selected = defenderBtn.selected = false;
  629. dispatchEvent( new GameEvent(GameEvent.MODE_ATTACK, true) );
  630. }
  631. }
  632. protected function onDefenderClick(e:MouseEvent):void {
  633. if( !defenderBtn.selected ){
  634. attackerBtn.selected = defenderBtn.selected = false;
  635. dispatchEvent( new GameEvent(GameEvent.MODE_DEFENCE, true) );
  636. }
  637. }
  638. }
  639. class Battery extends Sprite {
  640. protected var base:Sprite = new Sprite();
  641. protected var cannonBarrel:Sprite = new Sprite();
  642. protected var attackBase:Sprite = new Sprite();
  643. protected var tf:TextField = new TextField();
  644. protected var color:int;
  645. protected var baseColor:int;
  646. protected var attackComboEffect:Sprite = new Sprite();
  647. protected var defenceComboEffect:Sprite = new Sprite();
  648. public function Battery(isMySide:Boolean, baseLevel:int, color:int, baseColor:int) {
  649. draw(baseLevel, color, baseColor);
  650. this.addChild( attackBase );
  651. this.addChild( base );
  652. base.addChild( cannonBarrel );
  653. this.addChild( tf );
  654. tf.autoSize = "left";
  655. tf.defaultTextFormat = new TextFormat(TextFieldUtil.getFont(), null, 0xFFFFFF);
  656. setSide(isMySide);
  657. attackComboEffect.graphics.lineStyle(0, 0xFF0000);
  658. attackComboEffect.graphics.beginFill(0xFF8888, 0.5);
  659. attackComboEffect.graphics.drawCircle(0, 0, 50);
  660. attackComboEffect.alpha = 1.0; attackComboEffect.scaleX = attackComboEffect.scaleY = 0;
  661. defenceComboEffect.graphics.lineStyle(0, 0x0000FF);
  662. defenceComboEffect.graphics.beginFill(0x8888FF, 0.5);
  663. defenceComboEffect.graphics.drawEllipse(-70, -10, 140, 20);
  664. defenceComboEffect.alpha = 1.0; defenceComboEffect.scaleX = defenceComboEffect.scaleY = 0;
  665. defenceComboEffect.y = -20;
  666. base.addChild( defenceComboEffect );
  667. attackBase.addChild( attackComboEffect );
  668. attackComboEffect.visible = defenceComboEffect.visible = false;
  669. this.mouseEnabled = this.mouseChildren = false;
  670. }
  671. public function setSide(isMySide:Boolean):void {
  672. if( isMySide ){
  673. tf.y = 13;
  674. base.rotation = attackBase.rotation = 0;
  675. defenceComboEffect.rotation = 0;
  676. base.y = 0;
  677. attackBase.y = 0;
  678. } else {
  679. tf.y = -Constants.BATTERY_DEFAULT_Y;
  680. base.rotation = attackBase.rotation = 180;
  681. defenceComboEffect.rotation = 180;
  682. base.y = tf.y + 16 + Constants.BATTERY_DEFAULT_Y;
  683. attackBase.y = tf.y + 16 + Constants.BATTERY_DEFAULT_Y;
  684. }
  685. }
  686. protected function onEnterFrame(e:Event):void {
  687. if ( attackComboEffect.visible ) {
  688. attackComboEffect.alpha *= 0.88;
  689. attackComboEffect.scaleX += (1 - attackComboEffect.scaleX) * 0.05;
  690. attackComboEffect.scaleY += (1 - attackComboEffect.scaleY) * 0.05;
  691. if ( attackComboEffect.alpha <= 0.1 ) {
  692. attackComboEffect.alpha = 2.0; attackComboEffect.scaleX = attackComboEffect.scaleY = 0;
  693. }
  694. }
  695. if ( defenceComboEffect.visible ) {
  696. defenceComboEffect.alpha *= 0.88;
  697. defenceComboEffect.scaleX += (1 - defenceComboEffect.scaleX) * 0.05;
  698. defenceComboEffect.scaleY += (1 - defenceComboEffect.scaleY) * 0.05;
  699. if ( defenceComboEffect.alpha <= 0.1 ) {
  700. defenceComboEffect.alpha = 2.0; defenceComboEffect.scaleX = defenceComboEffect.scaleY = 0;
  701. }
  702. }
  703. }
  704. public function updateCombo(name:String, isStart:Boolean):void {
  705. switch ( name ) {
  706. case "attackCombo":
  707. attackComboEffect.visible = isStart;
  708. break;
  709. case "defenceCombo":
  710. defenceComboEffect.visible = isStart;
  711. break;
  712. }
  713. if ( isStart ) {
  714. this.addEventListener( Event.ENTER_FRAME, onEnterFrame, false, 0, true );
  715. }
  716. }
  717. public function setAngle(angle:Number):void {
  718. cannonBarrel.rotation = angle;
  719. }
  720. public function setMode(playMode:String):void {
  721. if ( playMode == Constants.PLAY_MODE_ATTACKER ) {
  722. base.visible = false;
  723. attackBase.visible = true;
  724. } else {
  725. attackBase.visible = false;
  726. base.visible = true;
  727. }
  728. }
  729. public function setName(name:String):void {
  730. tf.text = name;
  731. tf.x = -0.5 * tf.width;
  732. }
  733. public function draw(baseLevel:int = 0, color:int = 0x999999, baseColor:int = 0x999999):void {
  734. attackBase.graphics.clear();
  735. base.graphics.clear();
  736. cannonBarrel.graphics.clear();
  737. // switch( baseLevel ) {
  738. // case Constants.BASE_LEVEL_0:
  739. // default:
  740. attackBase.graphics.lineStyle(0, 0xFFFFFF, 0.5);
  741. attackBase.graphics.beginFill(color);
  742. attackBase.graphics.moveTo(0, -8);
  743. attackBase.graphics.lineTo(10, 10);
  744. attackBase.graphics.lineTo( -10, 10);
  745. attackBase.graphics.endFill();
  746. attackBase.graphics.beginFill(baseColor);
  747. attackBase.graphics.moveTo(0, -4);
  748. attackBase.graphics.lineTo(7, 8);
  749. attackBase.graphics.lineTo( -7, 8);
  750. attackBase.graphics.endFill();
  751. base.graphics.lineStyle(1, 0xFFFFFF, 0.5);
  752. base.graphics.beginFill(color);
  753. base.graphics.drawCircle(0, 0, 10);
  754. base.graphics.beginFill(baseColor);
  755. base.graphics.drawCircle(0, 0, 7);
  756. cannonBarrel.graphics.lineStyle(1, 0xFFFFFF, 0.5);
  757. cannonBarrel.graphics.beginFill(baseColor);
  758. cannonBarrel.graphics.drawRect( -2, -15, 4, 16 );
  759. cannonBarrel.graphics.beginFill(color);
  760. cannonBarrel.graphics.drawRect( -3, 0, 6, 3);
  761. // break;
  762. // }
  763. }
  764. public function attackMotion():void {
  765. attackBase.addChild( new AttackMotion() );
  766. }
  767. public function reflectMotion():void {
  768. base.addChild( new ReflectMotion() );
  769. }
  770. }
  771. class AttackMotion extends Sprite {
  772. public function AttackMotion() {
  773. this.mouseChildren = this.mouseEnabled = false;
  774. this.graphics.lineStyle(0, 0xFFFF00);
  775. this.graphics.drawCircle(0, 0, 10);
  776. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  777. }
  778. protected function onEnterFrame(e:Event):void {
  779. this.scaleX *= 1.1;
  780. this.scaleY *= 1.1;
  781. this.alpha *= 0.9;
  782. if ( this.alpha < 0.1 ) {
  783. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  784. if ( this.parent != null ) this.parent.removeChild( this );
  785. }
  786. }
  787. }
  788. class ReflectMotion extends Sprite {
  789. public function ReflectMotion() {
  790. this.mouseChildren = this.mouseEnabled = false;
  791. this.graphics.lineStyle(0, 0x00FF00);
  792. this.graphics.beginFill(0, 0x88FF88);
  793. this.graphics.drawEllipse(-8, 0, 16, 3);
  794. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  795. this.y = -20;
  796. }
  797. protected function onEnterFrame(e:Event):void {
  798. this.scaleX *= 1.1;
  799. this.alpha *= 0.92;
  800. if ( this.alpha < 0.1 ) {
  801. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  802. if ( this.parent != null ) this.parent.removeChild( this );
  803. }
  804. }
  805. }
  806. class DamageMotion extends Sprite {
  807. public function DamageMotion(vx:Number, vy:Number) {
  808. this.mouseChildren = this.mouseEnabled = false;
  809. this.graphics.beginFill(0x00FF00 | (int(Math.random()*80)<<24) | (int(Math.random()*80)));
  810. this.graphics.drawCircle( -60*vx + -3 + Math.random() * 6, -60*vy + -3 + Math.random() * 6, 0.8);
  811. this.graphics.drawCircle( -60*vx + -3 + Math.random() * 6, -60*vy + -3 + Math.random() * 6, 0.8);
  812. this.graphics.drawCircle( -60*vx + -3 + Math.random() * 6, -60*vy + -3 + Math.random() * 6, 0.8);
  813. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  814. }
  815. protected function onEnterFrame(e:Event):void {
  816. this.scaleX *= 1.1;
  817. this.scaleY *= 1.1;
  818. this.alpha *= 0.9;
  819. if ( this.alpha < 0.1 ) {
  820. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  821. if ( this.parent != null ) this.parent.removeChild( this );
  822. }
  823. }
  824. }
  825. // 本拠地のダメージモーション
  826. class HitMotion extends Sprite {
  827. public function HitMotion() {
  828. this.mouseChildren = this.mouseEnabled = false;
  829. this.graphics.beginFill(0xFF0000);
  830. this.graphics.drawRect(0, -1, Constants.STAGE_WIDTH, 2);
  831. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  832. }
  833. protected function onEnterFrame(e:Event):void {
  834. this.scaleY = this.scaleY + 0.3;
  835. this.alpha *= 0.9;
  836. if ( this.alpha < 0.1 ) {
  837. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  838. if ( this.parent != null ) this.parent.removeChild( this );
  839. }
  840. }
  841. }
  842. // CPUクライアント
  843. class CPUClient extends Sprite implements IClient {
  844. public var self:IClient;
  845. private var attr:Object = { };
  846. public var missiles:Array = [];
  847. private var _word:String;
  848. public var attackid:int;
  849. public var focus:Missile;
  850. public function CPUClient() {
  851. }
  852. public function start():void {
  853. enable();
  854. }
  855. protected var timer:Timer;
  856. public function enable():void {
  857. attackid = 0;
  858. typedLength = 0;
  859. defenceLength = 0;
  860. _word = Words.getJRandom()[1];
  861. timer = new Timer(1000 / Math.max(0.5, Score.cpuLV));
  862. missiles = [];
  863. timer.start();
  864. timer.addEventListener(TimerEvent.TIMER, onTimer);
  865. }
  866. public function disable():void {
  867. timer.stop();
  868. }
  869. protected var typedLength:int = 0;
  870. protected var defenceLength:int = 0;
  871. protected function onTimer(e:TimerEvent):void {
  872. for ( var i:int = 0; i < missiles.length; i++ ) {
  873. if ( missiles[i].y > (0.5*Constants.DISTANCE) && missiles[i].isMySide && (missiles[i].wordLength > 0)) {
  874. if ( focus == null ) focus = missiles[i];
  875. else if ( focus.y < missiles[i].y ) focus = missiles[i];
  876. }
  877. }
  878. if ( focus != null ) {
  879. focus.wordLength--;
  880. if ( focus.wordLength > 0 ) {
  881. dispatchEvent(new GameEvent(GameEvent.SHOOT, false, false, "0"));
  882. } else {
  883. dispatchEvent(new GameEvent(GameEvent.SHOOT, false, false, "1"));
  884. focus = null;
  885. }
  886. } else {
  887. typedLength++;
  888. if ( Roma.getRomaToType(_word).length == typedLength ) {
  889. dispatchEvent(new GameEvent(GameEvent.ATTACK, false, false, _word));
  890. _word = Words.getJRandom()[1];
  891. attackid++;
  892. typedLength = 0;
  893. }
  894. }
  895. }
  896. public function getConnectTime () : Number {return 0;}
  897. public function getConnectionState () : int { return 0; }
  898. public function IClient ():void{}
  899. public function isSelf () : Boolean { return false; }
  900. public function getAttribute (attrScope:String, attrName:String) : String{return attr[attrName]}
  901. public function getRoomIDs () : Array { return []; }
  902. public function getPing () : int { return 0; }
  903. public function isInRoom (roomID:String) : Boolean { return false; }
  904. public function setClientClass (scope:String, clientClass:Class, ...rest) : void{}
  905. public function getAttributes () : Object{ return {}}
  906. public function getAttributesByScope () : Object{ return {}}
  907. public function deleteAttribute (attrName:String, attrScope:String = null) : void{}
  908. public function getConnection () : Reactor { return null; }
  909. public function getTimeOnline () : int { return 0; }
  910. public function setAttribute (attrName:String, attrValue:String, attrScope:String = null, isShared:Boolean = true, isPersistent:Boolean = false, isUnique:Boolean = false, evaluate:Boolean = false) : void { attr[attrName] = attrValue; }
  911. public function getClientID () : String{ return "0"}
  912. public function getIP () : String{ return ""}
  913. public function sendMessage (messageName:String, ...rest) : void { }
  914. }
  915. // ゲーム全体・メッセージ制御
  916. class GameController extends EventDispatcher {
  917. protected var gameRoom:Room;
  918. protected var lobbyRoom:Room;
  919. protected var reactor:Reactor;
  920. protected var _lobbyUserNum:int;
  921. protected var infoUI:InfoUI;
  922. protected var gameStage:GameStage;
  923. protected var missileID:int = 0;
  924. protected var blueNum:int;
  925. protected var redNum:int;
  926. protected var cpu:CPUClient = new CPUClient();
  927. protected function clientStatusInit( selfClient:IClient ):void {
  928. LocalData.remove(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_LEVEL);
  929. if ( LocalData.read(Constants.LD_FIELD, Constants.USER_NAME) == null ) {
  930. LocalData.write(Constants.LD_FIELD, Constants.USER_NAME, "Guest" + selfClient.getClientID());
  931. }
  932. var userName:String = String(LocalData.read(Constants.LD_FIELD, Constants.USER_NAME));
  933. if( userName != null ) selfClient.setAttribute(Constants.USER_NAME, userName);
  934. selfClient.setAttribute("status", Constants.STATUS_CHATING);
  935. selfClient.setAttribute(Constants.HANDICAP, String(Score.handicap));
  936. cpu.self = selfClient;
  937. // 砲台の形とか色とか
  938. var baseLevel:String = (LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_LEVEL))?
  939. String(LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_LEVEL)):
  940. String(Constants.DEFAULT_USER_BATTERY_BASE_LEVEL);
  941. selfClient.setAttribute(Constants.USER_BATTERY_BASE_LEVEL, baseLevel, "");
  942. var color:String = (LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_COLOR))?
  943. String(LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_COLOR)):
  944. String(Constants.DEFAULT_USER_BATTERY_COLOR);
  945. selfClient.setAttribute(Constants.USER_BATTERY_COLOR, color, "");
  946. var baseColor:String = (LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_COLOR))?
  947. String(LocalData.read(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_COLOR)):
  948. String(Constants.DEFAULT_USER_BATTERY_BASE_COLOR);
  949. selfClient.setAttribute(Constants.USER_BATTERY_BASE_COLOR, baseColor, "");
  950. }
  951. // コンストラクタ
  952. public function GameController(reactor:Reactor, infoUI:InfoUI, gameStage:GameStage) {
  953. this.reactor = reactor;
  954. this.infoUI = infoUI;
  955. this.gameStage = gameStage;
  956. clientStatusInit( reactor.getClientManager().self() );
  957. reactor.getMessageManager().addMessageListener(Constants.ATTACK_LOG, attackLogAction);
  958. // ゲームのメッセージ類
  959. // gameRoom = reactor.getRoomManager().createRoom(Score.myGameRoom);
  960. // setupGameRoom();
  961. lobbyRoom = reactor.getRoomManager().createRoom(Constants.LOBBY_ROOM);
  962. lobbyRoom.addEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, onLobbyUpdateRoomAttribute);
  963. lobbyRoom.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onLobbyUpdateClientAttribute);
  964. lobbyRoom.addEventListener(RoomEvent.CLIENT_COUNT, onLobbyClientCount);
  965. // 情報画面からのイベントを受け取る
  966. infoUI.addEventListener(GameEvent.JOIN_BLUE, onJoinBlue);
  967. infoUI.addEventListener(GameEvent.JOIN_RED, onJoinRed);
  968. infoUI.addEventListener(GameEvent.JOIN_SOLO, onJoinSolo );
  969. infoUI.addEventListener(GameEvent.COLOR_SELECT, onColorSelect);
  970. infoUI.addEventListener(GameEvent.HANDICAP_SELECT, onHandicapSelect); // ハンデかわりました
  971. infoUI.addEventListener(GameEvent.NAME_CHANGE, onNameChange); // 名前かわりました
  972. // ゲーム画面からのイベントを受け取る
  973. gameStage.addEventListener(GameEvent.MOVE_BATTERY, onMoveBattery);
  974. gameStage.addEventListener(GameEvent.MODE_ATTACK, onModeAttack);
  975. gameStage.addEventListener(GameEvent.MODE_DEFENCE, onModeDefence);
  976. gameStage.addEventListener(GameEvent.ATTACK, onAttack); // 通常攻撃
  977. gameStage.addEventListener(GameEvent.ATTACK_DOUBLE, onAttackDouble); // ダブルアタック!
  978. gameStage.addEventListener(GameEvent.ATTACK_REFLECT, onAttackReflect); // オートリフレクション!
  979. gameStage.addEventListener(GameEvent.HIT, onHit); // 敵陣到達!
  980. gameStage.addEventListener(GameEvent.ATTACK_COMBO_START, onAttackComboStart);
  981. gameStage.addEventListener(GameEvent.ATTACK_COMBO_END, onAttackComboEnd);
  982. gameStage.addEventListener(GameEvent.DEFENCE_COMBO_START, onDefefnceComboStart);
  983. gameStage.addEventListener(GameEvent.DEFENCE_COMBO_END, onDeffenceComboEnd);
  984. gameStage.addEventListener(GameEvent.SHOOT, onShoot); // 撃ってます
  985. gameStage.addEventListener(GameEvent.MISSILE_DESTROY, onMissileDestroy); // ミサイルいっこ壊した
  986. gameStage.addEventListener(GameEvent.CHAT, onChat); // チームチャット
  987. gameStage.addEventListener(GameEvent.END_GAME, endGame); // エンディング描画完了
  988. }
  989. protected function onAttackComboStart(e:GameEvent):void {
  990. reactor.getClientManager().self().setAttribute("attackCombo", "true", Score.myGameRoom);
  991. }
  992. protected function onAttackComboEnd(e:GameEvent):void {
  993. reactor.getClientManager().self().setAttribute("attackCombo", "false", Score.myGameRoom);
  994. }
  995. protected function onDefefnceComboStart(e:GameEvent):void {
  996. reactor.getClientManager().self().setAttribute("defenceCombo", "true", Score.myGameRoom);
  997. }
  998. protected function onDeffenceComboEnd(e:GameEvent):void {
  999. reactor.getClientManager().self().setAttribute("defenceCombo", "false", Score.myGameRoom);
  1000. }
  1001. protected function onNameChange(e:GameEvent):void {
  1002. if( e.data != null ) reactor.getClientManager().self().setAttribute(Constants.USER_NAME, e.data, "");
  1003. }
  1004. protected function onHandicapSelect(e:GameEvent):void {
  1005. Score.handicap = Number(e.data);
  1006. reactor.getClientManager().self().setAttribute(Constants.HANDICAP, e.data, "");
  1007. infoUI.updateHandicap();
  1008. }
  1009. protected function onColorSelect(e:GameEvent):void {
  1010. var temp:Array = e.data.split("-");
  1011. var colorType:String = temp[0];
  1012. var color:String = temp[2];
  1013. if ( colorType == Constants.USER_BATTERY_BASE_COLOR || colorType == Constants.USER_BATTERY_COLOR ) {
  1014. reactor.getClientManager().self().setAttribute(colorType, color, "");
  1015. }
  1016. }
  1017. protected function setupGameRoom(startTime:String = "0"):void {
  1018. addListeners();
  1019. var nowTime:Number = ServerClockUtil.getTime();
  1020. var waitTime:Number = Number(startTime) - nowTime;
  1021. if ( waitTime > 0 ) {
  1022. var timer:Timer = new Timer(waitTime, 1);
  1023. timer.addEventListener(TimerEvent.TIMER_COMPLETE, onStart);
  1024. gameStage.setTimer(Number(startTime));
  1025. timer.start();
  1026. } else {
  1027. gameStage.enable = true;
  1028. }
  1029. }
  1030. protected function onStart(e:TimerEvent):void {
  1031. e.target.removeEventListener(TimerEvent.TIMER_COMPLETE, onStart);
  1032. gameRoom.setAttribute("status", Constants.STATUS_PLAYING); // 複数人でセットしてしまっている
  1033. if (Score.isSolo) gameStage.cpu = cpu;
  1034. else gameStage.cpu = null;
  1035. gameStage.enable = true;
  1036. }
  1037. protected function addListeners():void{
  1038. gameRoom.addMessageListener(Constants.ATTACK, attackAction);
  1039. gameRoom.addMessageListener(Constants.ATTACK_REFLECT, attackReflectAction);
  1040. gameRoom.addMessageListener(Constants.HIT, hitAction);
  1041. gameRoom.addMessageListener(Constants.SEND_ME_LOG, onAddClient);
  1042. gameRoom.addEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, onGameUpdateRoomAttribute);
  1043. gameRoom.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onGameUpdateClientAttribute);
  1044. gameRoom.addEventListener(RoomEvent.REMOVE_CLIENT, onLeaveClient);
  1045. gameRoom.addMessageListener(Constants.SHOOT, shootAction);
  1046. gameRoom.addMessageListener(Constants.DESTROY, destroyAction);
  1047. gameRoom.addMessageListener(Constants.GAME_CHAT, gameChatAction);
  1048. }
  1049. protected function removeListeners():void {
  1050. gameRoom.removeMessageListener(Constants.ATTACK, attackAction);
  1051. gameRoom.removeMessageListener(Constants.ATTACK_REFLECT, attackReflectAction);
  1052. gameRoom.removeMessageListener(Constants.HIT, hitAction);
  1053. gameRoom.removeMessageListener(Constants.SEND_ME_LOG, onAddClient);
  1054. gameRoom.removeEventListener(RoomEvent.UPDATE_ROOM_ATTRIBUTE, onGameUpdateRoomAttribute);
  1055. gameRoom.removeEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onGameUpdateClientAttribute);
  1056. gameRoom.removeEventListener(RoomEvent.REMOVE_CLIENT, onLeaveClient);
  1057. gameRoom.removeMessageListener(Constants.SHOOT, shootAction);
  1058. gameRoom.removeMessageListener(Constants.DESTROY, destroyAction);
  1059. gameRoom.removeMessageListener(Constants.GAME_CHAT, gameChatAction);
  1060. }
  1061. protected function gameChatAction(fromClient:IClient, msg:String):void {
  1062. gameStage.putChatMessage(ClientUtil.getUserName(fromClient) + "> " + String(decodeURI(msg)));
  1063. }
  1064. protected function onChat(e:GameEvent):void {
  1065. var filter:AttributeFilter = new AttributeFilter();
  1066. var myTeam:String = reactor.getClientManager().self().getAttribute("","team");
  1067. filter.addComparison( new AttributeComparison("team", myTeam, CompareType.EQUAL) );
  1068. gameRoom.sendMessage(Constants.GAME_CHAT, true, filter, String(encodeURI(e.data)));
  1069. }
  1070. protected function endGame(e:GameEvent):void { // ゲーム終了。部屋から出る。
  1071. startInfo();
  1072. var self:IClient = reactor.getClientManager().self();
  1073. Score.playMode = self.getAttribute(Score.myGameRoom, Constants.PLAY_MODE);
  1074. gameRoom.leave();
  1075. gameStage.clearAll();
  1076. gameStage.removeMissilesOf(reactor.getClientManager().self());
  1077. reactor.getClientManager().self().setAttribute("status", Constants.STATUS_CHATING);
  1078. reactor.getClientManager().self().setAttribute("team", Constants.TEAM_NONE);
  1079. reactor.getClientManager().self().setAttribute("isSolo", "");
  1080. reactor.getClientManager().self().setAttribute(Constants.BATTERY_X, "", Score.myGameRoom);
  1081. }
  1082. protected function shootAction(fromClient:IClient, clientId:int, missileId:int, shootTime:Number, bulletSpeed:Number, isDestroy:String):void {
  1083. gameStage.addBullet(fromClient, reactor.getClientManager().getClient(String(clientId)), missileId, shootTime, bulletSpeed, isMySide(fromClient), (isDestroy == "true"));
  1084. }
  1085. protected function destroyAction(fromClient:IClient, clientId:String, missileId:int):void {
  1086. if ( fromClient.isSelf() ) {
  1087. Score.defence++;
  1088. }
  1089. gameStage.destroy(fromClient, clientId, missileId);
  1090. }
  1091. protected function onShoot(e:GameEvent):void {
  1092. var sch:SoundChannel = SoundManager.TypeSound.play();
  1093. if( sch != null ) sch.soundTransform = new SoundTransform(0.5);
  1094. var arr:Array = e.data.split("-");
  1095. var clientId:int = arr[0];
  1096. var missileId:int = arr[1];
  1097. var isDestroy:Boolean = arr[2] == "1";
  1098. gameRoom.sendMessage(Constants.SHOOT, true, null, clientId, missileId, ServerClockUtil.getTime(), Constants.BULLET_SPEED, isDestroy);
  1099. LogAnalyzer.addDefenceLog(1);
  1100. }
  1101. protected function onMissileDestroy(e:GameEvent):void {
  1102. var arr:Array = e.data.split("-");
  1103. var clientId:int = arr[0];
  1104. var missileId:int = arr[1];
  1105. gameRoom.sendMessage(Constants.DESTROY, true, null, clientId, missileId);
  1106. }
  1107. protected function attackLogAction(fromClient:IClient, text:String, id:int, power:Number, attackTime:Number, arriveTime:Number, xpos:Number):void {
  1108. gameStage.addAttackLog(fromClient, text, isMySide(fromClient), id, power, attackTime, arriveTime, xpos);
  1109. }
  1110. protected function onAddClient(fromClient:IClient):void {
  1111. gameStage.sendLogTo(fromClient);
  1112. }
  1113. protected function onLeaveClient(e:RoomEvent):void {
  1114. gameStage.removeMissilesOf(e.getClient());
  1115. }
  1116. protected function hitAction(fromClient:IClient, id:String, damage:String):void {
  1117. if ( gameStage.cpu != null && damage == "cpu" ) {
  1118. fromClient = gameStage.cpu;
  1119. damage = "1";
  1120. }
  1121. SoundManager.HitSound.play();
  1122. var score:Number = 100;
  1123. var attName:String = "";
  1124. if ( fromClient.getAttribute("", "team") == Constants.TEAM_BLUE ) {
  1125. score *= redNum;
  1126. attName = "bluePoint";
  1127. } else if ( fromClient.getAttribute("", "team") == Constants.TEAM_RED ) {
  1128. score *= blueNum;
  1129. attName = "redPoint";
  1130. }
  1131. if ( isMySide( fromClient ) ) {
  1132. gameStage.hitMotion(true);
  1133. Score.score += score;
  1134. } else {
  1135. gameStage.hitMotion(false);
  1136. Score.score -= score;
  1137. }
  1138. if ( fromClient.isSelf() ) {
  1139. Score.hit++;
  1140. gameRoom.setAttribute(attName, "%v+" + Number(damage), true, false, true);
  1141. } else if ( ClientUtil.isCPU( fromClient ) ) {
  1142. gameRoom.setAttribute(attName, "%v+" + Number(damage), true, false, true);
  1143. }
  1144. setDamage();
  1145. }
  1146. protected function setDamage():void {
  1147. var bluePoint:int = int(gameRoom.getAttribute("bluePoint"));
  1148. var redPoint:int = int(gameRoom.getAttribute("redPoint"));
  1149. if ( ClientUtil.isTeamBlue(reactor.getClientManager().self()) ) {
  1150. gameStage.setDamage( redPoint, bluePoint );
  1151. } else {
  1152. gameStage.setDamage( bluePoint, redPoint );
  1153. }
  1154. }
  1155. protected function onHit(e:GameEvent):void {
  1156. var temp:Array = e.data.split("-");
  1157. var missileId:String = temp[0];
  1158. var damage:String = temp[1];
  1159. gameRoom.sendMessage(Constants.HIT, true, null, temp[0], temp[1]);
  1160. }
  1161. protected function attackAction(fromClient:Client, msg:String, xpos:Number, arriveTime:Number, id:int, power:Number):void {
  1162. SoundManager.AttackSound.play();
  1163. gameStage.addAttack(fromClient, msg, isMySide(fromClient), id, power, ServerClockUtil.getTime()+arriveTime, xpos);
  1164. }
  1165. protected function attackReflectAction(fromClient:Client, msg:String, xpos:Number, arriveTime:Number, id:int, power:Number):void {
  1166. SoundManager.ReflectSound.play();
  1167. gameStage.addAttack(fromClient, msg, isMySide(fromClient), id, power, ServerClockUtil.getTime()+arriveTime, xpos, true);
  1168. }
  1169. protected function onAttack(e:GameEvent):void {
  1170. if ( !gameStage.enable ) return;
  1171. attackHandler(e, true);
  1172. }
  1173. protected function onAttackDouble(e:GameEvent):void {
  1174. attackHandler(e, false);
  1175. }
  1176. protected function attackHandler(e:GameEvent, logTrack:Boolean):void {
  1177. var temp:Array = e.data.split("-");
  1178. var missileMsg:String = temp[0];
  1179. var missilePower:String = temp[1];
  1180. Score.attack++;
  1181. var attackLoc:Number = 425-Number(reactor.getClientManager().self().getAttribute(Score.myGameRoom, Constants.BATTERY_X)) - 50 + Math.random() * 100;
  1182. if ( attackLoc < 0 ) attackLoc = 50 + Math.random() * 50;
  1183. if ( attackLoc > 385 ) attackLoc = 285 + Math.random() * 50;
  1184. gameRoom.sendMessage(Constants.ATTACK, true, null, missileMsg, attackLoc, Constants.MISSILE_ARRIVE_TIME, missileID++, Number(missilePower));
  1185. if( logTrack && (missilePower == "1"))LogAnalyzer.addAttackLog(e.data.length);
  1186. }
  1187. protected function onAttackReflect(e:GameEvent):void {
  1188. var temp:Array = e.data.split("-");
  1189. var missileMsg:String = temp[0];
  1190. var missilePower:String = temp[1];
  1191. Score.attack++;
  1192. var attackLoc:Number = 425-Number(reactor.getClientManager().self().getAttribute(Score.myGameRoom, Constants.BATTERY_X)) - 20 + Math.random() * 40;
  1193. if ( attackLoc < 0 ) attackLoc = 20 + Math.random() * 20;
  1194. if ( attackLoc > 385 ) attackLoc = 345 + Math.random() * 20;
  1195. gameRoom.sendMessage(Constants.ATTACK_REFLECT, true, null, missileMsg, attackLoc, Constants.MISSILE_ARRIVE_TIME, missileID++, Number(missilePower));
  1196. }
  1197. protected function onModeAttack(e:GameEvent):void {
  1198. reactor.getClientManager().self().setAttribute(Constants.PLAY_MODE, Constants.PLAY_MODE_ATTACKER, Score.myGameRoom);
  1199. }
  1200. protected function onModeDefence(e:GameEvent):void {
  1201. reactor.getClientManager().self().setAttribute(Constants.PLAY_MODE, Constants.PLAY_MODE_DEFENDER, Score.myGameRoom);
  1202. }
  1203. protected function isMySide(client:IClient):Boolean {
  1204. return ( reactor.getClientManager().self().getAttribute("", "team") == client.getAttribute("", "team") );
  1205. }
  1206. protected function onMoveBattery(e:GameEvent):void {
  1207. reactor.getClientManager().self().setAttribute(Constants.BATTERY_X, String(gameStage.myBatteryMoveTo), Score.myGameRoom);
  1208. }
  1209. protected function onJoin(e:RoomEvent = null):void {
  1210. SoundManager.playGameBgm();
  1211. infoUI.fadeOut();
  1212. }
  1213. protected function onSynchronize(e:RoomEvent = null):void {
  1214. gameRoom.removeEventListener(RoomEvent.JOIN, onJoin);
  1215. gameRoom.removeEventListener(RoomEvent.SYNCHRONIZE, onSynchronize);
  1216. ServerClockUtil.init( reactor.getServer() );
  1217. Score.resetCombo();
  1218. gameRoom.sendMessage(Constants.SEND_ME_LOG);
  1219. var self:Client = reactor.getClientManager().self();
  1220. // 既存のゲーム内情報を追加
  1221. var users:Array = gameRoom.getClients();
  1222. var teamNum:int = 1;
  1223. for ( var i:int = 0; i < users.length; i++ ) {
  1224. if ( !users[i].isSelf() ) {
  1225. if ( isMySide(users[i]) ) teamNum++;
  1226. var batteryX:String = users[i].getAttribute(Score.myGameRoom, Constants.BATTERY_X);
  1227. if ( batteryX != null ) gameStage.setBattery(users[i], Number(batteryX), isMySide(users[i]));
  1228. var playMode:String = users[i].getAttribute(Score.myGameRoom, Constants.PLAY_MODE);
  1229. if ( playMode != null ) gameStage.setPlayMode(users[i], playMode);
  1230. }
  1231. }
  1232. var loc:Number = 22;
  1233. var tempLoc:Number = 210;
  1234. while ( teamNum > 0 ) {
  1235. loc += tempLoc * (teamNum & 1);
  1236. tempLoc *= 0.5;
  1237. teamNum >>= 1;
  1238. }
  1239. self.setAttribute(Constants.BATTERY_X, String(loc), Score.myGameRoom);
  1240. self.setAttribute("status", Constants.STATUS_WAITING);
  1241. gameStage.setBattery(self, loc, true);
  1242. gameStage.setPlayMode(self, Score.playMode);
  1243. if ( Score.isSolo ) {
  1244. cpu.setAttribute(Constants.USER_NAME, "COM Lv " + Score.cpuLV );
  1245. cpu.setAttribute(Constants.BATTERY_X, "232");
  1246. cpu.setAttribute(Constants.PLAY_MODE, Constants.PLAY_MODE_ATTACKER);
  1247. cpu.setAttribute("team", Constants.TEAM_RED);
  1248. gameStage.setBattery(cpu, Number(cpu.getAttribute("", Constants.BATTERY_X)), false);
  1249. gameStage.setPlayMode(cpu, Constants.PLAY_MODE_ATTACKER);
  1250. } else {
  1251. self.setAttribute("isSolo", "false");
  1252. }
  1253. var str:String = gameRoom.getAttribute("status");
  1254. if ( str == null ) {
  1255. setupGameRoom(String(ServerClockUtil.getTime() + (Score.isSolo?Constants.CPU_START_WAITTIME:Constants.GAME_START_WAITTIME)));
  1256. gameRoom.setAttribute("status", Constants.STATUS_WAITING);
  1257. gameRoom.setAttribute("startTime", String(ServerClockUtil.getTime() + (Score.isSolo?Constants.CPU_START_WAITTIME:Constants.GAME_START_WAITTIME)));
  1258. if( !Score.isSolo ){
  1259. lobbyRoom.setAttribute("gameRoomStartTime", String(ServerClockUtil.getTime() + (Score.isSolo?Constants.CPU_START_WAITTIME:Constants.GAME_START_WAITTIME)), true );
  1260. }
  1261. } else {
  1262. if ( str == Constants.STATUS_PLAYING ) {
  1263. setupGameRoom();
  1264. reactor.getClientManager().self().setAttribute("status", Constants.STATUS_PLAYING);
  1265. } else if ( str == Constants.STATUS_WAITING ) {
  1266. setupGameRoom(gameRoom.getAttribute("startTime"));
  1267. reactor.getClientManager().self().setAttribute("status", Constants.STATUS_WAITING);
  1268. }
  1269. }
  1270. setDamage();
  1271. LogAnalyzer.reset();
  1272. }
  1273. protected function onJoinBlue(e:GameEvent):void {
  1274. reactor.getClientManager().self().setAttribute("team", Constants.TEAM_BLUE);
  1275. gameStage.setup(Constants.TEAM_BLUE);
  1276. Score.isSolo = false;
  1277. Score.myGameRoom = Constants.GAME_ROOM;
  1278. if ( Score.playMode == null )
  1279. Score.playMode = Constants.PLAY_MODE_DEFENDER;
  1280. joinTeam();
  1281. }
  1282. protected function onJoinRed(e:GameEvent):void {
  1283. reactor.getClientManager().self().setAttribute("team", Constants.TEAM_RED);
  1284. gameStage.setup(Constants.TEAM_RED);
  1285. Score.isSolo = false;
  1286. Score.myGameRoom = Constants.GAME_ROOM;
  1287. if ( Score.playMode == null )
  1288. Score.playMode = Constants.PLAY_MODE_ATTACKER;
  1289. joinTeam();
  1290. }
  1291. protected function joinTeam():void {
  1292. gameRoom = reactor.getRoomManager().createRoom(Score.myGameRoom);
  1293. gameRoom.addEventListener(RoomEvent.JOIN, onJoin);
  1294. gameRoom.addEventListener(RoomEvent.SYNCHRONIZE, onSynchronize);
  1295. reactor.getClientManager().self().setAttribute(Constants.PLAY_MODE, Score.playMode, Score.myGameRoom);
  1296. if ( gameRoom.clientIsInRoom() ) {
  1297. onJoin();
  1298. onSynchronize();
  1299. } else {
  1300. gameRoom.join();
  1301. }
  1302. }
  1303. protected function onJoinSolo(e:GameEvent):void {
  1304. reactor.getClientManager().self().setAttribute("isSolo", "true");
  1305. reactor.getClientManager().self().setAttribute("team", Constants.TEAM_BLUE);
  1306. gameStage.setup(Constants.TEAM_BLUE);
  1307. Score.isSolo = true;
  1308. Score.myGameRoom = Constants.CPU_ROOM_DEFAULT + "_" + reactor.getClientManager().self().getClientID();
  1309. if ( Score.playMode == null )
  1310. Score.playMode = Constants.PLAY_MODE_ATTACKER;
  1311. joinTeam();
  1312. }
  1313. // 情報ウィンドウ表示。ロビー入室
  1314. public function startInfo():void {
  1315. var self:IClient = reactor.getClientManager().self();
  1316. var typeNums:Array = LogAnalyzer.analyze();
  1317. self.setAttribute(Constants.ATTACK_POWER, String(Score.attackPower));
  1318. self.setAttribute(Constants.DEFENCE_POWER, String(Score.defencePower));
  1319. self.setAttribute("attackCombo", "false", Score.myGameRoom);
  1320. self.setAttribute("defenceCombo", "false", Score.myGameRoom);
  1321. SoundManager.stopGameBgm();
  1322. if ( !lobbyRoom.clientIsInRoom() ) {
  1323. lobbyRoom.join();
  1324. infoUI.setChatRoom(lobbyRoom);
  1325. }
  1326. if ( typeNums[0] != -1 ) {
  1327. infoUI.setInfoMessage("Type count: " + typeNums[0] + "("+ int(typeNums[1]/typeNums[0]*10000)/100 +"%)");
  1328. }
  1329. infoUI.display();
  1330. infoUI.updateSoloInfo("COM LV: " + Score.cpuLV);
  1331. infoUI.setBatteryColors(ClientUtil.getBaseLevel(self), ClientUtil.getColor(self), ClientUtil.getBaseColor(self));
  1332. }
  1333. // ゲームルームの属性変更
  1334. protected function onGameUpdateRoomAttribute(e:RoomEvent):void {
  1335. switch( e.getChangedAttr().name ) {
  1336. case "startTime": // スタート時間変化
  1337. setupGameRoom( e.getChangedAttr().value );
  1338. // lobbyRoom.setAttribute("gameRoomStartTime", e.getChangedAttr().value);
  1339. break;
  1340. case "redPoint": // RED 勝利
  1341. if ( int(e.getChangedAttr().value) >= (0.8 * Constants.VICTORY_POINT) ) {
  1342. // if ( e.getClient().isSelf() )gameRoom.setAttribute("status", Constants.STATUS_FINISHING);
  1343. }
  1344. if ( int(e.getChangedAttr().value) >= Constants.VICTORY_POINT ) {
  1345. if ( reactor.getClientManager().self().getAttribute("", "team") == Constants.TEAM_RED ) {
  1346. infoUI.setInfoMessage("おめでとう!あなたの勝利です!");
  1347. Score.win++;
  1348. gameStage.end(true);
  1349. } else {
  1350. if (gameStage.cpu != null ) {
  1351. gameStage.cpu.disable();
  1352. infoUI.setInfoMessage("あなたは敗北しました。");
  1353. Score.cpuLV-= 0.5;
  1354. if ( Score.cpuLV < 0.5 ) Score.cpuLV = 0.5;
  1355. } else {
  1356. infoUI.setInfoMessage("あなたのチームは敗北しました。");
  1357. }
  1358. SoundManager.DangerSound.play();
  1359. Score.lose++;
  1360. gameStage.end(false);
  1361. }
  1362. removeListeners();
  1363. if ( e.getClient().isSelf() ) {
  1364. gameRoom.setAttribute("bluePoint", "0", true, false, true);
  1365. gameRoom.setAttribute("redPoint", "0", true, false, true);
  1366. }
  1367. gameRoom.setAttribute("status", Constants.STATUS_WAITING);
  1368. gameRoom.setAttribute("startTime", String(ServerClockUtil.getTime() + Constants.GAME_END_NEXT_WAITTIME));
  1369. Score.save();
  1370. }
  1371. break;
  1372. case "bluePoint": // BLUE 勝利
  1373. if ( int(e.getChangedAttr().value) >= (0.8 * Constants.VICTORY_POINT) ) {
  1374. // if ( e.getClient().isSelf() )gameRoom.setAttribute("status", Constants.STATUS_FINISHING);
  1375. }
  1376. if ( int(e.getChangedAttr().value) >= Constants.VICTORY_POINT ) {
  1377. if ( reactor.getClientManager().self().getAttribute("", "team") == Constants.TEAM_BLUE ) {
  1378. if (gameStage.cpu != null ) {
  1379. gameStage.cpu.disable();
  1380. infoUI.setInfoMessage("おめでとう!あなたの勝利です!");
  1381. Score.cpuLV += 1;
  1382. } else {
  1383. infoUI.setInfoMessage("おめでとう!あなたの勝利です!");
  1384. }
  1385. Score.win++;
  1386. gameStage.end(true);
  1387. } else {
  1388. infoUI.setInfoMessage("あなたのチームは敗北しました。");
  1389. SoundManager.DangerSound.play();
  1390. Score.lose++;
  1391. gameStage.end(false);
  1392. }
  1393. removeListeners();
  1394. if ( e.getClient().isSelf() ) {
  1395. gameRoom.setAttribute("bluePoint", "0", true, false, true);
  1396. gameRoom.setAttribute("redPoint", "0", true, false, true);
  1397. }
  1398. gameRoom.setAttribute("status", Constants.STATUS_WAITING);
  1399. gameRoom.setAttribute("startTime", String(ServerClockUtil.getTime() + 20000));
  1400. Score.save();
  1401. }
  1402. break;
  1403. }
  1404. }
  1405. protected function onLobbyUpdateRoomAttribute(e:RoomEvent):void {
  1406. switch ( e.getChangedAttr().name ) {
  1407. case "gameRoomStartTime": // ゲームルームの状態
  1408. if ( Number(e.getChangedAttr().value) < ServerClockUtil.getTime() ) {
  1409. if ( redNum == 0 && blueNum == 0 ) {
  1410. infoUI.updateNormalRoomStatus("参加できます");
  1411. } else {
  1412. infoUI.updateNormalRoomStatus("対戦中です");
  1413. }
  1414. } else if ( Number(e.getChangedAttr().value) >= ServerClockUtil.getTime() ) {
  1415. infoUI.addEventListener( Event.ENTER_FRAME, onGameRoomCountDown );
  1416. }
  1417. break;
  1418. }
  1419. }
  1420. protected function onGameRoomCountDown(e:Event):void {
  1421. var time:Number = Number(lobbyRoom.getAttribute("gameRoomStartTime")) - ServerClockUtil.getTime();
  1422. if( time > 0 ) {
  1423. infoUI.updateNormalRoomStatus("開始まで " + Math.ceil(time / 1000) + "秒");
  1424. } else {
  1425. infoUI.removeEventListener(Event.ENTER_FRAME, onGameRoomCountDown);
  1426. infoUI.updateNormalRoomStatus("対戦中です");
  1427. }
  1428. }
  1429. // ゲームルーム中のクライアントの属性変更
  1430. protected function onGameUpdateClientAttribute(e:RoomEvent):void {
  1431. // if ( ClientUtil.getStatus(e.getClient()) != Constants.STATUS_PLAYING ) return;
  1432. switch( e.getChangedAttr().name ) {
  1433. case Constants.BATTERY_X: // 位置の移動
  1434. gameStage.setBattery(e.getClient(), Number(e.getChangedAttr().value), isMySide(e.getClient()) );
  1435. break;
  1436. case Constants.PLAY_MODE: // プレイモード変更
  1437. gameStage.setPlayMode(e.getClient(), e.getChangedAttr().value);
  1438. break;
  1439. case Constants.ANGLE: // 砲台の角度
  1440. gameStage.setBatteryAngle(e.getClient(), Number(e.getChangedAttr().value));
  1441. break;
  1442. case "attackCombo":
  1443. case "defenceCombo":
  1444. gameStage.updateComboStatus(e.getClient(), e.getChangedAttr().name, (e.getChangedAttr().value == "true"));
  1445. break;
  1446. case "status": // 当然STATUS_PLAYING
  1447. gameStage.setBattery(e.getClient(), Number(e.getClient().getAttribute(Score.myGameRoom, Constants.BATTERY_X)), isMySide(e.getClient()) );
  1448. gameStage.setPlayMode(e.getClient(), e.getClient().getAttribute(Score.myGameRoom,Constants.PLAY_MODE));
  1449. break;
  1450. case "team":
  1451. gameStage.setBattery(e.getClient(), Number(e.getClient().getAttribute(Score.myGameRoom, Constants.BATTERY_X)), isMySide(e.getClient()) );
  1452. break;
  1453. }
  1454. }
  1455. // ロビー中のクライアントの属性変更
  1456. protected function onLobbyUpdateClientAttribute(e:RoomEvent):void {
  1457. updateTeamUsersNum();
  1458. if( e.getClient().isSelf() ){
  1459. switch( e.getChangedAttr().name ) {
  1460. case Constants.USER_BATTERY_BASE_COLOR:
  1461. case Constants.USER_BATTERY_COLOR:
  1462. case Constants.USER_BATTERY_BASE_LEVEL:
  1463. var client:IClient = e.getClient();
  1464. infoUI.setBatteryColors(ClientUtil.getBaseLevel(client), ClientUtil.getColor(client), ClientUtil.getBaseColor(client));
  1465. }
  1466. }
  1467. }
  1468. protected function onLobbyClientCount(e:RoomEvent):void {
  1469. lobbyUserNum = e.getNumClients();
  1470. updateTeamUsersNum();
  1471. }
  1472. protected function updateTeamUsersNum():void {
  1473. var clients:Array = lobbyRoom.getClients();
  1474. var blueNum:int = 0;
  1475. var redNum:int = 0;
  1476. var blueAttack:Number = 0;
  1477. var blueDefence:Number = 0;
  1478. var redAttack:Number = 0;
  1479. var redDefence:Number = 0;
  1480. for ( var i:int = 0; i < clients.length; i++ ) {
  1481. var teamAtt:String = Client( clients[i] ).getAttribute("", "team");
  1482. var isSolo:Boolean = Client( clients[i] ).getAttribute("", "isSolo") == "true";
  1483. var attackPower:Number = ClientUtil.getAttackPower(clients[i]);
  1484. var defencePower:Number = ClientUtil.getDefencePower(clients[i]);
  1485. var handiCap:Number = ClientUtil.getHandicap(clients[i]);
  1486. if( !isSolo ){
  1487. if ( teamAtt == Constants.TEAM_BLUE ) {
  1488. blueNum++;
  1489. blueAttack += attackPower/handiCap;
  1490. blueDefence += defencePower/handiCap;
  1491. }
  1492. if ( teamAtt == Constants.TEAM_RED ) {
  1493. redNum++;
  1494. redAttack += attackPower/handiCap;
  1495. redDefence += defencePower/handiCap;
  1496. }
  1497. }
  1498. }
  1499. this.blueNum = blueNum;
  1500. this.redNum = redNum;
  1501. if( blueNum == 0 && redNum == 0 ) infoUI.updateNormalRoomStatus("参加できます!");
  1502. infoUI.setBlueTeamInfo( blueNum, blueAttack, blueDefence );
  1503. infoUI.setRedTeamInfo( redNum, redAttack, redDefence );
  1504. }
  1505. public function get lobbyUserNum():int { return _lobbyUserNum; }
  1506. public function set lobbyUserNum(value:int):void
  1507. {
  1508. _lobbyUserNum = value;
  1509. infoUI.setLobbyUserNum( value );
  1510. }
  1511. }
  1512. // 測定くん
  1513. class LogAnalyzer {
  1514. protected static var attackLog:Array = [];
  1515. protected static var defenceLog:Array = [];
  1516. protected static var old_type:Number = -1;
  1517. protected static var old_correct:Number = -1;
  1518. public static function reset():void {
  1519. attackLog = [];
  1520. defenceLog = [];
  1521. old_type = Score.type;
  1522. old_correct = Score.correct;
  1523. }
  1524. public static function addAttackLog(wordLength:int):void {
  1525. attackLog.push([wordLength, getTimer()]);
  1526. }
  1527. public static function addDefenceLog(wordLength:int):void {
  1528. defenceLog.push([wordLength, getTimer()]);
  1529. }
  1530. protected static function analyzeArray(log:Array):Number {
  1531. var power:Number = 0;
  1532. var count:int = log.length;
  1533. var lastEnd:int = 0;
  1534. var limitTime:Number;
  1535. var strNum:Number;
  1536. if ( count < 2 ) return 0;
  1537. for ( var i:int = 0; i < count; i++ ) {
  1538. limitTime = log[i][1] + 10000;
  1539. for ( var j:int = lastEnd; j < count; j++ ) {
  1540. if ( log[j][1] > limitTime ) {
  1541. break;
  1542. }
  1543. }
  1544. lastEnd = j;
  1545. strNum = 0;
  1546. for ( j = i+1; j < lastEnd; j++ ) {
  1547. strNum += log[j][0];
  1548. }
  1549. if ( i == lastEnd ) continue;
  1550. var temp:Number = (log[lastEnd - 1][1] - log[i][1]);
  1551. if ( temp < 3000 ) continue; // 最低3秒間持続
  1552. temp = 1000000 * strNum / temp;
  1553. if ( temp > power ) power = temp;
  1554. if ( lastEnd == count ) break;
  1555. }
  1556. return power;
  1557. }
  1558. public static function analyze():Array {
  1559. var attackPower:Number = analyzeArray(attackLog);
  1560. var defencePower:Number = analyzeArray(defenceLog);
  1561. if( attackPower > 0 ){
  1562. if ( Score.attackPower < attackPower ) {
  1563. Score.attackPower = (attackPower + Score.attackPower/4)/1.25;
  1564. } else {
  1565. Score.attackPower = (attackPower/16 + Score.attackPower)/1.0625;
  1566. }
  1567. }
  1568. if( defencePower > 0 ){
  1569. if ( Score.defencePower < defencePower ) {
  1570. Score.defencePower = (defencePower + Score.defencePower/4)/1.25;
  1571. } else {
  1572. Score.defencePower = (defencePower/16 + Score.defencePower)/1.0625;
  1573. }
  1574. }
  1575. Score.save();
  1576. if ( old_type == -1 ) {
  1577. return [-1, -1];
  1578. } else {
  1579. return [Score.type - old_type, Score.correct - old_correct];
  1580. }
  1581. }
  1582. }
  1583. // 弾の軌道制御とか
  1584. class Bullet extends Sprite {
  1585. protected var startX:Number;
  1586. protected var startY:Number;
  1587. protected var vx:Number;
  1588. protected var vy:Number;
  1589. protected var startTime:Number;
  1590. protected var hitTime:Number;
  1591. protected var target:Missile;
  1592. protected var isDestroy:Boolean;
  1593. public function Bullet(targetMissile:Missile, bulletSpeed:Number, startX:Number, startY:Number, startTime:Number, isDestroy:Boolean) {
  1594. this.graphics.beginFill(0xFFFFFF - int(Math.random() * 0x40));
  1595. this.graphics.drawRect(0, 0, 2, 2);
  1596. this.mouseEnabled = this.mouseChildren = false;
  1597. this.startX = startX;
  1598. this.startY = startY;
  1599. this.startTime = startTime;
  1600. this.target = targetMissile;
  1601. this.isDestroy = isDestroy;
  1602. var x:Number = (385 - targetMissile.x) - startX;
  1603. var yd:Number = Constants.DISTANCE - targetMissile.y - startY + 5;
  1604. var missileSpeed:Number = targetMissile.durationT;
  1605. var vd:Number = missileSpeed * missileSpeed;
  1606. var md:Number = bulletSpeed * bulletSpeed;
  1607. var meetTime:Number = (yd * missileSpeed - Math.sqrt( yd * yd * vd - (x * x + yd * yd) * (vd - md) ) ) / (vd - md);
  1608. vx = x / meetTime;
  1609. vy = Math.sqrt(md - vx * vx);
  1610. hitTime = startTime + meetTime;
  1611. }
  1612. public function getAngle():String {
  1613. return String( 180 * Math.atan2(-vx, vy) / Math.PI );
  1614. }
  1615. // 弾が進む。ヒットしたか画面外にいったらtrueを返してremoveChildしてもらう。 効果音つき
  1616. public function update(time:Number):Boolean {
  1617. var ellapse:Number = time - startTime;
  1618. this.x = ellapse * vx + startX;
  1619. this.y = ellapse * vy + startY;
  1620. if ( target.parent != null && time > hitTime ) {
  1621. // dispatchEvent(new GameEvent(GameEvent.MISSILE_DAMAGE, true));
  1622. target.damage(vx, vy, isDestroy);
  1623. var sch:SoundChannel = SoundManager.ShootSound.play();
  1624. if( sch != null ) sch.soundTransform = new SoundTransform(0.5);
  1625. return true;
  1626. }
  1627. if ( this.x > 665 || this.x < -200 || this.y > 665 || this.y < -200 ) {
  1628. return true;
  1629. }
  1630. return false;
  1631. }
  1632. }
  1633. // ミサイルの軌道制御とか
  1634. class Missile extends Sprite {
  1635. public var arriveTime:Number;
  1636. public var attackTime:Number;
  1637. public var durationT:Number;
  1638. public var id:int;
  1639. public var client:IClient;
  1640. public var isSelf:Boolean;
  1641. public var text:String = "";
  1642. public var word:String = "";
  1643. public var wordLength:int = 0;
  1644. public var isMySide:Boolean;
  1645. public var power:Number;
  1646. protected var circle:Sprite = new Sprite();
  1647. protected var body:Sprite = new Sprite();
  1648. protected var inputIndex:int = 0;
  1649. protected var tf:TextField = new TextField();
  1650. protected var tfCover:Sprite = new Sprite();
  1651. protected var index:int = 0;
  1652. protected var isJapaneseWord:Boolean = false;
  1653. public function get isTypable():Boolean {
  1654. return tf.visible;
  1655. }
  1656. public function Missile(client:IClient, attackTime:Number, arriveTime:Number, id:int, power:Number, isSelf:Boolean) {
  1657. this.mouseChildren = false;
  1658. this.mouseEnabled = false;
  1659. this.client = client;
  1660. this.attackTime = attackTime;
  1661. this.arriveTime = arriveTime;
  1662. this.power = power;
  1663. durationT = Constants.DISTANCE / (arriveTime - attackTime);
  1664. this.id = id;
  1665. this.isSelf = isSelf;
  1666. if ( ClientUtil.isTeamBlue(client) ) {
  1667. body.graphics.lineStyle(0, 0x3366FF);
  1668. body.graphics.beginFill(0x3399FF);
  1669. } else if ( ClientUtil.isTeamRed(client) ) {
  1670. body.graphics.lineStyle(0, 0xFF3333);
  1671. body.graphics.beginFill(0xFF8888);
  1672. }
  1673. body.graphics.lineTo(power * 4, power * -16)
  1674. body.graphics.lineTo(power * -4, power * -16);
  1675. body.graphics.lineTo(0, 0);
  1676. addChild( body );
  1677. body.y = power * 8;
  1678. tf.defaultTextFormat = new TextFormat(TextFieldUtil.getFont(), 14, 0xFFFFFF);
  1679. tf.autoSize = "left";
  1680. tf.border = true;
  1681. tf.background = true;
  1682. tf.backgroundColor = 0x0;
  1683. tf.borderColor = 0xFFFFFF;
  1684. }
  1685. public function damage(vx:Number, vy:Number, isDestroy:Boolean):void {
  1686. var damageMotion:DamageMotion = new DamageMotion(vx, vy);
  1687. if ( this.parent != null ) {
  1688. this.parent.addChild( damageMotion );
  1689. damageMotion.x = this.x;
  1690. damageMotion.y = this.y;
  1691. }
  1692. if ( isDestroy && (client.isSelf() || ClientUtil.isCPU(client) ) ) { // 自分のミサイルだったら破壊判定
  1693. dispatchEvent(new GameEvent(GameEvent.MISSILE_DESTROY, true, false, client.getClientID() + "-" + id));
  1694. }
  1695. }
  1696. // ミサイル破壊モーション 効果音つき
  1697. public function destroiedMotion():void {
  1698. SoundManager.DamageSound.play();
  1699. tf.visible = false;
  1700. this.graphics.clear();
  1701. this.graphics.lineStyle(1, 0xFFFF00, 0.5);
  1702. this.graphics.drawCircle(0, 0, 5);
  1703. body.visible = false;
  1704. this.addEventListener(Event.ENTER_FRAME, onDestroyEnterFrame);
  1705. }
  1706. protected function onDestroyEnterFrame(e:Event):void {
  1707. this.scaleX *= 1.2;
  1708. this.scaleY *= 1.2;
  1709. this.alpha *= 0.85;
  1710. if ( this.alpha < 0.1 ) {
  1711. this.removeEventListener(Event.ENTER_FRAME, onDestroyEnterFrame);
  1712. this.parent.removeChild(this);
  1713. }
  1714. }
  1715. public function update(time:Number):void {
  1716. this.y = (time-attackTime) * durationT;
  1717. body.rotationY += power * 8;
  1718. }
  1719. public function setText(text:String, isMySide:Boolean):void {
  1720. isJapaneseWord = Roma.isJapaneseWord(text);
  1721. this.word = text;
  1722. this.wordLength = isJapaneseWord?Roma.getRomaToType(word).length:word.length;
  1723. this.text = HandicapUtil.getHandicapWord(text);
  1724. this.isMySide = isMySide;
  1725. if( !isMySide ){
  1726. this.addChild( tf );
  1727. this.addChild( tfCover );
  1728. this.addChild( circle );
  1729. isJapaneseWord?setJIndex(Roma.getRomaToType(word)):setIndex(0);
  1730. }
  1731. }
  1732. public function tryType(char:String):int {
  1733. if ( isJapaneseWord ) {
  1734. char = char.toUpperCase();
  1735. var str:String = Roma.getRomaToType(text, typed + char );
  1736. if ( str ) {
  1737. typed += char;
  1738. var toType:String = str.substr(typed.length);
  1739. // setJIndex(toType);
  1740. setJIndex("" + typed + "" + toType + "");
  1741. } else {
  1742. return Constants.RESULT_FAULT;
  1743. }
  1744. if ( toType.length ) {
  1745. return Constants.RESULT_SUCCESS;
  1746. } else {
  1747. tf.visible = false;
  1748. return Constants.RESULT_DESTROY;
  1749. }
  1750. } else {
  1751. if ( text.substr(index, 1) == char ) {
  1752. setIndex(++index);
  1753. } else {
  1754. return Constants.RESULT_FAULT;
  1755. }
  1756. if ( text.length == index ) {
  1757. tf.visible = false;
  1758. return Constants.RESULT_DESTROY;
  1759. } else {
  1760. return Constants.RESULT_SUCCESS;
  1761. }
  1762. }
  1763. }
  1764. protected var typed:String = "";
  1765. public function tryStart(char:String):Boolean {
  1766. if ( isMySide || (typed != "") || !tf.visible ) return false;
  1767. if ( isJapaneseWord ) {
  1768. char = char.toUpperCase();
  1769. var str:String = Roma.getRomaToType(text, char);
  1770. if ( str ) {
  1771. typed = char;
  1772. setJIndex("" + typed + "" + str.substr(typed.length) + "");
  1773. setFocus();
  1774. return true;
  1775. }
  1776. return false;
  1777. } else {
  1778. if ( text.charAt(0) == char ) {
  1779. setIndex(1);
  1780. setFocus();
  1781. return true;
  1782. }
  1783. return false;
  1784. }
  1785. }
  1786. public function get center():Number {
  1787. return this.x + this.width * 0.5;
  1788. }
  1789. protected var focused:Boolean = false;
  1790. public function setFocus():void {
  1791. focused = true;
  1792. tf.borderColor = 0xFFFF00;
  1793. }
  1794. public function setCircle(level:int):void {
  1795. circle.graphics.clear();
  1796. switch ( level ) {
  1797. case 2:
  1798. circle.graphics.lineStyle(0, 0xFFFF00, 0.3);
  1799. circle.graphics.drawCircle(0, 0, 30);
  1800. break;
  1801. case 1:
  1802. circle.graphics.lineStyle(1, 0xFFFF00, 0.4);
  1803. circle.graphics.drawCircle(0, 0, 35);
  1804. break;
  1805. case 0:
  1806. circle.graphics.lineStyle(2, 0xFFFF00, 0.5);
  1807. circle.graphics.drawCircle(0, 0, 40);
  1808. break;
  1809. default:
  1810. break;
  1811. }
  1812. }
  1813. public function darken():void {
  1814. if ( !focused ) tf.borderColor = 0x333333;
  1815. }
  1816. public function undarken():void {
  1817. if ( !focused ) tf.borderColor = 0xFFFFFF;
  1818. }
  1819. public function reset():void {
  1820. focused = false;
  1821. tf.borderColor = 0xFFFFFF;
  1822. isJapaneseWord?setJIndex(Roma.getRomaToType(word)):setIndex(0);
  1823. }
  1824. protected function setJIndex(toType:String):void {
  1825. tf.htmlText = " " + text + " " + "\n" + " " + toType + " ";
  1826. tf.x = -0.5 * tf.width;
  1827. }
  1828. protected function setIndex(num:int):void {
  1829. index = num;
  1830. tf.htmlText = " " + text.substr(num) + " ";
  1831. tf.x = -0.5 * tf.width;
  1832. }
  1833. }
  1834. // チームチャット
  1835. class ChatItem extends Sprite {
  1836. protected var tf:TextField = new TextField();
  1837. public function ChatItem(msg:String) {
  1838. tf.autoSize = "left";
  1839. tf.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF);
  1840. tf.text = msg;
  1841. this.addChild(tf);
  1842. this.mouseChildren = this.mouseEnabled = false;
  1843. var timer:Timer = new Timer(Constants.TEAM_CHAT_DURATION, 1);
  1844. timer.start();
  1845. timer.addEventListener(TimerEvent.TIMER_COMPLETE, onTimer);
  1846. }
  1847. protected function onTimer(e:TimerEvent):void {
  1848. e.target.removeEventListener(TimerEvent.TIMER_COMPLETE, onTimer);
  1849. this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  1850. }
  1851. protected function onEnterFrame(e:Event):void {
  1852. this.alpha *= 0.9;
  1853. if ( this.alpha < 0.1 ) {
  1854. this.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  1855. if( this.parent != null ){
  1856. this.parent.removeChild(this);
  1857. }
  1858. }
  1859. }
  1860. }
  1861. // ディフェンスUI
  1862. class DefenceTargets extends Sprite {
  1863. public var missileList:Array;
  1864. public var firstClaster:Array = [];
  1865. public var secondClaster:Array = [];
  1866. public var thirdClaster:Array = [];
  1867. protected var maxWidth:Number = 180;
  1868. protected var speed:Number = Constants.DISTANCE / Constants.MISSILE_ARRIVE_TIME;
  1869. public function DefenceTargets() {
  1870. this.graphics.lineStyle(2, 0x00FF00, 0.5);
  1871. this.graphics.moveTo( -0.5 * maxWidth, 0);
  1872. this.graphics.lineTo( -0.5 * maxWidth, 300);
  1873. this.graphics.moveTo( 0.5 * maxWidth, 0);
  1874. this.graphics.lineTo( 0.5 * maxWidth, 300);
  1875. this.graphics.lineStyle(0, 0x00FF00, 1);
  1876. this.graphics.moveTo( -0.5 * maxWidth, 0);
  1877. this.graphics.lineTo( -0.5 * maxWidth, 300);
  1878. this.graphics.moveTo( 0.5 * maxWidth, 0);
  1879. this.graphics.lineTo( 0.5 * maxWidth, 300);
  1880. this.visible = false;
  1881. // this.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  1882. }
  1883. public function updateTopFocus():void {
  1884. firstClaster = [];
  1885. secondClaster = [];
  1886. thirdClaster = [];
  1887. var maxX:Number = this.x + 0.5 * maxWidth;
  1888. var minX:Number = this.x - 0.5 * maxWidth;
  1889. var maxX2nd:Number = this.x + maxWidth;
  1890. var minX2nd:Number = this.x - maxWidth;
  1891. var count:int = missileList.length;
  1892. for ( var i:int = 0; i < count; i++ ) {
  1893. var missile:Missile = missileList[i];
  1894. // if ( !missile.isMySide && missile.word.length ) {
  1895. if ( missile.isTypable ) {
  1896. // missile.setCircle(4);
  1897. if ( missile.center > minX && missile.center < maxX ) {
  1898. firstClaster.push( missileList[i] );
  1899. missile.undarken();
  1900. } else if ( missile.center > minX2nd && missile.center < maxX2nd ) {
  1901. secondClaster.push( missile );
  1902. missile.darken();
  1903. } else {
  1904. thirdClaster.push( missile );
  1905. missile.darken();
  1906. }
  1907. }
  1908. }
  1909. firstClaster = firstClaster.sort( sortFunc );
  1910. // i = 0;
  1911. // for ( i = 0; i < Math.min(3, firstClaster.length); i++ ) {
  1912. // firstClaster[i].setCircle(i);
  1913. // }
  1914. }
  1915. public function getDefenceText():Array {
  1916. var count:int = firstClaster.length;
  1917. var ret1:String = "";
  1918. for ( var i:int = 0; i < count; i++ ) {
  1919. ret1 += firstClaster[i].word + " ";
  1920. }
  1921. return []; // 改良予定地
  1922. // return [ret1];
  1923. }
  1924. protected function sortFunc(value1:Missile, value2:Missile):int {
  1925. if ( value1.y < value2.y ) {
  1926. return 1;
  1927. } else if ( value1.y > value2.y ) {
  1928. return -1;
  1929. } else {
  1930. return 0;
  1931. }
  1932. }
  1933. }
  1934. // ゲーム画面管理
  1935. class GameStage extends Sprite {
  1936. protected var bgGrid:Sprite = new Sprite();
  1937. protected var myMissiles:Sprite = new Sprite();
  1938. protected var enemyMissiles:Sprite = new Sprite();
  1939. protected var operationBG:Sprite = new Sprite();
  1940. protected var operationUI:OperationUI = new OperationUI();
  1941. protected var moveUI:MoveBatteryUI = new MoveBatteryUI();
  1942. protected var enemyBG:Sprite = new Sprite();
  1943. protected var batteryList:UDictionary = new UDictionary(false);
  1944. protected var bulletList:Array = [];
  1945. protected var _missileList:Array = [];
  1946. protected var chatInputBar:TextField = new TextField();
  1947. protected var effectSp:EffectSprite = new EffectSprite();
  1948. protected var bg:BackGround = new BackGround(effectSp);
  1949. protected var defenceTargets:DefenceTargets = new DefenceTargets();
  1950. protected var _myBatteryMoveTo:Number;
  1951. protected var chatUI:Sprite = new Sprite(); // インプットバーとログの表示
  1952. public var cpu:CPUClient;
  1953. public function setPlayMode(client:IClient, playMode:String):void {
  1954. if ( client.isSelf() ) {
  1955. operationUI.setMode(playMode);
  1956. moveUI.setMode(playMode);
  1957. // 防御UI表示/非表示
  1958. if ( playMode == Constants.PLAY_MODE_DEFENDER) {
  1959. defenceTargets.visible = true;
  1960. } else {
  1961. defenceTargets.visible = false;
  1962. }
  1963. }
  1964. if ( batteryList[client.getClientID()] != undefined ) {
  1965. Battery(batteryList[client.getClientID()]).setMode(playMode);
  1966. }
  1967. }
  1968. public function GameStage() {
  1969. drawBG();
  1970. this.addChild( bgGrid );
  1971. this.addChild( bg );
  1972. bg.y = 40;
  1973. effectSp.y = 40;
  1974. bgGrid.addChild( myMissiles );
  1975. myMissiles.rotation = 180;
  1976. bgGrid.addChild( enemyMissiles );
  1977. enemyMissiles.x = 40;
  1978. myMissiles.x = 425;
  1979. myMissiles.y = 340;
  1980. enemyMissiles.y = 40;
  1981. myMissiles.mouseEnabled = enemyMissiles.mouseEnabled =
  1982. myMissiles.mouseChildren = enemyMissiles.mouseChildren = false;
  1983. this.addChild( operationBG );
  1984. operationBG.addChild( moveUI ); // 砲台移動用
  1985. moveUI.addEventListener(MouseEvent.CLICK, onMoveClick);
  1986. operationBG.addChild( operationUI);
  1987. operationUI.y = 40;
  1988. defenceTargets.missileList = _missileList;
  1989. operationBG.y = 340;
  1990. this.addChild( enemyBG );
  1991. this.addChild( defenceTargets );
  1992. defenceTargets.y = 40;
  1993. bgGrid.mouseEnabled = bgGrid.mouseChildren = false;
  1994. operationBG.mouseEnabled = false;
  1995. operationUI.addEventListener(GameEvent.DEFENCE_TYPE, onDefenceKeyDown);
  1996. this.addChild(chatUI);
  1997. chatUI.x = 15;
  1998. chatUI.y = 315;
  1999. this.addChild(chatInputBar);
  2000. chatInputBar.border = true;
  2001. chatInputBar.type = "input";
  2002. chatInputBar.borderColor = 0xFFFFFF;
  2003. chatInputBar.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF);
  2004. chatInputBar.width = 250;
  2005. chatInputBar.height = 20;
  2006. chatInputBar.y = 315;
  2007. chatInputBar.x = 15;
  2008. chatInputBar.addEventListener(KeyboardEvent.KEY_UP, onChatKeyUp);
  2009. chatInputBar.addEventListener(KeyboardEvent.KEY_DOWN, onChatKeyDown);
  2010. chatInputBar.multiline = true;
  2011. chatInputBar.visible = false;
  2012. }
  2013. protected var startTime:Number;
  2014. public function setTimer(startTime:Number):void {
  2015. bg.setFilter(0);
  2016. this.startTime = startTime;
  2017. this.addEventListener(Event.ENTER_FRAME, onCountDown);
  2018. }
  2019. protected var lastTime:Number = -1;
  2020. protected function onCountDown(e:Event):void {
  2021. var rest:int = ((startTime - ServerClockUtil.getTime()) / 1000);
  2022. if ( rest <= 0 ) this.removeEventListener(Event.ENTER_FRAME, onCountDown);
  2023. if ( lastTime == rest ) return;
  2024. lastTime = rest;
  2025. var temp:TextField = new TextField();
  2026. temp.defaultTextFormat = new TextFormat("Arial", 60, 0xFFFF00, true);
  2027. temp.text = (rest >= 0)?String(1+int(rest)):"";
  2028. temp.autoSize = "left";
  2029. bg.bitmapData.draw(temp, new Matrix(1,0,0,1,232-0.5*temp.textWidth,130));
  2030. }
  2031. public function updateComboStatus(client:IClient, attrName:String, isStart:Boolean):void {
  2032. if( batteryList[client.getClientID()] != undefined )
  2033. batteryList[client.getClientID()].updateCombo(attrName, isStart);
  2034. }
  2035. protected function clearLoserAndMissiles():void {
  2036. for ( var i:int = 0; i < _missileList.length; i++ ) {
  2037. if (_missileList[i].parent != null )_missileList[i].parent.removeChild(_missileList[i]);
  2038. }
  2039. _missileList = [];
  2040. defenceTargets.missileList = _missileList;
  2041. for ( i = 0; i < bulletList.length; i++ ) {
  2042. if (bulletList[i].parent != null )bulletList[i].parent.removeChild(bulletList[i]);
  2043. }
  2044. bulletList = [];
  2045. var clearTarget:Sprite = (mySideWon)?enemyBG:operationBG;
  2046. for( var id:String in batteryList ) {
  2047. if( batteryList[id].parent == clearTarget ){
  2048. clearTarget.removeChild(batteryList[id]);
  2049. }
  2050. }
  2051. }
  2052. public function clearAll():void {
  2053. for ( var i:int = 0; i < _missileList.length; i++ ) {
  2054. if (_missileList[i].parent != null )_missileList[i].parent.removeChild(_missileList[i]);
  2055. }
  2056. _missileList = [];
  2057. defenceTargets.missileList = _missileList;
  2058. for ( i = 0; i < bulletList.length; i++ ) {
  2059. if (bulletList[i].parent != null )bulletList[i].parent.removeChild(bulletList[i]);
  2060. }
  2061. bulletList = [];
  2062. for each( var battery:Battery in batteryList ) {
  2063. if( battery.parent != null )
  2064. battery.parent.removeChild(battery);
  2065. }
  2066. batteryList = new UDictionary(false);
  2067. }
  2068. protected function onShortcutKeyDown(e:KeyboardEvent):void {
  2069. switch( e.keyCode ) {
  2070. case Keyboard.TAB:
  2071. switch( operationUI.getPlayMode() ) {
  2072. case Constants.PLAY_MODE_ATTACKER:
  2073. operationUI.setFocus();
  2074. break;
  2075. case Constants.PLAY_MODE_DEFENDER:
  2076. changeFocus(e.shiftKey);
  2077. break;
  2078. }
  2079. break;
  2080. case Constants.CHAT_KEY:
  2081. chatInputMode = true;
  2082. break;
  2083. case Keyboard.UP:
  2084. SoundManager.ClickSound.play();
  2085. dispatchEvent( new GameEvent(GameEvent.MODE_ATTACK, true) );
  2086. break;
  2087. case Keyboard.DOWN:
  2088. SoundManager.ClickSound.play();
  2089. dispatchEvent( new GameEvent(GameEvent.MODE_DEFENCE, true) );
  2090. break;
  2091. case Keyboard.RIGHT:
  2092. myBatteryMoveTo = myBatteryMoveTo + 30;
  2093. break;
  2094. case Keyboard.LEFT:
  2095. myBatteryMoveTo = myBatteryMoveTo - 30;
  2096. break;
  2097. }
  2098. }
  2099. public function hitMotion(isMySide:Boolean):void {
  2100. var hitMotion:HitMotion = new HitMotion();
  2101. this.addChild( hitMotion );
  2102. if ( isMySide ) {
  2103. hitMotion.y = 40;
  2104. } else {
  2105. hitMotion.y = 340;
  2106. this.addEventListener(Event.ENTER_FRAME, onHitEnterFrame);
  2107. }
  2108. }
  2109. protected function onHitEnterFrame(e:Event):void {
  2110. if ( this.x == 0 ) {
  2111. this.x = -5 + 10 * Math.random();
  2112. this.y = -5 + 10 * Math.random();
  2113. } else {
  2114. this.x = this.y = 0;
  2115. this.removeEventListener(Event.ENTER_FRAME, onHitEnterFrame);
  2116. }
  2117. }
  2118. public function putChatMessage(msg:String):void {
  2119. var chatItem:ChatItem = new ChatItem(msg);
  2120. chatUI.addChild( chatItem );
  2121. var count:int = chatUI.numChildren;
  2122. for ( var i:int = 0; i < count; i++ ){
  2123. chatUI.getChildAt(i).y -= chatItem.height;
  2124. }
  2125. }
  2126. protected var endEffect:Sprite = new Sprite();
  2127. protected var mySideWon:Boolean;
  2128. public function end(isVictory:Boolean):void {
  2129. mySideWon = isVictory;
  2130. this.stage.removeEventListener(KeyboardEvent.KEY_DOWN, onShortcutKeyDown);
  2131. this.addEventListener( Event.ENTER_FRAME, onEndEnterFrame);
  2132. this.addChild( endEffect );
  2133. endEffect.graphics.clear();
  2134. endEffect.scaleX = 1.0;
  2135. endEffect.scaleY = 1.0;
  2136. if ( isVictory ) {
  2137. endEffect.graphics.lineStyle(8, 0xFFFFFF);
  2138. endEffect.x = 230;
  2139. endEffect.y = 20;
  2140. } else {
  2141. endEffect.graphics.lineStyle(8, 0xFFCCCC);
  2142. endEffect.x = 230;
  2143. endEffect.y = 360;
  2144. }
  2145. endEffect.graphics.moveTo( -400, 0);
  2146. endEffect.graphics.lineTo( 400, 0);
  2147. endEffect.graphics.moveTo( 0, -400);
  2148. endEffect.graphics.lineTo( 0, 400);
  2149. endEffect.alpha = 1.5;
  2150. firstFlg = true;
  2151. }
  2152. protected var firstFlg:Boolean;
  2153. protected function onEndEnterFrame(e:Event):void {
  2154. endEffect.scaleX *= 1.1;
  2155. endEffect.scaleY *= 1.1;
  2156. endEffect.alpha *= 0.99;
  2157. if ( endEffect.alpha < 1.0 && firstFlg ) {
  2158. clearLoserAndMissiles();
  2159. firstFlg = false;
  2160. }
  2161. if ( endEffect.alpha < 0.3 ) {
  2162. this.removeChild(endEffect);
  2163. this.removeEventListener( Event.ENTER_FRAME, onEndEnterFrame );
  2164. onEnd();
  2165. }
  2166. }
  2167. protected function onEnd():void{
  2168. this.removeEventListener( Event.ENTER_FRAME, onEnterFrame);
  2169. dispatchEvent(new GameEvent(GameEvent.END_GAME, true));
  2170. }
  2171. public function setBatteryAngle(client:IClient, angle:Number):void {
  2172. if ( batteryList[client.getClientID()] == undefined ) return;
  2173. batteryList[client.getClientID()].setAngle(angle);
  2174. }
  2175. protected function onMissileDamage(e:GameEvent):void { // 未使用だったり
  2176. for ( var i:int = 0; i < bulletList.length; i++ ) {
  2177. var bullet:Bullet = bulletList[i];
  2178. if ( e.target == bullet ) {
  2179. bulletList.splice(i, 1);
  2180. bullet.parent.removeChild(bullet);
  2181. break;
  2182. }
  2183. }
  2184. }
  2185. public function destroy(destroyer:IClient, missileClientId:String, missileId:int):void {
  2186. for ( var i:int = 0; i < _missileList.length; i++ ) {
  2187. var missile:Missile = _missileList[i];
  2188. if ( missile.client.getClientID() == missileClientId && missile.id == missileId ) {
  2189. var p:Point = effectSp.globalToLocal(missile.localToGlobal(new Point(0, 0)));
  2190. effectSp.missileDestroy(p);
  2191. missile.destroiedMotion();
  2192. _missileList.splice(i, 1);
  2193. break;
  2194. }
  2195. }
  2196. }
  2197. protected var clientsForcusList:Object = { }; // [clientID] = Misslie
  2198. protected var focus:Missile = null;
  2199. public function addBullet(shooter:IClient, target:IClient, missileId:int, shootTime:Number, bulletSpeed:Number, isMySide:Boolean, isDestroy:Boolean):void {
  2200. var count:int = _missileList.length;
  2201. for ( var i:int = 0; i < count; i++ ) {
  2202. var missile:Missile = _missileList[i];
  2203. if ( missile.client == target && missile.id == missileId ) {
  2204. if ( isMySide ) {
  2205. if( !isDestroy ){
  2206. clientsForcusList[shooter.getClientID()] = missile;
  2207. } else {
  2208. clientsForcusList[shooter.getClientID()] = null;
  2209. }
  2210. }
  2211. var bullet:Bullet = new Bullet(missile, bulletSpeed, 425 - Number(shooter.getAttribute(Score.myGameRoom, Constants.BATTERY_X)), -Constants.BATTERY_DEFAULT_Y, shootTime, isDestroy );
  2212. if ( shooter.isSelf() ) { shooter.setAttribute(Constants.ANGLE, bullet.getAngle(), Score.myGameRoom) };
  2213. if ( cpu != null && ClientUtil.isCPU(shooter) ) batteryList["0"].setAngle(bullet.getAngle());
  2214. var bulletLayer:Sprite = (isMySide?myMissiles:enemyMissiles);
  2215. bulletLayer.addChild( bullet );
  2216. bulletList.push(bullet);
  2217. break;
  2218. }
  2219. }
  2220. }
  2221. protected var focusIndex:int = -1;
  2222. protected function changeFocus(isShiftKeyDown:Boolean):void {
  2223. if ( focus != null ) {
  2224. focus.reset();
  2225. focus = null;
  2226. }
  2227. var count:int = _missileList.length;
  2228. if ( count == 0 ) return;
  2229. for ( var i:int = 0; i < count; i++ ) {
  2230. if ( !Missile(_missileList[i]).isMySide ) break;
  2231. }
  2232. if ( i == count ) return;
  2233. do {
  2234. // focusIndex = ( (focusIndex + (isShiftKeyDown)? -1:1) + count) % count;
  2235. focusIndex += (isShiftKeyDown)? -1:1;
  2236. focusIndex = (focusIndex + count) % count;
  2237. } while ( Missile(_missileList[focusIndex]).isMySide )
  2238. focus = _missileList[focusIndex];
  2239. focus.setFocus();
  2240. var focusParent:DisplayObjectContainer = focus.parent;
  2241. if ( focusParent != null ) {
  2242. focusParent.addChild( focus );
  2243. }
  2244. }
  2245. protected var isPerfect:Boolean = true;
  2246. protected function onDefenceKeyDown(e:GameEvent):void {
  2247. var keyCode:int = int(e.data);
  2248. var char:String = String.fromCharCode(keyCode).toLowerCase();
  2249. if ( focus != null && focus.parent == null ) {
  2250. focus = null;
  2251. }
  2252. if ( focus != null ) {
  2253. if ( focus.parent != null ) {
  2254. if ( keyCode == Keyboard.ESCAPE ) {
  2255. focus.reset();
  2256. focus = null;
  2257. return;
  2258. }
  2259. var result:int = focus.tryType(char);
  2260. switch( result ) {
  2261. case Constants.RESULT_SUCCESS:
  2262. Score.type++;
  2263. Score.correct++;
  2264. if ( cpu != null ) {
  2265. LogAnalyzer.addDefenceLog(1);
  2266. addBullet(cpu.self, cpu, focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, true, false);
  2267. var sch:SoundChannel = SoundManager.TypeSound.play();
  2268. if( sch != null ) sch.soundTransform = new SoundTransform(0.5);
  2269. } else {
  2270. dispatchEvent( new GameEvent(GameEvent.SHOOT, false, false, focus.client.getClientID() + "-" + focus.id + "-0") );
  2271. }
  2272. break;
  2273. case Constants.RESULT_FAULT:
  2274. Score.type++;
  2275. if ( (Score.defenceCombo >= Constants.DEFENCE_COMBO_START) ) {
  2276. dispatchEvent( new GameEvent(GameEvent.DEFENCE_COMBO_END) );
  2277. }
  2278. Score.defenceCombo = 0;
  2279. isPerfect = false;
  2280. break;
  2281. case Constants.RESULT_DESTROY:
  2282. Score.type++;
  2283. Score.correct++;
  2284. Score.defence++;
  2285. if ( isPerfect ) Score.defenceCombo++;
  2286. if ( (Score.defenceCombo == Constants.DEFENCE_COMBO_START) ) {
  2287. dispatchEvent( new GameEvent(GameEvent.DEFENCE_COMBO_START) );
  2288. SoundManager.ComboSound.play();
  2289. }
  2290. if ( cpu != null ) {
  2291. LogAnalyzer.addDefenceLog(1);
  2292. addBullet(cpu.self, cpu, focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, true, true);
  2293. sch = SoundManager.TypeSound.play();
  2294. if( sch != null ) sch.soundTransform = new SoundTransform(0.5);
  2295. } else {
  2296. dispatchEvent( new GameEvent(GameEvent.SHOOT, false, false, focus.client.getClientID() + "-" + focus.id + "-1") ); // 破壊フラグk
  2297. }
  2298. if ( Score.getDefenceBonusRate() > (Math.random()*100) ) {
  2299. dispatchEvent( new GameEvent(GameEvent.ATTACK_REFLECT, false, false, focus.word + "-" + focus.power) );
  2300. }
  2301. focus = null;
  2302. break;
  2303. }
  2304. }
  2305. } else {
  2306. var count:int = defenceTargets.firstClaster.length;
  2307. for ( var i:int = 0; i < count; i++ ) {
  2308. if ( Missile(defenceTargets.firstClaster[i]).tryStart(char) ) {
  2309. Score.correct++;
  2310. focus = defenceTargets.firstClaster[i];
  2311. var focusParent:DisplayObjectContainer = focus.parent;
  2312. if ( focusParent != null ) {
  2313. focusParent.addChild( focus );
  2314. }
  2315. if ( cpu != null ) {
  2316. addBullet(cpu.self, cpu, focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, true, false);
  2317. LogAnalyzer.addDefenceLog(1);
  2318. sch = SoundManager.TypeSound.play();
  2319. if( sch != null ) sch.soundTransform = new SoundTransform(0.5);
  2320. } else {
  2321. dispatchEvent( new GameEvent(GameEvent.SHOOT, false, false, focus.client.getClientID() + "-" + focus.id + "-0") );
  2322. }
  2323. break;
  2324. }
  2325. }
  2326. if( i == count ){
  2327. count = defenceTargets.secondClaster.length;
  2328. for ( i = 0; i < count; i++ ) {
  2329. if ( Missile(defenceTargets.secondClaster[i]).tryStart(char) ) {
  2330. Score.correct++;
  2331. focus = defenceTargets.secondClaster[i];
  2332. focusParent = focus.parent;
  2333. if ( focusParent != null ) {
  2334. focusParent.addChild( focus );
  2335. }
  2336. if ( cpu != null ) {
  2337. addBullet(cpu.self, cpu, focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, true, false);
  2338. LogAnalyzer.addDefenceLog(1);
  2339. } else {
  2340. dispatchEvent( new GameEvent(GameEvent.SHOOT, false, false, focus.client.getClientID() + "-" + focus.id + "-0") );
  2341. }
  2342. break;
  2343. }
  2344. }
  2345. }
  2346. if( i == count ){
  2347. count = defenceTargets.thirdClaster.length;
  2348. for ( i = 0; i < count; i++ ) {
  2349. if ( Missile(defenceTargets.thirdClaster[i]).tryStart(char) ) {
  2350. Score.correct++;
  2351. focus = defenceTargets.thirdClaster[i];
  2352. focusParent = focus.parent;
  2353. if ( focusParent != null ) {
  2354. focusParent.addChild( focus );
  2355. }
  2356. if ( cpu != null ) {
  2357. addBullet(cpu.self, cpu, focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, true, false);
  2358. LogAnalyzer.addDefenceLog(1);
  2359. } else {
  2360. dispatchEvent( new GameEvent(GameEvent.SHOOT, false, false, focus.client.getClientID() + "-" + focus.id + "-0") );
  2361. }
  2362. break;
  2363. }
  2364. }
  2365. }
  2366. if ( focus != null ) {
  2367. Score.type++;
  2368. isPerfect = true;
  2369. }
  2370. }
  2371. }
  2372. // クライアント退室時にミサイルと砲台を除去
  2373. public function removeMissilesOf(client:IClient):void {
  2374. var count:int = _missileList.length;
  2375. var removeList:Array = [];
  2376. for ( var i:int = 0; i < count; i++ ) {
  2377. if ( Missile(_missileList[i]).client == client ) {
  2378. removeList.unshift(i);
  2379. }
  2380. }
  2381. for ( i = 0; i < removeList.length; i++ ) {
  2382. _missileList[removeList[i]].parent.removeChild( _missileList[removeList[i]] );
  2383. _missileList.splice(removeList[i], 1);
  2384. }
  2385. if ( batteryList[client.getClientID()] != undefined ) {
  2386. batteryList[client.getClientID()].parent.removeChild(batteryList[client.getClientID()]);
  2387. }
  2388. }
  2389. public function sendLogTo(client:IClient):void {
  2390. var count:int = _missileList.length;
  2391. for ( var i:int = 0; i < count; i++ ) {
  2392. var missile:Missile = Missile(_missileList[i]);
  2393. if ( missile.isSelf ) {
  2394. client.sendMessage(Constants.ATTACK_LOG, missile.text, missile.id, missile.power, missile.attackTime, missile.arriveTime, missile.x);
  2395. }
  2396. }
  2397. }
  2398. protected function onEnterFrame(e:Event):void {
  2399. if( cpu != null ) cpu.missiles = _missileList;
  2400. var count:int = _missileList.length;
  2401. var removeList:Array = [];
  2402. var nowTime:Number = ServerClockUtil.getTime();
  2403. for ( var i:int = 0; i < count; i++ ) {
  2404. var missile:Missile = _missileList[i];
  2405. missile.update( nowTime );
  2406. if ( missile.y > 300 ) {
  2407. removeList.unshift(i);
  2408. if ( missile.isSelf ) {
  2409. dispatchEvent(new GameEvent(GameEvent.HIT, false, false, String(missile.id)+"-"+String(missile.power)) );
  2410. } else if ( cpu && ClientUtil.isCPU(missile.client) ) {
  2411. dispatchEvent(new GameEvent(GameEvent.HIT, false, false, String(missile.id)+"-cpu") );
  2412. }
  2413. }
  2414. }
  2415. for ( i = 0; i < removeList.length; i++ ) {
  2416. _missileList[removeList[i]].parent.removeChild( _missileList[removeList[i]] );
  2417. _missileList.splice(removeList[i], 1);
  2418. }
  2419. var bcount:int = bulletList.length;
  2420. // for ( i = 0; i < bcount; i++ ) {
  2421. for ( i = bulletList.length-1; i >= 0; i-- ) {
  2422. if ( bulletList[i].update( nowTime ) ) {
  2423. bulletList[i].parent.removeChild(bulletList[i]);
  2424. bulletList.splice(i, 1);
  2425. }
  2426. }
  2427. defenceTargets.updateTopFocus();
  2428. operationUI.setDefenceText(defenceTargets.getDefenceText());
  2429. }
  2430. public function addAttack(client:IClient, text:String, isMySide:Boolean, id:int, power:Number, arriveTime:Number, xpos:Number, isReflect:Boolean = false):void {
  2431. var missile:Missile = new Missile(client, ServerClockUtil.getTime(), arriveTime, id, power, client.isSelf());
  2432. var target:Sprite = (isMySide?myMissiles:enemyMissiles);
  2433. target.addChildAt( missile, 0 );
  2434. missile.x = xpos;
  2435. _missileList.push(missile);
  2436. missile.setText( text, isMySide );
  2437. if( batteryList[client.getClientID()] != undefined ) {
  2438. if ( isReflect ) {
  2439. Battery(batteryList[client.getClientID()]).reflectMotion();
  2440. } else {
  2441. Battery(batteryList[client.getClientID()]).attackMotion();
  2442. }
  2443. }
  2444. }
  2445. // addAttackと統一しても問題ないとは思う・・
  2446. public function addAttackLog(client:IClient, text:String, isMySide:Boolean, id:int, power:Number,attackTime:Number, arriveTime:Number, xpos:Number):void {
  2447. var missile:Missile = new Missile(client, attackTime, arriveTime, id, power, client.isSelf());
  2448. var target:Sprite = (isMySide?myMissiles:enemyMissiles);
  2449. target.addChildAt( missile, 0 );
  2450. missile.x = xpos;
  2451. _missileList.push(missile);
  2452. missile.setText( text, isMySide );
  2453. }
  2454. protected function onMoveClick(e:MouseEvent):void {
  2455. myBatteryMoveTo = moveUI.mouseX;
  2456. }
  2457. // 砲台設置など
  2458. public function setBattery(client:IClient, position:Number, isMySide:Boolean):void {
  2459. if ( client.isSelf() ){ _myBatteryMoveTo = position; defenceTargets.x = position }
  2460. if ( batteryList[client.getClientID()] == undefined ) { // 未設置
  2461. var battery:Battery = new Battery(isMySide, ClientUtil.getBaseLevel(client), ClientUtil.getColor(client), ClientUtil.getBaseColor(client));
  2462. battery.updateCombo( "attackCombo", String(client.getAttribute("", "attackCombo")) == "true" );
  2463. battery.updateCombo( "defenceCombo", String(client.getAttribute("", "defenceCombo")) == "true" );
  2464. // battery.draw(ClientUtil.getBaseLevel(client), ClientUtil.getColor(client), ClientUtil.getBaseColor(client));
  2465. battery.setName( ClientUtil.getUserName(client) );
  2466. batteryList[client.getClientID()] = battery;
  2467. (isMySide?operationBG:enemyBG).addChild( battery );
  2468. battery.x = (isMySide?position:(Constants.STAGE_WIDTH - position));
  2469. battery.y = Constants.BATTERY_DEFAULT_Y;
  2470. battery.setMode( client.getAttribute("", Constants.PLAY_MODE));
  2471. } else {
  2472. battery = batteryList[client.getClientID()];
  2473. (isMySide?operationBG:enemyBG).addChild( battery );
  2474. battery.setSide(isMySide);
  2475. battery.x = (isMySide?position:(Constants.STAGE_WIDTH - position));
  2476. }
  2477. // 設置完了
  2478. }
  2479. protected function drawBG():void {
  2480. bgGrid.graphics.lineStyle(0, 0x00FF00, 0.5);
  2481. for ( var i:int = 0; i <= Constants.STAGE_WIDTH/30; i++ ) {
  2482. bgGrid.graphics.moveTo( 7 + 30 * i, 0 );
  2483. bgGrid.graphics.lineTo( 7 + 30 * i, Constants.STAGE_HEIGHT );
  2484. bgGrid.graphics.moveTo( 0, 7 + 30 * i );
  2485. bgGrid.graphics.lineTo( Constants.STAGE_WIDTH, 7 + 30 * i );
  2486. }
  2487. setup( Constants.TEAM_NONE );
  2488. }
  2489. protected function drawOperationBG(color:uint):void {
  2490. operationBG.graphics.clear();
  2491. operationBG.graphics.beginGradientFill("linear", [color, color], [1.0, 0.0], [0, 255], new Matrix(0, -0.1, 0.1, 0, 0, 50));
  2492. operationBG.graphics.drawRect( 0, 0, Constants.STAGE_WIDTH, 125);
  2493. operationBG.graphics.lineStyle(2, 0xFFFFFF);
  2494. operationBG.graphics.moveTo(0, 0);
  2495. operationBG.graphics.lineTo(Constants.STAGE_WIDTH, 0);
  2496. operationBG.graphics.moveTo(0, 40);
  2497. operationBG.graphics.lineTo(Constants.STAGE_WIDTH, 40);
  2498. }
  2499. public function setDamage(mySide:int, enemySide:int):void {
  2500. operationBG.graphics.lineStyle(2, 0xFF0000 | (0x101 * int(255 - 255 * (mySide / Constants.VICTORY_POINT))));
  2501. enemyBG.graphics.lineStyle(2, 0xFF0000 | (0x101 * int(255 - 255 * (enemySide / Constants.VICTORY_POINT))));
  2502. operationBG.graphics.moveTo(0, 0);
  2503. operationBG.graphics.lineTo(Constants.STAGE_WIDTH, 0);
  2504. enemyBG.graphics.moveTo(0, 40);
  2505. enemyBG.graphics.lineTo(Constants.STAGE_WIDTH, 40);
  2506. }
  2507. protected function drawEnemyBG(color:uint):void {
  2508. enemyBG.graphics.clear();
  2509. enemyBG.graphics.beginGradientFill("linear", [color, color], [1.0, 0.0], [0, 255], new Matrix(0, 0.1, -0.1, 0, 0, -10));
  2510. enemyBG.graphics.drawRect(0, 0, Constants.STAGE_WIDTH, 40);
  2511. enemyBG.graphics.lineStyle(2, 0xFFFFFF);
  2512. enemyBG.graphics.moveTo(0, 40);
  2513. enemyBG.graphics.lineTo(Constants.STAGE_WIDTH, 40);
  2514. }
  2515. protected var _chatInputMode:Boolean = false;
  2516. protected function onChatKeyUp(e:KeyboardEvent):void {
  2517. if ( e.keyCode == Keyboard.ENTER ) {
  2518. var arr:Array = chatInputBar.text.split("\r");
  2519. if ( arr.length >= 2 ) {
  2520. /*
  2521. if ( chatInputBar.text == "\r" ) {
  2522. chatInputMode = false;
  2523. operationUI.setFocus();
  2524. return;
  2525. }
  2526. */
  2527. chatInputMode = false;
  2528. operationUI.setFocus();
  2529. dispatchEvent(new GameEvent(GameEvent.CHAT, false, false, arr.join("")));
  2530. chatInputBar.text = "";
  2531. }
  2532. }
  2533. }
  2534. protected function onChatKeyDown(e:KeyboardEvent):void {
  2535. if ( e.keyCode == Keyboard.LEFT || e.keyCode == Keyboard.RIGHT ) {
  2536. e.stopPropagation();
  2537. }
  2538. }
  2539. // チームに入ってゲーム開始
  2540. public function setup(team:String):void {
  2541. var operationBGColor:uint;
  2542. var enemyBGColor:uint;
  2543. operationUI.reset();
  2544. if ( team == Constants.TEAM_BLUE ) {
  2545. operationUI.setup();
  2546. operationBGColor = 0x0000AA;
  2547. enemyBGColor = 0x990000;
  2548. // operationUI.setMode(Constants.PLAY_MODE_DEFENDER); // デフォルトで防御モード
  2549. this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onShortcutKeyDown);
  2550. this.addEventListener( Event.ENTER_FRAME, onEnterFrame );
  2551. } else if ( team == Constants.TEAM_RED ) {
  2552. operationUI.setup();
  2553. operationBGColor = 0x990000;
  2554. enemyBGColor = 0x0000AA;
  2555. // operationUI.setMode(Constants.PLAY_MODE_ATTACKER); // デフォルトで攻撃モード
  2556. this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onShortcutKeyDown);
  2557. this.addEventListener( Event.ENTER_FRAME, onEnterFrame );
  2558. } else if ( team == Constants.TEAM_NONE ) {
  2559. operationBGColor = 0x666666;
  2560. enemyBGColor = 0x666666;
  2561. operationUI.setMode("");
  2562. if ( this.stage != null ) {
  2563. this.stage.removeEventListener( KeyboardEvent.KEY_DOWN, onShortcutKeyDown );
  2564. }
  2565. }
  2566. drawOperationBG(operationBGColor);
  2567. drawEnemyBG(enemyBGColor);
  2568. enable = false;
  2569. }
  2570. protected var _enable:Boolean = false;
  2571. public function get enable():Boolean { return _enable; }
  2572. public function set enable(value:Boolean ):void {
  2573. if ( !_enable && value ) {
  2574. bg.setFilter(1);
  2575. var temp:TextField = new TextField();
  2576. temp.defaultTextFormat = new TextFormat("Arial", 60, 0xFFFF00, true);
  2577. temp.text = "START";
  2578. temp.autoSize = "left";
  2579. bg.bitmapData.draw(temp, new Matrix(1, 0, 0, 1, 232 - 0.5 * temp.textWidth, 130));
  2580. if( cpu != null ){
  2581. cpu.start();
  2582. cpu.addEventListener(GameEvent.ATTACK, onCPUAttack);
  2583. cpu.addEventListener(GameEvent.SHOOT, onCPUShoot);
  2584. }
  2585. } else if ( _enable && !value ) {
  2586. if( cpu != null ){
  2587. cpu.disable();
  2588. cpu.removeEventListener(GameEvent.ATTACK, onCPUAttack);
  2589. cpu.removeEventListener(GameEvent.SHOOT, onCPUShoot);
  2590. }
  2591. }
  2592. _enable = value;
  2593. this.mouseChildren = value;
  2594. this.operationUI.visible = value;
  2595. if( value ){
  2596. this.stage.addEventListener(KeyboardEvent.KEY_DOWN, onShortcutKeyDown);
  2597. this.addEventListener( GameEvent.MISSILE_DAMAGE, onMissileDamage );
  2598. } else {
  2599. this.removeEventListener( GameEvent.MISSILE_DAMAGE, onMissileDamage );
  2600. }
  2601. }
  2602. // 一人用
  2603. protected function onCPUAttack(e:GameEvent):void {
  2604. SoundManager.AttackSound.play();
  2605. batteryList["0"].setMode(Constants.PLAY_MODE_ATTACKER);
  2606. addAttack(cpu, e.data, false, cpu.attackid, 1, ServerClockUtil.getTime()+Constants.MISSILE_ARRIVE_TIME, -62+80*Math.random()+Number(cpu.getAttribute("",Constants.BATTERY_X)));
  2607. }
  2608. protected function onCPUShoot(e:GameEvent):void {
  2609. batteryList["0"].setMode(Constants.PLAY_MODE_DEFENDER);
  2610. addBullet(cpu, cpu.self, cpu.focus.id, ServerClockUtil.getTime(), Constants.BULLET_SPEED, false, (e.data=="1"));
  2611. }
  2612. public function get myBatteryMoveTo():Number { return _myBatteryMoveTo; }
  2613. public function set myBatteryMoveTo(value:Number):void
  2614. {
  2615. if ( value < 22 ) value = 22;
  2616. if ( value > 442 ) value = 442;
  2617. _myBatteryMoveTo = value;
  2618. dispatchEvent( new GameEvent(GameEvent.MOVE_BATTERY) );
  2619. }
  2620. public function get chatInputMode():Boolean { return _chatInputMode; }
  2621. public function set chatInputMode(value:Boolean):void
  2622. {
  2623. if ( _chatInputMode == false && value == true ) {
  2624. chatInputBar.visible = true;
  2625. } else if( !value ) {
  2626. chatInputBar.visible = false;
  2627. }
  2628. if ( value ) {
  2629. stage.focus = chatInputBar;
  2630. if ( Capabilities.hasIME ) {
  2631. try {
  2632. IME.enabled = true;
  2633. } catch(e:*){}
  2634. }
  2635. }
  2636. _chatInputMode = value;
  2637. }
  2638. }
  2639. class ColorSettingPanel extends Sprite {
  2640. protected var colorTable:Array = [
  2641. 0x888888, 0xAA8888, 0x88AA88, 0x8888AA, 0x88AAAA, 0xAA88AA, 0xAAAA88, 0x666666, 0xAA6666, 0x66AA66,
  2642. 0x6666AA, 0x226666, 0x662266, 0x666622, 0xCC2222, 0x22CC22, 0x2222CC, 0x22CCCC, 0xCC22CC, 0xCCCC22
  2643. ];
  2644. protected var bg:Sprite = new Sprite;
  2645. protected var colors:Sprite = new Sprite;
  2646. public function ColorSettingPanel() {
  2647. bg.mouseEnabled = false;
  2648. this.addChild( colors );
  2649. this.addChild( bg );
  2650. colors.addEventListener(MouseEvent.CLICK, onClick);
  2651. colors.buttonMode = true;
  2652. }
  2653. public function setLevel(level:int):void {
  2654. if ( level > colorTable.length ) level = colorTable.length;
  2655. bg.graphics.clear();
  2656. colors.graphics.clear();
  2657. for ( var i:int = 0; i
  2658. bg.graphics.lineStyle( 0, 0xFFFFFF );
  2659. bg.graphics.drawRect( 27 * (i % 10), 28 * int(i / 10), 16, 16);
  2660. colors.graphics.beginFill( colorTable[i] );
  2661. colors.graphics.drawRect( 27 * (i % 10), 28 * int(i / 10), 16, 16);
  2662. }
  2663. for ( ; i < 20; i++ ) { // 20: max level
  2664. bg.graphics.lineStyle(0, 0xFFFFFF, 0.25);
  2665. bg.graphics.drawRect( 27 * (i % 10), 28 * int(i / 10), 16, 16);
  2666. }
  2667. }
  2668. protected function onClick(e:MouseEvent):void {
  2669. var index:int = 10 * int(e.localY / 28) + int(e.localX / 27);
  2670. dispatchEvent(new GameEvent("color", false, false, index + "-" + colorTable[index]) );
  2671. }
  2672. }
  2673. // 設定ウィンドウ
  2674. class OptionWindow extends Sprite {
  2675. protected var attackTF:TextField = new TextField();
  2676. protected var defenceTF:TextField = new TextField();
  2677. protected var titleTF:TextField = new TextField();
  2678. protected var baseColorTF:TextField = new TextField();
  2679. protected var colorTF:TextField = new TextField();
  2680. protected var handicapTitleTF:TextField = new TextField();
  2681. protected var handicapTF:TextField = new TextField();
  2682. protected var nameTF:TextField = new TextField();
  2683. protected var nameChangeTF:TextField = new TextField();
  2684. protected var languageTF:TextField = new TextField();
  2685. protected var attackBattery:Battery = new Battery( true, 0, 0, 0);
  2686. protected var defenceBattery:Battery = new Battery( true, 0, 0, 0);
  2687. protected var baseColorPanel:ColorSettingPanel = new ColorSettingPanel();
  2688. protected var colorPanel:ColorSettingPanel = new ColorSettingPanel();
  2689. protected var closeBtn:Button = new Button(100, 20, "閉じる", true, false, 0x888888);
  2690. protected var normalBtn:Button = new Button(100, 20, "NO HANDICAP", true, true, 0x0);
  2691. protected var hardBtn:Button = new Button(100, 20, "DOUBLE WORD", true, false, 0x0);
  2692. protected var veryHardBtn:Button = new Button(100, 20, "TRIPLE WORD", true, false, 0x0);
  2693. protected var EngBtn:Button = new Button(90, 20, "英語のみ", true, false, 0x0);
  2694. protected var BothBtn:Button = new Button(80, 20, "日英両方", true, false, 0x0);
  2695. protected var JpnBtn:Button = new Button(80, 20, "日本語のみ", true, false, 0x0);
  2696. public function OptionWindow() {
  2697. this.graphics.beginFill(0x0, 0.5);
  2698. this.graphics.drawRect( -this.x, -this.y, Constants.STAGE_WIDTH, Constants.STAGE_HEIGHT);
  2699. this.graphics.endFill();
  2700. this.graphics.beginFill(0x888888, 0.90);
  2701. this.graphics.lineStyle(2, 0xFFFFFF);
  2702. this.graphics.drawRoundRect(0, 0, 425, 330, 10);
  2703. this.graphics.lineStyle(1, 0xFFFFFF);
  2704. this.graphics.beginFill(0x0);
  2705. this.graphics.drawRoundRect(15, 80, 275, 33, 10);
  2706. this.graphics.drawRoundRect(15, 140, 275, 58, 10);
  2707. this.graphics.drawRoundRect(15, 225, 275, 58, 10);
  2708. // this.graphics.drawRoundRect(310, 170, 100, 113, 10);
  2709. this.graphics.moveTo(300, 10);
  2710. this.graphics.lineTo(300, 50);
  2711. this.graphics.moveTo(15, 55);
  2712. this.graphics.lineTo(410, 55);
  2713. // this.graphics.moveTo(300, 60);
  2714. // this.graphics.lineTo(300, 283);
  2715. baseColorPanel.x = 22;
  2716. baseColorPanel.y = 147;
  2717. colorPanel.x = 22;
  2718. colorPanel.y = 232;
  2719. TextFieldUtil.setupNoBorder(attackTF, false);
  2720. TextFieldUtil.setupNoBorder(defenceTF, false);
  2721. TextFieldUtil.setupNoBorder(titleTF, false);
  2722. TextFieldUtil.setupNoBorder(baseColorTF, false);
  2723. TextFieldUtil.setupNoBorder(colorTF, false);
  2724. TextFieldUtil.setupNoBorder(handicapTitleTF, false);
  2725. TextFieldUtil.setupNoBorder(handicapTF, false);
  2726. TextFieldUtil.setupNoBorder(nameTF, false);
  2727. TextFieldUtil.setupNoBorder(languageTF, false);
  2728. TextFieldUtil.setupBorder(nameChangeTF);
  2729. attackTF.text = "攻撃モード";
  2730. defenceTF.text = "防御モード";
  2731. titleTF.text = "砲台カラー設定";
  2732. baseColorTF.text = "カラー設定1";
  2733. colorTF.text = "カラー設定2";
  2734. handicapTitleTF.text = "HANDICAP SETTING";
  2735. nameTF.text = "あなたの名前";
  2736. languageTF.text = "攻撃用言語設定";
  2737. nameChangeTF.type = "input";
  2738. nameChangeTF.text = String(LocalData.read(Constants.LD_FIELD, Constants.USER_NAME));
  2739. this.addChild(titleTF);
  2740. this.addChild(baseColorTF);
  2741. this.addChild(colorTF);
  2742. this.addChild(nameTF);
  2743. this.addChild(nameChangeTF);
  2744. this.addChild(languageTF);
  2745. this.addChild(EngBtn);
  2746. this.addChild(BothBtn);
  2747. this.addChild(JpnBtn);
  2748. // this.addChild(handicapTF);
  2749. // this.addChild(handicapTitleTF);
  2750. this.addChild(attackTF);
  2751. this.addChild(defenceTF);
  2752. this.addChild(attackBattery);
  2753. this.addChild(defenceBattery);
  2754. this.addChild(closeBtn);
  2755. // this.addChild(normalBtn);
  2756. // this.addChild(hardBtn);
  2757. // this.addChild(veryHardBtn);
  2758. nameTF.x = 310;
  2759. nameTF.y = 7;
  2760. nameChangeTF.x = 310;
  2761. nameChangeTF.y = 27;
  2762. nameChangeTF.width = 100;
  2763. nameChangeTF.height = 20;
  2764. languageTF.x = 15;
  2765. languageTF.y = 7;
  2766. EngBtn.x = 15;
  2767. BothBtn.x = 115;
  2768. JpnBtn.x = 205;
  2769. EngBtn.y = BothBtn.y = JpnBtn.y = 27;
  2770. // handicapTitleTF.x = 310;
  2771. // handicapTitleTF.y = 60;
  2772. // handicapTF.x = 315;
  2773. // handicapTF.y = 175;
  2774. // handicapTF.width = 90;
  2775. // handicapTF.wordWrap = true;
  2776. // normalBtn.x = 310;
  2777. // normalBtn.y = 80;
  2778. // hardBtn.x = 310;
  2779. // hardBtn.y = 110;
  2780. // veryHardBtn.x = 310;
  2781. // veryHardBtn.y = 140;
  2782. titleTF.x = 15;
  2783. titleTF.y = 60;
  2784. baseColorTF.x = 15;
  2785. baseColorTF.y = 120;
  2786. colorTF.x = 15;
  2787. colorTF.y = 205;
  2788. attackTF.x = 20;
  2789. attackTF.y = 90;
  2790. defenceTF.x = 175;
  2791. defenceTF.y = 90;
  2792. attackBattery.x = 110;
  2793. attackBattery.y = 95;
  2794. defenceBattery.x = 265;
  2795. defenceBattery.y = 98;
  2796. closeBtn.x = 170;
  2797. closeBtn.y = 300;
  2798. this.addChild( baseColorPanel );
  2799. this.addChild( colorPanel );
  2800. attackBattery.setMode(Constants.PLAY_MODE_ATTACKER);
  2801. defenceBattery.setMode(Constants.PLAY_MODE_DEFENDER);
  2802. closeBtn.addEventListener(MouseEvent.CLICK, onClick);
  2803. EngBtn.addEventListener(MouseEvent.CLICK, onEngClick);
  2804. BothBtn.addEventListener(MouseEvent.CLICK, onBothClick);
  2805. JpnBtn.addEventListener(MouseEvent.CLICK, onJpnClick);
  2806. // normalBtn.addEventListener(MouseEvent.CLICK, onNormalClick);
  2807. // hardBtn.addEventListener(MouseEvent.CLICK, onHardClick);
  2808. // veryHardBtn.addEventListener(MouseEvent.CLICK, onVeryHardClick);
  2809. baseColorPanel.addEventListener("color", onBaseColor);
  2810. colorPanel.addEventListener("color", onColor);
  2811. }
  2812. protected function onEngClick(e:MouseEvent):void {
  2813. Score.japaneseRate = 0;
  2814. setLanguage();
  2815. }
  2816. protected function onBothClick(e:MouseEvent):void {
  2817. Score.japaneseRate = 0.5;
  2818. setLanguage();
  2819. }
  2820. protected function onJpnClick(e:MouseEvent):void {
  2821. Score.japaneseRate = 1.0;
  2822. setLanguage();
  2823. }
  2824. protected function onNormalClick(e:MouseEvent):void {
  2825. dispatchEvent( new GameEvent(GameEvent.HANDICAP_SELECT, true, false, "1") );
  2826. }
  2827. protected function onHardClick(e:MouseEvent):void {
  2828. dispatchEvent( new GameEvent(GameEvent.HANDICAP_SELECT, true, false, "2") );
  2829. }
  2830. protected function onVeryHardClick(e:MouseEvent):void {
  2831. dispatchEvent( new GameEvent(GameEvent.HANDICAP_SELECT, true, false, "3") );
  2832. }
  2833. protected function onBaseColor(e:GameEvent):void {
  2834. dispatchEvent( new GameEvent(GameEvent.COLOR_SELECT, true, false, Constants.USER_BATTERY_BASE_COLOR + "-" + e.data) );
  2835. }
  2836. public function setLanguage():void {
  2837. EngBtn.selected = BothBtn.selected = JpnBtn.selected = false;
  2838. switch( Score.japaneseRate ) {
  2839. case 0:
  2840. EngBtn.selected = true;
  2841. break;
  2842. case 1:
  2843. JpnBtn.selected = true;
  2844. break;
  2845. default:
  2846. BothBtn.selected = true;
  2847. break;
  2848. }
  2849. }
  2850. public function setHandicap():void {
  2851. normalBtn.selected = hardBtn.selected = veryHardBtn.selected = false;
  2852. var str:String = "";
  2853. switch( Score.handicap ) {
  2854. case 1:
  2855. normalBtn.selected = true;
  2856. str= "NO HANDICAP.\n";
  2857. break;
  2858. case 2:
  2859. hardBtn.selected = true;
  2860. str = "YOU HAVE TO TYPE WORDS TWICE TO ATTACK OR DEFENCE.\n";
  2861. break;
  2862. case 3:
  2863. veryHardBtn.selected = true;
  2864. str= "YOU HAVE TO TYPE WORDS THREE TIMES TO ATTACK OR DEFENCE.\n";
  2865. break;
  2866. }
  2867. str +="\nATK:" +int(Score.attackPower / 1000) + "->" +int(Score.attackPower / 1000 / Score.handicap);
  2868. str += "\nDEF:" +int(Score.defencePower / 1000) + "->" +int(Score.defencePower / 1000 / Score.handicap);
  2869. handicapTF.text = str;
  2870. }
  2871. public function setLevel():void {
  2872. baseColorPanel.setLevel(Score.getLevel());
  2873. colorPanel.setLevel(Score.getLevel());
  2874. }
  2875. protected function onColor(e:GameEvent):void {
  2876. dispatchEvent( new GameEvent(GameEvent.COLOR_SELECT, true, false, Constants.USER_BATTERY_COLOR + "-" + e.data) );
  2877. }
  2878. // 砲台の色設定
  2879. public function setColors(baseLevel:int, color:int, baseColor:int):void {
  2880. attackBattery.draw(baseLevel, color, baseColor);
  2881. defenceBattery.draw(baseLevel, color, baseColor);
  2882. }
  2883. protected function onClick(e:MouseEvent):void {
  2884. var oldName:String = String(LocalData.read(Constants.LD_FIELD, Constants.USER_NAME));
  2885. if ( nameChangeTF.text != oldName && nameChangeTF.text != "" ) {
  2886. dispatchEvent(new GameEvent(GameEvent.NAME_CHANGE, true, false, nameChangeTF.text));
  2887. LocalData.write(Constants.LD_FIELD, Constants.USER_NAME, nameChangeTF.text);
  2888. }
  2889. Score.save();
  2890. dispatchEvent(new Event("close"));
  2891. }
  2892. }
  2893. // 情報ウィンドウ
  2894. class InfoUI extends Sprite {
  2895. protected var lobbyUserNumText:TextField = new TextField();
  2896. protected var blueTeamNumText:TextField = new TextField();
  2897. protected var redTeamNumText:TextField = new TextField();
  2898. protected var defaultTextFormat:TextFormat = new TextFormat(TextFieldUtil.getFont(), null, 0xFFFFFF, true);
  2899. protected var blueBtn:Button = new Button(60, 18, "ブルー", true, false, 0x0000FF);
  2900. protected var redBtn:Button = new Button(60, 18, "レッド", true, false, 0xFF0000);
  2901. protected var autoJoinBtn:Button = new Button(100, 40, "自動入室", true, false, 0x999999);
  2902. protected var optionBtn:Button = new Button(80, 20, "設定", true, false, 0x333333);
  2903. protected var tweetBtn:Button = new Button(60, 20, "TWEET", true, false, 0x333333);
  2904. protected var gameRoomTF:TextField = new TextField();
  2905. protected var gameRoomStatusTF:TextField = new TextField();
  2906. protected var normalRoomPanel:Sprite = new Sprite();
  2907. protected var optionWindow:OptionWindow = new OptionWindow();
  2908. protected var chatWindow:ChatWindow;
  2909. protected var soloRoomPanel:Sprite = new Sprite();
  2910. protected var soloBtn:Button = new Button(100, 20, "COM対戦", true, false, 0x999999);
  2911. protected var soloTitle:TextField = new TextField();
  2912. protected var soloInfo:TextField = new TextField();
  2913. protected var blueNum:int;
  2914. protected var redNum:int;
  2915. public function InfoUI() {
  2916. this.graphics.beginFill(0x0, 0.5);
  2917. this.graphics.drawRect( -30, -30, 465, 465);
  2918. this.graphics.endFill();
  2919. this.graphics.beginFill(0x888888, 0.75);
  2920. this.graphics.lineStyle(2, 0xFFFFFF);
  2921. this.graphics.drawRoundRect(0, 0, 405, 415, 10);
  2922. lobbyUserNumText.defaultTextFormat = blueTeamNumText.defaultTextFormat = redTeamNumText.defaultTextFormat = defaultTextFormat;
  2923. lobbyUserNumText.autoSize = blueTeamNumText.autoSize = redTeamNumText.autoSize = "left";
  2924. this.addChild( lobbyUserNumText );
  2925. normalRoomPanel.addChild( blueTeamNumText );
  2926. normalRoomPanel.addChild( redTeamNumText );
  2927. normalRoomPanel.addChild( autoJoinBtn );
  2928. normalRoomPanel.addChild( blueBtn );
  2929. normalRoomPanel.addChild( redBtn );
  2930. normalRoomPanel.addChild( gameRoomTF );
  2931. normalRoomPanel.addChild( gameRoomStatusTF );
  2932. this.addChild( normalRoomPanel );
  2933. soloRoomPanel.addChild( soloTitle );
  2934. soloRoomPanel.addChild( soloBtn );
  2935. soloRoomPanel.addChild( soloInfo );
  2936. this.addChild( soloRoomPanel );
  2937. this.addChild( optionBtn );
  2938. this.addChild( tweetBtn );
  2939. blueBtn.addEventListener(MouseEvent.CLICK, onBlueClick);
  2940. redBtn.addEventListener(MouseEvent.CLICK, onRedClick);
  2941. autoJoinBtn.addEventListener(MouseEvent.CLICK, autoJoinFunc);
  2942. optionBtn.addEventListener(MouseEvent.CLICK, onOptionClick);
  2943. tweetBtn.addEventListener(MouseEvent.CLICK, onTweet);
  2944. soloBtn.addEventListener(MouseEvent.CLICK, onSolo);
  2945. TextFieldUtil.setupNoBorder( gameRoomTF, false );
  2946. TextFieldUtil.setupNoBorder( gameRoomStatusTF, false );
  2947. TextFieldUtil.setupNoBorder( soloTitle, false );
  2948. TextFieldUtil.setupNoBorder( soloInfo, false );
  2949. gameRoomTF.text = "通常ルーム";
  2950. gameRoomTF.y = 2;
  2951. gameRoomStatusTF.y = 20;
  2952. gameRoomStatusTF.defaultTextFormat.bold = true;
  2953. lobbyUserNumText.x = 10; lobbyUserNumText.y = 10;
  2954. tweetBtn.x = 245;
  2955. tweetBtn.y = 10;
  2956. optionBtn.x = 315;
  2957. optionBtn.y = 10;
  2958. optionWindow.x = -10;
  2959. optionWindow.y = 10;
  2960. normalRoomPanel.x = 10;
  2961. normalRoomPanel.y = 335;
  2962. soloRoomPanel.x = 10; soloRoomPanel.y = 387;
  2963. soloTitle.text = "COM対戦ルーム";
  2964. soloTitle.y = 2;
  2965. soloBtn.x = 120; soloBtn.y = 0;
  2966. soloInfo.x = 225; soloInfo.y = 2;
  2967. redTeamNumText.x = 290; redTeamNumText.y = 23;
  2968. blueTeamNumText.x = 290; blueTeamNumText.y = 1;
  2969. autoJoinBtn.x = 120; autoJoinBtn.y = 0;
  2970. blueBtn.x = 225; blueBtn.y = 0;
  2971. redBtn.x = 225; redBtn.y = 22;
  2972. optionWindow.addEventListener("close", onClose);
  2973. }
  2974. public function updateSoloInfo(msg:String):void {
  2975. soloInfo.text = msg;
  2976. }
  2977. public function updateNormalRoomStatus(msg:String):void {
  2978. gameRoomStatusTF.text = msg;
  2979. }
  2980. public function onTweet(e:MouseEvent):void {
  2981. navigateToURL(new URLRequest("http://twitter.com/home/?status="
  2982. + escapeMultiByte("Join and play TypeShoot! http://wonderfl.net/code/bc91e1ddbdf13b313832b95f8eca60c3758a5228"))
  2983. );
  2984. }
  2985. public function updateHandicap():void {
  2986. optionWindow.setHandicap();
  2987. }
  2988. protected function onClose(e:Event):void {
  2989. removeChild(optionWindow);
  2990. }
  2991. protected function onOptionClick(e:MouseEvent):void {
  2992. optionWindow.setLevel();
  2993. optionWindow.setHandicap();
  2994. optionWindow.setLanguage();
  2995. addChild(optionWindow);
  2996. }
  2997. public function fadeOut():void {
  2998. this.mouseEnabled = false;
  2999. this.mouseChildren = false;
  3000. this.addEventListener(Event.ENTER_FRAME, onFadeOutEnterFrame);
  3001. }
  3002. protected function onFadeOutEnterFrame(e:Event):void {
  3003. this.alpha *= 0.9;
  3004. if ( this.alpha < 0.1 ) {
  3005. this.removeEventListener(Event.ENTER_FRAME, onFadeOutEnterFrame);
  3006. this.alpha = 0;
  3007. this.visible = false;
  3008. }
  3009. }
  3010. public function setInfoMessage(msg:String):void {
  3011. chatWindow.setInfoMessage(msg);
  3012. }
  3013. public function setChatRoom(lobby:Room):void {
  3014. chatWindow = new ChatWindow(lobby);
  3015. this.addChild( chatWindow );
  3016. chatWindow.y = 40;
  3017. chatWindow.x = 10;
  3018. }
  3019. public function display():void {
  3020. this.mouseEnabled = true;
  3021. this.mouseChildren = true;
  3022. this.alpha = 1.0;
  3023. this.visible = true;
  3024. if ( this.stage != null ) {
  3025. chatWindow.setFocus(this.stage);
  3026. }
  3027. if ( Score.lastLevel < Score.getLevel() ) {
  3028. chatWindow.setInfoMessage("LV UP! 機体色が増えました!");
  3029. }
  3030. Score.lastLevel = Score.getLevel();
  3031. }
  3032. public function setBatteryColors(baseLevel:int, color:int, baseColor:int):void {
  3033. LocalData.write(Constants.LD_FIELD, Constants.USER_BATTERY_COLOR, String(color));
  3034. LocalData.write(Constants.LD_FIELD, Constants.USER_BATTERY_BASE_COLOR, String(baseColor));
  3035. optionWindow.setColors(baseLevel, color, baseColor );
  3036. }
  3037. public function autoJoinFunc(e:MouseEvent):void {
  3038. this.mouseChildren = false;
  3039. if ( blueNum < redNum ) {
  3040. dispatchEvent(new GameEvent(GameEvent.JOIN_BLUE));
  3041. } else if ( blueNum > redNum ) {
  3042. dispatchEvent(new GameEvent(GameEvent.JOIN_RED));
  3043. } else {
  3044. if ( Math.random() < 0.5 ) {
  3045. dispatchEvent(new GameEvent(GameEvent.JOIN_BLUE));
  3046. } else {
  3047. dispatchEvent(new GameEvent(GameEvent.JOIN_RED));
  3048. }
  3049. }
  3050. }
  3051. public function onSolo(e:MouseEvent):void {
  3052. this.mouseChildren = false;
  3053. dispatchEvent(new GameEvent(GameEvent.JOIN_SOLO));
  3054. }
  3055. public function onBlueClick(e:MouseEvent):void {
  3056. // blueBtn.selected = true;
  3057. this.mouseChildren = false;
  3058. dispatchEvent(new GameEvent(GameEvent.JOIN_BLUE));
  3059. }
  3060. public function onRedClick(e:MouseEvent):void {
  3061. // redBtn.selected = true;
  3062. this.mouseChildren = false;
  3063. dispatchEvent(new GameEvent(GameEvent.JOIN_RED));
  3064. }
  3065. public function setLobbyUserNum(num:int ):void {
  3066. lobbyUserNumText.text = "" + num + " ユーザーが接続中です!";
  3067. }
  3068. public function setBlueTeamInfo(num:int, attack:Number, defence:Number):void {
  3069. blueNum = num;
  3070. blueTeamNumText.text = "参加 " + num + "名" + " ("+int(attack/1000)+"/"+int(defence/1000)+")";
  3071. }
  3072. public function setRedTeamInfo(num:int, attack:Number, defence:Number):void {
  3073. redNum = num;
  3074. redTeamNumText.text = "参加 " + num + "名" + " ("+int(attack/1000)+"/"+int(defence/1000)+")";
  3075. }
  3076. }
  3077. // チャットウィンドウ
  3078. class ChatWindow extends Sprite {
  3079. protected var input:TextField = new TextField();
  3080. protected var coming:TextField = new TextField();
  3081. protected var users:TextField = new TextField();
  3082. protected var lobby:Room;
  3083. public function ChatWindow(lobby:Room) {
  3084. this.lobby = lobby;
  3085. users.border = input.border = coming.border = true;
  3086. users.background = input.background = coming.background = true;
  3087. users.borderColor = input.borderColor = coming.borderColor = 0xFFFFFF;
  3088. users.backgroundColor = input.backgroundColor = coming.backgroundColor = 0x0;
  3089. TextFieldUtil.setupNoBorder(users);
  3090. TextFieldUtil.setupNoBorder(input);
  3091. TextFieldUtil.setupNoBorder(coming);
  3092. // users.defaultTextFormat = input.defaultTextFormat = coming.defaultTextFormat = new TextFormat(null, null, 0xFFFFFF);
  3093. coming.width = 280;
  3094. coming.height = 260;
  3095. coming.wordWrap = true;
  3096. coming.textColor = 0xFFFFFF;
  3097. input.type = "input";
  3098. input.width = 385;
  3099. input.height = 20;
  3100. input.y = 265;
  3101. users.width = 100;
  3102. users.height = 260;
  3103. users.x = 285;
  3104. this.addChild( coming );
  3105. this.addChild( input );
  3106. this.addChild( users );
  3107. var defaultText:String = "";
  3108. defaultText += getNowTimeFormat() + " *** TypeShoot へようこそ! ***\n";
  3109. defaultText += getNowTimeFormat() + " * ver 1.1.2.0\n";
  3110. defaultText += getNowTimeFormat() + " * これはタイピングゲームです。\n";
  3111. defaultText += getNowTimeFormat() + " * 青と赤のチームにわかれ、敵側に\n";
  3112. defaultText += getNowTimeFormat() + " * ミサイルを撃ち込みます。先に\n";
  3113. defaultText += getNowTimeFormat() + " * 敵のライフを0にすると勝利です。\n";
  3114. defaultText += getNowTimeFormat() + " * \n";
  3115. defaultText += getNowTimeFormat() + " * 攻撃モードを選択し、ワードを\n";
  3116. defaultText += getNowTimeFormat() + " * 打ちこむと攻撃できます。選択中の\n";
  3117. defaultText += getNowTimeFormat() + " * ワード入力にはボーナスがあります。\n";
  3118. defaultText += getNowTimeFormat() + " * 防御するには防御モードを選択し、\n";
  3119. defaultText += getNowTimeFormat() + " * 敵ミサイルのワードを撃ちます。\n";
  3120. defaultText += getNowTimeFormat() + " * \n";
  3121. defaultText += getNowTimeFormat() + " * ゲーム中はF1を押すことで\n";
  3122. defaultText += getNowTimeFormat() + " * チームチャットが可能です。\n";
  3123. defaultText += getNowTimeFormat() + " * \n";
  3124. defaultText += getNowTimeFormat() + " * それでは、お楽しみください!\n";
  3125. coming.text = defaultText;
  3126. input.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  3127. lobby.addEventListener(RoomEvent.CLIENT_COUNT, onClientCount);
  3128. lobby.addEventListener(RoomEvent.ADD_CLIENT, onJoin);
  3129. lobby.addEventListener(RoomEvent.REMOVE_CLIENT, onLeave);
  3130. lobby.addEventListener(RoomEvent.UPDATE_CLIENT_ATTRIBUTE, onUpdateClientAttribute);
  3131. lobby.addMessageListener("CHAT_MESSAGE", chatMessageAction);
  3132. }
  3133. public function setFocus(stage:Stage):void {
  3134. stage.focus = input;
  3135. }
  3136. protected function onJoin(e:RoomEvent):void {
  3137. setInfoMessage(ClientUtil.getUserName(e.getClient()) + " joined");
  3138. }
  3139. protected function onLeave(e:RoomEvent):void {
  3140. setInfoMessage(ClientUtil.getUserName(e.getClient()) + " left");
  3141. }
  3142. protected function onUpdateClientAttribute(e:RoomEvent):void {
  3143. switch( e.getChangedAttr().name ) {
  3144. case "team":
  3145. case "isSolo":
  3146. updateUserList();
  3147. break;
  3148. case Constants.USER_NAME:
  3149. if( e.getChangedAttr().oldValue != null ) setInfoMessage(e.getChangedAttr().oldValue + " is now " + e.getChangedAttr().value );
  3150. updateUserList();
  3151. break;
  3152. case Constants.ATTACK_POWER:
  3153. if ( e.getClient().isSelf() ) {
  3154. setInfoMessage("Your attack power: " + int(Number(e.getChangedAttr().oldValue)/100)/10 + " -> " + int(Number(e.getChangedAttr().value)/100)/10);
  3155. }
  3156. updateUserList();
  3157. break;
  3158. case Constants.DEFENCE_POWER:
  3159. if ( e.getClient().isSelf() ) {
  3160. setInfoMessage("Your defence power: " + int(Number(e.getChangedAttr().oldValue)/100)/10 + " -> " + int(Number(e.getChangedAttr().value)/100)/10);
  3161. }
  3162. updateUserList();
  3163. break;
  3164. case Constants.HANDICAP:
  3165. updateUserList();
  3166. break;
  3167. break;
  3168. }
  3169. }
  3170. protected function onClientCount(e:RoomEvent):void {
  3171. updateUserList();
  3172. }
  3173. protected function updateUserList():void {
  3174. var list:Array = lobby.getClients();
  3175. var listStr:String = "";
  3176. for ( var i:int = 0; i < list.length; i++ ) {
  3177. var userStr:String = ClientUtil.getUserName(list[i]);
  3178. var attackPower:Number = ClientUtil.getAttackPower(list[i]);
  3179. var defencePower:Number = ClientUtil.getDefencePower(list[i]);
  3180. var handicap:Number = ClientUtil.getHandicap(list[i]);
  3181. var colorStr:String = "#FFFFFF";
  3182. var powerColor:String = "#FFFFFF";
  3183. if ( ClientUtil.isSolo( list[i] ) ) {
  3184. colorStr = "#666666";
  3185. } else {
  3186. if ( ClientUtil.isTeamBlue( list[i] ) ) colorStr = "#6666FF";
  3187. if ( ClientUtil.isTeamRed( list[i] ) ) colorStr = "#FF6666";
  3188. }
  3189. if ( (list[i] as IClient).isSelf() ) colorStr = "#66FF66";
  3190. if ( handicap == 2 ) powerColor = "#FFFF66";
  3191. if ( handicap == 3 ) powerColor = "#FF6666";
  3192. listStr += "" + userStr + "" +
  3193. "("+int(int(attackPower)/1000/handicap)+"/"+int(int(defencePower)/1000/handicap)+")\n";
  3194. }
  3195. users.htmlText = "" + listStr +"";
  3196. }
  3197. protected function getNowTimeFormat():String {
  3198. var date:Date = new Date();
  3199. var timeStr:String =
  3200. String("00" + date.getHours()).substr( -2, 2) + ":" +
  3201. String("00" + date.getMinutes()).substr( -2, 2) + ":" +
  3202. String("00" + date.getSeconds()).substr( -2, 2);
  3203. return timeStr;
  3204. }
  3205. protected function chatMessageAction(from:IClient, msg:String):void {
  3206. if( from.isSelf() )
  3207. coming.appendText( getNowTimeFormat() + " )" + ClientUtil.getUserName(from) + "( " + String(decodeURI(msg)) + "\n" );
  3208. else
  3209. coming.appendText( getNowTimeFormat() + " (" + ClientUtil.getUserName(from) + ") " + String(decodeURI(msg)) + "\n" );
  3210. coming.scrollV = coming.maxScrollV;
  3211. }
  3212. public function setInfoMessage(msg:String):void {
  3213. coming.appendText( getNowTimeFormat() + " *** " + msg + "\n" );
  3214. coming.scrollV = coming.maxScrollV;
  3215. }
  3216. protected function onKeyDown(e:KeyboardEvent):void {
  3217. if ( (e.keyCode == Keyboard.ENTER) && ( input.text != "" ) ) {
  3218. switch( input.text ) {
  3219. case "/version":
  3220. case "/v":
  3221. setInfoMessage(Constants.VERSION);
  3222. break;
  3223. default:
  3224. lobby.sendMessage("CHAT_MESSAGE", true, null, String(encodeURI(input.text)));
  3225. break;
  3226. }
  3227. input.text = "";
  3228. }
  3229. }
  3230. }
  3231. class ClientUtil {
  3232. public static function isCPU(client:IClient):Boolean {
  3233. return ( client.getClientID() == "0" )
  3234. }
  3235. public static function isSolo(client:IClient):Boolean {
  3236. return ( client.getAttribute("", "isSolo") == "true" );
  3237. }
  3238. public static function isTeamBlue(client:IClient):Boolean {
  3239. return ( client.getAttribute("", "team") == Constants.TEAM_BLUE );
  3240. }
  3241. public static function isTeamRed(client:IClient):Boolean {
  3242. return ( client.getAttribute("", "team") == Constants.TEAM_RED );
  3243. }
  3244. public static function getUserName(client:IClient):String {
  3245. return decodeURIComponent(String(client.getAttribute("", Constants.USER_NAME)));
  3246. }
  3247. public static function getHandicap(client:IClient):Number {
  3248. return Number(client.getAttribute("", Constants.HANDICAP));
  3249. }
  3250. public static function getAttackPower(client:IClient):Number {
  3251. return Number(client.getAttribute("", Constants.ATTACK_POWER));
  3252. }
  3253. public static function getDefencePower(client:IClient):Number {
  3254. return Number(client.getAttribute("", Constants.DEFENCE_POWER));
  3255. }
  3256. public static function getBaseLevel(client:IClient):int {
  3257. return int(client.getAttribute("", Constants.USER_BATTERY_BASE_LEVEL));
  3258. }
  3259. public static function getColor(client:IClient):int {
  3260. return int(client.getAttribute("", Constants.USER_BATTERY_COLOR));
  3261. }
  3262. public static function getBaseColor(client:IClient):int {
  3263. return int(client.getAttribute("", Constants.USER_BATTERY_BASE_COLOR));
  3264. }
  3265. public static function setColor(client:IClient, color:int):void {
  3266. client.setAttribute(Constants.USER_BATTERY_COLOR, String(color), "");
  3267. }
  3268. public static function setBaseColor(client:IClient, baseColor:int):void {
  3269. client.setAttribute(Constants.USER_BATTERY_BASE_COLOR, String(baseColor), "");
  3270. }
  3271. public static function getStatus(client:IClient):String {
  3272. return String(client.getAttribute("", "status") );
  3273. }
  3274. }
  3275. //
  3276. class GameEvent extends Event {
  3277. // public static const INFO_START:String = "infoStart";
  3278. // public static const GAME_START:String = "gameStart";
  3279. // public static const LOBBY_USER_NUM_UPDATE:String = "lobbyUserNumUpdate";
  3280. // public static const GAME_USER_NUM_UPDATE:String = "gameUserNumUpdate";
  3281. public static const JOIN_BLUE:String = "joinBlue";
  3282. public static const JOIN_RED:String = "joinRed";
  3283. public static const JOIN_SOLO:String = "joinSolo";
  3284. public static const AUTO_JOIN:String = "autoJoin";
  3285. public static const MOVE_BATTERY:String = "moveBattery";
  3286. public static const MODE_ATTACK:String = "modeAttack";
  3287. public static const MODE_DEFENCE:String = "modeDefender";
  3288. public static const HIT:String = "hit";
  3289. public static const ATTACK:String = "attack";
  3290. public static const DEFENCE_TYPE:String = "defenceType";
  3291. public static const DESTROY:String = "destroy";
  3292. public static const SHOOT:String = "shoot";
  3293. public static const MISSILE_DESTROY:String = "missileDestroy";
  3294. public static const MISSILE_DAMAGE:String = "missileDamage";
  3295. public static const CHAT:String = "chat";
  3296. public static const END_GAME:String = "endGame";
  3297. public static const COLOR_SELECT:String = "colorSelect";
  3298. public static const HANDICAP_SELECT:String = "handicapSelect";
  3299. public static const ATTACK_REFLECT:String = "attackReflect";
  3300. public static const ATTACK_DOUBLE:String = "attackDouble";
  3301. public static const NAME_CHANGE:String = "nameChange";
  3302. public static const ATTACK_COMBO_END:String = "attackComboEnd";
  3303. public static const ATTACK_COMBO_START:String = "attackComboStart";
  3304. public static const DEFENCE_COMBO_END:String = "defenceComboEnd";
  3305. public static const DEFENCE_COMBO_START:String = "defenceComboStart";
  3306. public var data:String;
  3307. public function GameEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false, data:String=null) {
  3308. super(type, bubbles, cancelable);
  3309. this.data = data;
  3310. }
  3311. override public function clone():Event
  3312. {
  3313. return new GameEvent(type, bubbles, cancelable, data);
  3314. }
  3315. }
  3316. // 入室時のインターフェース
  3317. class EnterUI extends Sprite {
  3318. protected var tf:TextField = new TextField();
  3319. protected var btn:Button = new Button(100, 20, "ENTER", false);
  3320. public function EnterUI () {
  3321. draw();
  3322. }
  3323. protected function draw():void {
  3324. tf.width = 100;
  3325. tf.height = 18;
  3326. TextFieldUtil.setupBorder(tf);
  3327. tf.type = "input";
  3328. btn.y = 30;
  3329. var userNameObj:Object = LocalData.read(Constants.LD_FIELD, Constants.USER_NAME);
  3330. if ( userNameObj == null ) {
  3331. tf.text = "Input your name";
  3332. tf.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  3333. } else {
  3334. tf.text = String(userNameObj);
  3335. enterEnable();
  3336. }
  3337. tf.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
  3338. this.addChild( tf );
  3339. this.addChild( btn );
  3340. btn.addEventListener(MouseEvent.CLICK, onClick);
  3341. }
  3342. protected function onClick(e:MouseEvent = null):void {
  3343. LocalData.write(Constants.LD_FIELD, Constants.USER_NAME, tf.text);
  3344. LocalData.flush(Constants.LD_FIELD);
  3345. btn.selected = true;
  3346. this.dispatchEvent(new Event("enter"))
  3347. }
  3348. protected function onMouseDown(e:MouseEvent):void {
  3349. tf.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
  3350. tf.text = "";
  3351. }
  3352. protected function onKeyUp(e:KeyboardEvent):void {
  3353. if ( tf.text.length > 0 ) {
  3354. enterEnable();
  3355. if ( e.keyCode == Keyboard.ENTER ) {
  3356. onClick(); // ENTER押したのと同じにする
  3357. }
  3358. } else {
  3359. enterDisable();
  3360. }
  3361. }
  3362. protected function enterEnable():void {
  3363. btn.enable = true;
  3364. }
  3365. protected function enterDisable():void {
  3366. btn.enable = false;
  3367. }
  3368. }
  3369. // テキストとグラフィックで作るボタン
  3370. class Button extends Sprite {
  3371. protected var bgBlack:Sprite = new Sprite();
  3372. protected var bgGray:Sprite = new Sprite();
  3373. protected var highlight:Sprite = new Sprite();
  3374. protected var tf:TextField = new TextField();
  3375. public function Button(width:int, height:int, text:String, isEnabled:Boolean = true, isSelected:Boolean = false, bgColor:int = 0x0) {
  3376. bgBlack.graphics.lineStyle(0, 0xFFFFFF);
  3377. bgBlack.graphics.beginFill(bgColor, 0.75);
  3378. bgBlack.graphics.drawRoundRect(0, 0, width, height, 5);
  3379. bgGray.graphics.beginFill(0xFFFFFF, 0.5);
  3380. bgGray.graphics.drawRoundRect(0, 0, width, height, 5);
  3381. highlight.graphics.beginFill(0x88FF88, 0.5);
  3382. highlight.graphics.drawRoundRect(0, 0, width, height, 5);
  3383. this.addChild( bgBlack );
  3384. this.addChild( bgGray );
  3385. this.addChild( highlight );
  3386. highlight.mouseEnabled = highlight.mouseChildren = false;
  3387. this.selected = isSelected;
  3388. this.addEventListener(MouseEvent.ROLL_OVER, function():void { bgGray.alpha = 1.0 } );
  3389. this.addEventListener(MouseEvent.ROLL_OUT, function():void { bgGray.alpha = 0 } );
  3390. bgGray.alpha = 0;
  3391. tf.autoSize = "left";
  3392. TextFieldUtil.setupNoBorder(tf);
  3393. tf.text = text;
  3394. tf.x = 0.5 * (width - tf.width);
  3395. tf.y = 0.5 * (height - tf.height);
  3396. this.addChild( tf );
  3397. this.mouseChildren = false;
  3398. this.enable = isEnabled;
  3399. this.addEventListener(MouseEvent.CLICK, onClick);
  3400. }
  3401. protected function onClick(e:MouseEvent):void {
  3402. SoundManager.ClickSound.play();
  3403. }
  3404. public function get selected():Boolean {
  3405. return highlight.visible;
  3406. }
  3407. public function set selected(value:Boolean):void {
  3408. highlight.visible = value;
  3409. }
  3410. public function set enable(value:Boolean):void {
  3411. this.mouseEnabled = value;
  3412. // this.buttonMode = value;
  3413. this.alpha = (value?1.0:0.5);
  3414. }
  3415. }
  3416. // 砲台移動用ユーザーインターフェース
  3417. class MoveBatteryUI extends Sprite {
  3418. private var batteryShadow:Battery = new Battery(true, 0,0,0);
  3419. public function MoveBatteryUI() {
  3420. batteryShadow.filters =[ new ColorMatrixFilter([0, 0, 0, 0.4, 0, 0, 0, 0, 0.4, 0, 0, 0, 0, 0.4, 0, 0, 0, 0, 1.0, 0])];
  3421. this.addChild( batteryShadow );
  3422. batteryShadow.y = Constants.BATTERY_DEFAULT_Y;
  3423. batteryShadow.visible = false;
  3424. this.graphics.beginFill(0x0, 0);
  3425. this.graphics.drawRect(0, 0, 480, 40);
  3426. this.addEventListener(MouseEvent.ROLL_OVER, onRollOver);
  3427. this.addEventListener(MouseEvent.ROLL_OUT, onRollOut);
  3428. this.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMove);
  3429. }
  3430. protected function onRollOver(e:MouseEvent):void {
  3431. batteryShadow.visible = true;
  3432. }
  3433. protected function onRollOut(e:MouseEvent):void {
  3434. batteryShadow.visible = false;
  3435. }
  3436. protected function onMouseMove(e:MouseEvent):void {
  3437. batteryShadow.x = this.mouseX;
  3438. }
  3439. // 砲台シャドウの形態変更
  3440. public function setMode(playMode:String):void {
  3441. batteryShadow.setMode(playMode);
  3442. }
  3443. }
  3444. // ゲーム設定値とか定数とかとにかく放り込んだ
  3445. class Constants {
  3446. public static const VERSION:String = "version 1.1.0.2";
  3447. public static const STAGE_WIDTH:Number = 465;
  3448. public static const STAGE_HEIGHT:Number = 465;
  3449. public static const CPU_START_WAITTIME:Number = 3000;
  3450. public static const GAME_START_WAITTIME:Number = 10000;
  3451. public static const GAME_END_NEXT_WAITTIME:Number = 20000;
  3452. public static const ANGLE:String = "angle";
  3453. public static const LD_FIELD:String = "wonderflGame1";
  3454. public static const USER_NAME:String = "userName";
  3455. public static const STATUS_CHATING:String = "statusChating"; // lobby
  3456. public static const STATUS_WAITING:String = "statusWaiting"; // 入室まち
  3457. public static const STATUS_PLAYING:String = "statusPlaying"; // プレイ中
  3458. public static const STATUS_FINISHING:String = "statusFinishing"; // プレイ中
  3459. public static const CPU_ROOM_DEFAULT:String = "wonderfl.keno.missileGame.game.cpu";
  3460. public static const GAME_ROOM:String = "wonderfl.keno.missileGame.game.room2";
  3461. public static const LOBBY_ROOM:String = "wonderfl.keno.missileGame.lobby2";
  3462. public static const TEAM_NONE:String = "teamNone";
  3463. public static const TEAM_BLUE:String = "teamBlue";
  3464. public static const TEAM_RED:String = "teamRed";
  3465. public static const BATTERY_DEFAULT_Y:Number = 12;
  3466. public static const BATTERY_X:String = "batteryX";
  3467. public static const PLAY_MODE:String = "playMode";
  3468. public static const PLAY_MODE_ATTACKER:String = "playModeAttacker";
  3469. public static const PLAY_MODE_DEFENDER:String = "playModeDefender";
  3470. public static const USER_BATTERY_BASE_LEVEL:String = "userBatteryBaseLevel";
  3471. public static const USER_BATTERY_COLOR:String = "UserBatteryColor";
  3472. public static const USER_BATTERY_BASE_COLOR:String = "UserBatteryBaseColor";
  3473. public static const USER_BATTERY_EFFECT_LEVEL:String = "UserBatteryEffectLevel";
  3474. public static const DEFAULT_USER_BATTERY_BASE_LEVEL:int = 0;
  3475. public static const DEFAULT_USER_BATTERY_COLOR:int = 0x888888
  3476. public static const DEFAULT_USER_BATTERY_BASE_COLOR:int = 0x888888;
  3477. public static const ATTACK:String = "attack";
  3478. public static const ATTACK_LOG:String = "attackLog";
  3479. public static const ATTACK_REFLECT:String = "attackReflect";
  3480. public static const REMOVE_MISSILE:String = "attackLog";
  3481. public static const RESULT_SUCCESS:int = 1;
  3482. public static const NO_VALUE:int = -1;
  3483. public static const RESULT_FAULT:int = 0;
  3484. public static const RESULT_DESTROY:int = 3;
  3485. public static const SEND_ME_LOG:String = "sendMeLog";
  3486. public static const SHOOT:String = "shoot";
  3487. public static const DESTROY:String = "destroy";
  3488. public static const HIT:String = "hit";
  3489. public static const TEAM_CHAT_DURATION:Number = 5000; // 5000 msec
  3490. public static const GAME_CHAT:String = "gameChat";
  3491. public static const VICTORY_POINT:Number = 10;
  3492. public static var MISSILE_ARRIVE_TIME:Number = 27 * DISTANCE; // 8000 msec
  3493. public static const BULLET_SPEED:Number = 170 / 1000; // 170pixel per 1000msec
  3494. public static const DISTANCE:Number = 300; // 300pixel
  3495. public static const BASE_LEVEL_0:int = 0; // 円
  3496. public static const BASE_LEVEL_1:int = 1; // 三角
  3497. public static const BASE_LEVEL_2:int = 2; // A字
  3498. public static const BASE_LEVEL_3:int = 3; // スター
  3499. public static const CHAT_KEY:uint = Keyboard.F1;
  3500. public static const ATTACK_POWER:String = "attackPower";
  3501. public static const DEFENCE_POWER:String = "defencePower";
  3502. public static const HANDICAP:String = "handicap";
  3503. public static const ATTACK_COMBO_START:int = 15;
  3504. public static const DEFENCE_COMBO_START:int = 15;
  3505. }
  3506. // テキストフィールドでよく使う設定
  3507. class TextFieldUtil {
  3508. public static function getFont():String {
  3509. // return "_sans";
  3510. return "_等幅";
  3511. // return "MS ゴシック";
  3512. }
  3513. public static function setupBorder(tf:TextField):void {
  3514. tf.defaultTextFormat = new TextFormat(getFont(), null, 0xFFFFFF);
  3515. tf.border = true;
  3516. tf.borderColor = 0xFFFFFF;
  3517. tf.background = true;
  3518. tf.backgroundColor = 0x0;
  3519. }
  3520. public static function setupNoBorder(tf:TextField, selectable:Boolean = true):void {
  3521. tf.defaultTextFormat = new TextFormat(getFont(), null, 0xFFFFFF);
  3522. tf.selectable = selectable;
  3523. }
  3524. }
  3525. // 自分用データ(共有しない)
  3526. class Score {
  3527. public static var type:Number = 0; // SO保存
  3528. public static var correct:Number = 0; // SO保存
  3529. public static var attack:Number = 0; // SO保存
  3530. public static var defence:Number = 0; // SO保存
  3531. public static var hit:Number = 0; // SO保存
  3532. public static var damage:Number = 0; // SO保存
  3533. public static var win:Number = 0; // SO保存
  3534. public static var lose:Number = 0; // SO保存
  3535. public static var score:Number = 0;
  3536. public static var defencePower:Number = 0; // SO保存
  3537. public static var attackPower:Number = 0; // SO保存
  3538. public static var handicap:Number = 1;
  3539. public static var attackCombo:Number = 0;
  3540. public static var defenceCombo:Number = 0;
  3541. public static var japaneseRate:Number = 0.5; // SO保存
  3542. public static var lastLevel:int = 0;
  3543. public static var playMode:String = null;
  3544. public static var myGameRoom:String = "";
  3545. public static var isSolo:Boolean = false;
  3546. public static var cpuLV:Number = 3; // SO保存
  3547. protected static var expTable:Array = [0, 1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000, 12000, 14000, 16000, 18000, 20000, 25000, 30000, 35000, 40000, 45000];
  3548. public static function initScore():void {
  3549. type = Number(LocalData.read(Constants.LD_FIELD, "totalType"));
  3550. correct = Number(LocalData.read(Constants.LD_FIELD, "totalCorrect"));
  3551. attack = Number(LocalData.read(Constants.LD_FIELD, "attack"));
  3552. defence = Number(LocalData.read(Constants.LD_FIELD, "defence"));
  3553. hit = Number(LocalData.read(Constants.LD_FIELD, "hit"));
  3554. damage = Number(LocalData.read(Constants.LD_FIELD, "damage"));
  3555. win = Number(LocalData.read(Constants.LD_FIELD, "win"));
  3556. lose = Number(LocalData.read(Constants.LD_FIELD, "lose"));
  3557. attackPower = Number(LocalData.read(Constants.LD_FIELD, "attackPower"));
  3558. defencePower = Number(LocalData.read(Constants.LD_FIELD, "defencePower"));
  3559. // handicap = Number(LocalData.read(Constants.LD_FIELD, "handicap"));
  3560. // if ( handicap == 0 ) handicap = 1;
  3561. japaneseRate = Number(LocalData.read(Constants.LD_FIELD, "japaneseRate"));
  3562. if ( japaneseRate == 0 ) japaneseRate = 0;
  3563. cpuLV = Number(LocalData.read(Constants.LD_FIELD, "cpuLV"));
  3564. if ( cpuLV == 0 ) cpuLV = Math.max( int(attackPower/1000), int(defencePower/1000), 0.5 );
  3565. }
  3566. public static function save():void {
  3567. LocalData.write(Constants.LD_FIELD, "totalType", type);
  3568. LocalData.write(Constants.LD_FIELD, "totalCorrect", correct);
  3569. LocalData.write(Constants.LD_FIELD, "attack", attack);
  3570. LocalData.write(Constants.LD_FIELD, "defence", defence);
  3571. LocalData.write(Constants.LD_FIELD, "hit", hit);
  3572. LocalData.write(Constants.LD_FIELD, "damage", damage);
  3573. LocalData.write(Constants.LD_FIELD, "win", win);
  3574. LocalData.write(Constants.LD_FIELD, "lose", lose);
  3575. LocalData.write(Constants.LD_FIELD, "defencePower", defencePower);
  3576. LocalData.write(Constants.LD_FIELD, "attackPower", attackPower);
  3577. // LocalData.write(Constants.LD_FIELD, "handicap", handicap);
  3578. LocalData.write(Constants.LD_FIELD, "japaneseRate", japaneseRate);
  3579. LocalData.write(Constants.LD_FIELD, "cpuLV", cpuLV);
  3580. }
  3581. public static function resetCombo():void {
  3582. attackCombo = defenceCombo = 0;
  3583. }
  3584. public static function getLevel():int {
  3585. var exp:Number = win * 500 + lose * 100 + correct * 5 + hit * 100;
  3586. for ( var i:int = 0; i < 20; i++ ) {
  3587. if ( exp < expTable[i] ) {
  3588. break;
  3589. }
  3590. }
  3591. return i;
  3592. }
  3593. public static function getAttackBonusRate():Number {
  3594. var rate:Number = (attackCombo - Constants.ATTACK_COMBO_START) * 0.5 / handicap;
  3595. if ( rate > 80 ) rate = 80;
  3596. if ( rate < 0 ) rate = 0;
  3597. return int(rate);
  3598. }
  3599. public static function getDefenceBonusRate():Number {
  3600. var rate:Number = (defenceCombo - Constants.DEFENCE_COMBO_START) * 0.5 / handicap;
  3601. if ( rate > 80 ) rate = 80;
  3602. if ( rate < 0 ) rate = 0;
  3603. return int(rate);
  3604. }
  3605. public static function isJapanese():Boolean {
  3606. return ( japaneseRate > Math.random() );
  3607. }
  3608. }
  3609. // 時間の同期クラス
  3610. class ServerClockUtil {
  3611. public static var timeDiff:Number = 0;
  3612. public static function init(server:Server):void {
  3613. server.addEventListener(ServerEvent.TIME_SYNC, function():void {
  3614. timeDiff = server.getServerTime() - Number(getTimer());
  3615. });
  3616. server.syncTime();
  3617. // timeDiff = serverTime - Number(getTimer());
  3618. }
  3619. public static function getTime():Number {
  3620. return Number(getTimer()) + timeDiff;
  3621. }
  3622. }
  3623. // ローマ字変換クラス てきとうですが
  3624. class Roma {
  3625. public static function isJapaneseWord(word:String):Boolean {
  3626. return ( word.charCodeAt(0) > 127 );
  3627. }
  3628. public static function getHiragana(roma:String):String {
  3629. roma = roma.toUpperCase();
  3630. var index:int = 0;
  3631. var ret:String = "";
  3632. while ( index < roma.length ) {
  3633. var char:String = roma.charAt(index);
  3634. if ( roma.length > (index + 1) ) {
  3635. if ( (char != "A") && (char != "I") && (char != "U") && (char != "E") && (char != "O") &&
  3636. (char != "N") && (char != "-") && (char == roma.charAt(index + 1)) ) {
  3637. ret += "っ";
  3638. index++;
  3639. continue;
  3640. }
  3641. }
  3642. for ( var i:int = 3; i > 0; i-- ) {
  3643. var test:String = roma.substr(index, i);
  3644. var kana:String = hiraganaTable[test];
  3645. if ( kana ) {
  3646. ret += kana;
  3647. index += test.length;
  3648. break;
  3649. }
  3650. }
  3651. if ( i == 0 ) {
  3652. ret += roma.substr(index);
  3653. break;
  3654. }
  3655. }
  3656. return ret;
  3657. }
  3658. public static function init():void {
  3659. hiraganaTable = makeReverseTable( romaTable );
  3660. }
  3661. protected static var hiraganaTable:Object;
  3662. protected static function makeReverseTable(table:Object):Object {
  3663. var ret:Object = { };
  3664. for ( var str:String in table ) {
  3665. if ( table[str] is Array ) {
  3666. for each( var roma:String in table[str] ) {
  3667. ret[roma] = str;
  3668. }
  3669. } else {
  3670. var temp:Object = makeReverseTable( table[str] );
  3671. for ( var str2:String in temp ) {
  3672. ret[str2] = str + temp[str2];
  3673. }
  3674. }
  3675. }
  3676. return ret;
  3677. }
  3678. public static function getRomaToType(hiragana:String, typed:String = ""):String {
  3679. var default_ltu_alone:Boolean = false;
  3680. var index:int = 0;
  3681. var ret:String = "";
  3682. var char:String = "";
  3683. var addChar:String = "";
  3684. var nextChar:String = "";
  3685. var nn:Boolean = false;
  3686. var hatsuon:Boolean = false;
  3687. var typedIndex:int = 0;
  3688. var typedLength:int = typed.length;
  3689. var targetChar:String;
  3690. var wordLength:int;
  3691. var isOk:Boolean;
  3692. var i:int;
  3693. var j:int;
  3694. var test:String = "";
  3695. var oldTypedIndex:int = 0;
  3696. var targetArray:Array;
  3697. var nextTargetArray:Array;
  3698. var addIndex:int = 1;
  3699. while ( index < hiragana.length) {
  3700. char = hiragana.charAt(index);
  3701. if ( char == "ん" && (index + 1 < hiragana.length ) ) {
  3702. nn = true;
  3703. index++;
  3704. continue;
  3705. }
  3706. if ( char == "っ" ) {
  3707. //
  3708. if ( (typedIndex < typedLength) &&
  3709. ( typed.charAt(typedIndex) == "L" || typed.charAt(typedIndex) == "X" ) ) { // 単独文字として扱う
  3710. default_ltu_alone = true; // 実装未定・・
  3711. hatsuon = false;
  3712. } else
  3713. //
  3714. {
  3715. hatsuon = true; // 判断先送り
  3716. index++;
  3717. continue;
  3718. }
  3719. }
  3720. addIndex = 1;
  3721. if ( (romaTable[char] is Array) ) { // 一文字決まり
  3722. targetArray = romaTable[char];
  3723. } else {
  3724. if( ((index + 1) < hiragana.length) ){ // 二文字目あり
  3725. nextChar = hiragana.charAt(index + 1);
  3726. } else { // 二文字目なし
  3727. nextChar = "";
  3728. }
  3729. if ( romaTable[char][nextChar] == null ) { // 二文字目はあるけど候補なし
  3730. targetArray = romaTable[char][""];
  3731. } else { // 二文字目まで候補あり
  3732. targetArray = romaTable[char][nextChar];
  3733. nextTargetArray = romaTable[char][""];
  3734. addIndex = 2;
  3735. }
  3736. }
  3737. //
  3738. if ( typedIndex < typedLength ) {
  3739. if ( nn ) {
  3740. if ( typed.charAt(typedIndex) != "N" ) return null;
  3741. typedIndex++;
  3742. if ( typedIndex < typedLength ) {
  3743. if ( typed.charAt(typedIndex) == "N" ) {
  3744. typedIndex++;
  3745. } else {
  3746. switch( typed.charAt(typedIndex) ) {
  3747. case "A":
  3748. case "I":
  3749. case "U":
  3750. case "E":
  3751. case "O":
  3752. case "Y":
  3753. return null;
  3754. break;
  3755. default:
  3756. break;
  3757. }
  3758. }
  3759. }
  3760. }
  3761. if ( hatsuon ) {
  3762. test = getRomaToType(hiragana.substr(index, 2), typed.substr(typedIndex, 1));
  3763. if ( !test ) return null;
  3764. typedIndex++;
  3765. if ( (typedIndex < typedLength) && (typed.charAt(typedIndex) != test.charAt(0)) ) return null;
  3766. }
  3767. for ( i = 0; i < targetArray.length; i++ ) {
  3768. targetChar = targetArray[i];
  3769. wordLength = targetChar.length;
  3770. isOk = true;
  3771. for ( j = typedIndex; j < typedIndex + wordLength; j++ ) {
  3772. if ( j == typedLength ) break;
  3773. if ( typed.charAt(j) != targetChar.charAt(j - typedIndex) ) {
  3774. isOk = false;
  3775. break;
  3776. }
  3777. }
  3778. if ( isOk ) break;
  3779. }
  3780. if ( !isOk && (addIndex == 2) ) { // 二文字あるけど一文字ずつ区切って打とうとしている場合
  3781. addIndex = 1;
  3782. targetArray = nextTargetArray;
  3783. for ( i = 0; i < targetArray.length; i++ ) {
  3784. targetChar = targetArray[i];
  3785. wordLength = targetChar.length;
  3786. isOk = true;
  3787. for ( j = typedIndex; j < typedIndex + wordLength; j++ ) {
  3788. if ( j == typedLength ) break;
  3789. if ( typed.charAt(j) != targetChar.charAt(j - typedIndex) ) {
  3790. isOk = false;
  3791. break;
  3792. }
  3793. }
  3794. if ( isOk ) break;
  3795. }
  3796. }
  3797. if ( !isOk ) return null;
  3798. typedIndex += j - typedIndex;
  3799. if( i > 0 ){
  3800. targetArray.splice(i, 1);
  3801. targetArray.unshift(targetChar);
  3802. }
  3803. }
  3804. //
  3805. addChar = targetArray[0];
  3806. index += addIndex;
  3807. if ( hatsuon ) {
  3808. ret += addChar.substr(0, 1);
  3809. hatsuon = false;
  3810. }
  3811. if ( nn ) {
  3812. switch( addChar.substr(0, 1) ) {
  3813. case "A":
  3814. case "I":
  3815. case "U":
  3816. case "E":
  3817. case "O":
  3818. case "N":
  3819. case "Y":
  3820. ret += "NN";
  3821. break;
  3822. default:
  3823. ret += "N";
  3824. break;
  3825. }
  3826. nn = false;
  3827. }
  3828. ret += addChar;
  3829. addChar = "";
  3830. }
  3831. if ( nn ) {
  3832. ret += "NN";
  3833. }
  3834. return ret;
  3835. }
  3836. protected static const romaTable:Object = {
  3837. "あ": ["A"],
  3838. "い": {
  3839. "ぇ": ["YE"],
  3840. "": ["I", "YI"]
  3841. },
  3842. "う": {
  3843. "ぃ": ["WI"],
  3844. "ぇ": ["WE"],
  3845. "": ["U", "WU"]
  3846. },
  3847. "え": ["E"],
  3848. "お": ["O"],
  3849. "か": ["KA", "CA"],
  3850. "き": {
  3851. "ゃ": ["KYA"],
  3852. "ぃ": ["KYI"],
  3853. "ゅ": ["KYU"],
  3854. "ぇ": ["KYE"],
  3855. "ょ": ["KYO"],
  3856. "": ["KI"]
  3857. },
  3858. "く": {
  3859. "ぁ": ["KWA"],
  3860. "": ["KU", "CU"]
  3861. },
  3862. "け": ["KE"],
  3863. "こ": ["KO", "CO"],
  3864. "が": ["GA"],
  3865. "ぎ": {
  3866. "ゃ": ["GYA"],
  3867. "ぃ": ["GYI"],
  3868. "ゅ": ["GYU"],
  3869. "ぇ": ["GYE"],
  3870. "ょ": ["GYO"],
  3871. "": ["GI"]
  3872. },
  3873. "ぐ": {
  3874. "ぁ": ["GWA"],
  3875. "": ["GU"]
  3876. },
  3877. "げ": ["GE"],
  3878. "ご": ["GO"],
  3879. "さ": ["SA"],
  3880. "し": {
  3881. "ゃ": ["SYA", "SHA"],
  3882. "ぃ": ["SYI"],
  3883. "ゅ": ["SYU", "SHU"],
  3884. "ぇ": ["SYE", "SHE"],
  3885. "ょ": ["SYO", "SHO"],
  3886. "": ["SI", "SHI", "CI"]
  3887. },
  3888. "す": {
  3889. "ぁ": ["SWA"],
  3890. "ぃ": ["SWI"],
  3891. "ぅ": ["SWU"],
  3892. "ぇ": ["SWE"],
  3893. "ぉ": ["SWO"],
  3894. "": ["SU"]
  3895. },
  3896. "せ": ["SE", "CE"],
  3897. "そ": ["SO"],
  3898. "ざ": ["ZA"],
  3899. "じ": {
  3900. "ゃ": ["ZYA", "JYA", "JA"],
  3901. "ぃ": ["ZYI", "JYI"],
  3902. "ゅ": ["ZYU", "JYU", "JU"],
  3903. "ぇ": ["ZYE", "JYE"],
  3904. "ょ": ["ZYO", "JYO", "JO"],
  3905. "": ["ZI", "JI"]
  3906. },
  3907. "ず": ["ZU"],
  3908. "ぜ": ["ZE"],
  3909. "ぞ": ["ZO"],
  3910. "た": ["TA"],
  3911. "ち": {
  3912. "ゃ": ["TYA","CHA", "CYA"],
  3913. "ぃ": ["TYI","CYI"],
  3914. "ゅ": ["TYU","CHU", "CYU"],
  3915. "ぇ": ["TYE", "CHE", "CYE"],
  3916. "ょ": ["TYO", "CHO", "CYO"],
  3917. "": ["TI", "CHI"]
  3918. },
  3919. "つ": {
  3920. "ぁ": ["TSA"],
  3921. "ぃ": ["TSI"],
  3922. "ぅ": ["TSU"],
  3923. "ぇ": ["TSE"],
  3924. "ぉ": ["TSO"],
  3925. "": ["TU", "TSU"]
  3926. },
  3927. "て": {
  3928. "ゃ": ["THA"],
  3929. "ぃ": ["THI"],
  3930. "ゅ": ["THU"],
  3931. "ぇ": ["THE"],
  3932. "ょ": ["THO"],
  3933. "": ["TE"]
  3934. },
  3935. "と": {
  3936. "ぁ": ["TWA"],
  3937. "ぃ": ["TWI"],
  3938. "ぅ": ["TWU"],
  3939. "ぇ": ["TWE"],
  3940. "ぉ": ["TWO"],
  3941. "": ["TO"]
  3942. },
  3943. "だ": ["DA"],
  3944. "ぢ": {
  3945. "ゃ": ["DYA"],
  3946. "ぃ": ["DYI"],
  3947. "ゅ": ["DYU"],
  3948. "ぇ": ["DYE"],
  3949. "ょ": ["DYO"],
  3950. "": ["DI"]
  3951. },
  3952. "づ": ["DU"],
  3953. "で": {
  3954. "ゃ": ["DHA"],
  3955. "ぃ": ["DHI"],
  3956. "ゅ": ["DHU"],
  3957. "ぇ": ["DHE"],
  3958. "ょ": ["DHO"],
  3959. "": ["DE"]
  3960. },
  3961. "ど": {
  3962. "ぁ": ["DWA"],
  3963. "ぃ": ["DWI"],
  3964. "ぅ": ["DWU"],
  3965. "ぇ": ["DWE"],
  3966. "ぉ": ["DWO"],
  3967. "": ["DO"]
  3968. },
  3969. "な": ["NA"],
  3970. "に": {
  3971. "ゃ": ["NYA"],
  3972. "ぃ": ["NYI"],
  3973. "ゅ": ["NYU"],
  3974. "ぇ": ["NYE"],
  3975. "ょ": ["NYO"],
  3976. "": ["NI"]
  3977. },
  3978. "ぬ": ["NU"],
  3979. "ね": ["NE"],
  3980. "の": ["NO"],
  3981. "は": ["HA"],
  3982. "ひ": {
  3983. "ゃ": ["HYA"],
  3984. "ぃ": ["HYI"],
  3985. "ゅ": ["HYU"],
  3986. "ぇ": ["HYE"],
  3987. "ょ": ["HYO"],
  3988. "": ["HI"]
  3989. },
  3990. "ふ": {
  3991. "ぁ": ["FA"],
  3992. "ぃ": ["FI"],
  3993. "ぇ": ["FE"],
  3994. "ぉ": ["FO"],
  3995. "": ["FU", "HU"]
  3996. },
  3997. "へ": ["HE"],
  3998. "ほ": ["HO"],
  3999. "ば": ["BA"],
  4000. "び": {
  4001. "ゃ": ["BYA"],
  4002. "ぃ": ["BYI"],
  4003. "ゅ": ["BYU"],
  4004. "ぇ": ["BYE"],
  4005. "ょ": ["BYO"],
  4006. "": ["BI"]
  4007. },
  4008. "ぶ": ["BU"],
  4009. "べ": ["BE"],
  4010. "ぼ": ["BO"],
  4011. "ぱ": ["PA"],
  4012. "ぴ": {
  4013. "ゃ": ["PYA"],
  4014. "ぃ": ["PYI"],
  4015. "ゅ": ["PYU"],
  4016. "ぇ": ["PYE"],
  4017. "ょ": ["PYO"],
  4018. "": ["PI"]
  4019. },
  4020. "ぷ": ["PU"],
  4021. "ぺ": ["PE"],
  4022. "ぽ": ["PO"],
  4023. "ま": ["MA"],
  4024. "み": {
  4025. "ゃ": ["MYA"],
  4026. "ぃ": ["MYI"],
  4027. "ゅ": ["MYU"],
  4028. "ぇ": ["MYE"],
  4029. "ょ": ["MYO"],
  4030. "": ["MI"]
  4031. },
  4032. "む": ["MU"],
  4033. "め": ["ME"],
  4034. "も": ["MO"],
  4035. "や": ["YA"],
  4036. "ゆ": ["YU"],
  4037. "よ": ["YO"],
  4038. "ら": ["RA"],
  4039. "り": {
  4040. "ゃ": ["RYA"],
  4041. "ぃ": ["RYI"],
  4042. "ゅ": ["RYU"],
  4043. "ぇ": ["RYE"],
  4044. "ょ": ["RYO"],
  4045. "": ["RI"]
  4046. },
  4047. "る": ["RU"],
  4048. "れ": ["RE"],
  4049. "ろ": ["RO"],
  4050. "わ": ["WA"],
  4051. "を": ["WO"],
  4052. "ゎ": ["LWA", "XWA"],
  4053. "ぁ": ["LA", "XA"],
  4054. "ぃ": ["LI", "XI"],
  4055. "ぅ": ["LU", "XU"],
  4056. "ぇ": ["LE", "XE"],
  4057. "ぉ": ["LO", "XO"],
  4058. "ゃ": ["LYA", "XYA"],
  4059. "ゅ": ["LYU", "XYU"],
  4060. "ょ": ["LYO", "XYO"],
  4061. "っ": ["LTU", "XTU", "LTSU"],
  4062. "ん": ["N", "NN"],
  4063. "ー": ["-"],
  4064. " ": [" "]
  4065. // ん, っ については別ルール適用
  4066. }
  4067. }
  4068. // 単語管理クラス
  4069. class Words {
  4070. public static const jKanjiList:Array = [
  4071. "会う", "青い", "赤い", "明い", "秋", "開く", "開ける",
  4072. "上げる", "朝", "朝御飯", "あさって", "足", "あした", "あそこ",
  4073. "遊ぶ", "暖かい", "頭", "新しい", "あちら", "暑い", "熱い",
  4074. "厚い", "後", "あなた", "兄", "姉", "あの", "アパート", "あびる",
  4075. "危ない", "甘い", "あまり", "雨", "洗う", "ある", "歩く", "あれ",
  4076. "いい", "よい", "いいえ", "言う", "家", "行く", "行く", "いくつ",
  4077. "いくら", "池", "医者", "いす", "忙しい", "痛い", "一",
  4078. "一日", "いちばん", "いつ", "五日", "一緒", "五つ", "いつも",
  4079. "今", "意味", "妹", "嫌", "入口", "居る", "要る", "入れる",
  4080. "色", "いろいろ", "上", "後", "薄い", "歌", "歌う", "うち",
  4081. "生まれる", "海", "売る", "上着", "映画", "映画館", "英語",
  4082. "ええ", "駅", "エレベーター", "鉛筆", "おいしい", "大きい",
  4083. "大勢", "お母さん", "お菓子", "お金", "起きる", "置く", "奥さん",
  4084. "お酒", "お皿", "伯父", "叔父", "おじいさん", "教える", "押す",
  4085. "遅い", "お茶", "お手洗い", "お父さん", "弟", "男",
  4086. "男の子", "おととい", "おととし", "大人", "おなか", "同じ",
  4087. "お兄さん", "お姉さん", "伯母", "叔母", "おばあさん", "お弁当",
  4088. "覚える", "重い", "おもしろい", "泳ぐ", "降りる", "終る",
  4089. "音楽", "女", "女の子", "外国", "外国人", "会社",
  4090. "階段", "買い物", "買う", "返す", "帰る", "顔", "かぎ",
  4091. "書く", "学生", "かける", "傘", "貸す", "風", "家族",
  4092. "片仮名", "学校", "角", "家内", "かばん", "花瓶", "かぶる",
  4093. "紙", "カメラ", "火曜日", "辛い", "体", "借りる", "軽い",
  4094. "カレンダー", "川", "河", "かわいい", "漢字", "黄色い", "消える",
  4095. "聞く", "北", "ギター", "汚い", "喫茶店", "切手", "切符",
  4096. "昨日", "九", "牛肉", "今日", "教室", "兄弟", "去年",
  4097. "嫌い", "切る", "着る", "きれい", "キロ", "銀行", "金曜日",
  4098. "薬", "ください", "果物", "口", "靴", "靴下", "国", "曇る",
  4099. "暗い", "くらい", "ぐらい", "クラス", "グラム", "来る", "車",
  4100. "黒い", "今朝", "消す", "結構", "結婚", "月曜日",
  4101. "玄関", "元気", "五", "公園", "交番", "声", "コート",
  4102. "ここ", "午後", "九日", "九つ", "御主人", "午前", "答える",
  4103. "こちら", "コップ", "今年", "言葉", "子供", "この", "御飯",
  4104. "困る", "これ", "今月", "今週", "こんな", "今晩", "さあ",
  4105. "魚", "先", "咲く", "作文", "さす", "雑誌", "砂糖",
  4106. "寒い", "再来年", "三", "四", "散歩", "塩", "しかし",
  4107. "時間", "仕事", "辞書", "静か", "下", "七", "質問", "自転車",
  4108. "自動車", "死ぬ", "字引", "自分", "閉まる", "閉める", "締める",
  4109. "じゃあ", "写真", "シャツ", "十", "授業", "宿題", "上手",
  4110. "丈夫", "しょうゆ", "食堂", "知る", "白い", "新聞", "水曜日",
  4111. "吸う", "スカート", "好き", "すぐに", "少し", "涼しい", "ストーブ",
  4112. "スプーン", "スポーツ", "ズボン", "住む", "スリッパ", "する", "座る",
  4113. "背", "生徒", "せっけん", "セーター", "背広", "狭い", "ゼロ",
  4114. "千", "先月", "先週", "先生", "洗濯", "全部", "掃除",
  4115. "そうして", "そして", "そこ", "そちら", "外", "その", "そば", "空",
  4116. "それ", "それから", "それでは", "大学", "大使館", "大丈夫",
  4117. "大好き", "大切", "たいてい", "台所", "たいへん", "高い",
  4118. "たくさん", "タクシー", "出す", "立つ", "建物", "楽しい", "頼む",
  4119. "たばこ", "たぶん", "食べ物", "食べる", "卵", "だれ", "誕生日",
  4120. "だんだん", "小さい", "近い", "違う", "近く", "地下鉄",
  4121. "地図", "父", "茶色", "ちゃわん", "ちょうど", "ちょっと", "一日",
  4122. "使う", "疲れる", "次", "着く", "机", "作る", "つける", "勤める",
  4123. "つまらない", "冷たい", "強い", "手", "テープ", "テーブル", "出かける",
  4124. "手紙", "できる", "出口", "テスト", "では", "デパート", "でも",
  4125. "出る", "テレビ", "天気", "電気", "電車", "電話", "戸", "ドア",
  4126. "トイレ", "どうして", "どうぞ", "動物", "どうも", "十", "遠い", "十日",
  4127. "時々", "時計", "どこ", "所", "図書館", "どちら", "とても", "どなた",
  4128. "隣", "どの", "飛ぶ", "止まる", "友達", "土曜日", "鳥", "鳥肉",
  4129. "取る", "撮る", "どれ", "どんな", "ない", "ナイフ", "中", "長い",
  4130. "鳴く", "夏", "夏休み", "七つ", "何", "七日", "名前", "習う",
  4131. "並ぶ", "並べる", "二", "にぎやか", "肉", "西", "日曜日",
  4132. "荷物", "ニュース", "庭", "脱ぐ", "ネクタイ", "寝る", "ノート", "登る",
  4133. "飲み物", "飲む", "乗る", "歯", "パーティー", "はい", "灰皿",
  4134. "入る", "葉書", "はく", "箱", "橋", "はし", "始まる", "初めに",
  4135. "初めて", "走る", "バス", "バター", "二十歳", "働く", "八", "二十日",
  4136. "花", "鼻", "話", "話す", "母", "早い", "速い", "春",
  4137. "はる", "晴れる", "半", "晩", "パン", "ハンカチ", "番号",
  4138. "晩御飯", "半分", "東", "引く", "弾く", "低い", "飛行機",
  4139. "左", "人", "一つ", "一月", "一人", "暇", "百", "病院",
  4140. "病気", "平仮名", "昼", "昼御飯", "広い", "フィルム", "封筒",
  4141. "プール", "フォーク", "吹く", "服", "二つ", "豚肉", "二人", "二日",
  4142. "太い", "冬", "降る", "古い", "ふろ", "パージ", "下手", "ベッド",
  4143. "部屋", "辺", "ペン", "勉強", "便利", "ほう", "帽子", "ボールペン",
  4144. "外", "ポケット", "欲しい", "細い", "ボタン", "ホテル", "本",
  4145. "本棚", "ほんとうに", "毎朝", "毎月", "毎月", "毎週", "毎日",
  4146. "毎年", "毎年", "毎晩", "前", "曲る", "まずい", "また", "まだ",
  4147. "町", "待つ", "まっすぐ", "マッチ", "窓", "丸い", "円い", "万",
  4148. "万年筆", "磨く", "右", "短い", "水", "店", "見せる", "道",
  4149. "三日", "三つ", "皆さん", "南", "耳", "見る", "みんな", "六日",
  4150. "向こう", "難しい", "六つ", "目", "メートル", "眼鏡", "もう",
  4151. "木曜日", "もしもし", "もちろん", "持つ", "もっと", "物", "門",
  4152. "問題", "八百屋", "野菜", "易しい", "安い", "休み", "休む",
  4153. "八つ", "山", "やる", "夕方", "郵便局", "ゆうべ", "有名",
  4154. "雪", "ゆっくり", "八日", "洋服", "よく", "横", "四日", "四つ",
  4155. "呼ぶ", "読む", "夜", "来月", "来週", "来年", "ラジオ",
  4156. "りっぱ", "留学生", "両親", "料理", "旅行", "零", "冷蔵庫",
  4157. "レコード", "レストラン", "練習", "六", "ワイシャツ", "若い",
  4158. "分る","忘れる","私","わたし","渡す","渡る","悪い"
  4159. ];
  4160. public static const jList:Array = [
  4161. "あう","あおい","あかい","あかるい","あき","あく","あける", // JLPT lv 4
  4162. "あげる","あさ","あさごはん","あさって","あし","あした","あそこ",
  4163. "あそぶ","あたたかい","あたま","あたらしい","あちら","あつい","あつい",
  4164. "あつい","あと","あなた","あに","あね","あの","あぱーと","あびる",
  4165. "あぶない","あまい","あまり","あめ","あらう","ある","あるく","あれ",
  4166. "いい","よい","いいえ","いう","いえ","いく","ゆく","いくつ",
  4167. "いくら","いけ","いしゃ","いす","いそがしい","いたい","いち",
  4168. "いちにち","いちばん","いつ","いつか","いっしょ","いつつ","いつも",
  4169. "いま","いみ","いもうと","いや","いりぐち","いる","いる","いれる",
  4170. "いろ","いろいろ","うえ","うしろ","うすい","うた","うたう","うち",
  4171. "うまれる","うみ","うる","うわぎ","えいが","えいがかん","えいご",
  4172. "ええ","えき","えれべーたー","えんぴつ","おいしい","おおきい",
  4173. "おおぜい","おかあさん","おかし","おかね","おきる","おく","おくさん",
  4174. "おさけ","おさら","おじ","おじ","おじいさん","おしえる","おす",
  4175. "おそい","おちゃ","おてあらい","おとうさん","おとうと","おとこ",
  4176. "おとこのこ","おととい","おととし","おとな","おなか","おなじ",
  4177. "おにいさん","おねえさん","おば","おば","おばあさん","おべんとう",
  4178. "おぼえる","おもい","おもしろい","およぐ","おりる","おわる",
  4179. "おんがく","おんな","おんなのこ","がいこく","がいこくじん","かいしゃ",
  4180. "かいだん","かいもの","かう","かえす","かえる","かお","かぎ",
  4181. "かく","がくせい","かける","かさ","かす","かぜ","かぞく",
  4182. "かたかな","がっこう","かど","かない","かばん","かびん","かぶる",
  4183. "かみ","かめら","かようび","からい","からだ","かりる","かるい",
  4184. "かれんだー","かわ","かわ","かわいい","かんじ","きいろい","きえる",
  4185. "きく","きた","ぎたー","きたない","きっさてん","きって","きっぷ",
  4186. "きのう","きゅう","ぎゅうにく","きょう","きょうしつ","きょうだい","きょねん",
  4187. "きらい","きる","きる","きれい","きろ","ぎんこう","きんようび",
  4188. "くすり","ください","くだもの","くち","くつ","くつした","くに","くもる",
  4189. "くらい","くらい","ぐらい","くらす","ぐらむ","くる","くるま",
  4190. "くろい","けさ","けす","けっこう","けっこん","げつようび",
  4191. "げんかん","げんき","ご","こうえん","こうばん","こえ","こーと",
  4192. "ここ","ごご","ここのか","ここのつ","ごしゅじん","ごぜん","こたえる",
  4193. "こちら","こっぷ","ことし","ことば","こども","この","ごはん",
  4194. "こまる","これ","こんげつ","こんしゅう","こんな","こんばん","さあ",
  4195. "さかな","さき","さく","さくぶん","さす","ざっし","さとう",
  4196. "さむい","さらいねん","さん","し","さんぽ","しお","しかし",
  4197. "じかん","しごと","じしょ","しずか","した","しち","しつもん","じてんしゃ",
  4198. "じどうしゃ","しぬ","じびき","じぶん","しまる","しめる","しめる",
  4199. "じゃあ","しゃしん","しゃつ","じゅう","じゅぎょう","しゅくだい","じょうず",
  4200. "じょうぶ","しょうゆ","しょくどう","しる","しろい","しんぶん","すいようび",
  4201. "すう","すかーと","すき","すぐに","すこし","すずしい","すとーぶ",
  4202. "すぷーん","すぽーつ","ずぼん","すむ","すりっぱ","する","すわる",
  4203. "せい","せいと","せっけん","せーたー","せびろ","せまい","ぜろ",
  4204. "せん","せんげつ","せんしゅう","せんせい","せんたく","ぜんぶ","そうじ",
  4205. "そうして","そして","そこ","そちら","そと","その","そば","そら",
  4206. "それ","それから","それでは","だいがく","たいしかん","だいじょうぶ",
  4207. "だいすき","たいせつ","たいてい","だいどころ","たいへん","たかい",
  4208. "たくさん","たくしー","だす","たつ","たてもの","たのしい","たのむ",
  4209. "たばこ","たぶん","たべもの","たべる","たまご","だれ","たんじょうび",
  4210. "だんだん","ちいさい","ちかい","ちがう","ちかく","ちかてつ",
  4211. "ちず","ちち","ちゃいろ","ちゃわん","ちょうど","ちょっと","ついたち",
  4212. "つかう","つかれる","つぎ","つく","つくえ","つくる","つける","つとめる",
  4213. "つまらない","つめたい","つよい","て","てーぷ","てーぶる","でかける",
  4214. "てがみ","できる","でぐち","てすと","では","でぱーと","でも",
  4215. "でる","てれび","てんき","でんき","でんしゃ","でんわ","と","どあ",
  4216. "といれ","どうして","どうぞ","どうぶつ","どうも","とお","とおい","とおか",
  4217. "ときどき","とけい","どこ","ところ","としょかん","どちら","とても","どなた",
  4218. "となり","どの","とぶ","とまる","ともだち","どようび","とり","とりにく",
  4219. "とる","とる","どれ","どんな","ない","ないふ","なか","ながい",
  4220. "なく","なつ","なつやすみ","ななつ","なに","なのか","なまえ","ならう",
  4221. "ならぶ","ならべる","に","にぎやか","にく","にし","にちようび",
  4222. "にもつ","にゅーす","にわ","ぬぐ","ねくたい","ねる","のーと","のぼる",
  4223. "のみもの","のむ","のる","は","ぱーてぃー","はい","はいざら",
  4224. "はいる","はがき","はく","はこ","はし","はし","はじまる","はじめに",
  4225. "はじめて","はしる","ばす","ばたー","はたち","はたらく","はち","はつか",
  4226. "はな","はな","はなし","はなす","はは","はやい","はやい","はる",
  4227. "はる","はれる","はん","ばん","ぱん","はんかち","ばんごう",
  4228. "ばんごはん","はんぶん","ひがし","ひく","ひく","ひくい","ひこうき",
  4229. "ひだり","ひと","ひとつ","ひとつき","ひとり","ひま","ひゃく","びょういん",
  4230. "びょうき","ひらがな","ひる","ひるごはん","ひろい","ふぃるむ","ふうとう",
  4231. "ぷーる","ふぉーく","ふく","ふく","ふたつ","ぶたにく","ふたり","ふつか",
  4232. "ふとい","ふゆ","ふる","ふるい","ふろ","ぱーじ","へた","べっど",
  4233. "へや","へん","ぺん","べんきょう","べんり","ほう","ぼうし","ぼーるぺん",
  4234. "ほか","ぽけっと","ほしい","ほそい","ぼたん","ほてる","ほん",
  4235. "ほんだな","ほんとうに","まいあさ","まいげつ","まいつき","まいしゅう","まいにち",
  4236. "まいねん","まいとし","まいばん","まえ","まがる","まずい","また","まだ",
  4237. "まち","まつ","まっすぐ","まっち","まど","まるい","まるい","まん",
  4238. "まんねんひつ","みがく","みぎ","みじかい","みず","みせ","みせる","みち",
  4239. "みっか","みっつ","みなさん","みなみ","みみ","みる","みんな","むいか",
  4240. "むこう","むずかしい","むっつ","め","めーとる","めがね","もう",
  4241. "もくようび","もしもし","もちろん","もつ","もっと","もの","もん",
  4242. "もんだい","やおや","やさい","やさしい","やすい","やすみ","やすむ",
  4243. "やっつ","やま","やる","ゆうがた","ゆうびんきょく","ゆうべ","ゆうめい",
  4244. "ゆき","ゆっくり","ようか","ようふく","よく","よこ","よっか","よっつ",
  4245. "よぶ","よむ","よる","らいげつ","らいしゅう","らいねん","らじお",
  4246. "りっぱ","りゅうがくせい","りょうしん","りょうり","りょこう","れい","れいぞうこ",
  4247. "れこーど","れすとらん","れんしゅう","ろく","わいしゃつ","わかい",
  4248. "わかる","わすれる","わたくし","わたし","わたす","わたる","わるい",
  4249. "ああ","あいさつ","あいだ","あう","あかちゃん","あがる","あかんぼう","あく","あくせさりー","あげる","あさい","あじ","あじあ","あす","あそび", // JLPT lv 3
  4250. "あつまる","あつめる","あなうんさー","あふりか","あめりか","あやまる","あるこーる","あるばいと","あんしん","あんぜん","あんな","あんない",
  4251. "いか","いがい","いがく","いきる","いけん","いし","いじめる","いじょう","いそぐ","いたす","いただく","いちど","いっしょうけんめい","いっぱい",
  4252. "いと","いない","いなか","いのる","いらっしゃる","うえる","うかがう","うかがう","うけつけ","うける","うごく","うそ","うち","うつ","うつくしい",
  4253. "うつす","うつる","うで","うまい","うら","うりば","うれしい","うん","うんてんしゅ","うんてん","うんどう","えすかれーたー","えだ","えらぶ","えんりょ",
  4254. "おいでになる","おいわい","おーとばい","おーばー","おかげ","おかしい","おく","おくじょう","おくりもの","おくる","おくれる","おこさん","おこす",
  4255. "おこなう","おこる","おしいれ","おじょうさん","おたく","おちる","おっしゃる","おっと","おつり","おと","おとす","おどり","おどる","おどろく",
  4256. "おまつり","おみまい","おみやげ","おもいだす","おもう","おもちゃ","おもて","おや","おりる","おる","おる","おれい","おれる","おわり","かーてん",
  4257. "かいがん","かいぎ","かいぎしつ","かいじょう","かいわ","かえり","かえる","かがく","かがみ","かける","かける","かける","かざる","かじ","がす",
  4258. "がそりん","がそりんすたんど","かた","かたい","かたち","かたづける","かちょう","かつ","かっこう","かない","かなしい","かならず","かねもち",
  4259. "おかねもち","かのじょ","かべ","かまう","かみ","かむ","かよう","がらす","かれ","かれら","かわく","かわり","かわる","かんがえる","かんけい",
  4260. "かんごふ","かんたん","がんばる","き","きかい","きけん","きこえる","きしゃ","ぎじゅつ","きせつ","きそく","きっと","きぬ","きびしい","きぶん",
  4261. "きまる","きみ","きめる","きもち","きもの","きゃく","きゅう","きゅうこう","きょういく","きょうかい","きょうそう","きょうみ","きんじょ","ぐあい",
  4262. "くうき","くうこう","くさ","くださる","くび","くも","くらべる","くれる","くれる","け","け","けいかく","けいけん","けいざい","けいさつ","けが",
  4263. "けーき","けしき","けしごむ","げしゅく","けっして","けれど","けれども","げんいん","けんか","げんかん","けんきゅう","けんきゅうしつ","けんぶつ",
  4264. "こ","こう","こうがい","こうぎ","こうぎょう","こうこう","こうとうがっこう","こうこうせい","こうじょう","こうちょう","こうつう","こうどう",
  4265. "こうむいん","こくさい","こころ","ごしゅじん","こしょう","ごぞんじ","こたえ","ごちそう","こっち","こと","ことり","このあいだ","このごろ",
  4266. "こまかい","ごみ","こむ","こめ","ごらんになる","これから","こわい","こわす","こわれる","こんさーと","こんど","こんや","さいきん","さいご",
  4267. "さいしょ","さか","さがす","さがる","さかん","さげる","さしあげる","さっき","さびしい","さらいげつ","さらいしゅう","さらだ","さわぐ","さわる",
  4268. "さんぎょう","さんだる","さんどいっち","ざんねん","し","じ","しあい","しかた","しかる","しけん","じこ","じしん","じだい","したぎ","したくする",
  4269. "しっかり","しっぱい","しつれい","じてん","しなもの","しばらく","しま","しみん","じむしょ","しゃかい","しゃちょう","じゃま","じゃむ","じゆう",
  4270. "しゅうかん","じゅうしょ","じゅうどう","じゅうぶん","しゅっせきする","しゅっぱつする","しゅみ","じゅんびする","しょうかい","しょうがつ",
  4271. "しょうがっこう","しょうせつ","しょうたいする","しょうちする","しょうらい","しょくじする","しょくしゅ","しょくりょうひん","じょせい","しらせる",
  4272. "しらべる","じんこう","じんじゃ","しんせつ","しんぱいする","しんぶんしゃ","すいえい","すいどう","ずいぶん","すうがく","すーつ","すーつけーす",
  4273. "すーぱー","すぎる","すく","すく","すくりーん","すごい","すすむ","すっかり","ずっと","すてーき","すてれお","すてる","すな","すばらしい",
  4274. "すべる","すみ","すむ","すり","すると","せいかつする","せいさんする","せいじ","せいよう","せかい","せき","せつめい","せなか","ぜひ","せわする",
  4275. "せん","ぜんぜん","せんそう","せんぱい","せんもん","そう","そうだんする","そだてる","そつぎょう","そふ","そふと","そぼ","それで","それに",
  4276. "それほど","そろそろ","そんな","そんなに","たいいんする","だいがくせい","だいじ","だいたい","たいてい","たいぷ","だいぶ","たいふう",
  4277. "たおれる","だから","たしか","たす","たずねる","たずねる","ただしい","たたみ","たてる","たてる","たとえば","たな","たのしむ","たのしみ",
  4278. "たまに","ため","だめ","たりる","だんせい","だんぼう","ち","ちぇっく","ちから","ちっとも","ちゅうい","ちゅうがっこう","ちゅうしゃ",
  4279. "ちゅうしゃじょう","ちり","つかまえる","つき","つく","つける","つける","つごう","つたえる","つづく","つづける","つつむ","つま","つもり",
  4280. "つる","つれる","ていねい","てきすと","てきとう","できる","できるだけ","てつだう","てにす","てぶくろ","てら","てん","てんいん",
  4281. "てんきよほう","でんとう","でんぽう","てんらんかい","と","どうぐ","とうとう","どうぶつえん","とおく","とおり","とおる","とくに","とくべつ",
  4282. "とこや","とちゅう","とっきゅう","とどける","とまる","とめる","とりかえる","どろぼう","どんどん","なおす","なおる","なおる","なかなか",
  4283. "なく","なくなる","なくなる","なげる","なさる","なる","なるべく","なるほど","なれる","におい","にがい","にげる","にっき","にゅういん",
  4284. "にゅうがく","にる","にんぎょう","ぬすむ","ぬる","ぬれる","ねだん","ねつ","ねっしん","ねぼう","ねむい","ねむる","のこる","のど","のりかえる",
  4285. "のりもの","は","ばあい","ぱーと","ばい","はいけん","はいしゃ","はこぶ","はじめる","ばしょ","はず","はずかしい","ぱそこん","はつおん",
  4286. "はっきり","はなみ","ぱぱ","はやし","はらう","ばんぐみ","はんたい","はんばーぐ","ひ","ぴあの","ひえる","ひかる","ひかり","ひきだし","ひげ",
  4287. "ひこうじょう","ひさしぶり","びじゅつかん","ひじょうに","びっくりする","ひっこす","ひつよう","ひどい","ひらく","びる","ひるま","ひるやすみ",
  4288. "ひろう","ふぁっくす","ふえる","ふかい","ふくざつ","ふくしゅう","ぶちょう","ふつう","ぶどう","ふとる","ふとん","ふね","ふべん","ふむ",
  4289. "ぷれぜんと","ぶんか","ぶんがく","ぶんぽう","べつ","べる","へん","へんじ","ぼうえき","ほうそう","ほうりつ","ぼく","ほし","ほど","ほとんど",
  4290. "ほめる","ほんやく","まいる","まける","まじめ","まず","または","まちがえる","まにあう","まわり","まわる","まんが","まんなか","みえる",
  4291. "みずうみ","みそ","みつかる","みつける","みな","みなと","むかえる","むかう","むかし","むし","むすこ","むすめ","むり","めしあがる","めずらしい",
  4292. "もうしあげる","もうす","もうすぐ","もし","もちろん","もっとも","もどる","もめん","もらう","もり","やく","やくにたつ","やくそく","やける",
  4293. "やさしい","やせる","やっと","やはり","やっぱり","やむ","やめる","やる","やわらかい","ゆ","ゆうはん","ゆしゅつ","ゆにゅう","ゆび","ゆびわ",
  4294. "ゆめ","ゆれる","よう","よう","ようい","ようじ","よごれる","よしゅう","よてい","よやく","よる","よろこぶ","よろしい","りゆう","りよう",
  4295. "りょうほう","りょかん","るす","れいぼう","れきし","れじ","れぽーと","れんらく","わーぷろ","わかす","わかれる","わく","わけ","わすれもの","わらう","わりあい","われる"
  4296. ];
  4297. public static const list:Array = [
  4298. "able","about","account","acid","across","act","addition","adjustment","advertisement","after","again","against","agreement","air","all","almost","among","amount","amusement","and","angle","angry","animal","answer","ant","any","apparatus","apple","approval","arch","argument","arm","army","art","as","at","attack","attempt","attention","attraction","authority","automatic","awake",
  4299. "baby","back","bad","bag","balance","ball","band","base","basin","basket","bath","be","beautiful","because","bed","bee","before","behaviour","belief","bell","bent","berry","between","bird","birth","bit","bite","bitter","black","blade","blood","blow","blue","board","boat","body","boiling","bone","book","boot","bottle","box","boy","brain","brake","branch","brass","bread","breath","brick","bridge","bright","broken","brother","brown","brush","bucket","building","bulb","burn","burst","business","but","butter","button","by",
  4300. "cake","camera","canvas","card","care","carriage","cart","cat","cause","certain","chain","chalk","chance","change","cheap","cheese","chemical","chest","chief","chin","church","circle","clean","clear","clock","cloth","cloud","coal","coat","cold","collar","colour","comb","come","comfort","committee","common","company","comparison","competition","complete","complex","condition","connection","conscious","control","cook","copper","copy","cord","cork","cotton","cough","country","cover","cow","crack","credit","crime","cruel","crush","cry","cup","cup","current","curtain","curve","cushion",
  4301. "damage","danger","dark","daughter","day","dead","dear","death","debt","decision","deep","degree","delicate","dependent","design","desire","destruction","detail","development","different","digestion","direction","dirty","discovery","discussion","disease","disgust","distance","distribution","division","do","dog","door","doubt","down","drain","drawer","dress","drink","driving","drop","dry","dust",
  4302. "ear","early","earth","east","edge","education","effect","egg","elastic","electric","end","engine","enough","equal","error","even","event","ever","every","example","exchange","existence","expansion","experience","expert","eye",
  4303. "face","fact","fall","false","family","far","farm","fat","father","fear","feather","feeble","feeling","female","fertile","fiction","field","fight","finger","fire","first","fish","fixed","flag","flame","flat","flight","floor","flower","fly","fold","food","foolish","foot","for","force","fork","form","forward","fowl","frame","free","frequent","friend","from","front","fruit","full","future",
  4304. "garden","general","get","girl","give","glass","glove","go","goat","gold","good","government","grain","grass","great","green","grey","grip","group","growth","guide","gun",
  4305. "hair","hammer","hand","hanging","happy","harbour","hard","harmony","hat","hate","have","he","head","healthy","hear","hearing","heart","heat","help","high","history","hole","hollow","hook","hope","horn","horse","hospital","hour","house","how","humour",
  4306. "ice","idea","if","ill","important","impulse","in","increase","industry","ink","insect","instrument","insurance","interest","invention","iron","island",
  4307. "jelly","jewel","join","journey","judge","jump",
  4308. "keep","kettle","key","kick","kind","kiss","knee","knife","knot","knowledge",
  4309. "land","language","last","late","laugh","law","lead","leaf","learning","leather","left","leg","let","letter","level","library","lift","light","like","limit","line","linen","lip","liquid","list","little","living","lock","long","look","loose","loss","loud","love","low",
  4310. "machine","make","male","man","manager","map","mark","market","married","mass","match","material","may","meal","measure","meat","medical","meeting","memory","metal","middle","military","milk","mind","mine","minute","mist","mixed","money","monkey","month","moon","morning","mother","motion","mountain","mouth","move","much","muscle","music",
  4311. "nail","name","narrow","nation","natural","near","necessary","neck","need","needle","nerve","net","new","news","night","no","noise","normal","north","nose","not","note","now","number","nut",
  4312. "observation","of","off","offer","office","oil","old","on","only","open","operation","opinion","opposite","or","orange","order","organization","ornament","other","out","oven","over","owner",
  4313. "page","pain","paint","paper","parallel","parcel","part","past","paste","payment","peace","pen","pencil","person","physical","picture","pig","pin","pipe","place","plane","plant","plate","play","please","pleasure","plough","pocket","point","poison","polish","political","poor","porter","position","possible","pot","potato","powder","power","present","price","print","prison","private","probable","process","produce","profit","property","prose","protest","public","pull","pump","punishment","purpose","push","put",
  4314. "quality","question","quick","quiet","quite",
  4315. "rail","rain","range","rat","rate","ray","reaction","reading","ready","reason","receipt","record","red","regret","regular","relation","religion","representative","request","respect","responsible","rest","reward","rhythm","rice","right","ring","river","road","rod","roll","roof","room","root","rough","round","rub","rule","run",
  4316. "sad","safe","sail","salt","same","sand","say","scale","school","science","scissors","screw","sea","seat","second","secret","secretary","see","seed","seem","selection","self","send","sense","separate","serious","servant","sex","shade","shake","shame","sharp","sheep","shelf","ship","shirt","shock","shoe","short","shut","side","sign","silk","silver","simple","sister","size","skin","skirt","sky","sleep","slip","slope","slow","small","smash","smell","smile","smoke","smooth","snake","sneeze","snow","so","soap","society","sock","soft","solid","some","son","song","sort","sound","soup","south","space","spade","special","sponge","spoon","spring","square","stage","stamp","star","start","statement","station","steam","steel","stem","step","stick","sticky","stiff","still","stitch","stocking","stomach","stone","stop","store","story","straight","strange","street","stretch","strong","structure","substance","such","sudden","sugar","suggestion","summer","sun","support","surprise","sweet","swim","system",
  4317. "table","tail","take","talk","tall","taste","tax","teaching","tendency","test","than","that","the","then","theory","there","thick","thin","thing","this","thought","thread","throat","through","through","thumb","thunder","ticket","tight","till","time","tin","tired","to","toe","together","tomorrow","tongue","tooth","top","touch","town","trade","train","transport","tray","tree","trick","trouble","trousers","true","turn","twist",
  4318. "umbrella","under","unit","up","use",
  4319. "value","verse","very","vessel","view","violent","voice",
  4320. "waiting","walk","wall","war","warm","wash","waste","watch","water","wave","wax","way","weather","week","weight","well","west","wet","wheel","when","where","while","whip","whistle","white","who","why","wide","will","wind","window","wine","wing","winter","wire","wise","with","woman","wood","wool","word","work","worm","wound","writing","wrong",
  4321. "year", "yellow", "yes", "yesterday", "you", "young"
  4322. ];
  4323. public static function getRandom():String {
  4324. return list[ int(Math.random() * list.length) ];
  4325. }
  4326. public static function getJRandom():Array {
  4327. var index:int = int(Math.random() * jList.length);
  4328. //return [jKanjiList[index], jList[index]];
  4329. return ["", jList[index]];
  4330. }
  4331. public static function isExist(word:String):Boolean {
  4332. return( (list.indexOf(word) >= 0) );
  4333. }
  4334. public static function isJExist(word:String):Boolean {
  4335. if ( word.charCodeAt(0) < 128 ) {
  4336. word = Roma.getHiragana(word);
  4337. }
  4338. return( (jList.indexOf(word) >= 0 ) );
  4339. }
  4340. }
  4341. // 音管理クラス
  4342. class SoundManager {
  4343. public static var ClickSound:Sound;
  4344. public static var ComboSound:Sound;
  4345. public static var ShootSound:Sound;
  4346. public static var AttackSound:Sound;
  4347. public static var HitSound:Sound;
  4348. public static var DamageSound:Sound;
  4349. public static var DangerSound:Sound;
  4350. public static var TypeSound:Sound;
  4351. public static var GameBGM:Sound;
  4352. public static var ReflectSound:Sound;
  4353. public static var count:Number = 0;
  4354. public static const countMax:Number = 10;
  4355. public static var initChecker:EventDispatcher = new EventDispatcher();
  4356. public static function init():void {
  4357. ClickSound = new Sound();
  4358. ClickSound.addEventListener(Event.COMPLETE, onComplete);
  4359. ClickSound.load(new URLRequest("http://keno.serio.jp/sound/click.mp3"));
  4360. ComboSound = new Sound();
  4361. ComboSound.addEventListener(Event.COMPLETE, onComplete);
  4362. ComboSound.load(new URLRequest("http://keno.serio.jp/sound/combo.mp3"));
  4363. ShootSound = new Sound();
  4364. ShootSound.addEventListener(Event.COMPLETE, onComplete);
  4365. ShootSound.load(new URLRequest("http://keno.serio.jp/sound/shoot.mp3"));
  4366. AttackSound = new Sound();
  4367. AttackSound.addEventListener(Event.COMPLETE, onComplete);
  4368. AttackSound.load(new URLRequest("http://keno.serio.jp/sound/attack.mp3"));
  4369. HitSound = new Sound();
  4370. HitSound.addEventListener(Event.COMPLETE, onComplete);
  4371. HitSound.load(new URLRequest("http://keno.serio.jp/sound/hit.mp3"));
  4372. DamageSound = new Sound();
  4373. DamageSound.addEventListener(Event.COMPLETE, onComplete);
  4374. DamageSound.load(new URLRequest("http://keno.serio.jp/sound/damage.mp3"));
  4375. DangerSound = new Sound();
  4376. DangerSound.addEventListener(Event.COMPLETE, onComplete);
  4377. DangerSound.load(new URLRequest("http://keno.serio.jp/sound/danger.mp3"));
  4378. TypeSound = new Sound();
  4379. TypeSound.addEventListener(Event.COMPLETE, onComplete);
  4380. TypeSound.load(new URLRequest("http://keno.serio.jp/sound/type.mp3"));
  4381. GameBGM = new Sound();
  4382. GameBGM.addEventListener(Event.COMPLETE, onComplete);
  4383. GameBGM.load(new URLRequest("http://keno.serio.jp/sound/gameBgm.mp3"));
  4384. ReflectSound = new Sound();
  4385. ReflectSound.addEventListener(Event.COMPLETE, onComplete);
  4386. ReflectSound.load(new URLRequest("http://keno.serio.jp/sound/reflect.mp3"));
  4387. }
  4388. private static var gameBgmCh:SoundChannel;
  4389. public static function playGameBgm():void {
  4390. timer.stop();
  4391. if( gameBgmCh == null ) gameBgmCh = GameBGM.play(0, 99999);
  4392. }
  4393. public static function stopGameBgm():void {
  4394. if ( gameBgmCh != null ) {
  4395. timer.start();
  4396. timer.addEventListener(TimerEvent.TIMER, onTimer);
  4397. }
  4398. }
  4399. private static var timer:Timer = new Timer(100, 10);
  4400. private static var volume:Number = 1.0;
  4401. private static function onTimer(e:TimerEvent):void {
  4402. gameBgmCh.soundTransform = new SoundTransform(volume);
  4403. volume-= 0.1;
  4404. if ( volume < 0.1 ) {
  4405. e.target.removeEventListener(TimerEvent.TIMER, onTimer);
  4406. gameBgmCh.stop();
  4407. gameBgmCh = null;
  4408. }
  4409. }
  4410. private static function onComplete(e:Event):void {
  4411. count++;
  4412. e.target.removeEventListener(Event.COMPLETE, onComplete);
  4413. initChecker.dispatchEvent(new ProgressEvent(ProgressEvent.PROGRESS, false, false, count, countMax));
  4414. }
  4415. }
flash swf thumbnail play
出題者からのコメント
これはすごい!とても楽しくて、ハマってしまいますね。クライアントサイドでこれほど複雑なロジックを実現するのは、もはや感動的です。
Comments from King
Incredible! Very fun and addictive game, and impressive to achieve such complex logic all client-side!

Bishopclockmaker

  1. // forked from checkmate's colin challenge for professionals
  2. /**
  3.  * Create a Flash app using Union Platform,
  4.  * where you can collaborate with more than 4 people online.
  5.  *
  6.  * UnionRamen is an example app,
  7.  * you can write code based on this, or build from scratch.
  8.  *
  9.  * UnionRamen is a multiuser bowl of ramen built on the Union Platform.
  10.  * Press the 'n' key to add naruto to the bowl.
  11.  * For Union Platform documentation, see www.unionplatform.com.
  12.  * 
  13.  * @author   Colin Moock
  14.  * @date     July 2009
  15.  * @location Toronto, Canada
  16.  */
  17.  /**
  18.   * テノリオンのオンライン共有型で3Dで作ってみました。
  19.   * ネット上の誰かが変更すると、その変更が反映されます。
  20.   * 
  21.   * 音 powered by SiONライブラリ
  22.   * ネット共有 powered by Union プラットフォーム
  23.   * 3D powered by Papervision3D
  24.   */
  25. package
  26. {
  27.     // Flash
  28.     import flash.display.*;
  29.     import flash.events.*;
  30.     import flash.filters.*;
  31.     import flash.geom.*;
  32.     import flash.text.*;
  33.     import flash.utils.*;
  34.     
  35.     // Union
  36.     import net.user1.reactor.*;
  37.     import net.user1.logger.Logger;
  38.     
  39.     // SiON
  40.     import org.si.sion.*;
  41.     import org.si.sion.events.*;
  42.     import org.si.sion.sequencer.SiMMLTrack;
  43.     import org.si.sion.utils.SiONPresetVoice;
  44.     
  45.     // PV3D
  46.     import org.papervision3d.core.proto.MaterialObject3D;
  47.     import org.papervision3d.lights.PointLight3D;
  48.     import org.papervision3d.materials.shadematerials.FlatShadeMaterial;
  49.     import org.papervision3d.objects.primitives.*;
  50.     import org.papervision3d.view.BasicView;
  51.     import org.papervision3d.events.InteractiveScene3DEvent;
  52.     import org.papervision3d.materials.special.*;
  53.     import org.papervision3d.materials.*;
  54.     import org.papervision3d.objects.special.*;
  55.     
  56.     [SWF(width = "465", height = "465", backgroundColor = "0", frameRate = 30)]
  57.     
  58.     public class Main extends Sprite
  59.     {
  60.         static private const USER_COLOR:uint = Math.random() * 0xFF0000;
  61.         static private const MATRIX_NUM:int = 16;
  62.         static private const DEF_COLOR:int = 0x555555;
  63.         static private const ACTIVE_COLOR:int = 0xEEEEEE;
  64.         static private const OVER_COLOR:int = 0x999999;
  65.             
  66.         //-----------------------------------
  67.         // Union
  68.         //-----------------------------------
  69.         protected var reactor:Reactor;
  70.         protected var room:Room;
  71.         
  72.         
  73.         //-----------------------------------
  74.         // SiON
  75.         //-----------------------------------
  76.         
  77.         // driver
  78.         public var driver:SiONDriver = new SiONDriver();
  79.         
  80.         // preset voice
  81.         public var presetVoice:SiONPresetVoice = new SiONPresetVoice();
  82.         
  83.         // voices, notes and tracks
  84.         public var tracks:Vector.<SiMMLTrack> = new Vector.<SiMMLTrack>(16);
  85.         public var voices:Vector.<int> = Vector.<int>([ 0123,  4444,  4444,  4444]);
  86.         public var notes:Vector.<int>  = Vector.<int>([36,48,60,7243,48,55,6065,67,70,7277,79,82,84]);
  87.         
  88.         // beat counter
  89.         public var beatCounter:int;
  90.         
  91.         
  92.         //-----------------------------------
  93.         // PV3d
  94.         //-----------------------------------
  95.         private var world:BasicView = new BasicView(465465falsetrue);
  96.         private var light:PointLight3D = new PointLight3D();
  97.         private var cubes:Array = [];
  98.         private var logicMatrix:Array = [];
  99.         private var oldDispMatrix:Array = [];
  100.         private var dispMatrix:Array = [];
  101.         private var rollOverMatrix:Array = [];
  102.         
  103.         
  104.         /**
  105.          * コンストラクタ
  106.          */
  107.         public function Main()
  108.         {
  109.             stage.quality = StageQuality.MEDIUM;
  110.             
  111.             setupUnion();
  112.             setupPV3D();
  113.             setupSiON();
  114.             setupUI();
  115.             
  116.             Wonderfl.capture_delay( 10 );
  117.         }
  118.         
  119.         //-----------------------------------
  120.         // Union
  121.         //-----------------------------------
  122.         
  123.         private function setupUnion():void
  124.         {
  125.             // 接続用のReactorオブジェクトを作成
  126.             reactor = new Reactor();
  127.             // 接続完了したら readyListener() を起動
  128.             reactor.addEventListener(ReactorEvent.READY, readyListener);
  129.             // Unionに接続。
  130.             // "tryunion.com:9100"は自由に使えるUnionテスト用の公開サーバーです
  131.             reactor.connect("tryunion.com"9100);
  132.             reactor.getLog().setLevel(Logger.DEBUG);
  133.         }
  134.         
  135.         // 接続完了時に起動されるメソッド
  136.         protected function readyListener (e:ReactorEvent):void
  137.         {
  138.             reactor.getMessageManager().addMessageListener("GIVE_ME_LOG", sendLog);
  139.             reactor.getMessageManager().addMessageListener("THIS_IS_LOG", happyToReceiveLog);
  140.             
  141.             // このアプリ用のルームを作成
  142.             room = reactor.getRoomManager().createRoom("wonderfl.clockmaker.tenorion");
  143.             // 他ユーザーがこのルームに送信する"SOMEONE_CHANGE"メッセージを監視します
  144.             room.addMessageListener("SOMEONE_CHANGE", changeCellHandler);
  145.             room.addEventListener(RoomEvent.SYNCHRONIZE, onSynchronize);
  146.             // ルームに入室
  147.             room.join();
  148.         }
  149.         
  150.         // invoked when received map from someone
  151.         protected function happyToReceiveLog(from:IClient, data:String):void
  152.         {
  153.             trace(data);
  154.             var arr:Array = data.split(",");
  155.             
  156.             for (var i:int = 0; i < arr.length; i++) 
  157.             {
  158.                 var u:int = i % MATRIX_NUM;
  159.                 var v:int = Math.floor(i / MATRIX_NUM);
  160.                 
  161.                 logicMatrix[u][v] = arr[i];
  162.             }
  163.         }
  164.         
  165.         // send map to new comer
  166.         protected function sendLog(from:IClient):void
  167.         {
  168.             var data:Array = [];
  169.             for (var i:int = 0; i < logicMatrix.length; i++) 
  170.                 for (var j:int = 0; j < logicMatrix[i].length; j++) 
  171.                     data.push(logicMatrix[i][j]);
  172.             from.sendMessage("THIS_IS_LOG", data.join(","));
  173.         }
  174.         
  175.         private function onSynchronize(e:RoomEvent):void 
  176.         {
  177.             if ( room.getClients().length == 1 ) {
  178.                 // 何もしない
  179.             } else {
  180.                 var topClient:IClient = room.getClients()[0];
  181.                 topClient.sendMessage("GIVE_ME_LOG");
  182.             }
  183.         }
  184.         
  185.         protected function sendCellStatus (o:Object):void
  186.         {
  187.             // 未接続だったら何もしない
  188.             if (!reactor.isReady()) return;
  189.             room.sendMessage("SOMEONE_CHANGE"truenull, o.colorId, o.u, o.v);
  190.         }
  191.         // 他ユーザーの"ADD_NARUTO"メッセージ受信時に起動するメソッド
  192.         protected function changeCellHandler (fromClient:IClient, colorId:uint, u:int, v:int):void
  193.         {
  194.             logicMatrix[u][v] = colorId;
  195.         }
  196.         
  197.         
  198.         
  199.         //-----------------------------------
  200.         // SiON
  201.         //-----------------------------------
  202.         
  203.         private function setupSiON():void
  204.         {
  205.             driver.setVoice(0, presetVoice["valsound.percus1"]);  // bass drum
  206.             driver.setVoice(1, presetVoice["valsound.percus28"]); // snare drum
  207.             driver.setVoice(2, presetVoice["valsound.percus17"]); // close hihat
  208.             driver.setVoice(3, presetVoice["valsound.percus23"]); // open hihat
  209.             driver.setVoice(4, presetVoice["valsound.bass18"]);
  210.             
  211.             // listen click
  212.             driver.setTimerInterruption(1, _onTimerInterruption);
  213.             driver.setBeatCallbackInterval(1);
  214.             driver.addEventListener(SiONTrackEvent.BEAT, _onBeat);
  215.             driver.addEventListener(SiONEvent.STREAM_START, _onStreamStart);
  216.             // start streaming
  217.             driver.play();
  218.         }
  219.         
  220.         // _onStreamStart (SiONEvent.STREAM_START) is called back first of all after SiONDriver.play().
  221.         private function _onStreamStart(e:SiONEvent) : void
  222.         {
  223.             // create new controlable tracks and set voice
  224.             for (var i:int=0; i<MATRIX_NUM; i++) {
  225.                 tracks[i] = driver.sequencer.newControlableTrack();
  226.                 tracks[i].setChannelModuleType(60, voices[i]);
  227.                 tracks[i].velocity = 64;
  228.             }
  229.             beatCounter = 0;
  230.         }
  231.         
  232.         
  233.         // _onBeat (SiONTrackEvent.BEAT) is called back in each beat at the sound timing.
  234.         private function _onBeat(e:SiONTrackEvent) : void 
  235.         {
  236.             //matrixPad.beat(e.eventTriggerID & 15);
  237.             beat(e.eventTriggerID & MATRIX_NUM - 1);
  238.         }
  239.         
  240.         
  241.         // _onTimerInterruption (SiONDriver.setTimerInterruption) is called back in each beat at the buffering timing.
  242.         private function _onTimerInterruption() : void
  243.         {
  244.             var beatIndex:int = beatCounter & (MATRIX_NUM - 1);
  245.             for (var i:int = 0; i < MATRIX_NUM; i++)
  246.             {
  247.                 if (logicMatrix[beatIndex][i] != DEF_COLOR)
  248.                     tracks[i].keyOn(notes[i]);
  249.             }
  250.             
  251.             beatCounter++;
  252.         }
  253.         
  254.         
  255.         
  256.         //-----------------------------------
  257.         // PV3d
  258.         //-----------------------------------
  259.         
  260.         private function setupPV3D():void
  261.         {
  262.             addChild(world);
  263.             world.startRendering();
  264.             
  265.             for (var i:int = 0; i < MATRIX_NUM; i++) 
  266.             {
  267.                 cubes[i] = [];
  268.                 logicMatrix[i] = [];
  269.                 rollOverMatrix[i] = [];
  270.                 for (var j:int = 0; j < MATRIX_NUM; j++) 
  271.                 {
  272.                     var material:MaterialObject3D = new FlatShadeMaterial(light, DEF_COLOR);
  273.                     //var material:MaterialObject3D = new ColorMaterial(DEF_COLOR);
  274.                     material.interactive = true;
  275.                     var cube:Plane = new Plane(material, 7070);
  276.                     cube.x = 80 * (i - MATRIX_NUM / 2);
  277.                     cube.z = 80 * (j - MATRIX_NUM / 2);
  278.                     cube.y = 100;
  279.                     cube.extra = { u:i, v:j };
  280.                     cube.rotationX = 90;
  281.                     cube.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK, cubeClickHandler);
  282.                     world.scene.addChild(cube);
  283.                     cubes[i][j] = cube;
  284.                     logicMatrix[i][j] = DEF_COLOR;
  285.                     rollOverMatrix[i][j] = false;
  286.                 }
  287.             }
  288.             
  289.             // ついでにパーティクルを生成します(彗星)
  290.             var particleMat:ParticleMaterial = new ParticleMaterial(0xFFFFFF, 1);
  291.             var particles:ParticleField = new ParticleField(particleMat, 5005600040006000);
  292.             particles.y = -150;
  293.             world.scene.addChild( particles );
  294.             
  295.             dispMatrix = copyArray2(logicMatrix);
  296.             oldDispMatrix = copyArray2(dispMatrix);
  297.             
  298.             // ライト
  299.             light.x = 200;
  300.             light.y = 400;
  301.             light.z = 200;
  302.             
  303.             world.camera.zoom = 1;
  304.             world.camera.focus = 400;
  305.             
  306.             addEventListener(Event.ENTER_FRAME, loop);
  307.         }
  308.         
  309.         private function beat(beat16th:int):void 
  310.         {
  311.             for (var i:int = 0; i < dispMatrix.length; i++) 
  312.             {
  313.                 for (var j:int = 0; j < dispMatrix[i].length; j++) 
  314.                 {
  315.                     if (beat16th == i)
  316.                     {
  317.                         dispMatrix[i][j] = ACTIVE_COLOR;
  318.                         
  319.                         if (logicMatrix[i][j] != DEF_COLOR)
  320.                             dispMatrix[i][j] = uint(logicMatrix[i][j] * 0x666666);
  321.                     }
  322.                     else
  323.                     {
  324.                         dispMatrix[i][j] = logicMatrix[i][j];
  325.                     }
  326.                     
  327.                     if (rollOverMatrix[i][j]) dispMatrix[i][j] = OVER_COLOR;
  328.                 }
  329.             }
  330.             
  331.             update();
  332.         }
  333.         
  334.         private function cubeClickHandler(e:InteractiveScene3DEvent):void 
  335.         {
  336.             var u:int = e.target.extra.u;
  337.             var v:int = e.target.extra.v;
  338.             
  339.             if (logicMatrix[u][v] == DEF_COLOR)
  340.             {
  341.                 logicMatrix[u][v] = USER_COLOR;
  342.                 sendCellStatus( { colorId:USER_COLOR, u:u, v:v } );
  343.             }
  344.             else
  345.             {
  346.                 logicMatrix[u][v] = DEF_COLOR;
  347.                 sendCellStatus( { colorId:DEF_COLOR, u:u, v:v } );
  348.             }
  349.             
  350.             update();
  351.         }
  352.         
  353.         private function update():void
  354.         {
  355.             var oldTime:Number = getTimer();
  356.             for (var i:int = 0; i < dispMatrix.length; i++) 
  357.             {
  358.                 for (var j:int = 0; j < dispMatrix[i].length; j++) 
  359.                 {
  360.                     var c:Plane = cubes[i][j];
  361.                     if (dispMatrix[i][j] != oldDispMatrix[i][j])
  362.                     {
  363.                         var material:MaterialObject3D = new FlatShadeMaterial(light, dispMatrix[i][j]);
  364.                         material.interactive = true;
  365.                         c.material = material;
  366.                     }
  367.                 }
  368.             }
  369.             
  370.             oldDispMatrix = copyArray2(dispMatrix);
  371.             //trace((getTimer() - oldTime) / 1000);
  372.         }
  373.         
  374.         private function copyArray2(arr:Array):Array
  375.         {
  376.             var r:Array = [];
  377.             for (var i:int = 0; i < arr.length; i++) 
  378.             {
  379.                 r[i] = arr[i].concat();
  380.             }
  381.             return r;
  382.         }
  383.         // アニメーション
  384.         private var rot:Number = 45// 角度
  385.         private var pitch:Number = 500// 高さ
  386.         private function loop(e:Event):void
  387.         {
  388.             rot += 0.1;
  389.             pitch = 500 * Math.sin(getTimer() / 2500) + 900;
  390.             
  391.             // 角度に応じてカメラの位置を設定
  392.             world.camera.x = 1000 * Math.sin(rot * Math.PI / 180);
  393.             world.camera.z = 1000 * Math.cos(rot * Math.PI / 180);
  394.             world.camera.y = pitch;
  395.         }
  396.         
  397.         private function setupUI():void
  398.         {
  399.             var bmp:Bitmap = new Bitmap(new BitmapData(1010false, USER_COLOR));
  400.             bmp.x = 10;
  401.             bmp.y = 26;
  402.             addChild(bmp);
  403.             
  404.             var txtFormat:TextFormat = new TextFormat();
  405.             txtFormat.font = "Arial";
  406.             
  407.             var text1:TextField = new TextField();
  408.             text1.selectable = false;
  409.             text1.defaultTextFormat = txtFormat;
  410.             text1.x = 8;
  411.             text1.y = 6;
  412.             text1.autoSize = "left";
  413.             text1.htmlText = "<font color='#FFFFFF' size='14'>Online Share Tenorion</font>";
  414.             addChild(text1);
  415.             
  416.             var text:TextField = new TextField();
  417.             text.selectable = false;
  418.             text.defaultTextFormat = txtFormat;
  419.             text.x = 25;
  420.             text.y = 24;
  421.             text.htmlText = "<font color='#FFFFFF' size='9'>YOUR COLOR</font>";
  422.             addChild(text);
  423.             
  424.             // BackGround Color
  425.             var bgMatrix:Matrix = new Matrix();
  426.             bgMatrix.rotate(90 * Math.PI / 180);
  427.             graphics.clear()
  428.             graphics.beginGradientFill("linear", [0x332244, 0x000000], [100100], [0255], bgMatrix);
  429.             graphics.drawRect(00, stage.stageWidth, stage.stageHeight);
  430.         }
  431.     }
  432. }
flash swf thumbnail play
出題者からのコメント
美しい!シンプルな音楽作成プログラムも、たくさんのユーザーがリアルタイムで協働すると、ずっと魅力的になりますね。3D Tenorionで、何人かのユーザーが一緒に作曲をしていく姿を見れたのは非常に楽しかったです
Comments from King
Beautiful! A simple music maker becomes so much more intriguing when many users cooperate in realtime. Great to see several Wonderfl members collaborating to create 3D Tenorion.

Knightcoppieee

  1. // forked from checkmate's colin challenge for professionals
  2. /**
  3.  * やっぱネットワークするならゲームだろ!
  4.  * ということで前のSnake Game「http://wonderfl.net/code/7f8f78663b1487a4dda53dcc7be1fc81ae6706f4」のリベンジ
  5.  * 
  6.  * Tweetでtwitterで「仲間を呼ぶ」ボタン
  7.  * 勝手に「http://wonderfl.net/code/7bc146049d06410fea6c857e542597666671d1e6」を参考に追加した。
  8.  * 
  9.  * ローカル部分(Main)とネットワーク部分(UnionRamen)と完全に切り離せるのがウリ。
  10.  * @author coppieee
  11.  */
  12. package {
  13.     import com.bit101.components.PushButton;
  14.     import flash.display.Sprite;
  15.     import flash.events.KeyboardEvent;
  16.     import flash.events.MouseEvent;
  17.     import flash.net.navigateToURL;
  18.     import flash.net.URLRequest;
  19.     import flash.text.TextField;
  20.     import flash.ui.Keyboard;
  21.     import flash.utils.escapeMultiByte;
  22.     import net.user1.reactor.*;
  23.     import net.user1.logger.Logger;
  24.     
  25.     public class UnionRamen extends Sprite {
  26.         protected var _reactor:Reactor;
  27.         protected var _room:Room;
  28.         private var _main:Main;
  29.         public function UnionRamen ()
  30.         {
  31.             _main = new Main();
  32.             _main.x = (465 -_main.width) / 2;
  33.             addChild(_main);
  34.             
  35.             var twitButton:PushButton = new PushButton(this);
  36.             twitButton.label = "Tweet";
  37.             twitButton.x = (465 - twitButton.width) / 2;
  38.             twitButton.y = (465 - twitButton.height);
  39.             twitButton.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void {
  40.                 navigateToURL(new URLRequest("http://twitter.com/home/?status=" 
  41.                     + escapeMultiByte("Let's Snake Game! http://wonderfl.net/code/912e5bbfb8bfc055345361cee2b222d2c8a182a8")
  42.                 ));
  43.             });
  44.             
  45.             _reactor = new Reactor();
  46.             _reactor.addEventListener(ReactorEvent.READY, onReady);
  47.             _reactor.connect("tryunion.com"9100);
  48.             //_reactor.getLog().setLevel(Logger.DEBUG);
  49.             
  50.              Wonderfl.capture_delay( 15 );
  51.         }
  52.         
  53.         private function onReady(e:ReactorEvent):void 
  54.         {
  55.             _main.addEventListener(PixelChangeEvent.PIXEL_CHANGE, function(e:PixelChangeEvent):void {
  56.                 _room.sendMessage("PICEL_GANGE"falsenull, e.toDataString());
  57.             });
  58.             _main.addEventListener(PixelChangeEvent.PIXEL_CLEAR, function(e:PixelChangeEvent):void { 
  59.                 _room.sendMessage("PICEL_CLEAR"falsenull, e.toDataString());
  60.             });
  61.             _room = _reactor.getRoomManager().createRoom("wonderfl.coppieee.MultiSnakeGame");
  62.             //_room.addMessageListener("ADD_NARUTO", addNarutoListener);
  63.             _room.addMessageListener("PICEL_GANGE", onPixelChangeMessage);
  64.             _room.addMessageListener("PICEL_CLEAR", onPixelClearMessage);
  65.             _room.join();
  66.         }
  67.         private function onPixelChangeMessage(from:IClient,data:String):void
  68.         {
  69.             trace(data);
  70.             var buffer:/*String*/Array = data.split(",");
  71.             var row:int = int(buffer[0]);
  72.             var column:int = int(buffer[1]);
  73.             var color:uint = uint(buffer[2]);
  74.             trace(row, column, color);
  75.             _main.setPixel(new Position(row, column), color);
  76.         }
  77.         private function onPixelClearMessage(from:IClient, data:String):void
  78.         {
  79.             var buffer:/*String*/Array = data.split(",");
  80.             var row:int = int(buffer[0]);
  81.             var column:int = int(buffer[1]);
  82.             var color:uint = uint(buffer[2]);
  83.             _main.clearPixel(new Position(row,column), color);
  84.         }
  85.         
  86.     }
  87. }
  88. //pakage{
  89.     import flash.display.Bitmap;
  90.     import flash.display.BitmapData;
  91.     import flash.display.Sprite;
  92.     import flash.events.Event;
  93.     import flash.events.KeyboardEvent;
  94.     import flash.ui.Keyboard;
  95.     import frocessing.color.ColorHSV;
  96.     
  97.     class Main extends Sprite
  98.     {
  99.         private var _bitmapData:BitmapData;
  100.         public static const LENGTH:int = 16;
  101.         private static const BACKGROUND_COLOR:uint = 0x000000;
  102.         private static const FOOD_COLOR:uint = 0xFFFFFF;
  103.         
  104.         private var _snake:Snake;
  105.         private var _food:Position;
  106.         public function Main():void
  107.         {
  108.             _bitmapData = new BitmapData(LENGTH, LENGTH, false, BACKGROUND_COLOR);
  109.             var bitmap:Bitmap = new Bitmap(_bitmapData);
  110.             bitmap.width = 16 * 27;
  111.             bitmap.height = 16 * 27;
  112.             addChild(bitmap);
  113.             
  114.             _snake = new Snake(Position.createRamdom());
  115.             _food = Position.createRamdom();
  116.             addEventListener(Event.ENTER_FRAME, onEnterFrame);
  117.             addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
  118.             
  119.         }
  120.         
  121.         
  122.         private function onKeyDown(e:KeyboardEvent):void 
  123.         {
  124.             var angle:Angle = Angle.keyCodeToAngle(e.keyCode);
  125.             if (!angle) { return; }
  126.             _snake.nextAngle = angle;
  127.         }
  128.         private var _count:int = 0;
  129.         private function onEnterFrame(e:Event):void
  130.         {
  131.             stage.focus = this;
  132.             if (_count > 5)
  133.             {
  134.                 _count = 0;
  135.             
  136.                 var data:SnakeUpdateData = _snake.update();
  137.                 var nextColor:uint = getPixel(data.createPosition);
  138.             
  139.                 if (data.deletePosition)
  140.                 {
  141.                     clearPixel(data.deletePosition, _snake.color);
  142.                     dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CLEAR, data.deletePosition, _snake.color));
  143.                 }
  144.                 
  145.                 if (nextColor == FOOD_COLOR)
  146.                 {
  147.                     _snake.grow();
  148.                 }
  149.                 else if (nextColor != BACKGROUND_COLOR)
  150.                 {
  151.                     for each(var index:Position in _snake.indexs)
  152.                     {
  153.                         clearPixel(index, _snake.color);
  154.                         dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CLEAR, index, _snake.color));
  155.                     }
  156.                     _snake = new Snake(Position.createRamdom());
  157.                     return;
  158.                 }
  159.                 dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CHANGE, data.createPosition, _snake.color));
  160.                 setPixel(data.createPosition, _snake.color);
  161.             }
  162.             _count ++;
  163.             
  164.             if (getPixel(_food) != FOOD_COLOR)
  165.             {
  166.                 _food = Position.createRamdom();
  167.                 setPixel(_food, FOOD_COLOR);
  168.                 dispatchEvent(new PixelChangeEvent(PixelChangeEvent.PIXEL_CHANGE, _food, FOOD_COLOR));
  169.             }
  170.         }
  171.         public function clearPixel(p:Position, color:uint):void
  172.         {
  173.             if (getPixel(p) != color) { return; }
  174.             _bitmapData.setPixel(p.column, p.row, BACKGROUND_COLOR);
  175.         }
  176.         public function getPixel(p:Position):uint
  177.         {
  178.             return _bitmapData.getPixel(p.column, p.row);
  179.         }
  180.         public function setPixel(p:Position, color:uint):void
  181.         {
  182.             _bitmapData.setPixel(p.column, p.row, color);
  183.         }
  184.     }
  185. //}
  186. import flash.geom.Point;
  187. import flash.utils.Dictionary;
  188. import flash.ui.Keyboard;
  189. import frocessing.color.ColorHSV;
  190. import flash.events.Event;
  191. class Snake
  192. {
  193.     private static const COLOR:uint =  new ColorHSV(Math.random() * 360).value;
  194.     public function get nextAngle():Angle { return _nextAngle; }
  195.     public function set nextAngle(value:Angle):void
  196.     {
  197.         if ((value.row + _prevAngle.row) == 0 && (value.column + _prevAngle.column) == 0)
  198.         {
  199.             return;
  200.         }
  201.         _nextAngle = value;
  202.     }
  203.     private var _nextAngle:Angle = Angle.RIGHT;
  204.     private var _prevAngle:Angle = Angle.RIGHT;
  205.     public var indexs:/*Position*/Array;
  206.     public const color:uint = COLOR;
  207.     public function Snake(position:Position)
  208.     {
  209.         indexs = [];
  210.         indexs.push(position);
  211.     }
  212.     public function update():SnakeUpdateData
  213.     {
  214.         _prevAngle = nextAngle;
  215.         
  216.         var nextHead:Position = nextAngle.add(indexs[indexs.length - 1]);
  217.         
  218.         indexs.push(nextHead);
  219.         var data:SnakeUpdateData =  new SnakeUpdateData();
  220.         data.createPosition = nextHead;
  221.         if (_isGrowed)
  222.         {
  223.             _isGrowed = false;
  224.             return data;
  225.         }
  226.         var tail:Position = indexs[0];
  227.         indexs.shift();
  228.         data.deletePosition = tail;
  229.         return data;
  230.     }
  231.     private var _isGrowed:Boolean = false;
  232.     public function grow():void
  233.     {
  234.         _isGrowed = true;
  235.     }
  236. }
  237. class SnakeUpdateData
  238. {
  239.     public var createPosition:Position;
  240.     public var deletePosition:Position;
  241.     public function SnakeUpdateData(){}
  242. }
  243. class PixelChangeEvent extends Event
  244. {
  245.     public static const PIXEL_CHANGE:String = "pixelChange";
  246.     public static const PIXEL_CLEAR:String = "pixelClear";
  247.     
  248.     public function toDataString():Object { return position.row+","+position.column+","+color; }
  249.     public var position:Position;
  250.     public var color:uint;
  251.     public function PixelChangeEvent(type:String,position:Position,color:uint)
  252.     {
  253.         super(type);
  254.         this.position = position;
  255.         this.color = color;
  256.     }
  257. }
  258. class Position
  259. {
  260.     public static function createRamdom():Position
  261.     {
  262.         return new Position(Main.LENGTH * Math.random(),Main.LENGTH *Math.random());
  263.     }
  264.     
  265.     public function get row():int { return _row; }
  266.     public function set row(value:int):void 
  267.     { 
  268.         _row = value % Main.LENGTH;
  269.         if (_row < 0) { _row += Main.LENGTH; }
  270.     }
  271.     public var _row:int;
  272.     public function get column():int { return _column; }
  273.     public function set column(value:int):void 
  274.     { 
  275.         _column = value % Main.LENGTH;
  276.         if (_column < 0) { _column += Main.LENGTH; }
  277.     }
  278.     public var _column:int;
  279.     public function Position(row:int,column:int)
  280.     {
  281.         this.row = row;
  282.         this.column = column;
  283.     }
  284. }
  285. class Angle
  286. {
  287.     public static const LEFT:Angle = new Angle( 0, -1);
  288.     public static const RIGHT:Angle = new Angle(01);
  289.     public static const UP:Angle = new Angle( -10);
  290.     public static const DOWN:Angle = new Angle(10);
  291.     
  292.     public static function keyCodeToAngle(keyCode:int):Angle
  293.     {
  294.         return _angles[keyCode];
  295.     }
  296.     private static var _angles:Dictionary;
  297.     
  298.     //static initializer
  299.     {
  300.         _angles = new Dictionary();
  301.         _angles[Keyboard.LEFT] = LEFT;
  302.         _angles[Keyboard.RIGHT] = RIGHT;
  303.         _angles[Keyboard.UP] = UP;
  304.         _angles[Keyboard.DOWN] = DOWN;
  305.     }
  306.     
  307.     public function get row():int { return _row; }
  308.     private var _row:int;
  309.     public function get column():int { return _column; }
  310.     private var _column:int;
  311.     public function Angle(row:int, column:int)
  312.     {
  313.         _row = row;
  314.         _column = column;
  315.     }
  316.     public function add(p:Position):Position
  317.     {
  318.         return new Position(p.row + this.row, p.column + this.column);
  319.     }
  320.     public function toString():String
  321.     {
  322.         return "[Angle " + row + "," + column + "]";
  323.         return "[Angle row:" + row + ",column:" + column + "]";
  324.     }
  325. }
flash swf thumbnail play
出題者からのコメント
これは楽しい!定番のゲームも、マルチプレーヤーにするとまた楽しいものです
Comments from King
Tons of fun! This old classic really comes to life as a multiplayer game!

ad