notice: Flash editor updated! Join the development! Thanks to MiniBuilder


forked from : ABA's forked from: forked from: AAShip [diff(414)]

embed

FORKED

forked from: forked from: forked from: AAShip forked from: forked from: forked from: forked from: AAShip [diff(1)]

  1. // forked from ABA's forked from: forked from: forked from: AAShip
  2. // forked from ABA's forked from: forked from: AAShip
  3. // forked from ABA's forked from: AAShip
  4. // forked from ABA's AAShip
  5. // AAShip.as
  6. // Ascii art ship.
  7. // [Control]
  8. // Movement: Arrow or [WASD] keys.
  9. // Fire: [Z], [X], [.] or [/] key.
  10. package
  11. {
  12. import flash.display.Sprite;
  13. import flash.display.BitmapData;
  14. import flash.display.Bitmap;
  15. import flash.geom.Rectangle;
  16. import flash.text.TextField;
  17. import flash.events.Event;
  18. import flash.events.KeyboardEvent;
  19. [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  20. public class AAShip extends Sprite
  21. {
  22. public static const SCREEN_WIDTH:int = 465;
  23. public static const SCREEN_HEIGHT:int = 465;
  24. private const BLUR_MAX_COUNT:int = 512;
  25. private const BLUR_HISTORY_COUNT:int = 6;
  26. private const SHIP_SPEED:Number = 8;
  27. private const SHOT_MAX_COUNT:int = 12;
  28. private const SHOT_SPEED:Number = 20;
  29. private const SHIP_COLLISION_SIZE:Number = 5;
  30. private const SHIP_INVINCIBLE_TICKS:int = 90;
  31. private const ENEMY_MAX_COUNT:int = 16;
  32. private const BULLET_MAX_COUNT:int = 128;
  33. private const SPARK_MAX_COUNT:int = 64;
  34. private const ZAKO1_APPEARANCE_INTERVAL:Number = 30;
  35. private const MID1_APPEARANCE_INTERVAL:Number = 180;
  36. public static var gameSpeed:Number;
  37. private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
  38. private var rect:Rectangle = new Rectangle;
  39. private var offset:Vector2 = new Vector2;
  40. private var blurs:Vector.> = new Vector.>(BLUR_HISTORY_COUNT, true);
  41. private var blurCounts:Vector. = new Vector.(BLUR_HISTORY_COUNT, true);
  42. private var blurIndex:int;
  43. private var shipChar:AAChar;
  44. private var shipSprite:Sprite = new Sprite;
  45. private var shipPos:Vector2 = new Vector2;
  46. private var shipAngle:Number;
  47. private var shipInvincibleTicks:int;
  48. private var shipFireCount:int;
  49. private var shipFireTicks:Number;
  50. private var shotChar:AAChar;
  51. private var shots:Vector. = new Vector.(SHOT_MAX_COUNT, true);
  52. private var enemies:Vector. = new Vector.(ENEMY_MAX_COUNT, true);
  53. private var zako1:Zako1, mid1:Mid1;
  54. private var bulletChar:AAChar;
  55. private var bullets:Vector. = new Vector.(BULLET_MAX_COUNT, true);
  56. private var sparkChar:AAChar;
  57. private var sparks:Vector. = new Vector.(SPARK_MAX_COUNT, true);
  58. private var bulletIntervalRank:Number;
  59. private var bulletSpeedRank:Number;
  60. private var enemyIntervalRank:Number;
  61. private var enemySpeedRank:Number;
  62. private var rankTicks:int;
  63. public function AAShip()
  64. {
  65. stage.scaleMode = "noScale";
  66. addChild(new Bitmap(buffer));
  67. stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  68. stage.addEventListener(KeyboardEvent.KEY_UP, Key.onKeyUp);
  69. AAChar.initialize();
  70. Field.initialize();
  71. var i:int;
  72. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  73. {
  74. var bs:Vector. = new Vector.(BLUR_MAX_COUNT, true);
  75. for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  76. {
  77. bs[j] = new Blur;
  78. }
  79. blurs[i] = bs;
  80. blurCounts[i] = 0;
  81. }
  82. blurIndex = 0;
  83. shipChar = new AAChar([" A ", "I#I"], [" R ", "CBC"], 2, 2);
  84. shipChar.drawToSprite(shipSprite);
  85. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS;
  86. shotChar = new AAChar(["!"], ["Y"]);
  87. for (i = 0; i < SHOT_MAX_COUNT; i++)
  88. {
  89. shots[i] = new Shot;
  90. shotChar.drawToSprite(shots[i].sprite);
  91. }
  92. zako1 = new Zako1; mid1 = new Mid1;
  93. for (i = 0; i < ENEMY_MAX_COUNT; i++)
  94. {
  95. enemies[i] = new Enemy;
  96. }
  97. bulletChar = new AAChar(["#"], ["P"], 1, 1);
  98. for (i = 0; i < BULLET_MAX_COUNT; i++)
  99. {
  100. bullets[i] = new Bullet;
  101. bulletChar.drawToSprite(bullets[i].sprite);
  102. }
  103. sparkChar = new AAChar(["*"], ["Y"]);
  104. for (i = 0; i < SPARK_MAX_COUNT; i++)
  105. {
  106. sparks[i] = new Spark;
  107. sparkChar.drawToSprite(sparks[i].sprite);
  108. }
  109. bulletIntervalRank = bulletSpeedRank = enemyIntervalRank = enemySpeedRank = 1.0 / 0.5;
  110. gameSpeed = 1.0;
  111. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  112. }
  113. private function initializeShip():void
  114. {
  115. shipPos.x = 0;
  116. shipPos.y = Field.size.y / 2;
  117. shipAngle = 0.0;
  118. shipFireCount = 0;
  119. shipFireTicks = 0;
  120. bulletIntervalRank *= 0.5; bulletSpeedRank *= 0.5;
  121. enemyIntervalRank *= 0.5; enemySpeedRank *= 0.5;
  122. if (bulletIntervalRank < 0.5) bulletIntervalRank = 0.5;
  123. if (bulletSpeedRank < 0.5) bulletSpeedRank = 0.5;
  124. if (enemyIntervalRank < 0.5) enemyIntervalRank = 0.5;
  125. if (enemySpeedRank < 0.5) enemySpeedRank = 0.5;
  126. rankTicks = 0;
  127. zako1.appearanceTicks = 0;
  128. mid1.appearanceTicks = MID1_APPEARANCE_INTERVAL;
  129. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  130. addChild(shipSprite);
  131. }
  132. private function onEnterFrame(event:Event):void
  133. {
  134. buffer.fillRect(buffer.rect, 0);
  135. var i:int;
  136. blurCounts[blurIndex] = 0;
  137. updateSparks();
  138. updateShots();
  139. if (shipInvincibleTicks > -SHIP_INVINCIBLE_TICKS) updateShip();
  140. else if (shipInvincibleTicks == -SHIP_INVINCIBLE_TICKS) initializeShip();
  141. else Field.offsetX *= 0.95;
  142. shipInvincibleTicks++;
  143. updateEnemies();
  144. updateBullets();
  145. rankTicks++;
  146. bulletIntervalRank += 0.02;
  147. if (rankTicks % (10 * 30) == 0) bulletIntervalRank *= 0.5;
  148. bulletSpeedRank += 0.005;
  149. if (rankTicks % (15 * 30) == 0) bulletSpeedRank *= 0.5;
  150. enemyIntervalRank += 0.005;
  151. if (rankTicks % (21 * 30) == 0) enemyIntervalRank *= 0.5;
  152. enemySpeedRank += 0.002;
  153. if (rankTicks % (27 * 30) == 0) enemySpeedRank *= 0.5;
  154. buffer.lock();
  155. Field.draw(buffer);
  156. var bi:int = blurIndex + 1;
  157. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  158. {
  159. if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  160. for (var j:int = 0; j < blurCounts[bi]; j++)
  161. {
  162. updateBlur(blurs[bi][j]);
  163. }
  164. bi++;
  165. }
  166. Field.drawSideBoard(buffer);
  167. buffer.unlock();
  168. blurIndex++;
  169. if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  170. }
  171. private function updateShip():void
  172. {
  173. var px:Number = shipPos.x;
  174. var vx:Number = 0, vy:Number = 0;
  175. if (Key.left) vx = -1;
  176. if (Key.right) vx = 1;
  177. if (Key.up) vy = -1;
  178. if (Key.down) vy = 1;
  179. if (vx != 0 && vy != 0)
  180. {
  181. vx *= 0.7; vy *= 0.7;
  182. }
  183. shipPos.x += vx * SHIP_SPEED * gameSpeed;
  184. shipPos.y += vy * SHIP_SPEED * gameSpeed;
  185. if (shipPos.x < -SCREEN_WIDTH / 2) shipPos.x = -SCREEN_WIDTH / 2;
  186. if (shipPos.x > SCREEN_WIDTH / 2) shipPos.x = SCREEN_WIDTH / 2;
  187. if (shipPos.y < -SCREEN_HEIGHT / 2) shipPos.y = -SCREEN_HEIGHT / 2;
  188. if (shipPos.y > SCREEN_HEIGHT / 2) shipPos.y = SCREEN_HEIGHT / 2;
  189. shipAngle += (shipPos.x - px) * 0.01;
  190. shipAngle *= 0.8;
  191. Field.offsetX = shipPos.x * 0.33;
  192. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  193. if (shipInvincibleTicks >= 0 || (-shipInvincibleTicks % 15 > 7))
  194. {
  195. addBlursOfAAChar(shipChar, shipPos, shipAngle);
  196. }
  197. var s:Shot;
  198. if (Key.button1 && shipFireTicks <= 0)
  199. {
  200. shipFireTicks += 1.0;
  201. offset.x = 15;
  202. offset.y = 0;
  203. offset.rotation(shipAngle);
  204. s = getActorInstance(Vector.(shots));
  205. var i:int = shipFireCount % 2;
  206. if (s != null)
  207. {
  208. s.pos.x = shipPos.x + offset.x * (i * 2 - 1);
  209. s.pos.y = shipPos.y + offset.y * (i * 2 - 1);
  210. s.angle = shipAngle;
  211. s.ticks = 0;
  212. addBlur(s.pos.x, s.pos.y, 10, 10, 255, 255, 0);
  213. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  214. addChild(s.sprite);
  215. shipFireCount++;
  216. }
  217. }
  218. shipFireTicks -= gameSpeed;
  219. if (shipInvincibleTicks >= 0)
  220. {
  221. for each (var e:Enemy in enemies)
  222. {
  223. if (!e.exists) continue;
  224. if (Math.abs(shipPos.x - e.pos.x) <= e.spec.size.x - 12 &&
  225. Math.abs(shipPos.y - e.pos.y) <= e.spec.size.y - 12)
  226. {
  227. shipDestroyed();
  228. e.exists = false;
  229. removeChild(e.sprite);
  230. return;
  231. }
  232. }
  233. for each (var b:Bullet in bullets)
  234. {
  235. if (!b.exists) continue;
  236. if (shipPos.getRoughDistance(b.pos) <= SHIP_COLLISION_SIZE)
  237. {
  238. shipDestroyed();
  239. b.exists = false;
  240. removeChild(b.sprite);
  241. return;
  242. }
  243. }
  244. }
  245. }
  246. private function updateShots():void
  247. {
  248. var s:Shot;
  249. for each (s in shots)
  250. {
  251. if (!s.exists) continue;
  252. s.pos.x += Math.sin(s.angle) * SHOT_SPEED * gameSpeed;
  253. s.pos.y -= Math.cos(s.angle) * SHOT_SPEED * gameSpeed;
  254. if (s.pos.y < -SCREEN_HEIGHT / 2)
  255. {
  256. s.exists = false;
  257. removeChild(s.sprite);
  258. continue;
  259. }
  260. s.ticks += gameSpeed;
  261. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  262. addBlursOfAAChar(shotChar, s.pos, s.angle, 1.0, 1.0, 150, 100, 0);
  263. for each (var e:Enemy in enemies)
  264. {
  265. if (!e.exists) continue;
  266. if (Math.abs(s.pos.x - e.pos.x) <= e.spec.size.x &&
  267. Math.abs(s.pos.y - e.pos.y) <= e.spec.size.y)
  268. {
  269. addSpark(s.pos, s.angle + Math.PI, 0.2, SHOT_SPEED, 1.0, 2);
  270. e.shield--;
  271. e.isHit = true;
  272. s.exists = false;
  273. removeChild(s.sprite);
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. private function updateEnemies():void
  280. {
  281. var e:Enemy;
  282. var es:EnemySpec = null;
  283. zako1.appearanceTicks -= gameSpeed;
  284. if (zako1.appearanceTicks <= 0)
  285. {
  286. es = zako1;
  287. var ei:int = ZAKO1_APPEARANCE_INTERVAL / enemyIntervalRank;
  288. ei *= (0.75 + Math.random() * 0.5);
  289. if (ei < 5) ei = 5;
  290. zako1.appearanceTicks += ei;
  291. }
  292. mid1.appearanceTicks -= gameSpeed;
  293. if (mid1.appearanceTicks <= 0)
  294. {
  295. es = mid1;
  296. mid1.appearanceTicks += MID1_APPEARANCE_INTERVAL * (0.5 + Math.random());
  297. }
  298. if (es != null)
  299. {
  300. e = getActorInstance(Vector.(enemies));
  301. if (e != null)
  302. {
  303. e.spec = es;
  304. e.speedRatio = enemySpeedRank;
  305. var fsr:Number = bulletSpeedRank;
  306. if (fsr < 1.0) fsr = 1.0;
  307. e.fireSpeedRatio = fsr;
  308. var fir:Number = bulletIntervalRank;
  309. if (fir > 25.0) fir = 25.0;
  310. e.fireIntervalRatio = fir;
  311. e.ticks = 0;
  312. e.fireTicks = 0.0; e.fireSeqTicks = 0.0; e.fireCount = 0;
  313. e.shield = e.spec.shield;
  314. e.isHit = false;
  315. e.spec.initialize(e, shipPos);
  316. e.spec.aaChar.drawToSprite(e.sprite);
  317. addChild(e.sprite);
  318. }
  319. }
  320. for each (e in enemies)
  321. {
  322. if (!e.exists) continue;
  323. if (!Field.contains(e.pos) || e.shield <= 0)
  324. {
  325. e.exists = false;
  326. removeChild(e.sprite);
  327. if (e.shield <= 0) addSpark(e.pos, 0, Math.PI, 4.0, 1.5, 8);
  328. continue;
  329. }
  330. e.spec.update(e, shipPos, this);
  331. e.ticks += gameSpeed;
  332. e.fireTicks -= gameSpeed;
  333. e.spec.aaChar.setSpriteMatrix(e.sprite, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  334. if (e.isHit)
  335. {
  336. e.isHit = false;
  337. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x * 1.5, e.spec.scale.y * 1.5, 255, 255, 0);
  338. }
  339. else
  340. {
  341. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  342. }
  343. }
  344. }
  345. public function fireBullet(p:Vector2, angle:Number, speed:Number, size:Number):void
  346. {
  347. if (p.getRoughDistance(shipPos) <= 200 ||
  348. p.x - Field.offsetX <= -Field.size.x + Field.SIDE_BOARD_WIDTH ||
  349. p.x - Field.offsetX >= Field.size.x - Field.SIDE_BOARD_WIDTH) return;
  350. var b:Bullet = getActorInstance(Vector.(bullets));
  351. if (b == null) return;
  352. b.pos.x = p.x; b.pos.y = p.y;
  353. b.vel.x = Math.sin(angle) * speed;
  354. b.vel.y = -Math.cos(angle) * speed;
  355. b.speed = speed;
  356. b.size = size;
  357. addBlur(b.pos.x + b.vel.x * 2, b.pos.y + b.vel.y * 2, 20, 20, 255, 200, 100);
  358. b.ticks = 0;
  359. addChild(b.sprite);
  360. }
  361. private function updateBullets():void
  362. {
  363. var totalSpeed:Number = 0;
  364. for each (var b:Bullet in bullets)
  365. {
  366. if (!b.exists) continue;
  367. b.pos.addMultiplied(b.vel, gameSpeed);
  368. if (!Field.contains(b.pos))
  369. {
  370. b.exists = false;
  371. removeChild(b.sprite);
  372. continue;
  373. }
  374. var a:Number = b.ticks * 0.1;
  375. bulletChar.setSpriteMatrix(b.sprite, b.pos, a, b.size, b.size);
  376. var sz:Number = b.size * (1.1 + Math.sin(b.ticks * 0.2) * 0.2);
  377. var cl:int = 128 + 64 + Math.sin(b.ticks * 0.3) * 64;
  378. addBlursOfAAChar(bulletChar, b.pos, a, sz, sz, cl, 100, 255);
  379. b.ticks += gameSpeed;
  380. totalSpeed += b.speed + 5.0;
  381. }
  382. if (totalSpeed > 500.0)
  383. {
  384. gameSpeed = 1.0 - (totalSpeed - 500.0) / 250.0;
  385. if (gameSpeed < 0.7) gameSpeed = 0.7;
  386. }
  387. else
  388. {
  389. gameSpeed = 1.0;
  390. }
  391. }
  392. private function updateSparks():void
  393. {
  394. for each (var s:Spark in sparks)
  395. {
  396. if (!s.exists) continue;
  397. s.pos.addMultiplied(s.vel, gameSpeed);
  398. s.vel.mul(1 - 0.05 * gameSpeed);
  399. s.size *= (1 - 0.05 * gameSpeed);
  400. if (!Field.contains(s.pos) || s.ticks <= 0)
  401. {
  402. s.exists = false;
  403. removeChild(s.sprite);
  404. continue;
  405. }
  406. var a:Number = s.ticks * 0.2;
  407. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  408. addBlursOfAAChar(sparkChar, s.pos, a, s.size, s.size,
  409. 250, Math.random() * 128 + 128, 0);
  410. s.ticks -= gameSpeed;
  411. }
  412. }
  413. private function shipDestroyed():void
  414. {
  415. addSpark(shipPos, 0, Math.PI, 10.0, 6.0, 20);
  416. addSpark(shipPos, Math.PI / 2, 0, 30.0, 5.0, 10);
  417. addSpark(shipPos, -Math.PI / 2, 0, 30.0, 5.0, 10);
  418. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS * 1.5;
  419. removeChild(shipSprite);
  420. }
  421. private function addSpark(p:Vector2, angle:Number, ao:Number, speed:Number, size:Number, count:Number):void
  422. {
  423. for (var i:int = 0; i < count; i++)
  424. {
  425. var s:Spark = getActorInstance(Vector.(sparks));
  426. if (s == null) return;
  427. s.pos.x = p.x; s.pos.y = p.y;
  428. var a:Number = angle + ao * (Math.random() * 2 - 1);
  429. var sp:Number = speed * (0.5 + Math.random());
  430. s.vel.x = Math.sin(a) * sp;
  431. s.vel.y = -Math.cos(a) * sp;
  432. s.size = size;
  433. s.ticks = 15 + 15 * Math.random();
  434. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  435. addChild(s.sprite);
  436. }
  437. }
  438. private function addBlursOfAAChar(ac:AAChar, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1,
  439. cr:int = -1, cg:int = -1, cb:int = -1):void
  440. {
  441. var br:int, bg:int, bb:int;
  442. if (cr >= 0)
  443. {
  444. br = cr; bg = cg; bb = cb;
  445. }
  446. for each (var b:Blur in ac.blurs)
  447. {
  448. offset.x = b.pos.x * sx; offset.y = b.pos.y * sy;
  449. offset.rotation(angle);
  450. if (cr < 0)
  451. {
  452. br = b.r; bg = b.g; bb = b.b;
  453. }
  454. addBlur(p.x + offset.x, p.y + offset.y, b.width * sx, b.height * sy, br, bg, bb);
  455. }
  456. }
  457. private function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  458. {
  459. if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  460. var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  461. bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  462. bl.width = w; bl.height = h;
  463. bl.r = r; bl.g = g; bl.b = b;
  464. blurCounts[blurIndex]++;
  465. }
  466. private function updateBlur(b:Blur):void
  467. {
  468. rect.x = b.pos.x - b.width / 2 - Field.offsetX;
  469. rect.y = b.pos.y - b.height / 2;
  470. rect.width = b.width;
  471. rect.height = b.height;
  472. buffer.fillRect(rect, b.r * 0x10000 + b.g * 0x100 + b.b);
  473. b.width *= 1.2; b.height *= 1.2;
  474. var a:int = (b.r + b.g + b.b) / 3;
  475. b.r += (a - b.r) * 0.25;
  476. b.g += (a - b.g) * 0.25;
  477. b.b += (a - b.b) * 0.25;
  478. b.r *= 0.65; b.g *= 0.65; b.b *= 0.65;
  479. }
  480. private function getActorInstance(actors:Vector.):*
  481. {
  482. var al:int = actors.length
  483. for (var i:int = 0; i < al; i++)
  484. {
  485. if (!actors[i].exists)
  486. {
  487. actors[i].exists = true;
  488. return actors[i];
  489. }
  490. }
  491. return null;
  492. }
  493. }
  494. }
  495. import flash.display.BitmapData;
  496. import flash.display.Bitmap;
  497. import flash.display.Sprite;
  498. import flash.geom.Rectangle;
  499. import flash.geom.Matrix;
  500. import flash.text.TextField;
  501. import flash.text.TextFormat;
  502. import flash.events.KeyboardEvent;
  503. class Actor
  504. {
  505. public var exists:Boolean = false;
  506. public var pos:Vector2 = new Vector2;
  507. public var sprite:Sprite = new Sprite;
  508. public var ticks:Number;
  509. }
  510. class Shot extends Actor
  511. {
  512. public var angle:Number;
  513. }
  514. class Enemy extends Actor
  515. {
  516. public var angle:Number;
  517. public var speed:Number;
  518. public var speedRatio:Number;
  519. public var fireSpeedRatio:Number;
  520. public var fireIntervalRatio:Number;
  521. public var fireTicks:Number;
  522. public var fireSeqTicks:Number;
  523. public var fireCount:int;
  524. public var shield:int;
  525. public var isHit:Boolean;
  526. public var spec:EnemySpec;
  527. }
  528. class EnemySpec
  529. {
  530. public var size:Vector2 = new Vector2;
  531. public var scale:Vector2 = new Vector2;
  532. public var shield:int;
  533. public var aaChar:AAChar;
  534. public var appearanceTicks:Number;
  535. public function initialize(e:Enemy, shipPos:Vector2):void { }
  536. public function update(e:Enemy, shipPos:Vector2, main:AAShip):void {}
  537. }
  538. class Zako1 extends EnemySpec
  539. {
  540. private const SPEED:Number = 6;
  541. private const ANGLE_VELOCITY:Number = 0.05;
  542. private const FIRE_INTERVAL:Number = 60;
  543. private const BULLET_SPEED:Number = 5;
  544. public function Zako1()
  545. {
  546. size.x = size.y = 32;
  547. scale.x = scale.y = 1.0;
  548. shield = 1;
  549. aaChar = new AAChar(["", " v "], ["WGW", " C "], 2, 2);
  550. }
  551. override public function initialize(e:Enemy, shipPos:Vector2):void
  552. {
  553. e.pos.x = Field.size.x * (Math.random() * 2 - 1);
  554. e.pos.y = -Field.size.y;
  555. e.angle = Math.PI;
  556. e.speed = SPEED * e.speedRatio;
  557. }
  558. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  559. {
  560. e.pos.x += Math.sin(e.angle) * e.speed * AAShip.gameSpeed;
  561. e.pos.y -= Math.cos(e.angle) * e.speed * AAShip.gameSpeed;
  562. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  563. var ao:Number = pa - e.angle;
  564. ao = Util.normalizeAngle(ao);
  565. if (ao > ANGLE_VELOCITY) e.angle += ANGLE_VELOCITY;
  566. else if (ao < -ANGLE_VELOCITY) e.angle -= ANGLE_VELOCITY;
  567. else e.angle = pa;
  568. e.angle = Util.normalizeAngle(e.angle);
  569. if (e.fireTicks <= 0)
  570. {
  571. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  572. main.fireBullet(e.pos, pa, BULLET_SPEED * e.fireSpeedRatio, 1.0);
  573. }
  574. }
  575. }
  576. class Mid1 extends EnemySpec
  577. {
  578. private const WAVE_INTERVAL:int = 120;
  579. private const SPEED:Number = 1;
  580. private const FIRE_INTERVAL:Number = 150;
  581. private const BULLET_SPEED:Number = 5;
  582. public function Mid1()
  583. {
  584. size.x = 64; size.y = 48;
  585. scale.x = scale.y = 1.2;
  586. shield = 16;
  587. aaChar = new AAChar([".__.", "\\##/"], ["RYYR", "WCCW"], 2, 2);
  588. }
  589. override public function initialize(e:Enemy, shipPos:Vector2):void
  590. {
  591. e.pos.x = Field.size.x * 0.6 * (Math.random() * 2 - 1);
  592. e.ticks = Math.random() * WAVE_INTERVAL;
  593. e.pos.y = -Field.size.y;
  594. e.angle = 0;
  595. e.speed = SPEED * (Math.random() + 1.0);
  596. e.fireSpeedRatio = Math.sqrt(e.fireSpeedRatio);
  597. e.fireIntervalRatio = Math.sqrt(e.fireIntervalRatio);
  598. }
  599. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  600. {
  601. var xa:Number = e.ticks * Math.PI * 2.0 / WAVE_INTERVAL;
  602. e.pos.x += Math.sin(xa) * 1.0 * AAShip.gameSpeed;
  603. e.angle = -Math.sin(xa) * 0.2;
  604. e.pos.y += e.speed * AAShip.gameSpeed;
  605. if (e.pos.y < 0)
  606. {
  607. if (e.fireTicks <= 0)
  608. {
  609. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  610. e.fireSeqTicks = 0;
  611. e.fireCount = 4;
  612. }
  613. if (e.fireCount > 0)
  614. {
  615. e.fireSeqTicks -= AAShip.gameSpeed;
  616. if (e.fireSeqTicks <= 0)
  617. {
  618. e.fireSeqTicks = 3;
  619. e.fireCount--;
  620. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  621. for (var i:int = 0; i < 3; i++)
  622. {
  623. main.fireBullet(e.pos, pa - (i - 1) * 0.5,
  624. BULLET_SPEED * e.fireSpeedRatio * (1.0 + (3 - e.fireCount) * 0.25), 1.25);
  625. }
  626. }
  627. }
  628. }
  629. else
  630. {
  631. e.speed += (SPEED * 4 - e.speed) * 0.1;
  632. }
  633. }
  634. }
  635. class Bullet extends Actor
  636. {
  637. public var vel:Vector2 = new Vector2;
  638. public var speed:Number;
  639. public var size:Number;
  640. }
  641. class Spark extends Actor
  642. {
  643. public var vel:Vector2 = new Vector2;
  644. public var size:Number;
  645. }
  646. class Blur
  647. {
  648. public var pos:Vector2 = new Vector2;
  649. public var width:Number, height:Number;
  650. public var r:int, g:int, b:int;
  651. }
  652. class Field
  653. {
  654. public static const SIDE_BOARD_WIDTH:Number = AAShip.SCREEN_WIDTH / 6;
  655. private static const STAR_COUNT:int = 256;
  656. public static var size:Vector2;
  657. public static var offsetX:Number;
  658. private static var stars:Vector.;
  659. private static var rect:Rectangle = new Rectangle;
  660. public static function initialize():void
  661. {
  662. size = new Vector2;
  663. size.x = AAShip.SCREEN_WIDTH * 1.1 / 2; size.y = AAShip.SCREEN_HEIGHT * 1.1 / 2;
  664. stars = new Vector.(STAR_COUNT, true);
  665. for (var i:int = 0; i < STAR_COUNT; i++)
  666. {
  667. var s:Star = new Star;
  668. var z:Number = 1.0 + Math.random() * 10;
  669. var sz:int = (5 + Math.random() * 5) / z;
  670. if (sz < 1) sz = 1;
  671. s.pos.x = (Math.random() * 2 - 1) * size.x - sz;
  672. s.pos.y = (Math.random() * 2 - 1) * size.y - sz;
  673. s.size = sz;
  674. s.velRatio = 1.0 / z;
  675. s.color = (int)(Math.random() * 127 + 128) * 0x100 +
  676. (int)(Math.random() * 127 + 128);
  677. stars[i] = s;
  678. }
  679. }
  680. public static function draw(buffer:BitmapData):void
  681. {
  682. for each (var s:Star in stars)
  683. {
  684. rect.x = s.pos.x - offsetX * s.velRatio + AAShip.SCREEN_WIDTH / 2;
  685. rect.y = s.pos.y + AAShip.SCREEN_HEIGHT / 2;
  686. rect.width = rect.height = s.size;
  687. buffer.fillRect(rect, s.color);
  688. s.pos.y += 3.0 * s.velRatio;
  689. if (s.pos.y > size.y) s.pos.y -= size.y * 2;
  690. }
  691. }
  692. public static function drawSideBoard(buffer:BitmapData):void
  693. {
  694. rect.width = SIDE_BOARD_WIDTH;
  695. rect.height = AAShip.SCREEN_HEIGHT;
  696. rect.x = rect.y = 0;
  697. buffer.fillRect(rect, 0);
  698. rect.x = AAShip.SCREEN_WIDTH - rect.width;
  699. buffer.fillRect(rect, 0);
  700. }
  701. public static function contains(p:Vector2):Boolean
  702. {
  703. return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  704. }
  705. }
  706. class Star
  707. {
  708. public var pos:Vector2 = new Vector2;
  709. public var size:Number;
  710. public var color:int;
  711. public var velRatio:Number;
  712. }
  713. class AAChar
  714. {
  715. private static const COLOR_PATTERNS:Array =
  716. [["R", 250, 100, 100], ["G", 100, 250, 100], ["B", 100, 100, 250],
  717. ["Y", 250, 250, 100], ["P", 250, 100, 250], ["C", 100, 250, 250],
  718. ["W", 250, 250, 250]];
  719. private const CHAR_SIZE:int = 24;
  720. private const CHAR_OFFSET_X:int = 14;
  721. private const CHAR_OFFSET_Y:int = 17;
  722. private const CHAR_HEIGHT:int = 24;
  723. private static var colorCount:int;
  724. private static var textFormats:Vector. = new Vector.;
  725. public var textFields:Vector. = new Vector.;
  726. public var blurs:Vector. = new Vector.;
  727. public var width:int, height:int;
  728. private var bitmapData:BitmapData;
  729. public static function initialize():void
  730. {
  731. colorCount = 0;
  732. for each (var cp:Array in COLOR_PATTERNS)
  733. {
  734. var tf:TextFormat = new TextFormat;
  735. tf.font = "_typewriter";
  736. tf.bold = true;
  737. tf.size = 24;
  738. tf.leading = -10;
  739. tf.color = (int)(cp[1] * 0.75) * 0x10000 + (int)(cp[2] * 0.75) * 0x100 + (int)(cp[3] * 0.75);
  740. textFormats.push(tf);
  741. colorCount++;
  742. }
  743. }
  744. public function AAChar(chars:Array, colors:Array, divX:int = 1, divY:int = 1)
  745. {
  746. var i:int;
  747. var tfts:Vector. = new Vector.(colorCount, true);
  748. var tffs:Vector. = new Vector.(colorCount, true);
  749. for (i = 0; i < colorCount; i++)
  750. {
  751. tfts[i] = "";
  752. tffs[i] = false;
  753. }
  754. var cx:int, cy:int = 0;
  755. var bd:BitmapData;
  756. var tf:TextField;
  757. var b:Blur;
  758. for (i = 0; i < chars.length; i++)
  759. {
  760. var str:String = chars[i];
  761. var colorStr:String = colors[i];
  762. cx = 0;
  763. var j:int;
  764. for (j = 0; j < str.length; j++)
  765. {
  766. var c:String = str.charAt(j);
  767. var color:String = colorStr.charAt(j);
  768. var ci:int;
  769. for (var k:int = 0; k < colorCount; k++)
  770. {
  771. if (color == COLOR_PATTERNS[k][0])
  772. {
  773. tfts[k] += c;
  774. tffs[k] = true;
  775. ci = k;
  776. }
  777. else
  778. {
  779. tfts[k] += " ";
  780. }
  781. }
  782. bd = new BitmapData(CHAR_SIZE, CHAR_SIZE, false, 0);
  783. tf = new TextField;
  784. tf.defaultTextFormat = textFormats[ci];
  785. tf.text = c;
  786. bd.draw(tf);
  787. for (var dx:int = 0; dx < divX; dx++)
  788. {
  789. for (var dy:int = 0; dy < divY; dy++)
  790. {
  791. var minX:int = CHAR_SIZE, maxX:int = -1;
  792. var minY:int = CHAR_SIZE, maxY:int = -1;
  793. for (var x:int = dx * CHAR_SIZE / divX; x < (dx + 1) * CHAR_SIZE / divX; x++)
  794. {
  795. for (var y:int = dy * CHAR_SIZE / divY; y < (dy + 1) * CHAR_SIZE / divY; y++)
  796. {
  797. if (bd.getPixel(x, y) > 0)
  798. {
  799. if (minX > x) minX = x;
  800. if (maxX < x) maxX = x;
  801. if (minY > y) minY = y;
  802. if (maxY < y) maxY = y;
  803. }
  804. }
  805. }
  806. if (maxX >= 0)
  807. {
  808. b = new Blur;
  809. b.width = maxX - minX + 1;
  810. b.height = maxY - minY + 1;
  811. b.pos.x = minX + cx * CHAR_OFFSET_X + b.width / 2;
  812. b.pos.y = minY + cy * CHAR_OFFSET_Y + b.height / 2;
  813. b.r = COLOR_PATTERNS[ci][1] + (255 - COLOR_PATTERNS[ci][1]) * 0.5;
  814. b.g = COLOR_PATTERNS[ci][2] + (255 - COLOR_PATTERNS[ci][2]) * 0.5;
  815. b.b = COLOR_PATTERNS[ci][3] + (255 - COLOR_PATTERNS[ci][3]) * 0.5;
  816. blurs.push(b);
  817. }
  818. }
  819. }
  820. cx++;
  821. }
  822. for (j = 0; j < colorCount; j++)
  823. {
  824. tfts[j] += "\n";
  825. }
  826. cy++;
  827. }
  828. width = cx * CHAR_OFFSET_X;
  829. height = cy * CHAR_HEIGHT;
  830. for (i = 0; i < colorCount; i++)
  831. {
  832. if (!tffs[i]) continue;
  833. tf = new TextField;
  834. tf.defaultTextFormat = textFormats[i];
  835. tf.multiline = true;
  836. tf.text = tfts[i];
  837. textFields.push(tf);
  838. }
  839. for each (b in blurs)
  840. {
  841. b.pos.x -= width / 2;
  842. b.pos.y -= height / 2;
  843. }
  844. bitmapData = new BitmapData(width, height, true, 0);
  845. for each (tf in textFields)
  846. {
  847. bitmapData.draw(tf);
  848. }
  849. }
  850. public function drawToSprite(s:Sprite):void
  851. {
  852. while (s.numChildren > 0)
  853. {
  854. s.removeChildAt(0);
  855. }
  856. s.addChild(new Bitmap(bitmapData));
  857. }
  858. public function setSpriteMatrix(s:Sprite, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1):void
  859. {
  860. var m:Matrix = new Matrix;
  861. m.translate(-width / 2, -height / 2);
  862. m.scale(sx, sy);
  863. m.rotate(angle);
  864. m.translate(p.x + AAShip.SCREEN_WIDTH / 2 - Field.offsetX, p.y + AAShip.SCREEN_HEIGHT / 2);
  865. s.transform.matrix = m;
  866. }
  867. }
  868. // Utility classes.
  869. class Vector2
  870. {
  871. public var x:Number = 0;
  872. public var y:Number = 0;
  873. public function add(v:Vector2):void
  874. {
  875. x += v.x;
  876. y += v.y;
  877. }
  878. public function addMultiplied(v:Vector2, mv:Number):void
  879. {
  880. x += v.x * mv;
  881. y += v.y * mv;
  882. }
  883. public function sub(v:Vector2):void
  884. {
  885. x -= v.x;
  886. y -= v.y;
  887. }
  888. public function mul(v:Number):void
  889. {
  890. x *= v;
  891. y *= v;
  892. }
  893. public function div(v:Number):void
  894. {
  895. x /= v;
  896. y /= v;
  897. }
  898. public function normalize():void
  899. {
  900. div(length);
  901. }
  902. public function get length():Number
  903. {
  904. return Math.sqrt(x * x + y * y);
  905. }
  906. public function getRoughDistance(p:Vector2):Number
  907. {
  908. return Math.abs(x - p.x) + Math.abs(y - p.y);
  909. }
  910. public function rotation(v:Number):void
  911. {
  912. var sv:Number = Math.sin(v);
  913. var cv:Number = Math.cos(v);
  914. var rx:Number = cv * x - sv * y;
  915. y = sv * x + cv * y;
  916. x = rx;
  917. }
  918. }
  919. class Key
  920. {
  921. public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  922. public static var button1:Boolean;
  923. public static function onKeyUp(event:KeyboardEvent):void
  924. {
  925. switch (event.keyCode)
  926. {
  927. case 0x25:
  928. case 0x41:
  929. {
  930. left = false;
  931. break;
  932. }
  933. case 0x26:
  934. case 0x57:
  935. {
  936. up = false;
  937. break;
  938. }
  939. case 0x27:
  940. case 0x44:
  941. {
  942. right = false;
  943. break;
  944. }
  945. case 0x28:
  946. case 0x53:
  947. {
  948. down = false;
  949. break;
  950. }
  951. case 0x5a:
  952. case 0xbf:
  953. case 0x58:
  954. case 0xbe:
  955. {
  956. button1 = false;
  957. break;
  958. }
  959. }
  960. }
  961. public static function onKeyDown(event:KeyboardEvent):void
  962. {
  963. switch (event.keyCode)
  964. {
  965. case 0x25:
  966. case 0x41:
  967. {
  968. left = true;
  969. break;
  970. }
  971. case 0x26:
  972. case 0x57:
  973. {
  974. up = true;
  975. break;
  976. }
  977. case 0x27:
  978. case 0x44:
  979. {
  980. right = true;
  981. break;
  982. }
  983. case 0x28:
  984. case 0x53:
  985. {
  986. down = true;
  987. break;
  988. }
  989. case 0x5a:
  990. case 0xbf:
  991. case 0x58:
  992. case 0xbe:
  993. {
  994. button1 = true;
  995. break;
  996. }
  997. }
  998. }
  999. }
  1000. class Util
  1001. {
  1002. public static function normalizeAngle(v:Number):Number
  1003. {
  1004. if (v > Math.PI) return v - Math.PI * 2;
  1005. else if (v < -Math.PI) return v + Math.PI * 2;
  1006. else return v;
  1007. }
  1008. }
noswf
  1. // forked from ABA's forked from: forked from: forked from: AAShip
  2. // forked from ABA's forked from: forked from: AAShip
  3. // forked from ABA's forked from: AAShip
  4. // forked from ABA's AAShip
  5. // AAShip.as
  6. // Ascii art ship.
  7. // [Control]
  8. // Movement: Arrow or [WASD] keys.
  9. // Fire: [Z], [X], [.] or [/] key.
  10. package
  11. {
  12. import flash.display.Sprite;
  13. import flash.display.BitmapData;
  14. import flash.display.Bitmap;
  15. import flash.geom.Rectangle;
  16. import flash.text.TextField;
  17. import flash.events.Event;
  18. import flash.events.KeyboardEvent;
  19. [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  20. public class AAShip extends Sprite
  21. {
  22. public static const SCREEN_WIDTH:int = 465;
  23. public static const SCREEN_HEIGHT:int = 465;
  24. private const BLUR_MAX_COUNT:int = 512;
  25. private const BLUR_HISTORY_COUNT:int = 6;
  26. private const SHIP_SPEED:Number = 8;
  27. private const SHOT_MAX_COUNT:int = 12;
  28. private const SHOT_SPEED:Number = 20;
  29. private const SHIP_COLLISION_SIZE:Number = 5;
  30. private const SHIP_INVINCIBLE_TICKS:int = 90;
  31. private const ENEMY_MAX_COUNT:int = 16;
  32. private const BULLET_MAX_COUNT:int = 128;
  33. private const SPARK_MAX_COUNT:int = 64;
  34. private const ZAKO1_APPEARANCE_INTERVAL:Number = 30;
  35. private const MID1_APPEARANCE_INTERVAL:Number = 180;
  36. public static var gameSpeed:Number;
  37. private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
  38. private var rect:Rectangle = new Rectangle;
  39. private var offset:Vector2 = new Vector2;
  40. private var blurs:Vector.> = new Vector.>(BLUR_HISTORY_COUNT, true);
  41. private var blurCounts:Vector. = new Vector.(BLUR_HISTORY_COUNT, true);
  42. private var blurIndex:int;
  43. private var shipChar:AAChar;
  44. private var shipSprite:Sprite = new Sprite;
  45. private var shipPos:Vector2 = new Vector2;
  46. private var shipAngle:Number;
  47. private var shipInvincibleTicks:int;
  48. private var shipFireCount:int;
  49. private var shipFireTicks:Number;
  50. private var shotChar:AAChar;
  51. private var shots:Vector. = new Vector.(SHOT_MAX_COUNT, true);
  52. private var enemies:Vector. = new Vector.(ENEMY_MAX_COUNT, true);
  53. private var zako1:Zako1, mid1:Mid1;
  54. private var bulletChar:AAChar;
  55. private var bullets:Vector. = new Vector.(BULLET_MAX_COUNT, true);
  56. private var sparkChar:AAChar;
  57. private var sparks:Vector. = new Vector.(SPARK_MAX_COUNT, true);
  58. private var bulletIntervalRank:Number;
  59. private var bulletSpeedRank:Number;
  60. private var enemyIntervalRank:Number;
  61. private var enemySpeedRank:Number;
  62. private var rankTicks:int;
  63. public function AAShip()
  64. {
  65. stage.scaleMode = "noScale";
  66. addChild(new Bitmap(buffer));
  67. stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  68. stage.addEventListener(KeyboardEvent.KEY_UP, Key.onKeyUp);
  69. AAChar.initialize();
  70. Field.initialize();
  71. var i:int;
  72. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  73. {
  74. var bs:Vector. = new Vector.(BLUR_MAX_COUNT, true);
  75. for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  76. {
  77. bs[j] = new Blur;
  78. }
  79. blurs[i] = bs;
  80. blurCounts[i] = 0;
  81. }
  82. blurIndex = 0;
  83. shipChar = new AAChar([" A ", "I#I"], [" R ", "CBC"], 2, 2);
  84. shipChar.drawToSprite(shipSprite);
  85. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS;
  86. shotChar = new AAChar(["!"], ["Y"]);
  87. for (i = 0; i < SHOT_MAX_COUNT; i++)
  88. {
  89. shots[i] = new Shot;
  90. shotChar.drawToSprite(shots[i].sprite);
  91. }
  92. zako1 = new Zako1; mid1 = new Mid1;
  93. for (i = 0; i < ENEMY_MAX_COUNT; i++)
  94. {
  95. enemies[i] = new Enemy;
  96. }
  97. bulletChar = new AAChar(["#"], ["P"], 1, 1);
  98. for (i = 0; i < BULLET_MAX_COUNT; i++)
  99. {
  100. bullets[i] = new Bullet;
  101. bulletChar.drawToSprite(bullets[i].sprite);
  102. }
  103. sparkChar = new AAChar(["*"], ["Y"]);
  104. for (i = 0; i < SPARK_MAX_COUNT; i++)
  105. {
  106. sparks[i] = new Spark;
  107. sparkChar.drawToSprite(sparks[i].sprite);
  108. }
  109. bulletIntervalRank = bulletSpeedRank = enemyIntervalRank = enemySpeedRank = 1.0 / 0.5;
  110. gameSpeed = 1.0;
  111. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  112. }
  113. private function initializeShip():void
  114. {
  115. shipPos.x = 0;
  116. shipPos.y = Field.size.y / 2;
  117. shipAngle = 0.0;
  118. shipFireCount = 0;
  119. shipFireTicks = 0;
  120. bulletIntervalRank *= 0.5; bulletSpeedRank *= 0.5;
  121. enemyIntervalRank *= 0.5; enemySpeedRank *= 0.5;
  122. if (bulletIntervalRank < 0.5) bulletIntervalRank = 0.5;
  123. if (bulletSpeedRank < 0.5) bulletSpeedRank = 0.5;
  124. if (enemyIntervalRank < 0.5) enemyIntervalRank = 0.5;
  125. if (enemySpeedRank < 0.5) enemySpeedRank = 0.5;
  126. rankTicks = 0;
  127. zako1.appearanceTicks = 0;
  128. mid1.appearanceTicks = MID1_APPEARANCE_INTERVAL;
  129. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  130. addChild(shipSprite);
  131. }
  132. private function onEnterFrame(event:Event):void
  133. {
  134. buffer.fillRect(buffer.rect, 0);
  135. var i:int;
  136. blurCounts[blurIndex] = 0;
  137. updateSparks();
  138. updateShots();
  139. if (shipInvincibleTicks > -SHIP_INVINCIBLE_TICKS) updateShip();
  140. else if (shipInvincibleTicks == -SHIP_INVINCIBLE_TICKS) initializeShip();
  141. else Field.offsetX *= 0.95;
  142. shipInvincibleTicks++;
  143. updateEnemies();
  144. updateBullets();
  145. rankTicks++;
  146. bulletIntervalRank += 0.02;
  147. if (rankTicks % (10 * 30) == 0) bulletIntervalRank *= 0.5;
  148. bulletSpeedRank += 0.005;
  149. if (rankTicks % (15 * 30) == 0) bulletSpeedRank *= 0.5;
  150. enemyIntervalRank += 0.005;
  151. if (rankTicks % (21 * 30) == 0) enemyIntervalRank *= 0.5;
  152. enemySpeedRank += 0.002;
  153. if (rankTicks % (27 * 30) == 0) enemySpeedRank *= 0.5;
  154. buffer.lock();
  155. Field.draw(buffer);
  156. var bi:int = blurIndex + 1;
  157. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  158. {
  159. if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  160. for (var j:int = 0; j < blurCounts[bi]; j++)
  161. {
  162. updateBlur(blurs[bi][j]);
  163. }
  164. bi++;
  165. }
  166. Field.drawSideBoard(buffer);
  167. buffer.unlock();
  168. blurIndex++;
  169. if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  170. }
  171. private function updateShip():void
  172. {
  173. var px:Number = shipPos.x;
  174. var vx:Number = 0, vy:Number = 0;
  175. if (Key.left) vx = -1;
  176. if (Key.right) vx = 1;
  177. if (Key.up) vy = -1;
  178. if (Key.down) vy = 1;
  179. if (vx != 0 && vy != 0)
  180. {
  181. vx *= 0.7; vy *= 0.7;
  182. }
  183. shipPos.x += vx * SHIP_SPEED * gameSpeed;
  184. shipPos.y += vy * SHIP_SPEED * gameSpeed;
  185. if (shipPos.x < -SCREEN_WIDTH / 2) shipPos.x = -SCREEN_WIDTH / 2;
  186. if (shipPos.x > SCREEN_WIDTH / 2) shipPos.x = SCREEN_WIDTH / 2;
  187. if (shipPos.y < -SCREEN_HEIGHT / 2) shipPos.y = -SCREEN_HEIGHT / 2;
  188. if (shipPos.y > SCREEN_HEIGHT / 2) shipPos.y = SCREEN_HEIGHT / 2;
  189. shipAngle += (shipPos.x - px) * 0.01;
  190. shipAngle *= 0.8;
  191. Field.offsetX = shipPos.x * 0.33;
  192. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  193. if (shipInvincibleTicks >= 0 || (-shipInvincibleTicks % 15 > 7))
  194. {
  195. addBlursOfAAChar(shipChar, shipPos, shipAngle);
  196. }
  197. var s:Shot;
  198. if (Key.button1 && shipFireTicks <= 0)
  199. {
  200. shipFireTicks += 1.0;
  201. offset.x = 15;
  202. offset.y = 0;
  203. offset.rotation(shipAngle);
  204. s = getActorInstance(Vector.(shots));
  205. var i:int = shipFireCount % 2;
  206. if (s != null)
  207. {
  208. s.pos.x = shipPos.x + offset.x * (i * 2 - 1);
  209. s.pos.y = shipPos.y + offset.y * (i * 2 - 1);
  210. s.angle = shipAngle;
  211. s.ticks = 0;
  212. addBlur(s.pos.x, s.pos.y, 10, 10, 255, 255, 0);
  213. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  214. addChild(s.sprite);
  215. shipFireCount++;
  216. }
  217. }
  218. shipFireTicks -= gameSpeed;
  219. if (shipInvincibleTicks >= 0)
  220. {
  221. for each (var e:Enemy in enemies)
  222. {
  223. if (!e.exists) continue;
  224. if (Math.abs(shipPos.x - e.pos.x) <= e.spec.size.x - 12 &&
  225. Math.abs(shipPos.y - e.pos.y) <= e.spec.size.y - 12)
  226. {
  227. shipDestroyed();
  228. e.exists = false;
  229. removeChild(e.sprite);
  230. return;
  231. }
  232. }
  233. for each (var b:Bullet in bullets)
  234. {
  235. if (!b.exists) continue;
  236. if (shipPos.getRoughDistance(b.pos) <= SHIP_COLLISION_SIZE)
  237. {
  238. shipDestroyed();
  239. b.exists = false;
  240. removeChild(b.sprite);
  241. return;
  242. }
  243. }
  244. }
  245. }
  246. private function updateShots():void
  247. {
  248. var s:Shot;
  249. for each (s in shots)
  250. {
  251. if (!s.exists) continue;
  252. s.pos.x += Math.sin(s.angle) * SHOT_SPEED * gameSpeed;
  253. s.pos.y -= Math.cos(s.angle) * SHOT_SPEED * gameSpeed;
  254. if (s.pos.y < -SCREEN_HEIGHT / 2)
  255. {
  256. s.exists = false;
  257. removeChild(s.sprite);
  258. continue;
  259. }
  260. s.ticks += gameSpeed;
  261. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  262. addBlursOfAAChar(shotChar, s.pos, s.angle, 1.0, 1.0, 150, 100, 0);
  263. for each (var e:Enemy in enemies)
  264. {
  265. if (!e.exists) continue;
  266. if (Math.abs(s.pos.x - e.pos.x) <= e.spec.size.x &&
  267. Math.abs(s.pos.y - e.pos.y) <= e.spec.size.y)
  268. {
  269. addSpark(s.pos, s.angle + Math.PI, 0.2, SHOT_SPEED, 1.0, 2);
  270. e.shield--;
  271. e.isHit = true;
  272. s.exists = false;
  273. removeChild(s.sprite);
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. private function updateEnemies():void
  280. {
  281. var e:Enemy;
  282. var es:EnemySpec = null;
  283. zako1.appearanceTicks -= gameSpeed;
  284. if (zako1.appearanceTicks <= 0)
  285. {
  286. es = zako1;
  287. var ei:int = ZAKO1_APPEARANCE_INTERVAL / enemyIntervalRank;
  288. ei *= (0.75 + Math.random() * 0.5);
  289. if (ei < 5) ei = 5;
  290. zako1.appearanceTicks += ei;
  291. }
  292. mid1.appearanceTicks -= gameSpeed;
  293. if (mid1.appearanceTicks <= 0)
  294. {
  295. es = mid1;
  296. mid1.appearanceTicks += MID1_APPEARANCE_INTERVAL * (0.5 + Math.random());
  297. }
  298. if (es != null)
  299. {
  300. e = getActorInstance(Vector.(enemies));
  301. if (e != null)
  302. {
  303. e.spec = es;
  304. e.speedRatio = enemySpeedRank;
  305. var fsr:Number = bulletSpeedRank;
  306. if (fsr < 1.0) fsr = 1.0;
  307. e.fireSpeedRatio = fsr;
  308. var fir:Number = bulletIntervalRank;
  309. if (fir > 25.0) fir = 25.0;
  310. e.fireIntervalRatio = fir;
  311. e.ticks = 0;
  312. e.fireTicks = 0.0; e.fireSeqTicks = 0.0; e.fireCount = 0;
  313. e.shield = e.spec.shield;
  314. e.isHit = false;
  315. e.spec.initialize(e, shipPos);
  316. e.spec.aaChar.drawToSprite(e.sprite);
  317. addChild(e.sprite);
  318. }
  319. }
  320. for each (e in enemies)
  321. {
  322. if (!e.exists) continue;
  323. if (!Field.contains(e.pos) || e.shield <= 0)
  324. {
  325. e.exists = false;
  326. removeChild(e.sprite);
  327. if (e.shield <= 0) addSpark(e.pos, 0, Math.PI, 4.0, 1.5, 8);
  328. continue;
  329. }
  330. e.spec.update(e, shipPos, this);
  331. e.ticks += gameSpeed;
  332. e.fireTicks -= gameSpeed;
  333. e.spec.aaChar.setSpriteMatrix(e.sprite, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  334. if (e.isHit)
  335. {
  336. e.isHit = false;
  337. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x * 1.5, e.spec.scale.y * 1.5, 255, 255, 0);
  338. }
  339. else
  340. {
  341. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  342. }
  343. }
  344. }
  345. public function fireBullet(p:Vector2, angle:Number, speed:Number, size:Number):void
  346. {
  347. if (p.getRoughDistance(shipPos) <= 200 ||
  348. p.x - Field.offsetX <= -Field.size.x + Field.SIDE_BOARD_WIDTH ||
  349. p.x - Field.offsetX >= Field.size.x - Field.SIDE_BOARD_WIDTH) return;
  350. var b:Bullet = getActorInstance(Vector.(bullets));
  351. if (b == null) return;
  352. b.pos.x = p.x; b.pos.y = p.y;
  353. b.vel.x = Math.sin(angle) * speed;
  354. b.vel.y = -Math.cos(angle) * speed;
  355. b.speed = speed;
  356. b.size = size;
  357. addBlur(b.pos.x + b.vel.x * 2, b.pos.y + b.vel.y * 2, 20, 20, 255, 200, 100);
  358. b.ticks = 0;
  359. addChild(b.sprite);
  360. }
  361. private function updateBullets():void
  362. {
  363. var totalSpeed:Number = 0;
  364. for each (var b:Bullet in bullets)
  365. {
  366. if (!b.exists) continue;
  367. b.pos.addMultiplied(b.vel, gameSpeed);
  368. if (!Field.contains(b.pos))
  369. {
  370. b.exists = false;
  371. removeChild(b.sprite);
  372. continue;
  373. }
  374. var a:Number = b.ticks * 0.1;
  375. bulletChar.setSpriteMatrix(b.sprite, b.pos, a, b.size, b.size);
  376. var sz:Number = b.size * (1.1 + Math.sin(b.ticks * 0.2) * 0.2);
  377. var cl:int = 128 + 64 + Math.sin(b.ticks * 0.3) * 64;
  378. addBlursOfAAChar(bulletChar, b.pos, a, sz, sz, cl, 100, 255);
  379. b.ticks += gameSpeed;
  380. totalSpeed += b.speed + 5.0;
  381. }
  382. if (totalSpeed > 500.0)
  383. {
  384. gameSpeed = 1.0 - (totalSpeed - 500.0) / 250.0;
  385. if (gameSpeed < 0.7) gameSpeed = 0.7;
  386. }
  387. else
  388. {
  389. gameSpeed = 1.0;
  390. }
  391. }
  392. private function updateSparks():void
  393. {
  394. for each (var s:Spark in sparks)
  395. {
  396. if (!s.exists) continue;
  397. s.pos.addMultiplied(s.vel, gameSpeed);
  398. s.vel.mul(1 - 0.05 * gameSpeed);
  399. s.size *= (1 - 0.05 * gameSpeed);
  400. if (!Field.contains(s.pos) || s.ticks <= 0)
  401. {
  402. s.exists = false;
  403. removeChild(s.sprite);
  404. continue;
  405. }
  406. var a:Number = s.ticks * 0.2;
  407. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  408. addBlursOfAAChar(sparkChar, s.pos, a, s.size, s.size,
  409. 250, Math.random() * 128 + 128, 0);
  410. s.ticks -= gameSpeed;
  411. }
  412. }
  413. private function shipDestroyed():void
  414. {
  415. addSpark(shipPos, 0, Math.PI, 10.0, 6.0, 20);
  416. addSpark(shipPos, Math.PI / 2, 0, 30.0, 5.0, 10);
  417. addSpark(shipPos, -Math.PI / 2, 0, 30.0, 5.0, 10);
  418. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS * 1.5;
  419. removeChild(shipSprite);
  420. }
  421. private function addSpark(p:Vector2, angle:Number, ao:Number, speed:Number, size:Number, count:Number):void
  422. {
  423. for (var i:int = 0; i < count; i++)
  424. {
  425. var s:Spark = getActorInstance(Vector.(sparks));
  426. if (s == null) return;
  427. s.pos.x = p.x; s.pos.y = p.y;
  428. var a:Number = angle + ao * (Math.random() * 2 - 1);
  429. var sp:Number = speed * (0.5 + Math.random());
  430. s.vel.x = Math.sin(a) * sp;
  431. s.vel.y = -Math.cos(a) * sp;
  432. s.size = size;
  433. s.ticks = 15 + 15 * Math.random();
  434. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  435. addChild(s.sprite);
  436. }
  437. }
  438. private function addBlursOfAAChar(ac:AAChar, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1,
  439. cr:int = -1, cg:int = -1, cb:int = -1):void
  440. {
  441. var br:int, bg:int, bb:int;
  442. if (cr >= 0)
  443. {
  444. br = cr; bg = cg; bb = cb;
  445. }
  446. for each (var b:Blur in ac.blurs)
  447. {
  448. offset.x = b.pos.x * sx; offset.y = b.pos.y * sy;
  449. offset.rotation(angle);
  450. if (cr < 0)
  451. {
  452. br = b.r; bg = b.g; bb = b.b;
  453. }
  454. addBlur(p.x + offset.x, p.y + offset.y, b.width * sx, b.height * sy, br, bg, bb);
  455. }
  456. }
  457. private function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  458. {
  459. if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  460. var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  461. bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  462. bl.width = w; bl.height = h;
  463. bl.r = r; bl.g = g; bl.b = b;
  464. blurCounts[blurIndex]++;
  465. }
  466. private function updateBlur(b:Blur):void
  467. {
  468. rect.x = b.pos.x - b.width / 2 - Field.offsetX;
  469. rect.y = b.pos.y - b.height / 2;
  470. rect.width = b.width;
  471. rect.height = b.height;
  472. buffer.fillRect(rect, b.r * 0x10000 + b.g * 0x100 + b.b);
  473. b.width *= 1.2; b.height *= 1.2;
  474. var a:int = (b.r + b.g + b.b) / 3;
  475. b.r += (a - b.r) * 0.25;
  476. b.g += (a - b.g) * 0.25;
  477. b.b += (a - b.b) * 0.25;
  478. b.r *= 0.65; b.g *= 0.65; b.b *= 0.65;
  479. }
  480. private function getActorInstance(actors:Vector.):*
  481. {
  482. var al:int = actors.length
  483. for (var i:int = 0; i < al; i++)
  484. {
  485. if (!actors[i].exists)
  486. {
  487. actors[i].exists = true;
  488. return actors[i];
  489. }
  490. }
  491. return null;
  492. }
  493. }
  494. }
  495. import flash.display.BitmapData;
  496. import flash.display.Bitmap;
  497. import flash.display.Sprite;
  498. import flash.geom.Rectangle;
  499. import flash.geom.Matrix;
  500. import flash.text.TextField;
  501. import flash.text.TextFormat;
  502. import flash.events.KeyboardEvent;
  503. class Actor
  504. {
  505. public var exists:Boolean = false;
  506. public var pos:Vector2 = new Vector2;
  507. public var sprite:Sprite = new Sprite;
  508. public var ticks:Number;
  509. }
  510. class Shot extends Actor
  511. {
  512. public var angle:Number;
  513. }
  514. class Enemy extends Actor
  515. {
  516. public var angle:Number;
  517. public var speed:Number;
  518. public var speedRatio:Number;
  519. public var fireSpeedRatio:Number;
  520. public var fireIntervalRatio:Number;
  521. public var fireTicks:Number;
  522. public var fireSeqTicks:Number;
  523. public var fireCount:int;
  524. public var shield:int;
  525. public var isHit:Boolean;
  526. public var spec:EnemySpec;
  527. }
  528. class EnemySpec
  529. {
  530. public var size:Vector2 = new Vector2;
  531. public var scale:Vector2 = new Vector2;
  532. public var shield:int;
  533. public var aaChar:AAChar;
  534. public var appearanceTicks:Number;
  535. public function initialize(e:Enemy, shipPos:Vector2):void { }
  536. public function update(e:Enemy, shipPos:Vector2, main:AAShip):void {}
  537. }
  538. class Zako1 extends EnemySpec
  539. {
  540. private const SPEED:Number = 6;
  541. private const ANGLE_VELOCITY:Number = 0.05;
  542. private const FIRE_INTERVAL:Number = 60;
  543. private const BULLET_SPEED:Number = 5;
  544. public function Zako1()
  545. {
  546. size.x = size.y = 32;
  547. scale.x = scale.y = 1.0;
  548. shield = 1;
  549. aaChar = new AAChar(["", " v "], ["WGW", " C "], 2, 2);
  550. }
  551. override public function initialize(e:Enemy, shipPos:Vector2):void
  552. {
  553. e.pos.x = Field.size.x * (Math.random() * 2 - 1);
  554. e.pos.y = -Field.size.y;
  555. e.angle = Math.PI;
  556. e.speed = SPEED * e.speedRatio;
  557. }
  558. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  559. {
  560. e.pos.x += Math.sin(e.angle) * e.speed * AAShip.gameSpeed;
  561. e.pos.y -= Math.cos(e.angle) * e.speed * AAShip.gameSpeed;
  562. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  563. var ao:Number = pa - e.angle;
  564. ao = Util.normalizeAngle(ao);
  565. if (ao > ANGLE_VELOCITY) e.angle += ANGLE_VELOCITY;
  566. else if (ao < -ANGLE_VELOCITY) e.angle -= ANGLE_VELOCITY;
  567. else e.angle = pa;
  568. e.angle = Util.normalizeAngle(e.angle);
  569. if (e.fireTicks <= 0)
  570. {
  571. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  572. main.fireBullet(e.pos, pa, BULLET_SPEED * e.fireSpeedRatio, 1.0);
  573. }
  574. }
  575. }
  576. class Mid1 extends EnemySpec
  577. {
  578. private const WAVE_INTERVAL:int = 120;
  579. private const SPEED:Number = 1;
  580. private const FIRE_INTERVAL:Number = 150;
  581. private const BULLET_SPEED:Number = 5;
  582. public function Mid1()
  583. {
  584. size.x = 64; size.y = 48;
  585. scale.x = scale.y = 1.2;
  586. shield = 16;
  587. aaChar = new AAChar([".__.", "\\##/"], ["RYYR", "WCCW"], 2, 2);
  588. }
  589. override public function initialize(e:Enemy, shipPos:Vector2):void
  590. {
  591. e.pos.x = Field.size.x * 0.6 * (Math.random() * 2 - 1);
  592. e.ticks = Math.random() * WAVE_INTERVAL;
  593. e.pos.y = -Field.size.y;
  594. e.angle = 0;
  595. e.speed = SPEED * (Math.random() + 1.0);
  596. e.fireSpeedRatio = Math.sqrt(e.fireSpeedRatio);
  597. e.fireIntervalRatio = Math.sqrt(e.fireIntervalRatio);
  598. }
  599. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  600. {
  601. var xa:Number = e.ticks * Math.PI * 2.0 / WAVE_INTERVAL;
  602. e.pos.x += Math.sin(xa) * 1.0 * AAShip.gameSpeed;
  603. e.angle = -Math.sin(xa) * 0.2;
  604. e.pos.y += e.speed * AAShip.gameSpeed;
  605. if (e.pos.y < 0)
  606. {
  607. if (e.fireTicks <= 0)
  608. {
  609. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  610. e.fireSeqTicks = 0;
  611. e.fireCount = 4;
  612. }
  613. if (e.fireCount > 0)
  614. {
  615. e.fireSeqTicks -= AAShip.gameSpeed;
  616. if (e.fireSeqTicks <= 0)
  617. {
  618. e.fireSeqTicks = 3;
  619. e.fireCount--;
  620. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  621. for (var i:int = 0; i < 3; i++)
  622. {
  623. main.fireBullet(e.pos, pa - (i - 1) * 0.5,
  624. BULLET_SPEED * e.fireSpeedRatio * (1.0 + (3 - e.fireCount) * 0.25), 1.25);
  625. }
  626. }
  627. }
  628. }
  629. else
  630. {
  631. e.speed += (SPEED * 4 - e.speed) * 0.1;
  632. }
  633. }
  634. }
  635. class Bullet extends Actor
  636. {
  637. public var vel:Vector2 = new Vector2;
  638. public var speed:Number;
  639. public var size:Number;
  640. }
  641. class Spark extends Actor
  642. {
  643. public var vel:Vector2 = new Vector2;
  644. public var size:Number;
  645. }
  646. class Blur
  647. {
  648. public var pos:Vector2 = new Vector2;
  649. public var width:Number, height:Number;
  650. public var r:int, g:int, b:int;
  651. }
  652. class Field
  653. {
  654. public static const SIDE_BOARD_WIDTH:Number = AAShip.SCREEN_WIDTH / 6;
  655. private static const STAR_COUNT:int = 256;
  656. public static var size:Vector2;
  657. public static var offsetX:Number;
  658. private static var stars:Vector.;
  659. private static var rect:Rectangle = new Rectangle;
  660. public static function initialize():void
  661. {
  662. size = new Vector2;
  663. size.x = AAShip.SCREEN_WIDTH * 1.1 / 2; size.y = AAShip.SCREEN_HEIGHT * 1.1 / 2;
  664. stars = new Vector.(STAR_COUNT, true);
  665. for (var i:int = 0; i < STAR_COUNT; i++)
  666. {
  667. var s:Star = new Star;
  668. var z:Number = 1.0 + Math.random() * 10;
  669. var sz:int = (5 + Math.random() * 5) / z;
  670. if (sz < 1) sz = 1;
  671. s.pos.x = (Math.random() * 2 - 1) * size.x - sz;
  672. s.pos.y = (Math.random() * 2 - 1) * size.y - sz;
  673. s.size = sz;
  674. s.velRatio = 1.0 / z;
  675. s.color = (int)(Math.random() * 127 + 128) * 0x100 +
  676. (int)(Math.random() * 127 + 128);
  677. stars[i] = s;
  678. }
  679. }
  680. public static function draw(buffer:BitmapData):void
  681. {
  682. for each (var s:Star in stars)
  683. {
  684. rect.x = s.pos.x - offsetX * s.velRatio + AAShip.SCREEN_WIDTH / 2;
  685. rect.y = s.pos.y + AAShip.SCREEN_HEIGHT / 2;
  686. rect.width = rect.height = s.size;
  687. buffer.fillRect(rect, s.color);
  688. s.pos.y += 3.0 * s.velRatio;
  689. if (s.pos.y > size.y) s.pos.y -= size.y * 2;
  690. }
  691. }
  692. public static function drawSideBoard(buffer:BitmapData):void
  693. {
  694. rect.width = SIDE_BOARD_WIDTH;
  695. rect.height = AAShip.SCREEN_HEIGHT;
  696. rect.x = rect.y = 0;
  697. buffer.fillRect(rect, 0);
  698. rect.x = AAShip.SCREEN_WIDTH - rect.width;
  699. buffer.fillRect(rect, 0);
  700. }
  701. public static function contains(p:Vector2):Boolean
  702. {
  703. return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  704. }
  705. }
  706. class Star
  707. {
  708. public var pos:Vector2 = new Vector2;
  709. public var size:Number;
  710. public var color:int;
  711. public var velRatio:Number;
  712. }
  713. class AAChar
  714. {
  715. private static const COLOR_PATTERNS:Array =
  716. [["R", 250, 100, 100], ["G", 100, 250, 100], ["B", 100, 100, 250],
  717. ["Y", 250, 250, 100], ["P", 250, 100, 250], ["C", 100, 250, 250],
  718. ["W", 250, 250, 250]];
  719. private const CHAR_SIZE:int = 24;
  720. private const CHAR_OFFSET_X:int = 14;
  721. private const CHAR_OFFSET_Y:int = 17;
  722. private const CHAR_HEIGHT:int = 24;
  723. private static var colorCount:int;
  724. private static var textFormats:Vector. = new Vector.;
  725. public var textFields:Vector. = new Vector.;
  726. public var blurs:Vector. = new Vector.;
  727. public var width:int, height:int;
  728. private var bitmapData:BitmapData;
  729. public static function initialize():void
  730. {
  731. colorCount = 0;
  732. for each (var cp:Array in COLOR_PATTERNS)
  733. {
  734. var tf:TextFormat = new TextFormat;
  735. tf.font = "_typewriter";
  736. tf.bold = true;
  737. tf.size = 24;
  738. tf.leading = -10;
  739. tf.color = (int)(cp[1] * 0.75) * 0x10000 + (int)(cp[2] * 0.75) * 0x100 + (int)(cp[3] * 0.75);
  740. textFormats.push(tf);
  741. colorCount++;
  742. }
  743. }
  744. public function AAChar(chars:Array, colors:Array, divX:int = 1, divY:int = 1)
  745. {
  746. var i:int;
  747. var tfts:Vector. = new Vector.(colorCount, true);
  748. var tffs:Vector. = new Vector.(colorCount, true);
  749. for (i = 0; i < colorCount; i++)
  750. {
  751. tfts[i] = "";
  752. tffs[i] = false;
  753. }
  754. var cx:int, cy:int = 0;
  755. var bd:BitmapData;
  756. var tf:TextField;
  757. var b:Blur;
  758. for (i = 0; i < chars.length; i++)
  759. {
  760. var str:String = chars[i];
  761. var colorStr:String = colors[i];
  762. cx = 0;
  763. var j:int;
  764. for (j = 0; j < str.length; j++)
  765. {
  766. var c:String = str.charAt(j);
  767. var color:String = colorStr.charAt(j);
  768. var ci:int;
  769. for (var k:int = 0; k < colorCount; k++)
  770. {
  771. if (color == COLOR_PATTERNS[k][0])
  772. {
  773. tfts[k] += c;
  774. tffs[k] = true;
  775. ci = k;
  776. }
  777. else
  778. {
  779. tfts[k] += " ";
  780. }
  781. }
  782. bd = new BitmapData(CHAR_SIZE, CHAR_SIZE, false, 0);
  783. tf = new TextField;
  784. tf.defaultTextFormat = textFormats[ci];
  785. tf.text = c;
  786. bd.draw(tf);
  787. for (var dx:int = 0; dx < divX; dx++)
  788. {
  789. for (var dy:int = 0; dy < divY; dy++)
  790. {
  791. var minX:int = CHAR_SIZE, maxX:int = -1;
  792. var minY:int = CHAR_SIZE, maxY:int = -1;
  793. for (var x:int = dx * CHAR_SIZE / divX; x < (dx + 1) * CHAR_SIZE / divX; x++)
  794. {
  795. for (var y:int = dy * CHAR_SIZE / divY; y < (dy + 1) * CHAR_SIZE / divY; y++)
  796. {
  797. if (bd.getPixel(x, y) > 0)
  798. {
  799. if (minX > x) minX = x;
  800. if (maxX < x) maxX = x;
  801. if (minY > y) minY = y;
  802. if (maxY < y) maxY = y;
  803. }
  804. }
  805. }
  806. if (maxX >= 0)
  807. {
  808. b = new Blur;
  809. b.width = maxX - minX + 1;
  810. b.height = maxY - minY + 1;
  811. b.pos.x = minX + cx * CHAR_OFFSET_X + b.width / 2;
  812. b.pos.y = minY + cy * CHAR_OFFSET_Y + b.height / 2;
  813. b.r = COLOR_PATTERNS[ci][1] + (255 - COLOR_PATTERNS[ci][1]) * 0.5;
  814. b.g = COLOR_PATTERNS[ci][2] + (255 - COLOR_PATTERNS[ci][2]) * 0.5;
  815. b.b = COLOR_PATTERNS[ci][3] + (255 - COLOR_PATTERNS[ci][3]) * 0.5;
  816. blurs.push(b);
  817. }
  818. }
  819. }
  820. cx++;
  821. }
  822. for (j = 0; j < colorCount; j++)
  823. {
  824. tfts[j] += "\n";
  825. }
  826. cy++;
  827. }
  828. width = cx * CHAR_OFFSET_X;
  829. height = cy * CHAR_HEIGHT;
  830. for (i = 0; i < colorCount; i++)
  831. {
  832. if (!tffs[i]) continue;
  833. tf = new TextField;
  834. tf.defaultTextFormat = textFormats[i];
  835. tf.multiline = true;
  836. tf.text = tfts[i];
  837. textFields.push(tf);
  838. }
  839. for each (b in blurs)
  840. {
  841. b.pos.x -= width / 2;
  842. b.pos.y -= height / 2;
  843. }
  844. bitmapData = new BitmapData(width, height, true, 0);
  845. for each (tf in textFields)
  846. {
  847. bitmapData.draw(tf);
  848. }
  849. }
  850. public function drawToSprite(s:Sprite):void
  851. {
  852. while (s.numChildren > 0)
  853. {
  854. s.removeChildAt(0);
  855. }
  856. s.addChild(new Bitmap(bitmapData));
  857. }
  858. public function setSpriteMatrix(s:Sprite, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1):void
  859. {
  860. var m:Matrix = new Matrix;
  861. m.translate(-width / 2, -height / 2);
  862. m.scale(sx, sy);
  863. m.rotate(angle);
  864. m.translate(p.x + AAShip.SCREEN_WIDTH / 2 - Field.offsetX, p.y + AAShip.SCREEN_HEIGHT / 2);
  865. s.transform.matrix = m;
  866. }
  867. }
  868. // Utility classes.
  869. class Vector2
  870. {
  871. public var x:Number = 0;
  872. public var y:Number = 0;
  873. public function add(v:Vector2):void
  874. {
  875. x += v.x;
  876. y += v.y;
  877. }
  878. public function addMultiplied(v:Vector2, mv:Number):void
  879. {
  880. x += v.x * mv;
  881. y += v.y * mv;
  882. }
  883. public function sub(v:Vector2):void
  884. {
  885. x -= v.x;
  886. y -= v.y;
  887. }
  888. public function mul(v:Number):void
  889. {
  890. x *= v;
  891. y *= v;
  892. }
  893. public function div(v:Number):void
  894. {
  895. x /= v;
  896. y /= v;
  897. }
  898. public function normalize():void
  899. {
  900. div(length);
  901. }
  902. public function get length():Number
  903. {
  904. return Math.sqrt(x * x + y * y);
  905. }
  906. public function getRoughDistance(p:Vector2):Number
  907. {
  908. return Math.abs(x - p.x) + Math.abs(y - p.y);
  909. }
  910. public function rotation(v:Number):void
  911. {
  912. var sv:Number = Math.sin(v);
  913. var cv:Number = Math.cos(v);
  914. var rx:Number = cv * x - sv * y;
  915. y = sv * x + cv * y;
  916. x = rx;
  917. }
  918. }
  919. class Key
  920. {
  921. public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  922. public static var button1:Boolean;
  923. public static function onKeyUp(event:KeyboardEvent):void
  924. {
  925. switch (event.keyCode)
  926. {
  927. case 0x25:
  928. case 0x41:
  929. {
  930. left = false;
  931. break;
  932. }
  933. case 0x26:
  934. case 0x57:
  935. {
  936. up = false;
  937. break;
  938. }
  939. case 0x27:
  940. case 0x44:
  941. {
  942. right = false;
  943. break;
  944. }
  945. case 0x28:
  946. case 0x53:
  947. {
  948. down = false;
  949. break;
  950. }
  951. case 0x5a:
  952. case 0xbf:
  953. case 0x58:
  954. case 0xbe:
  955. {
  956. button1 = false;
  957. break;
  958. }
  959. }
  960. }
  961. public static function onKeyDown(event:KeyboardEvent):void
  962. {
  963. switch (event.keyCode)
  964. {
  965. case 0x25:
  966. case 0x41:
  967. {
  968. left = true;
  969. break;
  970. }
  971. case 0x26:
  972. case 0x57:
  973. {
  974. up = true;
  975. break;
  976. }
  977. case 0x27:
  978. case 0x44:
  979. {
  980. right = true;
  981. break;
  982. }
  983. case 0x28:
  984. case 0x53:
  985. {
  986. down = true;
  987. break;
  988. }
  989. case 0x5a:
  990. case 0xbf:
  991. case 0x58:
  992. case 0xbe:
  993. {
  994. button1 = true;
  995. break;
  996. }
  997. }
  998. }
  999. }
  1000. class Util
  1001. {
  1002. public static function normalizeAngle(v:Number):Number
  1003. {
  1004. if (v > Math.PI) return v - Math.PI * 2;
  1005. else if (v < -Math.PI) return v + Math.PI * 2;
  1006. else return v;
  1007. }
  1008. }
noswf
  1. // forked from ABA's forked from: forked from: forked from: AAShip
  2. // forked from ABA's forked from: forked from: AAShip
  3. // forked from ABA's forked from: AAShip
  4. // forked from ABA's AAShip
  5. // AAShip.as
  6. // Ascii art ship.
  7. // [Control]
  8. // Movement: Arrow or [WASD] keys.
  9. // Fire: [Z], [X], [.] or [/] key.
  10. package
  11. {
  12. import flash.display.Sprite;
  13. import flash.display.BitmapData;
  14. import flash.display.Bitmap;
  15. import flash.geom.Rectangle;
  16. import flash.text.TextField;
  17. import flash.events.Event;
  18. import flash.events.KeyboardEvent;
  19. [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  20. public class AAShip extends Sprite
  21. {
  22. public static const SCREEN_WIDTH:int = 465;
  23. public static const SCREEN_HEIGHT:int = 465;
  24. private const BLUR_MAX_COUNT:int = 512;
  25. private const BLUR_HISTORY_COUNT:int = 6;
  26. private const SHIP_SPEED:Number = 8;
  27. private const SHOT_MAX_COUNT:int = 12;
  28. private const SHOT_SPEED:Number = 20;
  29. private const SHIP_COLLISION_SIZE:Number = 5;
  30. private const SHIP_INVINCIBLE_TICKS:int = 90;
  31. private const ENEMY_MAX_COUNT:int = 16;
  32. private const BULLET_MAX_COUNT:int = 128;
  33. private const SPARK_MAX_COUNT:int = 64;
  34. private const ZAKO1_APPEARANCE_INTERVAL:Number = 30;
  35. private const MID1_APPEARANCE_INTERVAL:Number = 180;
  36. public static var gameSpeed:Number;
  37. private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
  38. private var rect:Rectangle = new Rectangle;
  39. private var offset:Vector2 = new Vector2;
  40. private var blurs:Vector.> = new Vector.>(BLUR_HISTORY_COUNT, true);
  41. private var blurCounts:Vector. = new Vector.(BLUR_HISTORY_COUNT, true);
  42. private var blurIndex:int;
  43. private var shipChar:AAChar;
  44. private var shipSprite:Sprite = new Sprite;
  45. private var shipPos:Vector2 = new Vector2;
  46. private var shipAngle:Number;
  47. private var shipInvincibleTicks:int;
  48. private var shipFireCount:int;
  49. private var shipFireTicks:Number;
  50. private var shotChar:AAChar;
  51. private var shots:Vector. = new Vector.(SHOT_MAX_COUNT, true);
  52. private var enemies:Vector. = new Vector.(ENEMY_MAX_COUNT, true);
  53. private var zako1:Zako1, mid1:Mid1;
  54. private var bulletChar:AAChar;
  55. private var bullets:Vector. = new Vector.(BULLET_MAX_COUNT, true);
  56. private var sparkChar:AAChar;
  57. private var sparks:Vector. = new Vector.(SPARK_MAX_COUNT, true);
  58. private var bulletIntervalRank:Number;
  59. private var bulletSpeedRank:Number;
  60. private var enemyIntervalRank:Number;
  61. private var enemySpeedRank:Number;
  62. private var rankTicks:int;
  63. public function AAShip()
  64. {
  65. stage.scaleMode = "noScale";
  66. addChild(new Bitmap(buffer));
  67. stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  68. stage.addEventListener(KeyboardEvent.KEY_UP, Key.onKeyUp);
  69. AAChar.initialize();
  70. Field.initialize();
  71. var i:int;
  72. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  73. {
  74. var bs:Vector. = new Vector.(BLUR_MAX_COUNT, true);
  75. for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  76. {
  77. bs[j] = new Blur;
  78. }
  79. blurs[i] = bs;
  80. blurCounts[i] = 0;
  81. }
  82. blurIndex = 0;
  83. shipChar = new AAChar([" A ", "I#I"], [" R ", "CBC"], 2, 2);
  84. shipChar.drawToSprite(shipSprite);
  85. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS;
  86. shotChar = new AAChar(["!"], ["Y"]);
  87. for (i = 0; i < SHOT_MAX_COUNT; i++)
  88. {
  89. shots[i] = new Shot;
  90. shotChar.drawToSprite(shots[i].sprite);
  91. }
  92. zako1 = new Zako1; mid1 = new Mid1;
  93. for (i = 0; i < ENEMY_MAX_COUNT; i++)
  94. {
  95. enemies[i] = new Enemy;
  96. }
  97. bulletChar = new AAChar(["#"], ["P"], 1, 1);
  98. for (i = 0; i < BULLET_MAX_COUNT; i++)
  99. {
  100. bullets[i] = new Bullet;
  101. bulletChar.drawToSprite(bullets[i].sprite);
  102. }
  103. sparkChar = new AAChar(["*"], ["Y"]);
  104. for (i = 0; i < SPARK_MAX_COUNT; i++)
  105. {
  106. sparks[i] = new Spark;
  107. sparkChar.drawToSprite(sparks[i].sprite);
  108. }
  109. bulletIntervalRank = bulletSpeedRank = enemyIntervalRank = enemySpeedRank = 1.0 / 0.5;
  110. gameSpeed = 1.0;
  111. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  112. }
  113. private function initializeShip():void
  114. {
  115. shipPos.x = 0;
  116. shipPos.y = Field.size.y / 2;
  117. shipAngle = 0.0;
  118. shipFireCount = 0;
  119. shipFireTicks = 0;
  120. bulletIntervalRank *= 0.5; bulletSpeedRank *= 0.5;
  121. enemyIntervalRank *= 0.5; enemySpeedRank *= 0.5;
  122. if (bulletIntervalRank < 0.5) bulletIntervalRank = 0.5;
  123. if (bulletSpeedRank < 0.5) bulletSpeedRank = 0.5;
  124. if (enemyIntervalRank < 0.5) enemyIntervalRank = 0.5;
  125. if (enemySpeedRank < 0.5) enemySpeedRank = 0.5;
  126. rankTicks = 0;
  127. zako1.appearanceTicks = 0;
  128. mid1.appearanceTicks = MID1_APPEARANCE_INTERVAL;
  129. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  130. addChild(shipSprite);
  131. }
  132. private function onEnterFrame(event:Event):void
  133. {
  134. buffer.fillRect(buffer.rect, 0);
  135. var i:int;
  136. blurCounts[blurIndex] = 0;
  137. updateSparks();
  138. updateShots();
  139. if (shipInvincibleTicks > -SHIP_INVINCIBLE_TICKS) updateShip();
  140. else if (shipInvincibleTicks == -SHIP_INVINCIBLE_TICKS) initializeShip();
  141. else Field.offsetX *= 0.95;
  142. shipInvincibleTicks++;
  143. updateEnemies();
  144. updateBullets();
  145. rankTicks++;
  146. bulletIntervalRank += 0.02;
  147. if (rankTicks % (10 * 30) == 0) bulletIntervalRank *= 0.5;
  148. bulletSpeedRank += 0.005;
  149. if (rankTicks % (15 * 30) == 0) bulletSpeedRank *= 0.5;
  150. enemyIntervalRank += 0.005;
  151. if (rankTicks % (21 * 30) == 0) enemyIntervalRank *= 0.5;
  152. enemySpeedRank += 0.002;
  153. if (rankTicks % (27 * 30) == 0) enemySpeedRank *= 0.5;
  154. buffer.lock();
  155. Field.draw(buffer);
  156. var bi:int = blurIndex + 1;
  157. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  158. {
  159. if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  160. for (var j:int = 0; j < blurCounts[bi]; j++)
  161. {
  162. updateBlur(blurs[bi][j]);
  163. }
  164. bi++;
  165. }
  166. Field.drawSideBoard(buffer);
  167. buffer.unlock();
  168. blurIndex++;
  169. if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  170. }
  171. private function updateShip():void
  172. {
  173. var px:Number = shipPos.x;
  174. var vx:Number = 0, vy:Number = 0;
  175. if (Key.left) vx = -1;
  176. if (Key.right) vx = 1;
  177. if (Key.up) vy = -1;
  178. if (Key.down) vy = 1;
  179. if (vx != 0 && vy != 0)
  180. {
  181. vx *= 0.7; vy *= 0.7;
  182. }
  183. shipPos.x += vx * SHIP_SPEED * gameSpeed;
  184. shipPos.y += vy * SHIP_SPEED * gameSpeed;
  185. if (shipPos.x < -SCREEN_WIDTH / 2) shipPos.x = -SCREEN_WIDTH / 2;
  186. if (shipPos.x > SCREEN_WIDTH / 2) shipPos.x = SCREEN_WIDTH / 2;
  187. if (shipPos.y < -SCREEN_HEIGHT / 2) shipPos.y = -SCREEN_HEIGHT / 2;
  188. if (shipPos.y > SCREEN_HEIGHT / 2) shipPos.y = SCREEN_HEIGHT / 2;
  189. shipAngle += (shipPos.x - px) * 0.01;
  190. shipAngle *= 0.8;
  191. Field.offsetX = shipPos.x * 0.33;
  192. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  193. if (shipInvincibleTicks >= 0 || (-shipInvincibleTicks % 15 > 7))
  194. {
  195. addBlursOfAAChar(shipChar, shipPos, shipAngle);
  196. }
  197. var s:Shot;
  198. if (Key.button1 && shipFireTicks <= 0)
  199. {
  200. shipFireTicks += 1.0;
  201. offset.x = 15;
  202. offset.y = 0;
  203. offset.rotation(shipAngle);
  204. s = getActorInstance(Vector.(shots));
  205. var i:int = shipFireCount % 2;
  206. if (s != null)
  207. {
  208. s.pos.x = shipPos.x + offset.x * (i * 2 - 1);
  209. s.pos.y = shipPos.y + offset.y * (i * 2 - 1);
  210. s.angle = shipAngle + 0.2*(shipFireCount % 7-3);
  211. s.ticks = 0;
  212. addBlur(s.pos.x, s.pos.y, 10, 10, 255, 255, 0);
  213. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  214. addChild(s.sprite);
  215. shipFireCount++;
  216. }
  217. }
  218. shipFireTicks -= gameSpeed;
  219. if (shipInvincibleTicks >= 0)
  220. {
  221. for each (var e:Enemy in enemies)
  222. {
  223. if (!e.exists) continue;
  224. if (Math.abs(shipPos.x - e.pos.x) <= e.spec.size.x - 12 &&
  225. Math.abs(shipPos.y - e.pos.y) <= e.spec.size.y - 12)
  226. {
  227. shipDestroyed();
  228. e.exists = false;
  229. removeChild(e.sprite);
  230. return;
  231. }
  232. }
  233. for each (var b:Bullet in bullets)
  234. {
  235. if (!b.exists) continue;
  236. if (shipPos.getRoughDistance(b.pos) <= SHIP_COLLISION_SIZE)
  237. {
  238. shipDestroyed();
  239. b.exists = false;
  240. removeChild(b.sprite);
  241. return;
  242. }
  243. }
  244. }
  245. }
  246. private function updateShots():void
  247. {
  248. var s:Shot;
  249. for each (s in shots)
  250. {
  251. if (!s.exists) continue;
  252. s.pos.x += Math.sin(s.angle) * SHOT_SPEED * gameSpeed;
  253. s.pos.y -= Math.cos(s.angle) * SHOT_SPEED * gameSpeed;
  254. if (s.pos.y < -SCREEN_HEIGHT / 2)
  255. {
  256. s.exists = false;
  257. removeChild(s.sprite);
  258. continue;
  259. }
  260. s.ticks += gameSpeed;
  261. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  262. addBlursOfAAChar(shotChar, s.pos, s.angle, 1.0, 1.0, 150, 100, 0);
  263. for each (var e:Enemy in enemies)
  264. {
  265. if (!e.exists) continue;
  266. if (Math.abs(s.pos.x - e.pos.x) <= e.spec.size.x &&
  267. Math.abs(s.pos.y - e.pos.y) <= e.spec.size.y)
  268. {
  269. addSpark(s.pos, s.angle + Math.PI, 0.2, SHOT_SPEED, 1.0, 2);
  270. e.shield--;
  271. e.isHit = true;
  272. s.exists = false;
  273. removeChild(s.sprite);
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. private function updateEnemies():void
  280. {
  281. var e:Enemy;
  282. var es:EnemySpec = null;
  283. zako1.appearanceTicks -= gameSpeed;
  284. if (zako1.appearanceTicks <= 0)
  285. {
  286. es = zako1;
  287. var ei:int = ZAKO1_APPEARANCE_INTERVAL / enemyIntervalRank;
  288. ei *= (0.75 + Math.random() * 0.5);
  289. if (ei < 5) ei = 5;
  290. zako1.appearanceTicks += ei;
  291. }
  292. mid1.appearanceTicks -= gameSpeed;
  293. if (mid1.appearanceTicks <= 0)
  294. {
  295. es = mid1;
  296. mid1.appearanceTicks += MID1_APPEARANCE_INTERVAL * (0.5 + Math.random());
  297. }
  298. if (es != null)
  299. {
  300. e = getActorInstance(Vector.(enemies));
  301. if (e != null)
  302. {
  303. e.spec = es;
  304. e.speedRatio = enemySpeedRank;
  305. var fsr:Number = bulletSpeedRank;
  306. if (fsr < 1.0) fsr = 1.0;
  307. e.fireSpeedRatio = fsr;
  308. var fir:Number = bulletIntervalRank;
  309. if (fir > 25.0) fir = 25.0;
  310. e.fireIntervalRatio = fir;
  311. e.ticks = 0;
  312. e.fireTicks = 0.0; e.fireSeqTicks = 0.0; e.fireCount = 0;
  313. e.shield = e.spec.shield;
  314. e.isHit = false;
  315. e.spec.initialize(e, shipPos);
  316. e.spec.aaChar.drawToSprite(e.sprite);
  317. addChild(e.sprite);
  318. }
  319. }
  320. for each (e in enemies)
  321. {
  322. if (!e.exists) continue;
  323. if (!Field.contains(e.pos) || e.shield <= 0)
  324. {
  325. e.exists = false;
  326. removeChild(e.sprite);
  327. if (e.shield <= 0) addSpark(e.pos, 0, Math.PI, 4.0, 1.5, 8);
  328. continue;
  329. }
  330. e.spec.update(e, shipPos, this);
  331. e.ticks += gameSpeed;
  332. e.fireTicks -= gameSpeed;
  333. e.spec.aaChar.setSpriteMatrix(e.sprite, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  334. if (e.isHit)
  335. {
  336. e.isHit = false;
  337. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x * 1.5, e.spec.scale.y * 1.5, 255, 255, 0);
  338. }
  339. else
  340. {
  341. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  342. }
  343. }
  344. }
  345. public function fireBullet(p:Vector2, angle:Number, speed:Number, size:Number):void
  346. {
  347. if (p.getRoughDistance(shipPos) <= 200 ||
  348. p.x - Field.offsetX <= -Field.size.x + Field.SIDE_BOARD_WIDTH ||
  349. p.x - Field.offsetX >= Field.size.x - Field.SIDE_BOARD_WIDTH) return;
  350. var b:Bullet = getActorInstance(Vector.(bullets));
  351. if (b == null) return;
  352. b.pos.x = p.x; b.pos.y = p.y;
  353. b.vel.x = Math.sin(angle) * speed;
  354. b.vel.y = -Math.cos(angle) * speed;
  355. b.speed = speed;
  356. b.size = size;
  357. addBlur(b.pos.x + b.vel.x * 2, b.pos.y + b.vel.y * 2, 20, 20, 255, 200, 100);
  358. b.ticks = 0;
  359. addChild(b.sprite);
  360. }
  361. private function updateBullets():void
  362. {
  363. var totalSpeed:Number = 0;
  364. for each (var b:Bullet in bullets)
  365. {
  366. if (!b.exists) continue;
  367. b.pos.addMultiplied(b.vel, gameSpeed);
  368. if (!Field.contains(b.pos))
  369. {
  370. b.exists = false;
  371. removeChild(b.sprite);
  372. continue;
  373. }
  374. var a:Number = b.ticks * 0.1;
  375. bulletChar.setSpriteMatrix(b.sprite, b.pos, a, b.size, b.size);
  376. var sz:Number = b.size * (1.1 + Math.sin(b.ticks * 0.2) * 0.2);
  377. var cl:int = 128 + 64 + Math.sin(b.ticks * 0.3) * 64;
  378. addBlursOfAAChar(bulletChar, b.pos, a, sz, sz, cl, 100, 255);
  379. b.ticks += gameSpeed;
  380. totalSpeed += b.speed + 5.0;
  381. }
  382. if (totalSpeed > 500.0)
  383. {
  384. gameSpeed = 1.0 - (totalSpeed - 500.0) / 250.0;
  385. if (gameSpeed < 0.7) gameSpeed = 0.7;
  386. }
  387. else
  388. {
  389. gameSpeed = 1.0;
  390. }
  391. }
  392. private function updateSparks():void
  393. {
  394. for each (var s:Spark in sparks)
  395. {
  396. if (!s.exists) continue;
  397. s.pos.addMultiplied(s.vel, gameSpeed);
  398. s.vel.mul(1 - 0.05 * gameSpeed);
  399. s.size *= (1 - 0.05 * gameSpeed);
  400. if (!Field.contains(s.pos) || s.ticks <= 0)
  401. {
  402. s.exists = false;
  403. removeChild(s.sprite);
  404. continue;
  405. }
  406. var a:Number = s.ticks * 0.2;
  407. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  408. addBlursOfAAChar(sparkChar, s.pos, a, s.size, s.size,
  409. 250, Math.random() * 128 + 128, 0);
  410. s.ticks -= gameSpeed;
  411. }
  412. }
  413. private function shipDestroyed():void
  414. {
  415. addSpark(shipPos, 0, Math.PI, 10.0, 6.0, 20);
  416. addSpark(shipPos, Math.PI / 2, 0, 30.0, 5.0, 10);
  417. addSpark(shipPos, -Math.PI / 2, 0, 30.0, 5.0, 10);
  418. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS * 1.5;
  419. removeChild(shipSprite);
  420. }
  421. private function addSpark(p:Vector2, angle:Number, ao:Number, speed:Number, size:Number, count:Number):void
  422. {
  423. for (var i:int = 0; i < count; i++)
  424. {
  425. var s:Spark = getActorInstance(Vector.(sparks));
  426. if (s == null) return;
  427. s.pos.x = p.x; s.pos.y = p.y;
  428. var a:Number = angle + ao * (Math.random() * 2 - 1);
  429. var sp:Number = speed * (0.5 + Math.random());
  430. s.vel.x = Math.sin(a) * sp;
  431. s.vel.y = -Math.cos(a) * sp;
  432. s.size = size;
  433. s.ticks = 15 + 15 * Math.random();
  434. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  435. addChild(s.sprite);
  436. }
  437. }
  438. private function addBlursOfAAChar(ac:AAChar, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1,
  439. cr:int = -1, cg:int = -1, cb:int = -1):void
  440. {
  441. var br:int, bg:int, bb:int;
  442. if (cr >= 0)
  443. {
  444. br = cr; bg = cg; bb = cb;
  445. }
  446. for each (var b:Blur in ac.blurs)
  447. {
  448. offset.x = b.pos.x * sx; offset.y = b.pos.y * sy;
  449. offset.rotation(angle);
  450. if (cr < 0)
  451. {
  452. br = b.r; bg = b.g; bb = b.b;
  453. }
  454. addBlur(p.x + offset.x, p.y + offset.y, b.width * sx, b.height * sy, br, bg, bb);
  455. }
  456. }
  457. private function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  458. {
  459. if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  460. var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  461. bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  462. bl.width = w; bl.height = h;
  463. bl.r = r; bl.g = g; bl.b = b;
  464. blurCounts[blurIndex]++;
  465. }
  466. private function updateBlur(b:Blur):void
  467. {
  468. rect.x = b.pos.x - b.width / 2 - Field.offsetX;
  469. rect.y = b.pos.y - b.height / 2;
  470. rect.width = b.width;
  471. rect.height = b.height;
  472. buffer.fillRect(rect, b.r * 0x10000 + b.g * 0x100 + b.b);
  473. b.width *= 1.2; b.height *= 1.2;
  474. var a:int = (b.r + b.g + b.b) / 3;
  475. b.r += (a - b.r) * 0.25;
  476. b.g += (a - b.g) * 0.25;
  477. b.b += (a - b.b) * 0.25;
  478. b.r *= 0.65; b.g *= 0.65; b.b *= 0.65;
  479. }
  480. private function getActorInstance(actors:Vector.):*
  481. {
  482. var al:int = actors.length
  483. for (var i:int = 0; i < al; i++)
  484. {
  485. if (!actors[i].exists)
  486. {
  487. actors[i].exists = true;
  488. return actors[i];
  489. }
  490. }
  491. return null;
  492. }
  493. }
  494. }
  495. import flash.display.BitmapData;
  496. import flash.display.Bitmap;
  497. import flash.display.Sprite;
  498. import flash.geom.Rectangle;
  499. import flash.geom.Matrix;
  500. import flash.text.TextField;
  501. import flash.text.TextFormat;
  502. import flash.events.KeyboardEvent;
  503. class Actor
  504. {
  505. public var exists:Boolean = false;
  506. public var pos:Vector2 = new Vector2;
  507. public var sprite:Sprite = new Sprite;
  508. public var ticks:Number;
  509. }
  510. class Shot extends Actor
  511. {
  512. public var angle:Number;
  513. }
  514. class Enemy extends Actor
  515. {
  516. public var angle:Number;
  517. public var speed:Number;
  518. public var speedRatio:Number;
  519. public var fireSpeedRatio:Number;
  520. public var fireIntervalRatio:Number;
  521. public var fireTicks:Number;
  522. public var fireSeqTicks:Number;
  523. public var fireCount:int;
  524. public var shield:int;
  525. public var isHit:Boolean;
  526. public var spec:EnemySpec;
  527. }
  528. class EnemySpec
  529. {
  530. public var size:Vector2 = new Vector2;
  531. public var scale:Vector2 = new Vector2;
  532. public var shield:int;
  533. public var aaChar:AAChar;
  534. public var appearanceTicks:Number;
  535. public function initialize(e:Enemy, shipPos:Vector2):void { }
  536. public function update(e:Enemy, shipPos:Vector2, main:AAShip):void {}
  537. }
  538. class Zako1 extends EnemySpec
  539. {
  540. private const SPEED:Number = 6;
  541. private const ANGLE_VELOCITY:Number = 0.05;
  542. private const FIRE_INTERVAL:Number = 60;
  543. private const BULLET_SPEED:Number = 5;
  544. public function Zako1()
  545. {
  546. size.x = size.y = 32;
  547. scale.x = scale.y = 1.0;
  548. shield = 1;
  549. aaChar = new AAChar(["", " v "], ["WGW", " C "], 2, 2);
  550. }
  551. override public function initialize(e:Enemy, shipPos:Vector2):void
  552. {
  553. e.pos.x = Field.size.x * (Math.random() * 2 - 1);
  554. e.pos.y = -Field.size.y;
  555. e.angle = Math.PI;
  556. e.speed = SPEED * e.speedRatio;
  557. }
  558. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  559. {
  560. e.pos.x += Math.sin(e.angle) * e.speed * AAShip.gameSpeed;
  561. e.pos.y -= Math.cos(e.angle) * e.speed * AAShip.gameSpeed;
  562. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  563. var ao:Number = pa - e.angle;
  564. ao = Util.normalizeAngle(ao);
  565. if (ao > ANGLE_VELOCITY) e.angle += ANGLE_VELOCITY;
  566. else if (ao < -ANGLE_VELOCITY) e.angle -= ANGLE_VELOCITY;
  567. else e.angle = pa;
  568. e.angle = Util.normalizeAngle(e.angle);
  569. if (e.fireTicks <= 0)
  570. {
  571. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  572. main.fireBullet(e.pos, pa, BULLET_SPEED * e.fireSpeedRatio, 1.0);
  573. }
  574. }
  575. }
  576. class Mid1 extends EnemySpec
  577. {
  578. private const WAVE_INTERVAL:int = 120;
  579. private const SPEED:Number = 1;
  580. private const FIRE_INTERVAL:Number = 150;
  581. private const BULLET_SPEED:Number = 5;
  582. public function Mid1()
  583. {
  584. size.x = 64; size.y = 48;
  585. scale.x = scale.y = 1.2;
  586. shield = 16;
  587. aaChar = new AAChar([".__.", "\\##/"], ["RYYR", "WCCW"], 2, 2);
  588. }
  589. override public function initialize(e:Enemy, shipPos:Vector2):void
  590. {
  591. e.pos.x = Field.size.x * 0.6 * (Math.random() * 2 - 1);
  592. e.ticks = Math.random() * WAVE_INTERVAL;
  593. e.pos.y = -Field.size.y;
  594. e.angle = 0;
  595. e.speed = SPEED * (Math.random() + 1.0);
  596. e.fireSpeedRatio = Math.sqrt(e.fireSpeedRatio);
  597. e.fireIntervalRatio = Math.sqrt(e.fireIntervalRatio);
  598. }
  599. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  600. {
  601. var xa:Number = e.ticks * Math.PI * 2.0 / WAVE_INTERVAL;
  602. e.pos.x += Math.sin(xa) * 1.0 * AAShip.gameSpeed;
  603. e.angle = -Math.sin(xa) * 0.2;
  604. e.pos.y += e.speed * AAShip.gameSpeed;
  605. if (e.pos.y < 0)
  606. {
  607. if (e.fireTicks <= 0)
  608. {
  609. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  610. e.fireSeqTicks = 0;
  611. e.fireCount = 4;
  612. }
  613. if (e.fireCount > 0)
  614. {
  615. e.fireSeqTicks -= AAShip.gameSpeed;
  616. if (e.fireSeqTicks <= 0)
  617. {
  618. e.fireSeqTicks = 3;
  619. e.fireCount--;
  620. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  621. for (var i:int = 0; i < 3; i++)
  622. {
  623. main.fireBullet(e.pos, pa - (i - 1) * 0.5,
  624. BULLET_SPEED * e.fireSpeedRatio * (1.0 + (3 - e.fireCount) * 0.25), 1.25);
  625. }
  626. }
  627. }
  628. }
  629. else
  630. {
  631. e.speed += (SPEED * 4 - e.speed) * 0.1;
  632. }
  633. }
  634. }
  635. class Bullet extends Actor
  636. {
  637. public var vel:Vector2 = new Vector2;
  638. public var speed:Number;
  639. public var size:Number;
  640. }
  641. class Spark extends Actor
  642. {
  643. public var vel:Vector2 = new Vector2;
  644. public var size:Number;
  645. }
  646. class Blur
  647. {
  648. public var pos:Vector2 = new Vector2;
  649. public var width:Number, height:Number;
  650. public var r:int, g:int, b:int;
  651. }
  652. class Field
  653. {
  654. public static const SIDE_BOARD_WIDTH:Number = AAShip.SCREEN_WIDTH / 6;
  655. private static const STAR_COUNT:int = 256;
  656. public static var size:Vector2;
  657. public static var offsetX:Number;
  658. private static var stars:Vector.;
  659. private static var rect:Rectangle = new Rectangle;
  660. public static function initialize():void
  661. {
  662. size = new Vector2;
  663. size.x = AAShip.SCREEN_WIDTH * 1.1 / 2; size.y = AAShip.SCREEN_HEIGHT * 1.1 / 2;
  664. stars = new Vector.(STAR_COUNT, true);
  665. for (var i:int = 0; i < STAR_COUNT; i++)
  666. {
  667. var s:Star = new Star;
  668. var z:Number = 1.0 + Math.random() * 10;
  669. var sz:int = (5 + Math.random() * 5) / z;
  670. if (sz < 1) sz = 1;
  671. s.pos.x = (Math.random() * 2 - 1) * size.x - sz;
  672. s.pos.y = (Math.random() * 2 - 1) * size.y - sz;
  673. s.size = sz;
  674. s.velRatio = 1.0 / z;
  675. s.color = (int)(Math.random() * 127 + 128) * 0x100 +
  676. (int)(Math.random() * 127 + 128);
  677. stars[i] = s;
  678. }
  679. }
  680. public static function draw(buffer:BitmapData):void
  681. {
  682. for each (var s:Star in stars)
  683. {
  684. rect.x = s.pos.x - offsetX * s.velRatio + AAShip.SCREEN_WIDTH / 2;
  685. rect.y = s.pos.y + AAShip.SCREEN_HEIGHT / 2;
  686. rect.width = rect.height = s.size;
  687. buffer.fillRect(rect, s.color);
  688. s.pos.y += 3.0 * s.velRatio;
  689. if (s.pos.y > size.y) s.pos.y -= size.y * 2;
  690. }
  691. }
  692. public static function drawSideBoard(buffer:BitmapData):void
  693. {
  694. rect.width = SIDE_BOARD_WIDTH;
  695. rect.height = AAShip.SCREEN_HEIGHT;
  696. rect.x = rect.y = 0;
  697. buffer.fillRect(rect, 0);
  698. rect.x = AAShip.SCREEN_WIDTH - rect.width;
  699. buffer.fillRect(rect, 0);
  700. }
  701. public static function contains(p:Vector2):Boolean
  702. {
  703. return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  704. }
  705. }
  706. class Star
  707. {
  708. public var pos:Vector2 = new Vector2;
  709. public var size:Number;
  710. public var color:int;
  711. public var velRatio:Number;
  712. }
  713. class AAChar
  714. {
  715. private static const COLOR_PATTERNS:Array =
  716. [["R", 250, 100, 100], ["G", 100, 250, 100], ["B", 100, 100, 250],
  717. ["Y", 250, 250, 100], ["P", 250, 100, 250], ["C", 100, 250, 250],
  718. ["W", 250, 250, 250]];
  719. private const CHAR_SIZE:int = 24;
  720. private const CHAR_OFFSET_X:int = 14;
  721. private const CHAR_OFFSET_Y:int = 17;
  722. private const CHAR_HEIGHT:int = 24;
  723. private static var colorCount:int;
  724. private static var textFormats:Vector. = new Vector.;
  725. public var textFields:Vector. = new Vector.;
  726. public var blurs:Vector. = new Vector.;
  727. public var width:int, height:int;
  728. private var bitmapData:BitmapData;
  729. public static function initialize():void
  730. {
  731. colorCount = 0;
  732. for each (var cp:Array in COLOR_PATTERNS)
  733. {
  734. var tf:TextFormat = new TextFormat;
  735. tf.font = "_typewriter";
  736. tf.bold = true;
  737. tf.size = 24;
  738. tf.leading = -10;
  739. tf.color = (int)(cp[1] * 0.75) * 0x10000 + (int)(cp[2] * 0.75) * 0x100 + (int)(cp[3] * 0.75);
  740. textFormats.push(tf);
  741. colorCount++;
  742. }
  743. }
  744. public function AAChar(chars:Array, colors:Array, divX:int = 1, divY:int = 1)
  745. {
  746. var i:int;
  747. var tfts:Vector. = new Vector.(colorCount, true);
  748. var tffs:Vector. = new Vector.(colorCount, true);
  749. for (i = 0; i < colorCount; i++)
  750. {
  751. tfts[i] = "";
  752. tffs[i] = false;
  753. }
  754. var cx:int, cy:int = 0;
  755. var bd:BitmapData;
  756. var tf:TextField;
  757. var b:Blur;
  758. for (i = 0; i < chars.length; i++)
  759. {
  760. var str:String = chars[i];
  761. var colorStr:String = colors[i];
  762. cx = 0;
  763. var j:int;
  764. for (j = 0; j < str.length; j++)
  765. {
  766. var c:String = str.charAt(j);
  767. var color:String = colorStr.charAt(j);
  768. var ci:int;
  769. for (var k:int = 0; k < colorCount; k++)
  770. {
  771. if (color == COLOR_PATTERNS[k][0])
  772. {
  773. tfts[k] += c;
  774. tffs[k] = true;
  775. ci = k;
  776. }
  777. else
  778. {
  779. tfts[k] += " ";
  780. }
  781. }
  782. bd = new BitmapData(CHAR_SIZE, CHAR_SIZE, false, 0);
  783. tf = new TextField;
  784. tf.defaultTextFormat = textFormats[ci];
  785. tf.text = c;
  786. bd.draw(tf);
  787. for (var dx:int = 0; dx < divX; dx++)
  788. {
  789. for (var dy:int = 0; dy < divY; dy++)
  790. {
  791. var minX:int = CHAR_SIZE, maxX:int = -1;
  792. var minY:int = CHAR_SIZE, maxY:int = -1;
  793. for (var x:int = dx * CHAR_SIZE / divX; x < (dx + 1) * CHAR_SIZE / divX; x++)
  794. {
  795. for (var y:int = dy * CHAR_SIZE / divY; y < (dy + 1) * CHAR_SIZE / divY; y++)
  796. {
  797. if (bd.getPixel(x, y) > 0)
  798. {
  799. if (minX > x) minX = x;
  800. if (maxX < x) maxX = x;
  801. if (minY > y) minY = y;
  802. if (maxY < y) maxY = y;
  803. }
  804. }
  805. }
  806. if (maxX >= 0)
  807. {
  808. b = new Blur;
  809. b.width = maxX - minX + 1;
  810. b.height = maxY - minY + 1;
  811. b.pos.x = minX + cx * CHAR_OFFSET_X + b.width / 2;
  812. b.pos.y = minY + cy * CHAR_OFFSET_Y + b.height / 2;
  813. b.r = COLOR_PATTERNS[ci][1] + (255 - COLOR_PATTERNS[ci][1]) * 0.5;
  814. b.g = COLOR_PATTERNS[ci][2] + (255 - COLOR_PATTERNS[ci][2]) * 0.5;
  815. b.b = COLOR_PATTERNS[ci][3] + (255 - COLOR_PATTERNS[ci][3]) * 0.5;
  816. blurs.push(b);
  817. }
  818. }
  819. }
  820. cx++;
  821. }
  822. for (j = 0; j < colorCount; j++)
  823. {
  824. tfts[j] += "\n";
  825. }
  826. cy++;
  827. }
  828. width = cx * CHAR_OFFSET_X;
  829. height = cy * CHAR_HEIGHT;
  830. for (i = 0; i < colorCount; i++)
  831. {
  832. if (!tffs[i]) continue;
  833. tf = new TextField;
  834. tf.defaultTextFormat = textFormats[i];
  835. tf.multiline = true;
  836. tf.text = tfts[i];
  837. textFields.push(tf);
  838. }
  839. for each (b in blurs)
  840. {
  841. b.pos.x -= width / 2;
  842. b.pos.y -= height / 2;
  843. }
  844. bitmapData = new BitmapData(width, height, true, 0);
  845. for each (tf in textFields)
  846. {
  847. bitmapData.draw(tf);
  848. }
  849. }
  850. public function drawToSprite(s:Sprite):void
  851. {
  852. while (s.numChildren > 0)
  853. {
  854. s.removeChildAt(0);
  855. }
  856. s.addChild(new Bitmap(bitmapData));
  857. }
  858. public function setSpriteMatrix(s:Sprite, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1):void
  859. {
  860. var m:Matrix = new Matrix;
  861. m.translate(-width / 2, -height / 2);
  862. m.scale(sx, sy);
  863. m.rotate(angle);
  864. m.translate(p.x + AAShip.SCREEN_WIDTH / 2 - Field.offsetX, p.y + AAShip.SCREEN_HEIGHT / 2);
  865. s.transform.matrix = m;
  866. }
  867. }
  868. // Utility classes.
  869. class Vector2
  870. {
  871. public var x:Number = 0;
  872. public var y:Number = 0;
  873. public function add(v:Vector2):void
  874. {
  875. x += v.x;
  876. y += v.y;
  877. }
  878. public function addMultiplied(v:Vector2, mv:Number):void
  879. {
  880. x += v.x * mv;
  881. y += v.y * mv;
  882. }
  883. public function sub(v:Vector2):void
  884. {
  885. x -= v.x;
  886. y -= v.y;
  887. }
  888. public function mul(v:Number):void
  889. {
  890. x *= v;
  891. y *= v;
  892. }
  893. public function div(v:Number):void
  894. {
  895. x /= v;
  896. y /= v;
  897. }
  898. public function normalize():void
  899. {
  900. div(length);
  901. }
  902. public function get length():Number
  903. {
  904. return Math.sqrt(x * x + y * y);
  905. }
  906. public function getRoughDistance(p:Vector2):Number
  907. {
  908. return Math.abs(x - p.x) + Math.abs(y - p.y);
  909. }
  910. public function rotation(v:Number):void
  911. {
  912. var sv:Number = Math.sin(v);
  913. var cv:Number = Math.cos(v);
  914. var rx:Number = cv * x - sv * y;
  915. y = sv * x + cv * y;
  916. x = rx;
  917. }
  918. }
  919. class Key
  920. {
  921. public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  922. public static var button1:Boolean;
  923. public static function onKeyUp(event:KeyboardEvent):void
  924. {
  925. switch (event.keyCode)
  926. {
  927. case 0x25:
  928. case 0x41:
  929. {
  930. left = false;
  931. break;
  932. }
  933. case 0x26:
  934. case 0x57:
  935. {
  936. up = false;
  937. break;
  938. }
  939. case 0x27:
  940. case 0x44:
  941. {
  942. right = false;
  943. break;
  944. }
  945. case 0x28:
  946. case 0x53:
  947. {
  948. down = false;
  949. break;
  950. }
  951. case 0x5a:
  952. case 0xbf:
  953. case 0x58:
  954. case 0xbe:
  955. {
  956. button1 = false;
  957. break;
  958. }
  959. }
  960. }
  961. public static function onKeyDown(event:KeyboardEvent):void
  962. {
  963. switch (event.keyCode)
  964. {
  965. case 0x25:
  966. case 0x41:
  967. {
  968. left = true;
  969. break;
  970. }
  971. case 0x26:
  972. case 0x57:
  973. {
  974. up = true;
  975. break;
  976. }
  977. case 0x27:
  978. case 0x44:
  979. {
  980. right = true;
  981. break;
  982. }
  983. case 0x28:
  984. case 0x53:
  985. {
  986. down = true;
  987. break;
  988. }
  989. case 0x5a:
  990. case 0xbf:
  991. case 0x58:
  992. case 0xbe:
  993. {
  994. button1 = true;
  995. break;
  996. }
  997. }
  998. }
  999. }
  1000. class Util
  1001. {
  1002. public static function normalizeAngle(v:Number):Number
  1003. {
  1004. if (v > Math.PI) return v - Math.PI * 2;
  1005. else if (v < -Math.PI) return v + Math.PI * 2;
  1006. else return v;
  1007. }
  1008. }
noswf

forked from: forked from: forked from: AAShip forked from: forked from: forked from: forked from: AAShip [diff(1)]

  1. // forked from ABA's forked from: forked from: forked from: AAShip
  2. // forked from ABA's forked from: forked from: AAShip
  3. // forked from ABA's forked from: AAShip
  4. // forked from ABA's AAShip
  5. // AAShip.as
  6. // Ascii art ship.
  7. // [Control]
  8. // Movement: Arrow or [WASD] keys.
  9. // Fire: [Z], [X], [.] or [/] key.
  10. package
  11. {
  12. import flash.display.Sprite;
  13. import flash.display.BitmapData;
  14. import flash.display.Bitmap;
  15. import flash.geom.Rectangle;
  16. import flash.text.TextField;
  17. import flash.events.Event;
  18. import flash.events.KeyboardEvent;
  19. [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  20. public class AAShip extends Sprite
  21. {
  22. public static const SCREEN_WIDTH:int = 465;
  23. public static const SCREEN_HEIGHT:int = 465;
  24. private const BLUR_MAX_COUNT:int = 512;
  25. private const BLUR_HISTORY_COUNT:int = 6;
  26. private const SHIP_SPEED:Number = 8;
  27. private const SHOT_MAX_COUNT:int = 12;
  28. private const SHOT_SPEED:Number = 20;
  29. private const SHIP_COLLISION_SIZE:Number = 5;
  30. private const SHIP_INVINCIBLE_TICKS:int = 90;
  31. private const ENEMY_MAX_COUNT:int = 16;
  32. private const BULLET_MAX_COUNT:int = 128;
  33. private const SPARK_MAX_COUNT:int = 64;
  34. private const ZAKO1_APPEARANCE_INTERVAL:Number = 30;
  35. private const MID1_APPEARANCE_INTERVAL:Number = 180;
  36. public static var gameSpeed:Number;
  37. private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
  38. private var rect:Rectangle = new Rectangle;
  39. private var offset:Vector2 = new Vector2;
  40. private var blurs:Vector.> = new Vector.>(BLUR_HISTORY_COUNT, true);
  41. private var blurCounts:Vector. = new Vector.(BLUR_HISTORY_COUNT, true);
  42. private var blurIndex:int;
  43. private var shipChar:AAChar;
  44. private var shipSprite:Sprite = new Sprite;
  45. private var shipPos:Vector2 = new Vector2;
  46. private var shipAngle:Number;
  47. private var shipInvincibleTicks:int;
  48. private var shipFireCount:int;
  49. private var shipFireTicks:Number;
  50. private var shotChar:AAChar;
  51. private var shots:Vector. = new Vector.(SHOT_MAX_COUNT, true);
  52. private var enemies:Vector. = new Vector.(ENEMY_MAX_COUNT, true);
  53. private var zako1:Zako1, mid1:Mid1;
  54. private var bulletChar:AAChar;
  55. private var bullets:Vector. = new Vector.(BULLET_MAX_COUNT, true);
  56. private var sparkChar:AAChar;
  57. private var sparks:Vector. = new Vector.(SPARK_MAX_COUNT, true);
  58. private var bulletIntervalRank:Number;
  59. private var bulletSpeedRank:Number;
  60. private var enemyIntervalRank:Number;
  61. private var enemySpeedRank:Number;
  62. private var rankTicks:int;
  63. public function AAShip()
  64. {
  65. stage.scaleMode = "noScale";
  66. addChild(new Bitmap(buffer));
  67. stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  68. stage.addEventListener(KeyboardEvent.KEY_UP, Key.onKeyUp);
  69. AAChar.initialize();
  70. Field.initialize();
  71. var i:int;
  72. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  73. {
  74. var bs:Vector. = new Vector.(BLUR_MAX_COUNT, true);
  75. for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  76. {
  77. bs[j] = new Blur;
  78. }
  79. blurs[i] = bs;
  80. blurCounts[i] = 0;
  81. }
  82. blurIndex = 0;
  83. shipChar = new AAChar([" A ", "I#I"], [" R ", "CBC"], 2, 2);
  84. shipChar.drawToSprite(shipSprite);
  85. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS;
  86. shotChar = new AAChar(["!"], ["Y"]);
  87. for (i = 0; i < SHOT_MAX_COUNT; i++)
  88. {
  89. shots[i] = new Shot;
  90. shotChar.drawToSprite(shots[i].sprite);
  91. }
  92. zako1 = new Zako1; mid1 = new Mid1;
  93. for (i = 0; i < ENEMY_MAX_COUNT; i++)
  94. {
  95. enemies[i] = new Enemy;
  96. }
  97. bulletChar = new AAChar(["#"], ["P"], 1, 1);
  98. for (i = 0; i < BULLET_MAX_COUNT; i++)
  99. {
  100. bullets[i] = new Bullet;
  101. bulletChar.drawToSprite(bullets[i].sprite);
  102. }
  103. sparkChar = new AAChar(["*"], ["Y"]);
  104. for (i = 0; i < SPARK_MAX_COUNT; i++)
  105. {
  106. sparks[i] = new Spark;
  107. sparkChar.drawToSprite(sparks[i].sprite);
  108. }
  109. bulletIntervalRank = bulletSpeedRank = enemyIntervalRank = enemySpeedRank = 1.0 / 0.5;
  110. gameSpeed = 1.0;
  111. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  112. }
  113. private function initializeShip():void
  114. {
  115. shipPos.x = 0;
  116. shipPos.y = Field.size.y / 2;
  117. shipAngle = 0.0;
  118. shipFireCount = 0;
  119. shipFireTicks = 0;
  120. bulletIntervalRank *= 0.5; bulletSpeedRank *= 0.5;
  121. enemyIntervalRank *= 0.5; enemySpeedRank *= 0.5;
  122. if (bulletIntervalRank < 0.5) bulletIntervalRank = 0.5;
  123. if (bulletSpeedRank < 0.5) bulletSpeedRank = 0.5;
  124. if (enemyIntervalRank < 0.5) enemyIntervalRank = 0.5;
  125. if (enemySpeedRank < 0.5) enemySpeedRank = 0.5;
  126. rankTicks = 0;
  127. zako1.appearanceTicks = 0;
  128. mid1.appearanceTicks = MID1_APPEARANCE_INTERVAL;
  129. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  130. addChild(shipSprite);
  131. }
  132. private function onEnterFrame(event:Event):void
  133. {
  134. buffer.fillRect(buffer.rect, 0);
  135. var i:int;
  136. blurCounts[blurIndex] = 0;
  137. updateSparks();
  138. updateShots();
  139. if (shipInvincibleTicks > -SHIP_INVINCIBLE_TICKS) updateShip();
  140. else if (shipInvincibleTicks == -SHIP_INVINCIBLE_TICKS) initializeShip();
  141. else Field.offsetX *= 0.95;
  142. shipInvincibleTicks++;
  143. updateEnemies();
  144. updateBullets();
  145. rankTicks++;
  146. bulletIntervalRank += 0.02;
  147. if (rankTicks % (10 * 30) == 0) bulletIntervalRank *= 0.5;
  148. bulletSpeedRank += 0.005;
  149. if (rankTicks % (15 * 30) == 0) bulletSpeedRank *= 0.5;
  150. enemyIntervalRank += 0.005;
  151. if (rankTicks % (21 * 30) == 0) enemyIntervalRank *= 0.5;
  152. enemySpeedRank += 0.002;
  153. if (rankTicks % (27 * 30) == 0) enemySpeedRank *= 0.5;
  154. buffer.lock();
  155. Field.draw(buffer);
  156. var bi:int = blurIndex + 1;
  157. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  158. {
  159. if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  160. for (var j:int = 0; j < blurCounts[bi]; j++)
  161. {
  162. updateBlur(blurs[bi][j]);
  163. }
  164. bi++;
  165. }
  166. Field.drawSideBoard(buffer);
  167. buffer.unlock();
  168. blurIndex++;
  169. if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  170. }
  171. private function updateShip():void
  172. {
  173. var px:Number = shipPos.x;
  174. var vx:Number = 0, vy:Number = 0;
  175. if (Key.left) vx = -1;
  176. if (Key.right) vx = 1;
  177. if (Key.up) vy = -1;
  178. if (Key.down) vy = 1;
  179. if (vx != 0 && vy != 0)
  180. {
  181. vx *= 0.7; vy *= 0.7;
  182. }
  183. shipPos.x += vx * SHIP_SPEED * gameSpeed;
  184. shipPos.y += vy * SHIP_SPEED * gameSpeed;
  185. if (shipPos.x < -SCREEN_WIDTH / 2) shipPos.x = -SCREEN_WIDTH / 2;
  186. if (shipPos.x > SCREEN_WIDTH / 2) shipPos.x = SCREEN_WIDTH / 2;
  187. if (shipPos.y < -SCREEN_HEIGHT / 2) shipPos.y = -SCREEN_HEIGHT / 2;
  188. if (shipPos.y > SCREEN_HEIGHT / 2) shipPos.y = SCREEN_HEIGHT / 2;
  189. shipAngle += (shipPos.x - px) * 0.01;
  190. shipAngle *= 0.8;
  191. Field.offsetX = shipPos.x * 0.33;
  192. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  193. if (shipInvincibleTicks >= 0 || (-shipInvincibleTicks % 15 > 7))
  194. {
  195. addBlursOfAAChar(shipChar, shipPos, shipAngle);
  196. }
  197. var s:Shot;
  198. if (Key.button1 && shipFireTicks <= 0)
  199. {
  200. shipFireTicks += 1.0;
  201. offset.x = 15;
  202. offset.y = 0;
  203. offset.rotation(shipAngle);
  204. s = getActorInstance(Vector.(shots));
  205. var i:int = shipFireCount % 2;
  206. if (s != null)
  207. {
  208. s.pos.x = shipPos.x + offset.x * (i * 2 - 1);
  209. s.pos.y = shipPos.y + offset.y * (i * 2 - 1);
  210. s.angle = shipAngle;
  211. s.ticks = 0;
  212. addBlur(s.pos.x, s.pos.y, 10, 10, 255, 255, 0);
  213. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  214. addChild(s.sprite);
  215. shipFireCount++;
  216. }
  217. }
  218. shipFireTicks -= gameSpeed;
  219. if (shipInvincibleTicks >= 0)
  220. {
  221. for each (var e:Enemy in enemies)
  222. {
  223. if (!e.exists) continue;
  224. if (Math.abs(shipPos.x - e.pos.x) <= e.spec.size.x - 12 &&
  225. Math.abs(shipPos.y - e.pos.y) <= e.spec.size.y - 12)
  226. {
  227. shipDestroyed();
  228. e.exists = false;
  229. removeChild(e.sprite);
  230. return;
  231. }
  232. }
  233. for each (var b:Bullet in bullets)
  234. {
  235. if (!b.exists) continue;
  236. if (shipPos.getRoughDistance(b.pos) <= SHIP_COLLISION_SIZE)
  237. {
  238. shipDestroyed();
  239. b.exists = false;
  240. removeChild(b.sprite);
  241. return;
  242. }
  243. }
  244. }
  245. }
  246. private function updateShots():void
  247. {
  248. var s:Shot;
  249. for each (s in shots)
  250. {
  251. if (!s.exists) continue;
  252. s.pos.x += Math.sin(s.angle) * SHOT_SPEED * gameSpeed;
  253. s.pos.y -= Math.cos(s.angle) * SHOT_SPEED * gameSpeed;
  254. if (s.pos.y < -SCREEN_HEIGHT / 2)
  255. {
  256. s.exists = false;
  257. removeChild(s.sprite);
  258. continue;
  259. }
  260. s.ticks += gameSpeed;
  261. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  262. addBlursOfAAChar(shotChar, s.pos, s.angle, 1.0, 1.0, 150, 100, 0);
  263. for each (var e:Enemy in enemies)
  264. {
  265. if (!e.exists) continue;
  266. if (Math.abs(s.pos.x - e.pos.x) <= e.spec.size.x &&
  267. Math.abs(s.pos.y - e.pos.y) <= e.spec.size.y)
  268. {
  269. addSpark(s.pos, s.angle + Math.PI, 0.2, SHOT_SPEED, 1.0, 2);
  270. e.shield--;
  271. e.isHit = true;
  272. s.exists = false;
  273. removeChild(s.sprite);
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. private function updateEnemies():void
  280. {
  281. var e:Enemy;
  282. var es:EnemySpec = null;
  283. zako1.appearanceTicks -= gameSpeed;
  284. if (zako1.appearanceTicks <= 0)
  285. {
  286. es = zako1;
  287. var ei:int = ZAKO1_APPEARANCE_INTERVAL / enemyIntervalRank;
  288. ei *= (0.75 + Math.random() * 0.5);
  289. if (ei < 5) ei = 5;
  290. zako1.appearanceTicks += ei;
  291. }
  292. mid1.appearanceTicks -= gameSpeed;
  293. if (mid1.appearanceTicks <= 0)
  294. {
  295. es = mid1;
  296. mid1.appearanceTicks += MID1_APPEARANCE_INTERVAL * (0.5 + Math.random());
  297. }
  298. if (es != null)
  299. {
  300. e = getActorInstance(Vector.(enemies));
  301. if (e != null)
  302. {
  303. e.spec = es;
  304. e.speedRatio = enemySpeedRank;
  305. var fsr:Number = bulletSpeedRank;
  306. if (fsr < 1.0) fsr = 1.0;
  307. e.fireSpeedRatio = fsr;
  308. var fir:Number = bulletIntervalRank;
  309. if (fir > 25.0) fir = 25.0;
  310. e.fireIntervalRatio = fir;
  311. e.ticks = 0;
  312. e.fireTicks = 0.0; e.fireSeqTicks = 0.0; e.fireCount = 0;
  313. e.shield = e.spec.shield;
  314. e.isHit = false;
  315. e.spec.initialize(e, shipPos);
  316. e.spec.aaChar.drawToSprite(e.sprite);
  317. addChild(e.sprite);
  318. }
  319. }
  320. for each (e in enemies)
  321. {
  322. if (!e.exists) continue;
  323. if (!Field.contains(e.pos) || e.shield <= 0)
  324. {
  325. e.exists = false;
  326. removeChild(e.sprite);
  327. if (e.shield <= 0) addSpark(e.pos, 0, Math.PI, 4.0, 1.5, 8);
  328. continue;
  329. }
  330. e.spec.update(e, shipPos, this);
  331. e.ticks += gameSpeed;
  332. e.fireTicks -= gameSpeed;
  333. e.spec.aaChar.setSpriteMatrix(e.sprite, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  334. if (e.isHit)
  335. {
  336. e.isHit = false;
  337. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x * 1.5, e.spec.scale.y * 1.5, 255, 255, 0);
  338. }
  339. else
  340. {
  341. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  342. }
  343. }
  344. }
  345. public function fireBullet(p:Vector2, angle:Number, speed:Number, size:Number):void
  346. {
  347. if (p.getRoughDistance(shipPos) <= 200 ||
  348. p.x - Field.offsetX <= -Field.size.x + Field.SIDE_BOARD_WIDTH ||
  349. p.x - Field.offsetX >= Field.size.x - Field.SIDE_BOARD_WIDTH) return;
  350. var b:Bullet = getActorInstance(Vector.(bullets));
  351. if (b == null) return;
  352. b.pos.x = p.x; b.pos.y = p.y;
  353. b.vel.x = Math.sin(angle) * speed;
  354. b.vel.y = -Math.cos(angle) * speed;
  355. b.speed = speed;
  356. b.size = size;
  357. addBlur(b.pos.x + b.vel.x * 2, b.pos.y + b.vel.y * 2, 20, 20, 255, 200, 100);
  358. b.ticks = 0;
  359. addChild(b.sprite);
  360. }
  361. private function updateBullets():void
  362. {
  363. var totalSpeed:Number = 0;
  364. for each (var b:Bullet in bullets)
  365. {
  366. if (!b.exists) continue;
  367. b.pos.addMultiplied(b.vel, gameSpeed);
  368. if (!Field.contains(b.pos))
  369. {
  370. b.exists = false;
  371. removeChild(b.sprite);
  372. continue;
  373. }
  374. var a:Number = b.ticks * 0.1;
  375. bulletChar.setSpriteMatrix(b.sprite, b.pos, a, b.size, b.size);
  376. var sz:Number = b.size * (1.1 + Math.sin(b.ticks * 0.2) * 0.2);
  377. var cl:int = 128 + 64 + Math.sin(b.ticks * 0.3) * 64;
  378. addBlursOfAAChar(bulletChar, b.pos, a, sz, sz, cl, 100, 255);
  379. b.ticks += gameSpeed;
  380. totalSpeed += b.speed + 5.0;
  381. }
  382. if (totalSpeed > 500.0)
  383. {
  384. gameSpeed = 1.0 - (totalSpeed - 500.0) / 250.0;
  385. if (gameSpeed < 0.7) gameSpeed = 0.7;
  386. }
  387. else
  388. {
  389. gameSpeed = 1.0;
  390. }
  391. }
  392. private function updateSparks():void
  393. {
  394. for each (var s:Spark in sparks)
  395. {
  396. if (!s.exists) continue;
  397. s.pos.addMultiplied(s.vel, gameSpeed);
  398. s.vel.mul(1 - 0.05 * gameSpeed);
  399. s.size *= (1 - 0.05 * gameSpeed);
  400. if (!Field.contains(s.pos) || s.ticks <= 0)
  401. {
  402. s.exists = false;
  403. removeChild(s.sprite);
  404. continue;
  405. }
  406. var a:Number = s.ticks * 0.2;
  407. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  408. addBlursOfAAChar(sparkChar, s.pos, a, s.size, s.size,
  409. 250, Math.random() * 128 + 128, 0);
  410. s.ticks -= gameSpeed;
  411. }
  412. }
  413. private function shipDestroyed():void
  414. {
  415. addSpark(shipPos, 0, Math.PI, 10.0, 6.0, 20);
  416. addSpark(shipPos, Math.PI / 2, 0, 30.0, 5.0, 10);
  417. addSpark(shipPos, -Math.PI / 2, 0, 30.0, 5.0, 10);
  418. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS * 1.5;
  419. removeChild(shipSprite);
  420. }
  421. private function addSpark(p:Vector2, angle:Number, ao:Number, speed:Number, size:Number, count:Number):void
  422. {
  423. for (var i:int = 0; i < count; i++)
  424. {
  425. var s:Spark = getActorInstance(Vector.(sparks));
  426. if (s == null) return;
  427. s.pos.x = p.x; s.pos.y = p.y;
  428. var a:Number = angle + ao * (Math.random() * 2 - 1);
  429. var sp:Number = speed * (0.5 + Math.random());
  430. s.vel.x = Math.sin(a) * sp;
  431. s.vel.y = -Math.cos(a) * sp;
  432. s.size = size;
  433. s.ticks = 15 + 15 * Math.random();
  434. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  435. addChild(s.sprite);
  436. }
  437. }
  438. private function addBlursOfAAChar(ac:AAChar, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1,
  439. cr:int = -1, cg:int = -1, cb:int = -1):void
  440. {
  441. var br:int, bg:int, bb:int;
  442. if (cr >= 0)
  443. {
  444. br = cr; bg = cg; bb = cb;
  445. }
  446. for each (var b:Blur in ac.blurs)
  447. {
  448. offset.x = b.pos.x * sx; offset.y = b.pos.y * sy;
  449. offset.rotation(angle);
  450. if (cr < 0)
  451. {
  452. br = b.r; bg = b.g; bb = b.b;
  453. }
  454. addBlur(p.x + offset.x, p.y + offset.y, b.width * sx, b.height * sy, br, bg, bb);
  455. }
  456. }
  457. private function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  458. {
  459. if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  460. var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  461. bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  462. bl.width = w; bl.height = h;
  463. bl.r = r; bl.g = g; bl.b = b;
  464. blurCounts[blurIndex]++;
  465. }
  466. private function updateBlur(b:Blur):void
  467. {
  468. rect.x = b.pos.x - b.width / 2 - Field.offsetX;
  469. rect.y = b.pos.y - b.height / 2;
  470. rect.width = b.width;
  471. rect.height = b.height;
  472. buffer.fillRect(rect, b.r * 0x10000 + b.g * 0x100 + b.b);
  473. b.width *= 1.2; b.height *= 1.2;
  474. var a:int = (b.r + b.g + b.b) / 3;
  475. b.r += (a - b.r) * 0.25;
  476. b.g += (a - b.g) * 0.25;
  477. b.b += (a - b.b) * 0.25;
  478. b.r *= 0.65; b.g *= 0.65; b.b *= 0.65;
  479. }
  480. private function getActorInstance(actors:Vector.):*
  481. {
  482. var al:int = actors.length
  483. for (var i:int = 0; i < al; i++)
  484. {
  485. if (!actors[i].exists)
  486. {
  487. actors[i].exists = true;
  488. return actors[i];
  489. }
  490. }
  491. return null;
  492. }
  493. }
  494. }
  495. import flash.display.BitmapData;
  496. import flash.display.Bitmap;
  497. import flash.display.Sprite;
  498. import flash.geom.Rectangle;
  499. import flash.geom.Matrix;
  500. import flash.text.TextField;
  501. import flash.text.TextFormat;
  502. import flash.events.KeyboardEvent;
  503. class Actor
  504. {
  505. public var exists:Boolean = false;
  506. public var pos:Vector2 = new Vector2;
  507. public var sprite:Sprite = new Sprite;
  508. public var ticks:Number;
  509. }
  510. class Shot extends Actor
  511. {
  512. public var angle:Number;
  513. }
  514. class Enemy extends Actor
  515. {
  516. public var angle:Number;
  517. public var speed:Number;
  518. public var speedRatio:Number;
  519. public var fireSpeedRatio:Number;
  520. public var fireIntervalRatio:Number;
  521. public var fireTicks:Number;
  522. public var fireSeqTicks:Number;
  523. public var fireCount:int;
  524. public var shield:int;
  525. public var isHit:Boolean;
  526. public var spec:EnemySpec;
  527. }
  528. class EnemySpec
  529. {
  530. public var size:Vector2 = new Vector2;
  531. public var scale:Vector2 = new Vector2;
  532. public var shield:int;
  533. public var aaChar:AAChar;
  534. public var appearanceTicks:Number;
  535. public function initialize(e:Enemy, shipPos:Vector2):void { }
  536. public function update(e:Enemy, shipPos:Vector2, main:AAShip):void {}
  537. }
  538. class Zako1 extends EnemySpec
  539. {
  540. private const SPEED:Number = 6;
  541. private const ANGLE_VELOCITY:Number = 0.05;
  542. private const FIRE_INTERVAL:Number = 60;
  543. private const BULLET_SPEED:Number = 5;
  544. public function Zako1()
  545. {
  546. size.x = size.y = 32;
  547. scale.x = scale.y = 1.0;
  548. shield = 1;
  549. aaChar = new AAChar(["", " v "], ["WGW", " C "], 2, 2);
  550. }
  551. override public function initialize(e:Enemy, shipPos:Vector2):void
  552. {
  553. e.pos.x = Field.size.x * (Math.random() * 2 - 1);
  554. e.pos.y = -Field.size.y;
  555. e.angle = Math.PI;
  556. e.speed = SPEED * e.speedRatio;
  557. }
  558. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  559. {
  560. e.pos.x += Math.sin(e.angle) * e.speed * AAShip.gameSpeed;
  561. e.pos.y -= Math.cos(e.angle) * e.speed * AAShip.gameSpeed;
  562. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  563. var ao:Number = pa - e.angle;
  564. ao = Util.normalizeAngle(ao);
  565. if (ao > ANGLE_VELOCITY) e.angle += ANGLE_VELOCITY;
  566. else if (ao < -ANGLE_VELOCITY) e.angle -= ANGLE_VELOCITY;
  567. else e.angle = pa;
  568. e.angle = Util.normalizeAngle(e.angle);
  569. if (e.fireTicks <= 0)
  570. {
  571. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  572. main.fireBullet(e.pos, pa, BULLET_SPEED * e.fireSpeedRatio, 1.0);
  573. }
  574. }
  575. }
  576. class Mid1 extends EnemySpec
  577. {
  578. private const WAVE_INTERVAL:int = 120;
  579. private const SPEED:Number = 1;
  580. private const FIRE_INTERVAL:Number = 150;
  581. private const BULLET_SPEED:Number = 5;
  582. public function Mid1()
  583. {
  584. size.x = 64; size.y = 48;
  585. scale.x = scale.y = 1.2;
  586. shield = 16;
  587. aaChar = new AAChar([".__.", "\\##/"], ["RYYR", "WCCW"], 2, 2);
  588. }
  589. override public function initialize(e:Enemy, shipPos:Vector2):void
  590. {
  591. e.pos.x = Field.size.x * 0.6 * (Math.random() * 2 - 1);
  592. e.ticks = Math.random() * WAVE_INTERVAL;
  593. e.pos.y = -Field.size.y;
  594. e.angle = 0;
  595. e.speed = SPEED * (Math.random() + 1.0);
  596. e.fireSpeedRatio = Math.sqrt(e.fireSpeedRatio);
  597. e.fireIntervalRatio = Math.sqrt(e.fireIntervalRatio);
  598. }
  599. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  600. {
  601. var xa:Number = e.ticks * Math.PI * 2.0 / WAVE_INTERVAL;
  602. e.pos.x += Math.sin(xa) * 1.0 * AAShip.gameSpeed;
  603. e.angle = -Math.sin(xa) * 0.2;
  604. e.pos.y += e.speed * AAShip.gameSpeed;
  605. if (e.pos.y < 0)
  606. {
  607. if (e.fireTicks <= 0)
  608. {
  609. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  610. e.fireSeqTicks = 0;
  611. e.fireCount = 4;
  612. }
  613. if (e.fireCount > 0)
  614. {
  615. e.fireSeqTicks -= AAShip.gameSpeed;
  616. if (e.fireSeqTicks <= 0)
  617. {
  618. e.fireSeqTicks = 3;
  619. e.fireCount--;
  620. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  621. for (var i:int = 0; i < 3; i++)
  622. {
  623. main.fireBullet(e.pos, pa - (i - 1) * 0.5,
  624. BULLET_SPEED * e.fireSpeedRatio * (1.0 + (3 - e.fireCount) * 0.25), 1.25);
  625. }
  626. }
  627. }
  628. }
  629. else
  630. {
  631. e.speed += (SPEED * 4 - e.speed) * 0.1;
  632. }
  633. }
  634. }
  635. class Bullet extends Actor
  636. {
  637. public var vel:Vector2 = new Vector2;
  638. public var speed:Number;
  639. public var size:Number;
  640. }
  641. class Spark extends Actor
  642. {
  643. public var vel:Vector2 = new Vector2;
  644. public var size:Number;
  645. }
  646. class Blur
  647. {
  648. public var pos:Vector2 = new Vector2;
  649. public var width:Number, height:Number;
  650. public var r:int, g:int, b:int;
  651. }
  652. class Field
  653. {
  654. public static const SIDE_BOARD_WIDTH:Number = AAShip.SCREEN_WIDTH / 6;
  655. private static const STAR_COUNT:int = 256;
  656. public static var size:Vector2;
  657. public static var offsetX:Number;
  658. private static var stars:Vector.;
  659. private static var rect:Rectangle = new Rectangle;
  660. public static function initialize():void
  661. {
  662. size = new Vector2;
  663. size.x = AAShip.SCREEN_WIDTH * 1.1 / 2; size.y = AAShip.SCREEN_HEIGHT * 1.1 / 2;
  664. stars = new Vector.(STAR_COUNT, true);
  665. for (var i:int = 0; i < STAR_COUNT; i++)
  666. {
  667. var s:Star = new Star;
  668. var z:Number = 1.0 + Math.random() * 10;
  669. var sz:int = (5 + Math.random() * 5) / z;
  670. if (sz < 1) sz = 1;
  671. s.pos.x = (Math.random() * 2 - 1) * size.x - sz;
  672. s.pos.y = (Math.random() * 2 - 1) * size.y - sz;
  673. s.size = sz;
  674. s.velRatio = 1.0 / z;
  675. s.color = (int)(Math.random() * 127 + 128) * 0x100 +
  676. (int)(Math.random() * 127 + 128);
  677. stars[i] = s;
  678. }
  679. }
  680. public static function draw(buffer:BitmapData):void
  681. {
  682. for each (var s:Star in stars)
  683. {
  684. rect.x = s.pos.x - offsetX * s.velRatio + AAShip.SCREEN_WIDTH / 2;
  685. rect.y = s.pos.y + AAShip.SCREEN_HEIGHT / 2;
  686. rect.width = rect.height = s.size;
  687. buffer.fillRect(rect, s.color);
  688. s.pos.y += 3.0 * s.velRatio;
  689. if (s.pos.y > size.y) s.pos.y -= size.y * 2;
  690. }
  691. }
  692. public static function drawSideBoard(buffer:BitmapData):void
  693. {
  694. rect.width = SIDE_BOARD_WIDTH;
  695. rect.height = AAShip.SCREEN_HEIGHT;
  696. rect.x = rect.y = 0;
  697. buffer.fillRect(rect, 0);
  698. rect.x = AAShip.SCREEN_WIDTH - rect.width;
  699. buffer.fillRect(rect, 0);
  700. }
  701. public static function contains(p:Vector2):Boolean
  702. {
  703. return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  704. }
  705. }
  706. class Star
  707. {
  708. public var pos:Vector2 = new Vector2;
  709. public var size:Number;
  710. public var color:int;
  711. public var velRatio:Number;
  712. }
  713. class AAChar
  714. {
  715. private static const COLOR_PATTERNS:Array =
  716. [["R", 250, 100, 100], ["G", 100, 250, 100], ["B", 100, 100, 250],
  717. ["Y", 250, 250, 100], ["P", 250, 100, 250], ["C", 100, 250, 250],
  718. ["W", 250, 250, 250]];
  719. private const CHAR_SIZE:int = 24;
  720. private const CHAR_OFFSET_X:int = 14;
  721. private const CHAR_OFFSET_Y:int = 17;
  722. private const CHAR_HEIGHT:int = 24;
  723. private static var colorCount:int;
  724. private static var textFormats:Vector. = new Vector.;
  725. public var textFields:Vector. = new Vector.;
  726. public var blurs:Vector. = new Vector.;
  727. public var width:int, height:int;
  728. private var bitmapData:BitmapData;
  729. public static function initialize():void
  730. {
  731. colorCount = 0;
  732. for each (var cp:Array in COLOR_PATTERNS)
  733. {
  734. var tf:TextFormat = new TextFormat;
  735. tf.font = "_typewriter";
  736. tf.bold = true;
  737. tf.size = 24;
  738. tf.leading = -10;
  739. tf.color = (int)(cp[1] * 0.75) * 0x10000 + (int)(cp[2] * 0.75) * 0x100 + (int)(cp[3] * 0.75);
  740. textFormats.push(tf);
  741. colorCount++;
  742. }
  743. }
  744. public function AAChar(chars:Array, colors:Array, divX:int = 1, divY:int = 1)
  745. {
  746. var i:int;
  747. var tfts:Vector. = new Vector.(colorCount, true);
  748. var tffs:Vector. = new Vector.(colorCount, true);
  749. for (i = 0; i < colorCount; i++)
  750. {
  751. tfts[i] = "";
  752. tffs[i] = false;
  753. }
  754. var cx:int, cy:int = 0;
  755. var bd:BitmapData;
  756. var tf:TextField;
  757. var b:Blur;
  758. for (i = 0; i < chars.length; i++)
  759. {
  760. var str:String = chars[i];
  761. var colorStr:String = colors[i];
  762. cx = 0;
  763. var j:int;
  764. for (j = 0; j < str.length; j++)
  765. {
  766. var c:String = str.charAt(j);
  767. var color:String = colorStr.charAt(j);
  768. var ci:int;
  769. for (var k:int = 0; k < colorCount; k++)
  770. {
  771. if (color == COLOR_PATTERNS[k][0])
  772. {
  773. tfts[k] += c;
  774. tffs[k] = true;
  775. ci = k;
  776. }
  777. else
  778. {
  779. tfts[k] += " ";
  780. }
  781. }
  782. bd = new BitmapData(CHAR_SIZE, CHAR_SIZE, false, 0);
  783. tf = new TextField;
  784. tf.defaultTextFormat = textFormats[ci];
  785. tf.text = c;
  786. bd.draw(tf);
  787. for (var dx:int = 0; dx < divX; dx++)
  788. {
  789. for (var dy:int = 0; dy < divY; dy++)
  790. {
  791. var minX:int = CHAR_SIZE, maxX:int = -1;
  792. var minY:int = CHAR_SIZE, maxY:int = -1;
  793. for (var x:int = dx * CHAR_SIZE / divX; x < (dx + 1) * CHAR_SIZE / divX; x++)
  794. {
  795. for (var y:int = dy * CHAR_SIZE / divY; y < (dy + 1) * CHAR_SIZE / divY; y++)
  796. {
  797. if (bd.getPixel(x, y) > 0)
  798. {
  799. if (minX > x) minX = x;
  800. if (maxX < x) maxX = x;
  801. if (minY > y) minY = y;
  802. if (maxY < y) maxY = y;
  803. }
  804. }
  805. }
  806. if (maxX >= 0)
  807. {
  808. b = new Blur;
  809. b.width = maxX - minX + 1;
  810. b.height = maxY - minY + 1;
  811. b.pos.x = minX + cx * CHAR_OFFSET_X + b.width / 2;
  812. b.pos.y = minY + cy * CHAR_OFFSET_Y + b.height / 2;
  813. b.r = COLOR_PATTERNS[ci][1] + (255 - COLOR_PATTERNS[ci][1]) * 0.5;
  814. b.g = COLOR_PATTERNS[ci][2] + (255 - COLOR_PATTERNS[ci][2]) * 0.5;
  815. b.b = COLOR_PATTERNS[ci][3] + (255 - COLOR_PATTERNS[ci][3]) * 0.5;
  816. blurs.push(b);
  817. }
  818. }
  819. }
  820. cx++;
  821. }
  822. for (j = 0; j < colorCount; j++)
  823. {
  824. tfts[j] += "\n";
  825. }
  826. cy++;
  827. }
  828. width = cx * CHAR_OFFSET_X;
  829. height = cy * CHAR_HEIGHT;
  830. for (i = 0; i < colorCount; i++)
  831. {
  832. if (!tffs[i]) continue;
  833. tf = new TextField;
  834. tf.defaultTextFormat = textFormats[i];
  835. tf.multiline = true;
  836. tf.text = tfts[i];
  837. textFields.push(tf);
  838. }
  839. for each (b in blurs)
  840. {
  841. b.pos.x -= width / 2;
  842. b.pos.y -= height / 2;
  843. }
  844. bitmapData = new BitmapData(width, height, true, 0);
  845. for each (tf in textFields)
  846. {
  847. bitmapData.draw(tf);
  848. }
  849. }
  850. public function drawToSprite(s:Sprite):void
  851. {
  852. while (s.numChildren > 0)
  853. {
  854. s.removeChildAt(0);
  855. }
  856. s.addChild(new Bitmap(bitmapData));
  857. }
  858. public function setSpriteMatrix(s:Sprite, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1):void
  859. {
  860. var m:Matrix = new Matrix;
  861. m.translate(-width / 2, -height / 2);
  862. m.scale(sx, sy);
  863. m.rotate(angle);
  864. m.translate(p.x + AAShip.SCREEN_WIDTH / 2 - Field.offsetX, p.y + AAShip.SCREEN_HEIGHT / 2);
  865. s.transform.matrix = m;
  866. }
  867. }
  868. // Utility classes.
  869. class Vector2
  870. {
  871. public var x:Number = 0;
  872. public var y:Number = 0;
  873. public function add(v:Vector2):void
  874. {
  875. x += v.x;
  876. y += v.y;
  877. }
  878. public function addMultiplied(v:Vector2, mv:Number):void
  879. {
  880. x += v.x * mv;
  881. y += v.y * mv;
  882. }
  883. public function sub(v:Vector2):void
  884. {
  885. x -= v.x;
  886. y -= v.y;
  887. }
  888. public function mul(v:Number):void
  889. {
  890. x *= v;
  891. y *= v;
  892. }
  893. public function div(v:Number):void
  894. {
  895. x /= v;
  896. y /= v;
  897. }
  898. public function normalize():void
  899. {
  900. div(length);
  901. }
  902. public function get length():Number
  903. {
  904. return Math.sqrt(x * x + y * y);
  905. }
  906. public function getRoughDistance(p:Vector2):Number
  907. {
  908. return Math.abs(x - p.x) + Math.abs(y - p.y);
  909. }
  910. public function rotation(v:Number):void
  911. {
  912. var sv:Number = Math.sin(v);
  913. var cv:Number = Math.cos(v);
  914. var rx:Number = cv * x - sv * y;
  915. y = sv * x + cv * y;
  916. x = rx;
  917. }
  918. }
  919. class Key
  920. {
  921. public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  922. public static var button1:Boolean;
  923. public static function onKeyUp(event:KeyboardEvent):void
  924. {
  925. switch (event.keyCode)
  926. {
  927. case 0x25:
  928. case 0x41:
  929. {
  930. left = false;
  931. break;
  932. }
  933. case 0x26:
  934. case 0x57:
  935. {
  936. up = false;
  937. break;
  938. }
  939. case 0x27:
  940. case 0x44:
  941. {
  942. right = false;
  943. break;
  944. }
  945. case 0x28:
  946. case 0x53:
  947. {
  948. down = false;
  949. break;
  950. }
  951. case 0x5a:
  952. case 0xbf:
  953. case 0x58:
  954. case 0xbe:
  955. {
  956. button1 = false;
  957. break;
  958. }
  959. }
  960. }
  961. public static function onKeyDown(event:KeyboardEvent):void
  962. {
  963. switch (event.keyCode)
  964. {
  965. case 0x25:
  966. case 0x41:
  967. {
  968. left = true;
  969. break;
  970. }
  971. case 0x26:
  972. case 0x57:
  973. {
  974. up = true;
  975. break;
  976. }
  977. case 0x27:
  978. case 0x44:
  979. {
  980. right = true;
  981. break;
  982. }
  983. case 0x28:
  984. case 0x53:
  985. {
  986. down = true;
  987. break;
  988. }
  989. case 0x5a:
  990. case 0xbf:
  991. case 0x58:
  992. case 0xbe:
  993. {
  994. button1 = true;
  995. break;
  996. }
  997. }
  998. }
  999. }
  1000. class Util
  1001. {
  1002. public static function normalizeAngle(v:Number):Number
  1003. {
  1004. if (v > Math.PI) return v - Math.PI * 2;
  1005. else if (v < -Math.PI) return v + Math.PI * 2;
  1006. else return v;
  1007. }
  1008. }
noswf

forked from: forked from: forked from: AAShip forked from: forked from: forked from: forked from: AAShip [diff(1)]

  1. // forked from ABA's forked from: forked from: forked from: AAShip
  2. // forked from ABA's forked from: forked from: AAShip
  3. // forked from ABA's forked from: AAShip
  4. // forked from ABA's AAShip
  5. // AAShip.as
  6. // Ascii art ship.
  7. // [Control]
  8. // Movement: Arrow or [WASD] keys.
  9. // Fire: [Z], [X], [.] or [/] key.
  10. package
  11. {
  12. import flash.display.Sprite;
  13. import flash.display.BitmapData;
  14. import flash.display.Bitmap;
  15. import flash.geom.Rectangle;
  16. import flash.text.TextField;
  17. import flash.events.Event;
  18. import flash.events.KeyboardEvent;
  19. [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
  20. public class AAShip extends Sprite
  21. {
  22. public static const SCREEN_WIDTH:int = 465;
  23. public static const SCREEN_HEIGHT:int = 465;
  24. private const BLUR_MAX_COUNT:int = 512;
  25. private const BLUR_HISTORY_COUNT:int = 6;
  26. private const SHIP_SPEED:Number = 8;
  27. private const SHOT_MAX_COUNT:int = 12;
  28. private const SHOT_SPEED:Number = 20;
  29. private const SHIP_COLLISION_SIZE:Number = 5;
  30. private const SHIP_INVINCIBLE_TICKS:int = 90;
  31. private const ENEMY_MAX_COUNT:int = 16;
  32. private const BULLET_MAX_COUNT:int = 128;
  33. private const SPARK_MAX_COUNT:int = 64;
  34. private const ZAKO1_APPEARANCE_INTERVAL:Number = 30;
  35. private const MID1_APPEARANCE_INTERVAL:Number = 180;
  36. public static var gameSpeed:Number;
  37. private var buffer:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
  38. private var rect:Rectangle = new Rectangle;
  39. private var offset:Vector2 = new Vector2;
  40. private var blurs:Vector.> = new Vector.>(BLUR_HISTORY_COUNT, true);
  41. private var blurCounts:Vector. = new Vector.(BLUR_HISTORY_COUNT, true);
  42. private var blurIndex:int;
  43. private var shipChar:AAChar;
  44. private var shipSprite:Sprite = new Sprite;
  45. private var shipPos:Vector2 = new Vector2;
  46. private var shipAngle:Number;
  47. private var shipInvincibleTicks:int;
  48. private var shipFireCount:int;
  49. private var shipFireTicks:Number;
  50. private var shotChar:AAChar;
  51. private var shots:Vector. = new Vector.(SHOT_MAX_COUNT, true);
  52. private var enemies:Vector. = new Vector.(ENEMY_MAX_COUNT, true);
  53. private var zako1:Zako1, mid1:Mid1;
  54. private var bulletChar:AAChar;
  55. private var bullets:Vector. = new Vector.(BULLET_MAX_COUNT, true);
  56. private var sparkChar:AAChar;
  57. private var sparks:Vector. = new Vector.(SPARK_MAX_COUNT, true);
  58. private var bulletIntervalRank:Number;
  59. private var bulletSpeedRank:Number;
  60. private var enemyIntervalRank:Number;
  61. private var enemySpeedRank:Number;
  62. private var rankTicks:int;
  63. public function AAShip()
  64. {
  65. stage.scaleMode = "noScale";
  66. addChild(new Bitmap(buffer));
  67. stage.addEventListener(KeyboardEvent.KEY_DOWN, Key.onKeyDown);
  68. stage.addEventListener(KeyboardEvent.KEY_UP, Key.onKeyUp);
  69. AAChar.initialize();
  70. Field.initialize();
  71. var i:int;
  72. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  73. {
  74. var bs:Vector. = new Vector.(BLUR_MAX_COUNT, true);
  75. for (var j:int = 0; j < BLUR_MAX_COUNT; j++)
  76. {
  77. bs[j] = new Blur;
  78. }
  79. blurs[i] = bs;
  80. blurCounts[i] = 0;
  81. }
  82. blurIndex = 0;
  83. shipChar = new AAChar([" A ", "I#I"], [" R ", "CBC"], 2, 2);
  84. shipChar.drawToSprite(shipSprite);
  85. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS;
  86. shotChar = new AAChar(["!"], ["Y"]);
  87. for (i = 0; i < SHOT_MAX_COUNT; i++)
  88. {
  89. shots[i] = new Shot;
  90. shotChar.drawToSprite(shots[i].sprite);
  91. }
  92. zako1 = new Zako1; mid1 = new Mid1;
  93. for (i = 0; i < ENEMY_MAX_COUNT; i++)
  94. {
  95. enemies[i] = new Enemy;
  96. }
  97. bulletChar = new AAChar(["#"], ["P"], 1, 1);
  98. for (i = 0; i < BULLET_MAX_COUNT; i++)
  99. {
  100. bullets[i] = new Bullet;
  101. bulletChar.drawToSprite(bullets[i].sprite);
  102. }
  103. sparkChar = new AAChar(["*"], ["Y"]);
  104. for (i = 0; i < SPARK_MAX_COUNT; i++)
  105. {
  106. sparks[i] = new Spark;
  107. sparkChar.drawToSprite(sparks[i].sprite);
  108. }
  109. bulletIntervalRank = bulletSpeedRank = enemyIntervalRank = enemySpeedRank = 1.0 / 0.5;
  110. gameSpeed = 1.0;
  111. addEventListener(Event.ENTER_FRAME, onEnterFrame);
  112. }
  113. private function initializeShip():void
  114. {
  115. shipPos.x = 0;
  116. shipPos.y = Field.size.y / 2;
  117. shipAngle = 0.0;
  118. shipFireCount = 0;
  119. shipFireTicks = 0;
  120. bulletIntervalRank *= 0.5; bulletSpeedRank *= 0.5;
  121. enemyIntervalRank *= 0.5; enemySpeedRank *= 0.5;
  122. if (bulletIntervalRank < 0.5) bulletIntervalRank = 0.5;
  123. if (bulletSpeedRank < 0.5) bulletSpeedRank = 0.5;
  124. if (enemyIntervalRank < 0.5) enemyIntervalRank = 0.5;
  125. if (enemySpeedRank < 0.5) enemySpeedRank = 0.5;
  126. rankTicks = 0;
  127. zako1.appearanceTicks = 0;
  128. mid1.appearanceTicks = MID1_APPEARANCE_INTERVAL;
  129. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  130. addChild(shipSprite);
  131. }
  132. private function onEnterFrame(event:Event):void
  133. {
  134. buffer.fillRect(buffer.rect, 0);
  135. var i:int;
  136. blurCounts[blurIndex] = 0;
  137. updateSparks();
  138. updateShots();
  139. if (shipInvincibleTicks > -SHIP_INVINCIBLE_TICKS) updateShip();
  140. else if (shipInvincibleTicks == -SHIP_INVINCIBLE_TICKS) initializeShip();
  141. else Field.offsetX *= 0.95;
  142. shipInvincibleTicks++;
  143. updateEnemies();
  144. updateBullets();
  145. rankTicks++;
  146. bulletIntervalRank += 0.02;
  147. if (rankTicks % (10 * 30) == 0) bulletIntervalRank *= 0.5;
  148. bulletSpeedRank += 0.005;
  149. if (rankTicks % (15 * 30) == 0) bulletSpeedRank *= 0.5;
  150. enemyIntervalRank += 0.005;
  151. if (rankTicks % (21 * 30) == 0) enemyIntervalRank *= 0.5;
  152. enemySpeedRank += 0.002;
  153. if (rankTicks % (27 * 30) == 0) enemySpeedRank *= 0.5;
  154. buffer.lock();
  155. Field.draw(buffer);
  156. var bi:int = blurIndex + 1;
  157. for (i = 0; i < BLUR_HISTORY_COUNT; i++)
  158. {
  159. if (bi >= BLUR_HISTORY_COUNT) bi = 0;
  160. for (var j:int = 0; j < blurCounts[bi]; j++)
  161. {
  162. updateBlur(blurs[bi][j]);
  163. }
  164. bi++;
  165. }
  166. Field.drawSideBoard(buffer);
  167. buffer.unlock();
  168. blurIndex++;
  169. if (blurIndex >= BLUR_HISTORY_COUNT) blurIndex = 0;
  170. }
  171. private function updateShip():void
  172. {
  173. var px:Number = shipPos.x;
  174. var vx:Number = 0, vy:Number = 0;
  175. if (Key.left) vx = -1;
  176. if (Key.right) vx = 1;
  177. if (Key.up) vy = -1;
  178. if (Key.down) vy = 1;
  179. if (vx != 0 && vy != 0)
  180. {
  181. vx *= 0.7; vy *= 0.7;
  182. }
  183. shipPos.x += vx * SHIP_SPEED * gameSpeed;
  184. shipPos.y += vy * SHIP_SPEED * gameSpeed;
  185. if (shipPos.x < -SCREEN_WIDTH / 2) shipPos.x = -SCREEN_WIDTH / 2;
  186. if (shipPos.x > SCREEN_WIDTH / 2) shipPos.x = SCREEN_WIDTH / 2;
  187. if (shipPos.y < -SCREEN_HEIGHT / 2) shipPos.y = -SCREEN_HEIGHT / 2;
  188. if (shipPos.y > SCREEN_HEIGHT / 2) shipPos.y = SCREEN_HEIGHT / 2;
  189. shipAngle += (shipPos.x - px) * 0.01;
  190. shipAngle *= 0.8;
  191. Field.offsetX = shipPos.x * 0.33;
  192. shipChar.setSpriteMatrix(shipSprite, shipPos, shipAngle);
  193. if (shipInvincibleTicks >= 0 || (-shipInvincibleTicks % 15 > 7))
  194. {
  195. addBlursOfAAChar(shipChar, shipPos, shipAngle);
  196. }
  197. var s:Shot;
  198. if (Key.button1 && shipFireTicks <= 0)
  199. {
  200. shipFireTicks += 1.0;
  201. offset.x = 15;
  202. offset.y = 0;
  203. offset.rotation(shipAngle);
  204. s = getActorInstance(Vector.(shots));
  205. var i:int = shipFireCount % 2;
  206. if (s != null)
  207. {
  208. s.pos.x = shipPos.x + offset.x * (i * 2 - 1);
  209. s.pos.y = shipPos.y + offset.y * (i * 2 - 1);
  210. s.angle = shipAngle;
  211. s.ticks = 0;
  212. addBlur(s.pos.x, s.pos.y, 10, 10, 255, 255, 0);
  213. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  214. addChild(s.sprite);
  215. shipFireCount++;
  216. }
  217. }
  218. shipFireTicks -= gameSpeed;
  219. if (shipInvincibleTicks >= 0)
  220. {
  221. for each (var e:Enemy in enemies)
  222. {
  223. if (!e.exists) continue;
  224. if (Math.abs(shipPos.x - e.pos.x) <= e.spec.size.x - 12 &&
  225. Math.abs(shipPos.y - e.pos.y) <= e.spec.size.y - 12)
  226. {
  227. shipDestroyed();
  228. e.exists = false;
  229. removeChild(e.sprite);
  230. return;
  231. }
  232. }
  233. for each (var b:Bullet in bullets)
  234. {
  235. if (!b.exists) continue;
  236. if (shipPos.getRoughDistance(b.pos) <= SHIP_COLLISION_SIZE)
  237. {
  238. shipDestroyed();
  239. b.exists = false;
  240. removeChild(b.sprite);
  241. return;
  242. }
  243. }
  244. }
  245. }
  246. private function updateShots():void
  247. {
  248. var s:Shot;
  249. for each (s in shots)
  250. {
  251. if (!s.exists) continue;
  252. s.pos.x += Math.sin(s.angle) * SHOT_SPEED * gameSpeed;
  253. s.pos.y -= Math.cos(s.angle) * SHOT_SPEED * gameSpeed;
  254. if (s.pos.y < -SCREEN_HEIGHT / 2)
  255. {
  256. s.exists = false;
  257. removeChild(s.sprite);
  258. continue;
  259. }
  260. s.ticks += gameSpeed;
  261. shotChar.setSpriteMatrix(s.sprite, s.pos, s.angle);
  262. addBlursOfAAChar(shotChar, s.pos, s.angle, 1.0, 1.0, 150, 100, 0);
  263. for each (var e:Enemy in enemies)
  264. {
  265. if (!e.exists) continue;
  266. if (Math.abs(s.pos.x - e.pos.x) <= e.spec.size.x &&
  267. Math.abs(s.pos.y - e.pos.y) <= e.spec.size.y)
  268. {
  269. addSpark(s.pos, s.angle + Math.PI, 0.2, SHOT_SPEED, 1.0, 2);
  270. e.shield--;
  271. e.isHit = true;
  272. s.exists = false;
  273. removeChild(s.sprite);
  274. break;
  275. }
  276. }
  277. }
  278. }
  279. private function updateEnemies():void
  280. {
  281. var e:Enemy;
  282. var es:EnemySpec = null;
  283. zako1.appearanceTicks -= gameSpeed;
  284. if (zako1.appearanceTicks <= 0)
  285. {
  286. es = zako1;
  287. var ei:int = ZAKO1_APPEARANCE_INTERVAL / enemyIntervalRank;
  288. ei *= (0.75 + Math.random() * 0.5);
  289. if (ei < 5) ei = 5;
  290. zako1.appearanceTicks += ei;
  291. }
  292. mid1.appearanceTicks -= gameSpeed;
  293. if (mid1.appearanceTicks <= 0)
  294. {
  295. es = mid1;
  296. mid1.appearanceTicks += MID1_APPEARANCE_INTERVAL * (0.5 + Math.random());
  297. }
  298. if (es != null)
  299. {
  300. e = getActorInstance(Vector.(enemies));
  301. if (e != null)
  302. {
  303. e.spec = es;
  304. e.speedRatio = enemySpeedRank;
  305. var fsr:Number = bulletSpeedRank;
  306. if (fsr < 1.0) fsr = 1.0;
  307. e.fireSpeedRatio = fsr;
  308. var fir:Number = bulletIntervalRank;
  309. if (fir > 25.0) fir = 25.0;
  310. e.fireIntervalRatio = fir;
  311. e.ticks = 0;
  312. e.fireTicks = 0.0; e.fireSeqTicks = 0.0; e.fireCount = 0;
  313. e.shield = e.spec.shield;
  314. e.isHit = false;
  315. e.spec.initialize(e, shipPos);
  316. e.spec.aaChar.drawToSprite(e.sprite);
  317. addChild(e.sprite);
  318. }
  319. }
  320. for each (e in enemies)
  321. {
  322. if (!e.exists) continue;
  323. if (!Field.contains(e.pos) || e.shield <= 0)
  324. {
  325. e.exists = false;
  326. removeChild(e.sprite);
  327. if (e.shield <= 0) addSpark(e.pos, 0, Math.PI, 4.0, 1.5, 8);
  328. continue;
  329. }
  330. e.spec.update(e, shipPos, this);
  331. e.ticks += gameSpeed;
  332. e.fireTicks -= gameSpeed;
  333. e.spec.aaChar.setSpriteMatrix(e.sprite, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  334. if (e.isHit)
  335. {
  336. e.isHit = false;
  337. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x * 1.5, e.spec.scale.y * 1.5, 255, 255, 0);
  338. }
  339. else
  340. {
  341. addBlursOfAAChar(e.spec.aaChar, e.pos, e.angle, e.spec.scale.x, e.spec.scale.y);
  342. }
  343. }
  344. }
  345. public function fireBullet(p:Vector2, angle:Number, speed:Number, size:Number):void
  346. {
  347. if (p.getRoughDistance(shipPos) <= 200 ||
  348. p.x - Field.offsetX <= -Field.size.x + Field.SIDE_BOARD_WIDTH ||
  349. p.x - Field.offsetX >= Field.size.x - Field.SIDE_BOARD_WIDTH) return;
  350. var b:Bullet = getActorInstance(Vector.(bullets));
  351. if (b == null) return;
  352. b.pos.x = p.x; b.pos.y = p.y;
  353. b.vel.x = Math.sin(angle) * speed;
  354. b.vel.y = -Math.cos(angle) * speed;
  355. b.speed = speed;
  356. b.size = size;
  357. addBlur(b.pos.x + b.vel.x * 2, b.pos.y + b.vel.y * 2, 20, 20, 255, 200, 100);
  358. b.ticks = 0;
  359. addChild(b.sprite);
  360. }
  361. private function updateBullets():void
  362. {
  363. var totalSpeed:Number = 0;
  364. for each (var b:Bullet in bullets)
  365. {
  366. if (!b.exists) continue;
  367. b.pos.addMultiplied(b.vel, gameSpeed);
  368. if (!Field.contains(b.pos))
  369. {
  370. b.exists = false;
  371. removeChild(b.sprite);
  372. continue;
  373. }
  374. var a:Number = b.ticks * 0.1;
  375. bulletChar.setSpriteMatrix(b.sprite, b.pos, a, b.size, b.size);
  376. var sz:Number = b.size * (1.1 + Math.sin(b.ticks * 0.2) * 0.2);
  377. var cl:int = 128 + 64 + Math.sin(b.ticks * 0.3) * 64;
  378. addBlursOfAAChar(bulletChar, b.pos, a, sz, sz, cl, 100, 255);
  379. b.ticks += gameSpeed;
  380. totalSpeed += b.speed + 5.0;
  381. }
  382. if (totalSpeed > 500.0)
  383. {
  384. gameSpeed = 1.0 - (totalSpeed - 500.0) / 250.0;
  385. if (gameSpeed < 0.7) gameSpeed = 0.7;
  386. }
  387. else
  388. {
  389. gameSpeed = 1.0;
  390. }
  391. }
  392. private function updateSparks():void
  393. {
  394. for each (var s:Spark in sparks)
  395. {
  396. if (!s.exists) continue;
  397. s.pos.addMultiplied(s.vel, gameSpeed);
  398. s.vel.mul(1 - 0.05 * gameSpeed);
  399. s.size *= (1 - 0.05 * gameSpeed);
  400. if (!Field.contains(s.pos) || s.ticks <= 0)
  401. {
  402. s.exists = false;
  403. removeChild(s.sprite);
  404. continue;
  405. }
  406. var a:Number = s.ticks * 0.2;
  407. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  408. addBlursOfAAChar(sparkChar, s.pos, a, s.size, s.size,
  409. 250, Math.random() * 128 + 128, 0);
  410. s.ticks -= gameSpeed;
  411. }
  412. }
  413. private function shipDestroyed():void
  414. {
  415. addSpark(shipPos, 0, Math.PI, 10.0, 6.0, 20);
  416. addSpark(shipPos, Math.PI / 2, 0, 30.0, 5.0, 10);
  417. addSpark(shipPos, -Math.PI / 2, 0, 30.0, 5.0, 10);
  418. shipInvincibleTicks = -SHIP_INVINCIBLE_TICKS * 1.5;
  419. removeChild(shipSprite);
  420. }
  421. private function addSpark(p:Vector2, angle:Number, ao:Number, speed:Number, size:Number, count:Number):void
  422. {
  423. for (var i:int = 0; i < count; i++)
  424. {
  425. var s:Spark = getActorInstance(Vector.(sparks));
  426. if (s == null) return;
  427. s.pos.x = p.x; s.pos.y = p.y;
  428. var a:Number = angle + ao * (Math.random() * 2 - 1);
  429. var sp:Number = speed * (0.5 + Math.random());
  430. s.vel.x = Math.sin(a) * sp;
  431. s.vel.y = -Math.cos(a) * sp;
  432. s.size = size;
  433. s.ticks = 15 + 15 * Math.random();
  434. sparkChar.setSpriteMatrix(s.sprite, s.pos, a, s.size, s.size);
  435. addChild(s.sprite);
  436. }
  437. }
  438. private function addBlursOfAAChar(ac:AAChar, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1,
  439. cr:int = -1, cg:int = -1, cb:int = -1):void
  440. {
  441. var br:int, bg:int, bb:int;
  442. if (cr >= 0)
  443. {
  444. br = cr; bg = cg; bb = cb;
  445. }
  446. for each (var b:Blur in ac.blurs)
  447. {
  448. offset.x = b.pos.x * sx; offset.y = b.pos.y * sy;
  449. offset.rotation(angle);
  450. if (cr < 0)
  451. {
  452. br = b.r; bg = b.g; bb = b.b;
  453. }
  454. addBlur(p.x + offset.x, p.y + offset.y, b.width * sx, b.height * sy, br, bg, bb);
  455. }
  456. }
  457. private function addBlur(x:Number, y:Number, w:Number, h:Number, r:int, g:int, b:int):void
  458. {
  459. if (blurCounts[blurIndex] >= BLUR_MAX_COUNT) return;
  460. var bl:Blur = blurs[blurIndex][blurCounts[blurIndex]];
  461. bl.pos.x = x + SCREEN_WIDTH / 2; bl.pos.y = y + SCREEN_HEIGHT / 2;
  462. bl.width = w; bl.height = h;
  463. bl.r = r; bl.g = g; bl.b = b;
  464. blurCounts[blurIndex]++;
  465. }
  466. private function updateBlur(b:Blur):void
  467. {
  468. rect.x = b.pos.x - b.width / 2 - Field.offsetX;
  469. rect.y = b.pos.y - b.height / 2;
  470. rect.width = b.width;
  471. rect.height = b.height;
  472. buffer.fillRect(rect, b.r * 0x10000 + b.g * 0x100 + b.b);
  473. b.width *= 1.2; b.height *= 1.2;
  474. var a:int = (b.r + b.g + b.b) / 3;
  475. b.r += (a - b.r) * 0.25;
  476. b.g += (a - b.g) * 0.25;
  477. b.b += (a - b.b) * 0.25;
  478. b.r *= 0.65; b.g *= 0.65; b.b *= 0.65;
  479. }
  480. private function getActorInstance(actors:Vector.):*
  481. {
  482. var al:int = actors.length
  483. for (var i:int = 0; i < al; i++)
  484. {
  485. if (!actors[i].exists)
  486. {
  487. actors[i].exists = true;
  488. return actors[i];
  489. }
  490. }
  491. return null;
  492. }
  493. }
  494. }
  495. import flash.display.BitmapData;
  496. import flash.display.Bitmap;
  497. import flash.display.Sprite;
  498. import flash.geom.Rectangle;
  499. import flash.geom.Matrix;
  500. import flash.text.TextField;
  501. import flash.text.TextFormat;
  502. import flash.events.KeyboardEvent;
  503. class Actor
  504. {
  505. public var exists:Boolean = false;
  506. public var pos:Vector2 = new Vector2;
  507. public var sprite:Sprite = new Sprite;
  508. public var ticks:Number;
  509. }
  510. class Shot extends Actor
  511. {
  512. public var angle:Number;
  513. }
  514. class Enemy extends Actor
  515. {
  516. public var angle:Number;
  517. public var speed:Number;
  518. public var speedRatio:Number;
  519. public var fireSpeedRatio:Number;
  520. public var fireIntervalRatio:Number;
  521. public var fireTicks:Number;
  522. public var fireSeqTicks:Number;
  523. public var fireCount:int;
  524. public var shield:int;
  525. public var isHit:Boolean;
  526. public var spec:EnemySpec;
  527. }
  528. class EnemySpec
  529. {
  530. public var size:Vector2 = new Vector2;
  531. public var scale:Vector2 = new Vector2;
  532. public var shield:int;
  533. public var aaChar:AAChar;
  534. public var appearanceTicks:Number;
  535. public function initialize(e:Enemy, shipPos:Vector2):void { }
  536. public function update(e:Enemy, shipPos:Vector2, main:AAShip):void {}
  537. }
  538. class Zako1 extends EnemySpec
  539. {
  540. private const SPEED:Number = 6;
  541. private const ANGLE_VELOCITY:Number = 0.05;
  542. private const FIRE_INTERVAL:Number = 60;
  543. private const BULLET_SPEED:Number = 5;
  544. public function Zako1()
  545. {
  546. size.x = size.y = 32;
  547. scale.x = scale.y = 1.0;
  548. shield = 1;
  549. aaChar = new AAChar(["", " v "], ["WGW", " C "], 2, 2);
  550. }
  551. override public function initialize(e:Enemy, shipPos:Vector2):void
  552. {
  553. e.pos.x = Field.size.x * (Math.random() * 2 - 1);
  554. e.pos.y = -Field.size.y;
  555. e.angle = Math.PI;
  556. e.speed = SPEED * e.speedRatio;
  557. }
  558. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  559. {
  560. e.pos.x += Math.sin(e.angle) * e.speed * AAShip.gameSpeed;
  561. e.pos.y -= Math.cos(e.angle) * e.speed * AAShip.gameSpeed;
  562. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  563. var ao:Number = pa - e.angle;
  564. ao = Util.normalizeAngle(ao);
  565. if (ao > ANGLE_VELOCITY) e.angle += ANGLE_VELOCITY;
  566. else if (ao < -ANGLE_VELOCITY) e.angle -= ANGLE_VELOCITY;
  567. else e.angle = pa;
  568. e.angle = Util.normalizeAngle(e.angle);
  569. if (e.fireTicks <= 0)
  570. {
  571. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  572. main.fireBullet(e.pos, pa, BULLET_SPEED * e.fireSpeedRatio, 1.0);
  573. }
  574. }
  575. }
  576. class Mid1 extends EnemySpec
  577. {
  578. private const WAVE_INTERVAL:int = 120;
  579. private const SPEED:Number = 1;
  580. private const FIRE_INTERVAL:Number = 150;
  581. private const BULLET_SPEED:Number = 5;
  582. public function Mid1()
  583. {
  584. size.x = 64; size.y = 48;
  585. scale.x = scale.y = 1.2;
  586. shield = 16;
  587. aaChar = new AAChar([".__.", "\\##/"], ["RYYR", "WCCW"], 2, 2);
  588. }
  589. override public function initialize(e:Enemy, shipPos:Vector2):void
  590. {
  591. e.pos.x = Field.size.x * 0.6 * (Math.random() * 2 - 1);
  592. e.ticks = Math.random() * WAVE_INTERVAL;
  593. e.pos.y = -Field.size.y;
  594. e.angle = 0;
  595. e.speed = SPEED * (Math.random() + 1.0);
  596. e.fireSpeedRatio = Math.sqrt(e.fireSpeedRatio);
  597. e.fireIntervalRatio = Math.sqrt(e.fireIntervalRatio);
  598. }
  599. override public function update(e:Enemy, shipPos:Vector2, main:AAShip):void
  600. {
  601. var xa:Number = e.ticks * Math.PI * 2.0 / WAVE_INTERVAL;
  602. e.pos.x += Math.sin(xa) * 1.0 * AAShip.gameSpeed;
  603. e.angle = -Math.sin(xa) * 0.2;
  604. e.pos.y += e.speed * AAShip.gameSpeed;
  605. if (e.pos.y < 0)
  606. {
  607. if (e.fireTicks <= 0)
  608. {
  609. e.fireTicks += FIRE_INTERVAL / e.fireIntervalRatio;
  610. e.fireSeqTicks = 0;
  611. e.fireCount = 4;
  612. }
  613. if (e.fireCount > 0)
  614. {
  615. e.fireSeqTicks -= AAShip.gameSpeed;
  616. if (e.fireSeqTicks <= 0)
  617. {
  618. e.fireSeqTicks = 3;
  619. e.fireCount--;
  620. var pa:Number = Math.atan2(-e.pos.x + shipPos.x, e.pos.y - shipPos.y);
  621. for (var i:int = 0; i < 3; i++)
  622. {
  623. main.fireBullet(e.pos, pa - (i - 1) * 0.5,
  624. BULLET_SPEED * e.fireSpeedRatio * (1.0 + (3 - e.fireCount) * 0.25), 1.25);
  625. }
  626. }
  627. }
  628. }
  629. else
  630. {
  631. e.speed += (SPEED * 4 - e.speed) * 0.1;
  632. }
  633. }
  634. }
  635. class Bullet extends Actor
  636. {
  637. public var vel:Vector2 = new Vector2;
  638. public var speed:Number;
  639. public var size:Number;
  640. }
  641. class Spark extends Actor
  642. {
  643. public var vel:Vector2 = new Vector2;
  644. public var size:Number;
  645. }
  646. class Blur
  647. {
  648. public var pos:Vector2 = new Vector2;
  649. public var width:Number, height:Number;
  650. public var r:int, g:int, b:int;
  651. }
  652. class Field
  653. {
  654. public static const SIDE_BOARD_WIDTH:Number = AAShip.SCREEN_WIDTH / 6;
  655. private static const STAR_COUNT:int = 256;
  656. public static var size:Vector2;
  657. public static var offsetX:Number;
  658. private static var stars:Vector.;
  659. private static var rect:Rectangle = new Rectangle;
  660. public static function initialize():void
  661. {
  662. size = new Vector2;
  663. size.x = AAShip.SCREEN_WIDTH * 1.1 / 2; size.y = AAShip.SCREEN_HEIGHT * 1.1 / 2;
  664. stars = new Vector.(STAR_COUNT, true);
  665. for (var i:int = 0; i < STAR_COUNT; i++)
  666. {
  667. var s:Star = new Star;
  668. var z:Number = 1.0 + Math.random() * 10;
  669. var sz:int = (5 + Math.random() * 5) / z;
  670. if (sz < 1) sz = 1;
  671. s.pos.x = (Math.random() * 2 - 1) * size.x - sz;
  672. s.pos.y = (Math.random() * 2 - 1) * size.y - sz;
  673. s.size = sz;
  674. s.velRatio = 1.0 / z;
  675. s.color = (int)(Math.random() * 127 + 128) * 0x100 +
  676. (int)(Math.random() * 127 + 128);
  677. stars[i] = s;
  678. }
  679. }
  680. public static function draw(buffer:BitmapData):void
  681. {
  682. for each (var s:Star in stars)
  683. {
  684. rect.x = s.pos.x - offsetX * s.velRatio + AAShip.SCREEN_WIDTH / 2;
  685. rect.y = s.pos.y + AAShip.SCREEN_HEIGHT / 2;
  686. rect.width = rect.height = s.size;
  687. buffer.fillRect(rect, s.color);
  688. s.pos.y += 3.0 * s.velRatio;
  689. if (s.pos.y > size.y) s.pos.y -= size.y * 2;
  690. }
  691. }
  692. public static function drawSideBoard(buffer:BitmapData):void
  693. {
  694. rect.width = SIDE_BOARD_WIDTH;
  695. rect.height = AAShip.SCREEN_HEIGHT;
  696. rect.x = rect.y = 0;
  697. buffer.fillRect(rect, 0);
  698. rect.x = AAShip.SCREEN_WIDTH - rect.width;
  699. buffer.fillRect(rect, 0);
  700. }
  701. public static function contains(p:Vector2):Boolean
  702. {
  703. return (p.x >= -size.x && p.x <= size.x && p.y >= -size.y && p.y <= size.y);
  704. }
  705. }
  706. class Star
  707. {
  708. public var pos:Vector2 = new Vector2;
  709. public var size:Number;
  710. public var color:int;
  711. public var velRatio:Number;
  712. }
  713. class AAChar
  714. {
  715. private static const COLOR_PATTERNS:Array =
  716. [["R", 250, 100, 100], ["G", 100, 250, 100], ["B", 100, 100, 250],
  717. ["Y", 250, 250, 100], ["P", 250, 100, 250], ["C", 100, 250, 250],
  718. ["W", 250, 250, 250]];
  719. private const CHAR_SIZE:int = 24;
  720. private const CHAR_OFFSET_X:int = 14;
  721. private const CHAR_OFFSET_Y:int = 17;
  722. private const CHAR_HEIGHT:int = 24;
  723. private static var colorCount:int;
  724. private static var textFormats:Vector. = new Vector.;
  725. public var textFields:Vector. = new Vector.;
  726. public var blurs:Vector. = new Vector.;
  727. public var width:int, height:int;
  728. private var bitmapData:BitmapData;
  729. public static function initialize():void
  730. {
  731. colorCount = 0;
  732. for each (var cp:Array in COLOR_PATTERNS)
  733. {
  734. var tf:TextFormat = new TextFormat;
  735. tf.font = "_typewriter";
  736. tf.bold = true;
  737. tf.size = 24;
  738. tf.leading = -10;
  739. tf.color = (int)(cp[1] * 0.75) * 0x10000 + (int)(cp[2] * 0.75) * 0x100 + (int)(cp[3] * 0.75);
  740. textFormats.push(tf);
  741. colorCount++;
  742. }
  743. }
  744. public function AAChar(chars:Array, colors:Array, divX:int = 1, divY:int = 1)
  745. {
  746. var i:int;
  747. var tfts:Vector. = new Vector.(colorCount, true);
  748. var tffs:Vector. = new Vector.(colorCount, true);
  749. for (i = 0; i < colorCount; i++)
  750. {
  751. tfts[i] = "";
  752. tffs[i] = false;
  753. }
  754. var cx:int, cy:int = 0;
  755. var bd:BitmapData;
  756. var tf:TextField;
  757. var b:Blur;
  758. for (i = 0; i < chars.length; i++)
  759. {
  760. var str:String = chars[i];
  761. var colorStr:String = colors[i];
  762. cx = 0;
  763. var j:int;
  764. for (j = 0; j < str.length; j++)
  765. {
  766. var c:String = str.charAt(j);
  767. var color:String = colorStr.charAt(j);
  768. var ci:int;
  769. for (var k:int = 0; k < colorCount; k++)
  770. {
  771. if (color == COLOR_PATTERNS[k][0])
  772. {
  773. tfts[k] += c;
  774. tffs[k] = true;
  775. ci = k;
  776. }
  777. else
  778. {
  779. tfts[k] += " ";
  780. }
  781. }
  782. bd = new BitmapData(CHAR_SIZE, CHAR_SIZE, false, 0);
  783. tf = new TextField;
  784. tf.defaultTextFormat = textFormats[ci];
  785. tf.text = c;
  786. bd.draw(tf);
  787. for (var dx:int = 0; dx < divX; dx++)
  788. {
  789. for (var dy:int = 0; dy < divY; dy++)
  790. {
  791. var minX:int = CHAR_SIZE, maxX:int = -1;
  792. var minY:int = CHAR_SIZE, maxY:int = -1;
  793. for (var x:int = dx * CHAR_SIZE / divX; x < (dx + 1) * CHAR_SIZE / divX; x++)
  794. {
  795. for (var y:int = dy * CHAR_SIZE / divY; y < (dy + 1) * CHAR_SIZE / divY; y++)
  796. {
  797. if (bd.getPixel(x, y) > 0)
  798. {
  799. if (minX > x) minX = x;
  800. if (maxX < x) maxX = x;
  801. if (minY > y) minY = y;
  802. if (maxY < y) maxY = y;
  803. }
  804. }
  805. }
  806. if (maxX >= 0)
  807. {
  808. b = new Blur;
  809. b.width = maxX - minX + 1;
  810. b.height = maxY - minY + 1;
  811. b.pos.x = minX + cx * CHAR_OFFSET_X + b.width / 2;
  812. b.pos.y = minY + cy * CHAR_OFFSET_Y + b.height / 2;
  813. b.r = COLOR_PATTERNS[ci][1] + (255 - COLOR_PATTERNS[ci][1]) * 0.5;
  814. b.g = COLOR_PATTERNS[ci][2] + (255 - COLOR_PATTERNS[ci][2]) * 0.5;
  815. b.b = COLOR_PATTERNS[ci][3] + (255 - COLOR_PATTERNS[ci][3]) * 0.5;
  816. blurs.push(b);
  817. }
  818. }
  819. }
  820. cx++;
  821. }
  822. for (j = 0; j < colorCount; j++)
  823. {
  824. tfts[j] += "\n";
  825. }
  826. cy++;
  827. }
  828. width = cx * CHAR_OFFSET_X;
  829. height = cy * CHAR_HEIGHT;
  830. for (i = 0; i < colorCount; i++)
  831. {
  832. if (!tffs[i]) continue;
  833. tf = new TextField;
  834. tf.defaultTextFormat = textFormats[i];
  835. tf.multiline = true;
  836. tf.text = tfts[i];
  837. textFields.push(tf);
  838. }
  839. for each (b in blurs)
  840. {
  841. b.pos.x -= width / 2;
  842. b.pos.y -= height / 2;
  843. }
  844. bitmapData = new BitmapData(width, height, true, 0);
  845. for each (tf in textFields)
  846. {
  847. bitmapData.draw(tf);
  848. }
  849. }
  850. public function drawToSprite(s:Sprite):void
  851. {
  852. while (s.numChildren > 0)
  853. {
  854. s.removeChildAt(0);
  855. }
  856. s.addChild(new Bitmap(bitmapData));
  857. }
  858. public function setSpriteMatrix(s:Sprite, p:Vector2, angle:Number, sx:Number = 1, sy:Number = 1):void
  859. {
  860. var m:Matrix = new Matrix;
  861. m.translate(-width / 2, -height / 2);
  862. m.scale(sx, sy);
  863. m.rotate(angle);
  864. m.translate(p.x + AAShip.SCREEN_WIDTH / 2 - Field.offsetX, p.y + AAShip.SCREEN_HEIGHT / 2);
  865. s.transform.matrix = m;
  866. }
  867. }
  868. // Utility classes.
  869. class Vector2
  870. {
  871. public var x:Number = 0;
  872. public var y:Number = 0;
  873. public function add(v:Vector2):void
  874. {
  875. x += v.x;
  876. y += v.y;
  877. }
  878. public function addMultiplied(v:Vector2, mv:Number):void
  879. {
  880. x += v.x * mv;
  881. y += v.y * mv;
  882. }
  883. public function sub(v:Vector2):void
  884. {
  885. x -= v.x;
  886. y -= v.y;
  887. }
  888. public function mul(v:Number):void
  889. {
  890. x *= v;
  891. y *= v;
  892. }
  893. public function div(v:Number):void
  894. {
  895. x /= v;
  896. y /= v;
  897. }
  898. public function normalize():void
  899. {
  900. div(length);
  901. }
  902. public function get length():Number
  903. {
  904. return Math.sqrt(x * x + y * y);
  905. }
  906. public function getRoughDistance(p:Vector2):Number
  907. {
  908. return Math.abs(x - p.x) + Math.abs(y - p.y);
  909. }
  910. public function rotation(v:Number):void
  911. {
  912. var sv:Number = Math.sin(v);
  913. var cv:Number = Math.cos(v);
  914. var rx:Number = cv * x - sv * y;
  915. y = sv * x + cv * y;
  916. x = rx;
  917. }
  918. }
  919. class Key
  920. {
  921. public static var left:Boolean, up:Boolean, right:Boolean, down:Boolean;
  922. public static var button1:Boolean;
  923. public static function onKeyUp(event:KeyboardEvent):void
  924. {
  925. switch (event.keyCode)
  926. {
  927. case 0x25:
  928. case 0x41:
  929. {
  930. left = false;
  931. break;
  932. }
  933. case 0x26:
  934. case 0x57:
  935. {
  936. up = false;
  937. break;
  938. }
  939. case 0x27:
  940. case 0x44:
  941. {
  942. right = false;
  943. break;
  944. }
  945. case 0x28:
  946. case 0x53:
  947. {
  948. down = false;
  949. break;
  950. }
  951. case 0x5a:
  952. case 0xbf:
  953. case 0x58:
  954. case 0xbe:
  955. {
  956. button1 = false;
  957. break;
  958. }
  959. }
  960. }
  961. public static function onKeyDown(event:KeyboardEvent):void
  962. {
  963. switch (event.keyCode)
  964. {
  965. case 0x25:
  966. case 0x41:
  967. {
  968. left = true;
  969. break;
  970. }
  971. case 0x26:
  972. case 0x57:
  973. {
  974. up = true;
  975. break;
  976. }
  977. case 0x27:
  978. case 0x44:
  979. {
  980. right = true;
  981. break;
  982. }
  983. case 0x28:
  984. case 0x53:
  985. {
  986. down = true;
  987. break;
  988. }
  989. case 0x5a:
  990. case 0xbf:
  991. case 0x58:
  992. case 0xbe:
  993. {
  994. button1 = true;
  995. break;
  996. }
  997. }
  998. }
  999. }
  1000. class Util
  1001. {
  1002. public static function normalizeAngle(v:Number):Number
  1003. {
  1004. if (v > Math.PI) return v - Math.PI * 2;
  1005. else if (v < -Math.PI) return v + Math.PI * 2;
  1006. else return v;
  1007. }
  1008. }
noswf
Get Adobe Flash Player