In case Flash no longer exists; a copy of this site is included in the Flashpoint archive's "ultimate" collection.

Dead Code Preservation :: Archived AS3 works from wonderfl.net

forked from: LaserShield

Icicles.as
Control the red box and freeze water with the shield, and break them.
<Operation>
Movement: Mouse
Shield  : Click
Get Adobe Flash player
by erakan 04 Feb 2009
// forked from ABA's LaserShield
// Icicles.as
//  Control the red box and freeze water with the shield, and break them.
//  <Operation>
//   Movement: Mouse
//   Shield  : Click
package {
    import flash.display.Sprite;
    [SWF(width="465", height="465", backgroundColor="0x000000", frameRate="30")]
    public class Icicles extends Sprite { public function Icicles() { main = this; initialize(); } }
}
import flash.display.*;
import flash.geom.*;
import flash.text.*;
import flash.events.*;
const SCREEN_WIDTH:int = 465, SCREEN_HEIGHT:int = 465, GAME_OVER_DURATION:int = 50;
const PLAYER_HIT_RADIUS:Number = 10, SHIELD_RADIUS:Number = 48.0;
const FREEZE_LIMIT:int = 4, BREAK_DURATION:int = 8, BREAK_DELAY:int = 8;
var main:Sprite, screen:BitmapData = new BitmapData(SCREEN_WIDTH, SCREEN_HEIGHT, false, 0);
var scoreField:TextField = new TextField, messageField:TextField = new TextField;
var isInGame:Boolean, score:int, ticks:int, waterTicks:int, isMousePressed:Boolean;
// Initialize UIs.
function initialize():void {
    main.addChild(new Bitmap(screen));
    main.stage.addEventListener(MouseEvent.MOUSE_DOWN, function(e:Event):void { isMousePressed = true; } );
    main.stage.addEventListener(MouseEvent.MOUSE_UP  , function(e:Event):void { isMousePressed = false; } );
    scoreField   = createTextField(SCREEN_WIDTH - 100, 0, 100, 24, 0xff6666, TextFormatAlign.RIGHT);
    messageField = createTextField(SCREEN_WIDTH - 256, SCREEN_HEIGHT / 2, 256, 36, 0xff6666);
    main.addChild(scoreField); main.addChild(messageField);
    startGameOver(); ticks = GAME_OVER_DURATION; main.addEventListener(Event.ENTER_FRAME, update);
}
// Update the game frame.
function update(event:Event):void {
    screen.fillRect(screen.rect, 0);
    for (i = 0; i < icicles.length; i++) if (!icicles[i].updateBreak()) { icicles.splice(i, 1);  i--; }
    if (isInGame) Player.update();
    else if (isMousePressed && ticks > GAME_OVER_DURATION) startGame();
    if (!isInGame && ticks == GAME_OVER_DURATION) {
        messageField.text = "Icicles"; waters = null; waters = new Vector.<Water>;
    }
    if (isInGame && !isMousePressed) { convertFrozenWatersToIcicles(); }
    ticks++; waterTicks--; if (waterTicks <= 0) addWater();
    for (var i:int = 0; i < waters.length; i++) if (!waters[i].update()) { waters.splice(i, 1);  i--; }
    transmitFrozenWaters();
}
// Waters.
var waters:Vector.<Water>;
var icicles:Vector.<Water> = new Vector.<Water>;
class Water {
    public var pos:Vector3D = new Vector3D, length:int, vel:Number = 1.0 + rand() * 1.0;
    public var angle:Number = rand() * PI * 2, angleVel:Number = rand() * 0.1 - 0.05;
	public var lengthLimit:int = 10 + rand() * 50;
    public var frame:int = 0, order:int = 0;
    public var local:Sprite = new Sprite;
    public var textField:TextField;
    public function update():Boolean {
        var isTouched:Boolean = false;
        var rate:Number = (frame >= FREEZE_LIMIT) ? 1.0 : frame / FREEZE_LIMIT / 2;
        for (var i:int = 0; i < length; i++) {
			var p:Vector3D = getJoint(i);
            if (isInGame && isMousePressed && Player.shieldEnergy > 0 &&
                Vector3D.distance(p, Player.pos) <= SHIELD_RADIUS) {
                isTouched = true;
                scoreField.text = String(score++); length = i; break;
            } else if (isInGame && (!isMousePressed || Player.shieldEnergy <= 0) &&
                Vector3D.distance(p, Player.pos) <= PLAYER_HIT_RADIUS) {
				startGameOver();
			}
            if (p.x < 0 || p.x >= SCREEN_WIDTH || p.y < 0 || p.y >= SCREEN_HEIGHT * 3) { length = i; break; }
        }
		render(4, getTweenColor(0x0000ff, 0xffffff, rate));
        render(2, getTweenColor(0x0088ff, 0xffffff, rate));
        frame = isTouched ? (frame+1 < FREEZE_LIMIT ? frame+1 : FREEZE_LIMIT) : 0;
        angle += angleVel; pos.y += vel; length++;
        if (pos.y < SCREEN_HEIGHT) length++;
        else length -= 3;
		if (length > lengthLimit) { length = lengthLimit; }
        return (length >= 0);
    }
    public function getJoint(stride:Number):Vector3D {
        return new Vector3D(pos.x + sin(angle) * 7.0 * stride, pos.y + cos(angle) * 7.0 * stride, 0);
    }
    public function render(radius:int, color:int):void {
        for (var i:int = 0; i < length; i++) {
			var p:Vector3D = getJoint(i);
            rect.x = p.x - radius; rect.y = p.y - radius; rect.width = rect.height = radius * 2 + 1;
            screen.fillRect(rect, color);
		}
    }
	public function beginBreak(order:int):void {
        this.frame = -BREAK_DELAY * order;
        textField = createTextField(pos.x, pos.y, 36*2, 36, 0xff6666);
        textField.text = "x" + String(order + 1);
        local.addChild(textField);
	}
    public function updateBreak():Boolean {
		render(8, 0xffffff);
		if (frame >= 0) {
			render(2 + (8-2) * frame / BREAK_DURATION, 0x000000);
		}
        if (frame == 0) {
            scoreField.text = String(score += length * (order + 1));
        }
        screen.draw(local);
        return (++frame <= BREAK_DURATION);
    }
}
function addWater():void {
    var l:Water = new Water; l.pos.x = rand() * SCREEN_WIDTH;
    waters.push(l); waterTicks = (25 + rand() * 50) * 2000 / (2000 + 30*60*2 + ticks);
}
function transmitFrozenWaters():void {
    for (var i:int = 0; i < waters.length; i++) {
        if (waters[i].frame >= FREEZE_LIMIT) {
            transmitByIntersection(i);
        }
    }
}
function transmitByIntersection(current:int):void {
    for (var i:int = 0; i < waters.length; i++) {
        if (i == current) { continue; }
        if (waters[i].frame >= FREEZE_LIMIT) { continue; }
        if (!isWatersIntersects(waters[current], waters[i])) { continue; }
        waters[i].frame = FREEZE_LIMIT;
        transmitByIntersection(i);
    }
}
function isWatersIntersects(a:Water, b:Water):Boolean {
    return isLinesIntersects(a.pos, a.getJoint(a.length), b.pos, b.getJoint(b.length));
}
function convertFrozenWatersToIcicles():void {
    var order:int = 0;
    for (var i:int = 0; i < waters.length; i++) {
        if (waters[i].frame < FREEZE_LIMIT) { continue; }
        waters[i].beginBreak(order++);
        icicles.push(waters[i]);
        waters.splice(i, 1);  i--;
    }
}
// Player.
class Player {
    public static var pos:Vector3D = new Vector3D, shieldEnergy:Number;
    public static function update():void {
        pos.x = main.stage.mouseX; pos.y = main.stage.mouseY;
        rect.x = pos.x - 9; rect.y = pos.y - 9; rect.width = rect.height = 19;
        screen.fillRect(rect, 0xff4444);
        if (isMousePressed && shieldEnergy > 0) {
			var color:int = getTweenColor(0x000000, 0x80ffff, shieldEnergy/100);
            var a:Number = ticks * 0.05; rect.width = rect.height = 7;
            for (var i:int = 0; i < 32; i++) {
                rect.x = pos.x + sin(a) * SHIELD_RADIUS - 3; rect.y = pos.y + cos(a) * SHIELD_RADIUS - 3;
                screen.fillRect(rect, color); a += PI / 16;
            }
            shieldEnergy -= 1.0; if (shieldEnergy < 0) shieldEnergy = 0;
        }
        if (!isMousePressed) {
            shieldEnergy += 5.0; if (shieldEnergy > 100.0) shieldEnergy = 100.0;
        }
        rect.x = pos.x; rect.y = pos.y + 15; rect.width = shieldEnergy; rect.height = 10;
        screen.fillRect(rect, int(shieldEnergy * 2 + 50) * 0x10000 + 0x88ff);
    }
}
// Handle the game lifecycle.
function startGame():void {
    isInGame = true; waters = null; waters = new Vector.<Water>; messageField.text = "";
    scoreField.text = String(score = 0); ticks = 0; Player.shieldEnergy = 100.0;
}
function startGameOver():void {
    isInGame = false; messageField.text = "GAME OVER"; isMousePressed = false; ticks = 0;
}
// Utility functions and variables.
var rect:Rectangle = new Rectangle, p:Vector3D = new Vector3D;
var rand:Function = Math.random, sin:Function = Math.sin, cos:Function = Math.cos, PI:Number = Math.PI;
function createTextField(x:int, y:int, width:int, size:int, color:int, align:String = TextFormatAlign.LEFT):TextField {
    var fm:TextFormat = new TextFormat, fi:TextField = new TextField;
    fm.font = "_typewriter"; fm.bold = true; fm.size = size; fm.color = color; fm.align = align;
    fi.defaultTextFormat = fm; fi.x = x; fi.y = y; fi.width = width; fi.selectable = false;
    return fi;
}
// intersection (where z = 0.)
function isLinesIntersects(a1:Vector3D, a2:Vector3D, b1:Vector3D, b2:Vector3D):Boolean {
    var a:Vector3D = a2.subtract(a1);
    var b:Vector3D = b2.subtract(b1);
    var c:Vector3D = b1.subtract(a1);
    var st_lower:Number = a.x * b.y - a.y * b.x;
    if (st_lower == 0.0) { return false; }
    var s:Number = (c.x * b.y - c.y * b.x) / st_lower;
    if (s < 0.0 || s > 1.0) { return false; }
    var t:Number = (c.x * a.y - c.y * a.x) / st_lower;
    if (t < 0.0 || t > 1.0) { return false; }
//  var pos:Vector3D = new Vector3D(a1.x + a.x * s, a1.y + a.y * s, 0);
    return true;
}
// color interpolation.
function getTweenColor(c1:uint, c2:uint, rate:Number):uint {
	var v1:Vector3D = new Vector3D((c1>>16)&0xff, (c1>>8)&0xff, c1&0xff);
	var v2:Vector3D = new Vector3D((c2>>16)&0xff, (c2>>8)&0xff, c2&0xff);
    var v:Vector3D = v2.subtract(v1); v.scaleBy(rate); v.incrementBy(v1);
    return ((uint)(v.x) << 16) | ((uint)(v.y) << 8) | (uint)(v.z);
}