AmidaDaMida
AmidaDaMida.as
Lead robots to a green lamp.
<Operation>
Mouse: Move a bar.
/**
* Copyright ABA ( http://wonderfl.net/user/ABA )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/k0GL
*/
// AmidaDaMida.as
// Lead robots to a green lamp.
// <Operation>
// Mouse: Move a bar.
package {
import flash.display.Sprite;
[SWF(width="465", height="465", backgroundColor="0", frameRate="30")]
public class AmidaDaMida extends Sprite {
public function AmidaDaMida() { main = this; initialize(); }
}
}
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.events.*;
const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465;
var main:Sprite, screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
var scoreField:TextField = new TextField, messageField:TextField = new TextField;
// Initialize UIs.
function initialize():void {
main.addChild(new Bitmap(screen));
main.stage.addEventListener(MouseEvent.CLICK, function(e:Event):void { startGame(); } );
scoreField = createTextField(SCREEN_WIDTH - 120, 0, 120, 24, 0xff6666);
messageField = createTextField(SCREEN_WIDTH - 360, SCREEN_HEIGHT * 0.9, 360, 20, 0xff6666);
main.addChild(scoreField); main.addChild(messageField);
initializeLamps();
startGame(); startGameOver();
main.addEventListener(Event.ENTER_FRAME, update);
}
// Update the game frame.
const LINE_INTERVAL:Number = 60, LINE_START_X:Number = 50, LINE_START_Y:Number = 50;
const LINE_COUNT:int = 7;
var mouseBar:Bar = new Bar, existsMouseBar:Boolean;
function update(event:Event):void {
screen.fillRect(screen.rect, 0);
var i:int;
for (i = 0; i < LINE_COUNT; i++)
fillRect(LINE_START_X + LINE_INTERVAL * i - 2, LINE_START_Y, 5, SCREEN_HEIGHT - LINE_START_Y * 2);
for each (var l:Lamp in lamps) l.draw();
for each (var b:Bar in bars) b.draw();
for (i = 0; i < robots.length; i++) if (!robots[i].update()) { robots.splice(i, 1); i--; }
if (robots.length <= 0) startGameOver();
existsMouseBar = false;
if (!isInGame) return;
var mx:int = main.stage.mouseX, my:int = main.stage.mouseY;
var ml:int = (mx - LINE_START_X) / LINE_INTERVAL;
if (mx >= LINE_START_X && ml >= 0 && ml < LINE_COUNT - 1 &&
my > LINE_START_Y + NEAR_BAR_WIDTH && my < SCREEN_HEIGHT - LINE_START_Y - NEAR_BAR_WIDTH) {
if (!haveNearBar(ml, my)) {
existsMouseBar = true;
mouseBar.lineX = ml; mouseBar.y = my;
mouseBar.draw();
}
}
}
// Robots.
var robots:Vector.<Robot>;
class Robot {
public var pos:Vector3D = new Vector3D, lineX:int, velX:int, velY:int, speed:Number;
public function update():Boolean {
if (velX == 0) {
var py:Number = pos.y;
pos.y += velY * speed;
var cb:Bar = checkBars(lineX, py, velY, abs(pos.y - py));
if (cb != null) {
if (cb.lineX == lineX) velX = 1;
else velX = -1;
lineX += velX;
pos.y = cb.y;
}
} else {
pos.x += velX * speed;
var tx:Number = LINE_START_X + LINE_INTERVAL * lineX;
if ((pos.x - tx) * velX >= 0) { velX = 0; pos.x = tx; }
}
fillRect(pos.x - 7, pos.y - 7, 15, 15, 0x44ee66);
if (pos.y <= LINE_START_Y || pos.y >= SCREEN_HEIGHT - LINE_START_Y) {
var li:int = lineX + int((velY + 1) / 2) * LINE_COUNT;
velY *= -1; pos.y += velY * speed;
if (!isInGame) return true;
if (!lamps[li].isGreen) return false;
lamps[li].isGreen = false;
var areAllLampsRed:Boolean = true;
for each (var l:Lamp in lamps) if (l.isGreen) { areAllLampsRed = false; break; }
if (areAllLampsRed) {
setLamps(); rank++;
for each (var r:Robot in robots) r.speed *= 1.5;
}
scoreField.text = String(score += robots.length);
var ar:Robot = addRobot(lineX, pos.y, velY);
if (ar.speed == speed) ar.speed += 0.5;
}
return true;
}
}
function addRobot(lx:int, y:int, vy:int = 0):Robot {
var r:Robot = new Robot;
r.lineX = lx; r.pos.x = LINE_START_X + LINE_INTERVAL * r.lineX; r.pos.y = y;
r.velX = 0;
if (vy == 0) r.velY = int(rand() * 2) * 2 - 1;
else r.velY = vy;
r.speed = (((robots.length + 3) % 4) + 2) * (1 + rank * 0.5);
robots.push(r);
return r;
}
// Bars.
const BAR_DISAPPEAR_COUNT:int = 12;
var bars:Vector.<Bar>;
class Bar {
public var lineX:int, y:Number, count:int = BAR_DISAPPEAR_COUNT;
public function draw():void {
var c:int = count * 155 / BAR_DISAPPEAR_COUNT + 100;
if (count <= 1) c -= 50;
c = c * 0x10000 + 0x100 * c + c;
fillRect(LINE_START_X + LINE_INTERVAL * lineX, y - 2, LINE_INTERVAL, 5, c);
}
public function getDistance(lx:int, by:Number, velY:int):int {
if (lineX != lx || (by - y) * velY >= 0) return 99999;
return abs(by - y);
}
}
function addBar(c:int):void {
var lx:int, y:Number;
do {
lx = rand() * (LINE_COUNT - 1);
y = rand() * (SCREEN_HEIGHT - LINE_START_Y * 4) + LINE_START_Y * 2;
} while (haveNearBar(lx, y));
var b:Bar = new Bar;
b.lineX = lx; b.y = y; b.count = c;
bars.push(b);
}
function checkBars(lineX:int, y:Number, velY:int, range:Number):Bar {
var lBar:Bar = getNearestBar(lineX - 1, y, velY);
var rBar:Bar = getNearestBar(lineX , y, velY);
var lr:Number = 99999, rr:Number= 99999;
if (lBar != null) lr = abs(lBar.y - y);
if (rBar != null) rr = abs(rBar.y - y);
if (lr <= range || rr <= range) {
if (lr < rr) {
if (lBar == mouseBar) addMouseBar();
return lBar;
} else {
if (rBar == mouseBar) addMouseBar();
return rBar;
}
}
return null;
}
function addMouseBar():void {
for (var i:int = 0; i < bars.length; i++) {
bars[i].count--;
if (bars[i].count <= 0) {
bars.splice(i, 1); i--;
}
}
bars.push(mouseBar);
mouseBar = new Bar;
}
const NEAR_BAR_WIDTH:Number = 7;
function haveNearBar(lineX:int, y:Number):Boolean {
var b1:Bar = getNearestBar(lineX - 1, y - NEAR_BAR_WIDTH, 1);
var b2:Bar = getNearestBar(lineX , y - NEAR_BAR_WIDTH, 1);
var b3:Bar = getNearestBar(lineX + 1, y - NEAR_BAR_WIDTH, 1);
var r1:Number = 99999, r2:Number = 99999, r3:Number = 99999;
if (b1 != null) r1 = abs(b1.y - y);
if (b2 != null) r2 = abs(b2.y - y);
if (b3 != null) r3 = abs(b3.y - y);
return (r1 < NEAR_BAR_WIDTH * 2 || r2 < NEAR_BAR_WIDTH * 2 || r3 < NEAR_BAR_WIDTH * 2);
}
function getNearestBar(lineX:int, y:Number, velY:int):Bar {
var bar:Bar;
var md:Number = 99999, d:Number;
for each (var b:Bar in bars) {
d = b.getDistance(lineX, y, velY);
if (d < md) { md = d; bar = b; }
}
if (existsMouseBar) {
d = mouseBar.getDistance(lineX, y, velY);
if (d < md) bar = mouseBar;
}
return bar;
}
// Lamps.
var lamps:Vector.<Lamp> = new Vector.<Lamp>;
class Lamp {
public var lineX:int, isOnTop:Boolean, isGreen:Boolean;
public function draw():void {
var x:Number = LINE_START_X + LINE_INTERVAL * lineX, y:Number, c:int;
if (isOnTop) y = LINE_START_Y;
else y = SCREEN_HEIGHT - LINE_START_Y;
if (isGreen) c = 0x22ff22;
else c = 0xff2222;
fillRect(x - 5, y - 5, 11, 11, c);
}
}
function initializeLamps():void {
for (var i:int = 0; i < LINE_COUNT * 2; i++) {
var l:Lamp = new Lamp;
l.lineX = i % LINE_COUNT; l.isOnTop = (i < LINE_COUNT);
lamps.push(l);
}
}
function setLamps():void {
for each (var l:Lamp in lamps) l.isGreen = true;
}
// Handle the game lifecycle.
var isInGame:Boolean, score:int, rank:int, robotAddCount:int;
function startGame():void {
if (isInGame) return;
isInGame = true;
messageField.text = ""; scoreField.text = String(score = 0);
rank = 0; robotAddCount = 0;
robots = null; robots = new Vector.<Robot>;
bars = null; bars = new Vector.<Bar>;
for (var i:int = 0; i < BAR_DISAPPEAR_COUNT; i++) addBar(i + 1);
addRobot(rand() * LINE_COUNT, SCREEN_HEIGHT / 2);
setLamps();
}
function startGameOver():void {
isInGame = false;
messageField.text = "AmidaDaMida\nClick to start";
setLamps();
}
// Utility functions and variables.
var rand:Function = Math.random, abs:Function = Math.abs, rect:Rectangle = new Rectangle;
function fillRect(x:Number, y:Number, w:Number, h:Number, c:int = 0xffffff):void {
rect.x = x; rect.y = y; rect.width = w; rect.height = h; screen.fillRect(rect, c);
}
function createTextField(x:int, y:int, width:int, size:int, color:int):TextField {
var fm:TextFormat = new TextFormat, fi:TextField = new TextField;
fm.font = "_typewriter"; fm.bold = true; fm.size = size; fm.color = color; fm.align = TextFormatAlign.RIGHT;
fi.defaultTextFormat = fm; fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
return fi;
}