forked from: Landolt Wars
/**
* Copyright MMMMMonchi ( http://wonderfl.net/user/MMMMMonchi )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/mD0W
*/
// forked from k0rin's Landolt Wars
package
{
import flash.display.*;
import flash.events.*;
import org.libspark.betweenas3.*;
[SWF(width = "465", height = "465", frameRate = "60")]
public class Main extends Sprite
{
public var score:Score = new Score();
public var board:Board;
public function Main()
{
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(e:Event):void
{
if (stage.stageWidth > 0) {
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
start();
}
}
public function start():void
{
board = new Board();
addChild(board);
score.x = 25;
score.y = 20;
addChild(score);
startTitle();
}
public function startTitle():void
{
//Helper.traceDisplayList(this);
var gameField:GameField = getChildByName("GameField") as GameField;
if (gameField) {
BetweenAS3.serial(
BetweenAS3.to(gameField, { alpha: 0 }, 0.3),
BetweenAS3.func(function ():void { gameField.destroy(); } )
).play();
}
board.turnOff();
addChild(new TitlePanel());
}
public function startGame():void
{
board.turnOn();
score.reset();
addChildAt(new GameField(), 1);
}
}
}
import flash.display.*;
import flash.events.*;
import flash.geom.*;
import flash.text.*;
import org.libspark.betweenas3.*;
import org.libspark.betweenas3.easing.*;
class GameSprite extends Sprite
{
private var active:Boolean = true;
private var frame:Number = 0;
public function GameSprite()
{
if (stage) {
start();
} else {
addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
}
}
private function addedToStageHandler(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
start();
addEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function removedFromStage(e:Event):void
{
removeEventListener(Event.REMOVED_FROM_STAGE, removedFromStage);
onDestroy();
removeEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(e:Event):void
{
if (active) {
frame++;
update();
}
}
public final function destroy():void
{
parent.removeChild(this);
}
public final function getFrame():Number
{
return frame;
}
public final function setActive(active:Boolean):void
{
for (var i:int = 0; i < numChildren; i++) {
var child:GameSprite = getChildAt(i) as GameSprite;
if (child) {
child.setActive(active);
}
}
this.active = active;
}
// Yeah, this class imitates Unity's GameObject a bit.
public function start():void {}
public function onDestroy():void {}
public function update():void {}
}
class TitlePanel extends GameSprite
{
public override function start():void
{
var titleText:TextField = Helper.createTextField("LANDOLT WARS");
addChild(titleText);
BetweenAS3.tween(titleText,
{ x: stage.stageWidth / 2 - titleText.width / 2, y: stage.stageHeight * 0.125 },
{ x: stage.stageWidth / 2 - titleText.width / 2, y: stage.stageHeight * -0.2 },
0.7,
Quint.easeOut).play();
var c:LandoltCShape = new LandoltCShape();
c.x = stage.stageWidth / 2;
c.y = stage.stageHeight * 0.5;
addChild(c);
BetweenAS3.tween(c,
{ scaleX: 1, scaleY: 1, alpha: 1 },
{ scaleX: 1.5, scaleY: 1.5, alpha: 0 },
0.7,
Quint.easeOut).play();
var getin:TextField = Helper.createTextField("<=== GET IN!!!");
getin.x = stage.stageWidth * 0.61;
getin.y = c.y - 12;
addChild(getin);
BetweenAS3.from(getin,
{ alpha: 0 },
1,
Quint.easeOut).play();
var startButton:Button = new Button("START", onStart);
addChild(startButton);
BetweenAS3.tween(startButton,
{ x: stage.stageWidth / 2, y: stage.stageHeight * 0.8 },
{ x: stage.stageWidth / 2, y: stage.stageHeight * 1.2 },
0.7,
Quint.easeOut).play();
}
private function onStart():void
{
Main(root).startGame();
BetweenAS3.serial(
BetweenAS3.to(this, { alpha: 0 }, 0.3),
BetweenAS3.removeFromParent(this)
).play();
}
}
class GameField extends GameSprite
{
private var difficulty:Number;
private var newLandoltCTime:Number = 0.7;
public override function start():void
{
name = "GameField";
addChild(new Pointer());
}
public override function update():void
{
difficulty = MyMath.clamp(MyMath.map(getFrame() / 60, 0, 60, 0, 1), 0, 1);
var landoltCNum:int = 0;
for (var i:int = 0; i < numChildren; i++) {
var landoltC:LandoltC = getChildAt(i) as LandoltC;
if (landoltC) {
landoltCNum++;
}
}
if (getFrame() > 60 && landoltCNum == 0) {
newLandoltCTime = 0;
}
newLandoltCTime -= 0.016667;
if (newLandoltCTime < 0 && landoltCNum < 5) {
addChildAt(new LandoltC(), 0);
newLandoltCTime = MyMath.map(difficulty, 0, 1, 3, 1);
}
}
}
class Pointer extends GameSprite
{
public override function update():void
{
var g:Graphics = graphics;
g.clear();
g.lineStyle(10, 0x000000, 0.1);
g.moveTo(mouseX, mouseY);
g.lineTo(mouseX + 500, mouseY / 3 + 600);
g.lineStyle(10, 0x666666, 1);
g.moveTo(mouseX, mouseY);
g.lineTo(mouseX / 1.5 + 600, mouseY / 3 + 400);
}
}
class LandoltCShape extends Shape
{
static public const OUTER_RADIUS:Number = 100;
static public const INNER_RADIUS:Number = OUTER_RADIUS * (1.5 / 2.5);
public function LandoltCShape()
{
var g:Graphics = graphics;
g.beginFill(0x000000);
drawArc(g, OUTER_RADIUS, MyMath.toRadian(15), MyMath.toRadian(360 - 15), true);
drawArc(g, INNER_RADIUS, MyMath.toRadian(360 - 26), MyMath.toRadian(26), false);
g.endFill();
}
private function drawArc(g:Graphics, radius:Number, start:Number, end:Number, moveFirst:Boolean):void
{
const SEGMENT:int = 8;
var angle:Number = start;
var deltaAngle:Number = (end - start) / SEGMENT;
for (var i:int = 0; i <= SEGMENT; i++) {
var x:Number = Math.cos(angle) * radius;
var y:Number = Math.sin(angle) * radius;
if (moveFirst && i == 0) {
g.moveTo(x, y);
} else if (i == 0) {
g.lineTo(x, y);
} else {
var cAngle:Number = angle - deltaAngle / 2;
var cRadius:Number = radius / Math.cos(deltaAngle / 2);
var cx:Number = Math.cos(cAngle) * cRadius;
var cy:Number = Math.sin(cAngle) * cRadius;
g.curveTo(cx, cy, x, y);
}
angle += deltaAngle;
}
}
}
class LandoltC extends GameSprite
{
private var vx:Number;
private var vy:Number;
private var va:Number;
private var alive:Boolean = true;
public override function start():void
{
addChild(new LandoltCShape());
var dx:Number = MyMath.random(LandoltCShape.OUTER_RADIUS, 465 - LandoltCShape.OUTER_RADIUS);
var dy:Number = MyMath.random(LandoltCShape.OUTER_RADIUS, 465 - LandoltCShape.OUTER_RADIUS);
var a:Number = MyMath.random(0, Math.PI * 2);
var len:Number = 465 * 1.41421356 + LandoltCShape.OUTER_RADIUS;
x = dx - Math.cos(a) * len;
y = dy - Math.sin(a) * len;
var speed:Number = 2;
vx = Math.cos(a) * speed;
vy = Math.sin(a) * speed;
while (!MyMath.inRange(x, -LandoltCShape.OUTER_RADIUS, 465 + LandoltCShape.OUTER_RADIUS) ||
!MyMath.inRange(y, -LandoltCShape.OUTER_RADIUS, 465 + LandoltCShape.OUTER_RADIUS)) {
x += vx;
y += vy;
}
rotation = MyMath.random(-180, 180);
va = MyMath.random(0.1, 1);
if (MyMath.random(0, 1) < 0.5) {
va = -va;
}
}
public override function update():void
{
const MARGIN:Number = LandoltCShape.OUTER_RADIUS * 0.5;
if ((x + vx < MARGIN && vx < 0) || (x + vx > 465 - MARGIN && vx > 0)) {
vx = -vx;
}
if ((y + vy < MARGIN && vy < 0) || (y + vy > 465 - MARGIN && vy > 0)) {
vy = -vy;
}
x += vx;
y += vy;
rotation += va;
if (!alive) {
alpha -= 0.1;
scaleX += 0.2;
scaleY += 0.2;
if (alpha < 0) {
destroy();
}
return;
}
if (isInner(stage.mouseX, stage.mouseY)) {
Object(root).score.increment();
alive = false;
}
if (hitTestPoint(stage.mouseX, stage.mouseY, true)) {
if (!Object(root).getChildByName("GameOver")) {
Object(root).addChild(new GameOver());
}
return;
}
}
private function isInner(mouseX:Number, mouseY:Number):Boolean
{
var dx:Number = mouseX - x;
var dy:Number = mouseY - y;
return (dx * dx + dy * dy < MyMath.square(LandoltCShape.INNER_RADIUS));
}
}
class Board extends GameSprite
{
private var level:int = 0;
public override function start():void
{
var g:Graphics = graphics;
var matrix:Matrix = new Matrix();
matrix.createGradientBox(stage.stageWidth, stage.stageHeight, 0, -100, -100);
g.beginGradientFill(GradientType.RADIAL, [0xbbb6b3, 0x9a9da2], null, [0, 255], matrix);
g.drawRect(0, 0, stage.stageWidth, stage.stageHeight);
g.endFill();
g.beginFill(0xe8e8e8);
g.moveTo(400, 0); g.lineTo(300, 100); g.lineTo(420, 0);
g.moveTo(450, 0); g.lineTo(320, 100); g.lineTo(470, 0);
g.endFill();
}
public override function update():void
{
if (level > 0) {
level++;
if (level <= 11) {
setLight(level % 2 == 1);
}
}
}
public function turnOn():void
{
level = 1;
}
public function turnOff():void
{
level = 0;
setLight(false);
}
private function setLight(flag:Boolean):void
{
var offset:int = flag ? 80 : 0;
transform.colorTransform = new ColorTransform(1, 1, 1, 1, offset, offset, offset);
}
}
class Score extends TextField
{
private var integer:int;
private var decimal:int;
public function Score()
{
defaultTextFormat = new TextFormat("Arial", 30, 0x000000);
autoSize = TextFieldAutoSize.LEFT;
selectable = false;
reset();
}
public function reset():void
{
integer = 0;
decimal = 0;
render();
}
public function increment():void
{
if (++decimal >= 10) {
decimal = 0;
integer++;
}
render();
}
private function render():void
{
text = integer + "." + decimal;
}
}
class GameOver extends GameSprite
{
private var gameOverText:TextField;
public override function start():void
{
name = "GameOver";
gameOverText = Helper.createTextField("GAME OVER");
gameOverText.x = 465 / 2 - gameOverText.width / 2;
gameOverText.y = 465 / 2 - gameOverText.height / 2;
addChild(gameOverText);
var gameField:GameField = GameField(Object(root).getChildByName("GameField"));
gameField.setActive(false);
gameField.transform.colorTransform = new ColorTransform(1, 1, 1, 1, 128, 128, 128);
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
public override function onDestroy():void
{
stage.removeEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
Object(root).startTitle();
}
private function mouseDownHandler(e:MouseEvent):void
{
destroy();
}
public override function update():void
{
gameOverText.visible = (getFrame() % 20 < 12);
if (getFrame() > 150) {
destroy();
}
}
}
class Button extends SimpleButton
{
private var onClick:Function;
function Button(name:String, onClick:Function)
{
this.onClick = onClick;
var button:Sprite = new Sprite();
var g:Graphics = button.graphics;
g.lineStyle(1.5, 0x000000);
g.beginFill(0x000000, 0);
g.drawRoundRect(-100, 0, 200, 30, 30, 30);
g.endFill();
var caption:TextField = Helper.createTextField(name);
caption.x = -caption.width / 2;
button.addChild(caption);
upState = button;
overState = button;
downState = button;
hitTestState = button;
addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
}
private function mouseDownHandler(e:MouseEvent):void
{
onClick();
}
}
class Helper
{
static public function createTextField(text:String):TextField
{
var textField:TextField = new TextField();
textField.autoSize = TextFieldAutoSize.LEFT;
textField.defaultTextFormat = new TextFormat("Arial", 20, 0x333333);
textField.text = text;
textField.selectable = false;
return textField;
}
static public function traceDisplayList(displayObject:DisplayObject, indent:String = ""):void
{
trace(indent + displayObject, displayObject.name);
var container:DisplayObjectContainer = displayObject as DisplayObjectContainer;
if (container) {
for (var i:int = 0; i < container.numChildren; i++) {
var child:DisplayObject = container.getChildAt(i);
traceDisplayList(child, indent + " ");
}
}
}
}
class MyMath
{
public static function clamp(value:Number, min:Number, max:Number):Number
{
// correct min and max order
if (min > max) {
var temp:Number = min;
min = max;
max = temp;
}
if (value < min) {
return min;
}
if (value > max) {
return max;
}
return value;
}
public static function random(min:Number, max:Number):Number
{
return min + (max - min) * Math.random();
// return lerp(min, max, Math.random());
}
public static function randomInt(min:int, max:int):int
{
// 0.683 secs
//return Math.floor(random(min, max + 1));
// 0.425 secs
return min + int((max - min + 1) * Math.random());
}
public static function map(value:Number, s0:Number, s1:Number, d0:Number, d1:Number):Number
{
// Avoid zero division.
if (s0 == s1) {
// Is this appropriate?
return d0;
}
return d0 + (d1 - d0) * ((value - s0) / (s1 - s0));
}
public static function lerp(a:Number, b:Number, t:Number):Number
{
return a + (b - a) * t;
}
public static function inRange(value:Number, min:Number, max:Number):Boolean
{
return (min <= value && value <= max);
}
public static const PI2:Number = Math.PI * 2;
private static const TO_DEGREE:Number = 360 / PI2;
private static const TO_RADIAN:Number = PI2 / 360;
public static function toRadian(degree:Number):Number
{
return degree * TO_RADIAN;
}
public static function toDegree(radian:Number):Number
{
return radian * TO_DEGREE;
}
public static function square(value:Number):Number
{
return value * value;
}
}