Billiards (3)
////////////////////////////////////////////////////////////////////////////////
// Billiards (3)
//
// ビリヤードもどき (4) [AS2.0]
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=839
//
// TODO
// 1. 不具合(すり抜け)対策 2. 不具合(すり代わり)対策
////////////////////////////////////////////////////////////////////////////////
/**
* Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/yITJ
*/
////////////////////////////////////////////////////////////////////////////////
// Billiards (3)
//
// ビリヤードもどき (4) [AS2.0]
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=839
//
// TODO
// 1. 不具合(すり抜け)対策 2. 不具合(すり代わり)対策
////////////////////////////////////////////////////////////////////////////////
package {
import flash.display.Sprite;
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.StageDisplayState;
import flash.display.Shape;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.events.MouseEvent;
[SWF(backgroundColor="#EEEEEE", width="465", height="465", frameRate="30")]
public class Main extends Sprite {
private var base:Shape;
private var controller:Sprite;
private var fullscreenBtn:Btn;
private var normalBtn:Btn;
private var rect:Rectangle;
private var area:Rectangle;
private var billiards:Billiards;
public function Main() {
//Wonderfl.disable_capture();
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.addEventListener(Event.RESIZE, resize, false, 0, true);
init();
}
private function init():void {
base = new Shape();
base.graphics.beginFill(0x339900);
base.graphics.drawRect(0, 0, 465, 465);
base.graphics.endFill();
base.graphics.beginFill(0x336600);
base.graphics.drawRect(5, 5, 455, 455);
base.graphics.endFill();
controller = new Sprite();
addChild(controller);
controller.x = 232;
controller.y = 445;
fullscreenBtn = new Btn();
controller.addChild(fullscreenBtn);
fullscreenBtn.init({label: "play", width: 80});
fullscreenBtn.addEventListener(MouseEvent.CLICK, click, false, 0, true);
normalBtn = new Btn();
controller.addChild(normalBtn);
normalBtn.init({label: "close", width: 80});
normalBtn.addEventListener(MouseEvent.CLICK, click, false, 0, true);
normalBtn.visible = false;
rect = new Rectangle(0, 0, 1200, 600);
billiards = new Billiards(rect);
resize();
}
private function resize(evt:Event = null):void {
update();
screenMode();
}
private function update():void {
var sw:uint = stage.stageWidth;
var sh:uint = stage.stageHeight;
var cx:uint = uint(sw/2);
var cy:uint = uint(sh/2);
billiards.x = cx - 600;
billiards.y = cy - 300;
controller.x = cx;
if (sh == 465) {
controller.y = cy;
} else {
controller.y = cy + 340;
}
}
private function screenMode():void {
if (stage.displayState == StageDisplayState.NORMAL) {
fullscreenBtn.visible = true;
normalBtn.visible = false;
addChildAt(base, 0);
if (contains(billiards)) {
billiards.stop();
removeChild(billiards);
}
} else {
fullscreenBtn.visible = false;
normalBtn.visible = true;
if (contains(base)) removeChild(base);
addChildAt(billiards, 0);
billiards.start();
}
}
private function click(evt:MouseEvent):void {
if (stage.displayState == StageDisplayState.NORMAL) {
stage.displayState = StageDisplayState.FULL_SCREEN;
} else {
stage.displayState = StageDisplayState.NORMAL;
}
}
}
}
//////////////////////////////////////////////////
// Billiardsクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Billiards extends Sprite {
private var rect:Rectangle;
private static var max:uint = 9;
private static var radius:uint = 25;
private var area:Rectangle;
private static var colors:Array;
private var base:Sprite;
private var overlay:Shape;
public var line:Shape;
private var balls:Array;
private var stocks:Array;
private var pockets:Array;
private static var limit:uint = radius*2;
private var xMin:uint;
private var xMax:uint;
private var yMin:uint;
private var yMax:uint;
public var manager:SoundManager;
private var source1:String = "http://www.project-nya.jp/images/flash/billiards/shoot.mp3";
private var source2:String = "http://www.project-nya.jp/images/flash/billiards/hit.mp3";
private var source3:String = "http://www.project-nya.jp/images/flash/billiards/drop.mp3";
public function Billiards(r:Rectangle) {
rect = r;
init();
}
private function init():void {
pockets = new Array();
draw();
colors = new Array();
colors.push(0xFFFFFF);
colors.push(0xFF9900);
colors.push(0x0066FF);
colors.push(0xFF0066);
colors.push(0x6633CC);
colors.push(0x339900);
colors.push(0xFF6600);
colors.push(0x0033FF);
colors.push(0xFF3366);
colors.push(0x993399);
colors.push(0x006600);
area = new Rectangle(rect.x+radius+5, rect.y+radius+5, rect.width-radius*2-10, rect.height-radius*2-10);
xMin = area.left;
xMax = area.right;
yMin = area.top;
yMax = area.bottom;
manager = new SoundManager();
manager.load(source1, "shoot", 0.4);
manager.load(source2, "hit", 0.2);
manager.load(source3, "drop", 1);
setup();
}
private function setup():void {
balls = new Array();
for (var n:uint = 0; n <= max; n++) {
var ball:Ball = new Ball(this, radius, colors[n]);
addChild(ball);
ball.x = area.x + Math.random()*area.width;
ball.y = area.y + Math.random()*area.height;
ball.setup(n);
ball.addEventListener(Event.COMPLETE, remove, false, 0, true);
balls.push(ball);
}
}
public function start():void {
addEventListener(Event.ENTER_FRAME, update, false, 0, true);
}
public function stop():void {
removeEventListener(Event.ENTER_FRAME, update);
}
private function update(evt:Event):void {
position();
checkHit();
motion();
checkPocket();
manageDepths();
}
private function position():void {
for (var n:uint = 0; n < balls.length; n++) {
var ball:Ball = balls[n];
ball.position();
}
}
private function checkHit():void {
for (var n:uint = 0; n < balls.length; n++) {
var ball0:Ball = balls[n];
for (var t:uint = n+1; t < balls.length; t++) {
var ball1:Ball = balls[t];
repulsion(ball0, ball1);
}
}
}
private function motion():void {
against();
for (var n:uint = 0; n < balls.length; n++) {
var ball:Ball = balls[n];
if (!ball.dropping) {
ball.motion();
} else {
ball.drop();
}
}
}
private function checkPocket():void {
for (var n:uint = 0; n < balls.length; n++) {
var ball:Ball = balls[n];
for (var p:uint = 0; p < 6; p++) {
var pocket:Sprite = pockets[p];
if (ball.hitTestObject(pocket)) {
ball.dropIn(pocket.x, pocket.y);
}
}
}
}
private function repulsion(ball0:Ball, ball1:Ball):void {
var x0:Number = ball0.px;
var y0:Number = ball0.py;
var vx0:Number = ball0.vx;
var vy0:Number = ball0.vy;
var x1:Number = ball1.px;
var y1:Number = ball1.py;
var vx1:Number = ball1.vx;
var vy1:Number = ball1.vy;
var d:Number = distance(x0, x1, y0, y1);
if (d <= limit) {
var l:Number = rebound(d, limit);
var v0:Number = speed(vx0, vy0);
var v1:Number = speed(vx1, vy1);
var r:Number = (v0 + v1)/d*2 + l;
ball0.repulsion((x0 - x1)*r, (y0 - y1)*r);
ball1.repulsion((x1 - x0)*r, (y1 - y0)*r);
}
}
private function distance(x0:Number, x1:Number, y0:Number, y1:Number):Number {
var d:Number = Math.sqrt((x1 - x0)*(x1 - x0) + (y1 - y0)*(y1 - y0));
return d;
}
private function rebound(d:Number, l:Number):Number {
var r:Number = (l - d)/l;
return r;
}
private function speed(vx:Number, vy:Number):Number {
var r:Number = Math.sqrt(vx*vx + vy*vy);
return r;
}
private function against():void {
for (var n:uint = 0; n < balls.length; n++) {
var ball:Ball = balls[n];
var wall:Number;
if (ball.px < (wall = xMin) || ball.px > (wall = xMax)) {
ball.against("x", wall);
} else if (ball.py < (wall = yMin) || ball.py > (wall = yMax)) {
ball.against("y", wall);
}
}
}
private function manageDepths():void {
balls.sortOn(["y", "id"], [Array.CASEINSENSITIVE | Array.NUMERIC, Array.DESCENDING | Array.NUMERIC]);
for (var n:uint = 0; n < balls.length; n++) {
var ball:Ball = balls[n];
addChildAt(ball, n+2);
}
}
private function remove(evt:Event):void {
var ball:Ball = Ball(evt.target);
ball.removeEventListener(Event.COMPLETE, remove);
for (var n:uint = 0; n < balls.length; n++) {
if (balls[n] == ball) {
balls.splice(n, 1);
}
}
removeChild(ball);
ball = null;
if (balls.length == 1) {
var cue:Ball = balls[0];
cue.removeCueLine();
var timer:Timer = new Timer(2000, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, finish, false, 0, true);
timer.start();
}
}
private function finish(evt:TimerEvent):void {
var cue:Ball = balls[0];
removeChild(cue);
cue = null;
setup();
}
private function draw():void {
base = new Sprite();
base.graphics.beginFill(0x339900);
base.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
base.graphics.endFill();
base.graphics.beginFill(0x336600);
base.graphics.drawRect(rect.x+5, rect.y+5, rect.width-10, rect.height-10);
base.graphics.endFill();
drawHoles();
drawPockets();
overlay = new Shape();
overlay.graphics.beginFill(0x000000);
overlay.graphics.drawRect(rect.x, rect.y, rect.width, rect.height);
overlay.graphics.endFill();
addChild(base);
addChild(overlay);
mask = overlay;
}
private function drawHoles():void {
createHole(rect.x+10, rect.y+10);
createHole(rect.right-10, rect.y+10);
createHole(rect.x+10, rect.bottom-10);
createHole(rect.right-10, rect.bottom-10);
createHole(rect.width/2, rect.y+10);
createHole(rect.width/2, rect.bottom-10);
}
private function createHole(hx:uint, hy:uint):void {
var hole:Shape = new Shape();
hole.x = hx;
hole.y = hy;
var colors:Array = [0x000000, 0x003300];
var alphas:Array = [1, 1];
var ratios:Array = [51, 204];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(80, 80, 0, -40, -40);
hole.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
hole.graphics.drawCircle(0, 0, 40);
hole.graphics.endFill();
base.addChild(hole);
}
private function drawPockets():void {
createPocket(rect.x+10, rect.y+10);
createPocket(rect.right-10, rect.y+10);
createPocket(rect.x+10, rect.bottom-10);
createPocket(rect.right-10, rect.bottom-10);
createPocket(rect.width/2, rect.y+10);
createPocket(rect.width/2, rect.bottom-10);
}
private function createPocket(px:uint, py:uint):void {
var pocket:Sprite = new Sprite();
pocket.x = px;
pocket.y = py;
pocket.graphics.beginFill(0xFFFFFF, 0);
pocket.graphics.drawCircle(0, 0, 10);
pocket.graphics.endFill();
base.addChild(pocket);
pockets.push(pocket);
}
}
//////////////////////////////////////////////////
// Ballクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.filters.DropShadowFilter;
import flash.filters.GlowFilter;
import flash.geom.Matrix;
import flash.display.GradientType;
import flash.display.SpreadMethod;
import flash.display.InterpolationMethod;
import flash.display.BlendMode;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.events.MouseEvent;
import flash.utils.Timer;
import flash.events.TimerEvent;
class Ball extends Sprite {
private var billiards:Billiards;
public var id:uint;
private var radius:uint;
private var color:uint;
private var ball:Sprite;
private var base:Shape;
private var shadow:Shape;
private var light:Shape;
private var reflection:Shape;
private var txt:TextField;
private var shade:Shape;
private static var bColor:uint = 0xFFFFFF;
private static var sColor:uint = 0x000000;
public var px:Number;
public var py:Number;
private var xTarget:Number;
private var yTarget:Number;
public var vx:Number;
public var vy:Number;
private static var deceleration:Number = 0.25;
private static var rebounce:Number = 1.6;
private static var cueRange:Number = 1.6;
public var dropping:Boolean = false;
private var dropped:Boolean = false;
public function Ball(b:Billiards, r:uint, c:uint) {
billiards = b;
radius = r;
color = c;
draw();
}
private function draw():void {
shade = new Shape();
addChild(shade);
shade.y = radius;
createShade();
ball = new Sprite();
addChild(ball);
base = new Shape();
ball.addChild(base);
shadow = new Shape();
ball.addChild(shadow);
light = new Shape();
ball.addChild(light);
reflection = new Shape();
ball.addChild(reflection);
createBase();
createShadow();
createLight();
createReflect();
}
public function setup(n:uint):void {
id = n;
if (id > 0) {
txt = new TextField();
ball.addChild(txt);
createTxt();
} else {
setCueBall();
setCueLine();
}
xTarget = px = x;
yTarget = py = y;
}
private function setCueBall():void {
billiards.addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
billiards.addEventListener(MouseEvent.MOUSE_MOVE, track, false, 0, true);
billiards.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
}
private function clearCueLine():void {
billiards.removeEventListener(MouseEvent.MOUSE_DOWN, press);
billiards.removeEventListener(MouseEvent.MOUSE_MOVE, track);
billiards.line.graphics.clear();
}
private function press(evt:MouseEvent):void {
billiards.manager.play("shoot");
xTarget = px + mouseX*cueRange;
yTarget = py + mouseY*cueRange;
}
private function release(evt:MouseEvent):void {
billiards.line.graphics.clear();
}
private function setCueLine():void {
billiards.line = new Shape();
billiards.addChildAt(billiards.line, 1);
}
private function track(evt:MouseEvent):void {
if (billiards.line) {
billiards.line.graphics.clear();
billiards.line.graphics.lineStyle(40, bColor, 0.2);
billiards.line.graphics.moveTo(px, py);
billiards.line.graphics.lineTo(px + mouseX, py + mouseY);
billiards.line.graphics.lineStyle(40, bColor, 0.1);
billiards.line.graphics.lineTo(px + mouseX*cueRange, py + mouseY*cueRange);
}
evt.updateAfterEvent();
}
public function repulsion(dx:Number, dy:Number):void {
billiards.manager.play("hit");
if (id != 0) {
dx *= rebounce;
dy *= rebounce;
}
xTarget = px + dx;
yTarget = py + dy;
}
public function against(direction:String, wall:Number):void {
var target:Number = this[direction+"Target"];
this[direction+"Target"] = wall*2 - target;
}
public function position():void {
vx = (xTarget - px)*deceleration;
vy = (yTarget - py)*deceleration;
px += vx;
py += vy;
}
public function motion():void {
x = px;
y = py;
}
public function dropIn(dx:Number, dy:Number):void {
if (!dropping) {
dropping = true;
billiards.manager.play("drop");
}
if (id == 0) clearCueLine();
x = px = xTarget = dx;
y = py = yTarget = dy;
}
public function drop():void {
alpha -= 0.05;
if (alpha <= 0) {
if (id == 0) {
visible = false;
y = py = yTarget = -100;
if (!dropped) {
dropped = true;
var timer:Timer = new Timer(1000, 1);
timer.addEventListener(TimerEvent.TIMER_COMPLETE, resetCueBall, false, 0, true);
timer.start();
}
} else {
dropping = false;
dispatchEvent(new Event(Event.COMPLETE));
}
}
}
private function resetCueBall(evt:TimerEvent):void {
evt.target.removeEventListener(TimerEvent.TIMER_COMPLETE, resetCueBall);
dropping = false;
dropped = false;
x = px = xTarget = 300;
y = py = yTarget = 200;
alpha = 1;
visible = true;
setCueBall();
setCueLine();
}
public function removeCueLine():void {
billiards.removeChild(billiards.line);
billiards.line = null;
}
private function createBase():void {
base.graphics.clear();
base.graphics.beginFill(color, 0.8);
base.graphics.drawCircle(0, 0, radius);
base.graphics.endFill();
}
private function createShadow():void {
var colors:Array = [sColor, sColor, sColor];
var alphas:Array = [0, 0.2, 0.3];
var ratios:Array = [0, 191, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(radius*3.2, radius*3.2, 0, -radius*2, -radius*2);
shadow.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
shadow.graphics.drawCircle(0, 0, radius);
shadow.graphics.endFill();
shadow.blendMode = BlendMode.HARDLIGHT;
}
private function createLight():void {
var colors:Array = [bColor, bColor, bColor];
var alphas:Array = [1, 0.2, 0];
var ratios:Array = [0, 191, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(radius*3.2, radius*3.2, 0, -radius*2, -radius*2);
light.graphics.beginGradientFill(GradientType.RADIAL, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
light.graphics.drawCircle(0, 0, radius);
light.graphics.endFill();
light.blendMode = BlendMode.OVERLAY;
}
private function createReflect():void {
var colors:Array = [bColor, bColor];
var alphas:Array = [0.7, 0];
var ratios:Array = [0, 191];
var matrix:Matrix = new Matrix();
var w:Number = radius*1.44;
var h:Number = radius*1.35;
var yOffset:Number = radius*0.95;
matrix.createGradientBox(w, h, 0.5*Math.PI, -w*0.5, -yOffset);
reflection.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0);
reflection.graphics.drawEllipse(-w*0.5, -yOffset, w, h);
reflection.graphics.endFill();
}
private function createTxt():void {
txt.x = -radius*0.5;
txt.y = -radius*0.6;
txt.width = radius;
txt.height = radius;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = "_ゴシック";
tf.size = 20;
tf.align = TextFormatAlign.CENTER;
txt.defaultTextFormat = tf;
txt.text = String(id);
txt.textColor = bColor;
var glow:GlowFilter = new GlowFilter(bColor, 1, 4, 4, 6, 3, false, true);
txt.filters = [glow];
}
private function createShade():void {
shade.graphics.beginFill(sColor, 0.6);
shade.graphics.drawEllipse(-radius*0.75, -radius*0.1775, radius*1.5, radius*0.375);
shade.graphics.endFill();
var shadow:DropShadowFilter = new DropShadowFilter(0, 90, sColor, 0.5, radius*0.15, radius*0.15, 1, 3, false, false, true);
shade.filters = [shadow];
}
}
//////////////////////////////////////////////////
// SoundManagerクラス
//////////////////////////////////////////////////
class SoundManager {
private var sounds:Object;
private var levels:Object;
public function SoundManager() {
init();
}
private function init():void {
sounds = new Object();
levels = new Object();
}
public function load(file:String, id:String, level:Number):void {
var se:SoundEffect = new SoundEffect();
se.load(file, id);
sounds[id] = se;
levels[id] = level;
}
public function play(id:String):void {
var se:SoundEffect = sounds[id];
var volume:Number = levels[id];
se.play(id, volume);
}
}
//////////////////////////////////////////////////
// SoundEffectクラス
//////////////////////////////////////////////////
import flash.events.EventDispatcher;
import flash.events.Event;
import flash.events.ProgressEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.media.SoundTransform;
import flash.events.ProgressEvent;
import flash.net.URLRequest;
class SoundEffect extends EventDispatcher {
private static var soundList:Object;
private var sound:Sound;
private var channel:SoundChannel;
private static var initialized:Boolean = false;
private var volume:Number;
private var looping:Boolean = false;
public function SoundEffect() {
if (!initialized) initialize();
}
private static function initialize():void {
initialized = true;
soundList = new Object();
}
public function init(Snd:Class, id:String):void {
var snd:Sound = new Snd();
soundList[id] = snd;
}
public function load(file:String, id:String):void {
var snd:Sound = new Sound();
snd.load(new URLRequest(file));
snd.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true);
snd.addEventListener(Event.COMPLETE, loaded, false, 0, true);
soundList[id] = snd;
}
public function play(id:String, vol:Number, loop:Boolean = false):void {
if (channel != null) channel.stop();
sound = soundList[id];
volume = vol;
looping = loop;
channel = sound.play();
var transform:SoundTransform = channel.soundTransform;
transform.volume = volume;
channel.soundTransform = transform;
if (looping) {
channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
}
}
public function stop():void {
if (channel != null) {
channel.stop();
channel.removeEventListener(Event.SOUND_COMPLETE, complete);
}
}
private function progress(evt:ProgressEvent):void {
dispatchEvent(evt);
}
private function loaded(evt:Event):void {
dispatchEvent(evt);
}
private function complete(evt:Event):void {
channel.removeEventListener(Event.SOUND_COMPLETE, complete);
if (looping) {
channel = sound.play(0);
channel.addEventListener(Event.SOUND_COMPLETE, complete, false, 0, true);
var transform:SoundTransform = channel.soundTransform;
transform.volume = volume;
channel.soundTransform = transform;
}
}
}
//////////////////////////////////////////////////
// Btnクラス
//////////////////////////////////////////////////
import flash.display.Sprite;
import flash.display.Shape;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.AntiAliasType;
import flash.text.TextFormat;
import flash.text.TextFormatAlign;
import flash.filters.GlowFilter;
import flash.events.MouseEvent;
class Btn extends Sprite {
public var id:uint;
private var shade:Shape;
private var bottom:Shape;
private var light:Shape;
private var base:Shape;
private var txt:TextField;
private var label:String = "";
private static var fontType:String = "_ゴシック";
private var _width:uint = 60;
private static var _height:uint = 20;
private static var corner:uint = 5;
private var type:uint = 1;
private static var bColor:uint = 0xFFFFFF;
private static var sColor:uint = 0x000000;
private static var upColor:uint = 0x666666;
private static var overColor:uint = 0x333333;
private static var offColor:uint = 0x999999;
private static var gColor:uint = 0x0099FF;
private var blueGlow:GlowFilter;
private var shadeGlow:GlowFilter;
private var _clicked:Boolean = false;
private var _enabled:Boolean = true;
public function Btn() {
}
public function init(option:Object):void {
if (option.id != undefined) id = option.id;
if (option.label != undefined) label = option.label;
if (option.width != undefined) _width = option.width;
if (option.type != undefined) type = option.type;
draw();
}
private function draw():void {
switch (type) {
case 1 :
bColor = 0xFFFFFF;
sColor = 0x000000;
upColor = 0x666666;
overColor = 0x333333;
offColor = 0x999999;
break;
case 2 :
bColor = 0x000000;
sColor = 0xFFFFFF;
upColor = 0x666666;
overColor = 0x999999;
offColor = 0x333333;
break;
}
blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true);
shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true);
shade = new Shape();
bottom = new Shape();
light = new Shape();
base = new Shape();
txt = new TextField();
addChild(shade);
addChild(bottom);
addChild(light);
addChild(base);
addChild(txt);
createBase(shade, _width, _height, corner, sColor);
shade.filters = [shadeGlow];
createBase(bottom, _width, _height, corner, sColor, 0.3);
createBase(light, _width, _height, corner, gColor);
light.filters = [blueGlow];
createBase(base, _width, _height, corner, bColor);
txt.x = -_width*0.5;
txt.y = -_height*0.5;
txt.width = _width;
txt.height = _height - 1;
txt.type = TextFieldType.DYNAMIC;
txt.selectable = false;
//txt.embedFonts = true;
//txt.antiAliasType = AntiAliasType.ADVANCED;
var tf:TextFormat = new TextFormat();
tf.font = fontType;
tf.size = 12;
tf.align = TextFormatAlign.CENTER;
txt.defaultTextFormat = tf;
txt.text = label;
enabled = true;
mouseChildren = false;
}
private function rollOver(evt:MouseEvent):void {
_over();
}
private function rollOut(evt:MouseEvent):void {
_up();
}
private function press(evt:MouseEvent):void {
_down();
}
private function release(evt:MouseEvent):void {
_up();
}
private function click(evt:MouseEvent):void {
}
private function _up():void {
txt.y = -_height*0.5;
txt.textColor = upColor;
base.y = -1;
light.visible = false;
light.y = -1;
}
private function _over():void {
txt.y = -_height*0.5;
txt.textColor = overColor;
base.y = -1;
light.visible = true;
light.y = -1;
}
private function _down():void {
txt.y = -_height*0.5 + 1;
txt.textColor = overColor;
base.y = 0;
light.visible = true;
light.y = 0;
}
private function _off():void {
txt.y = -_height*0.5 + 1;
txt.textColor = offColor;
base.y = 0;
light.visible = false;
light.y = 0;
}
public function get clicked():Boolean {
return _clicked;
}
public function set clicked(param:Boolean):void {
_clicked = param;
enabled = !_clicked;
if (_clicked) {
_down();
} else {
_up();
}
}
public function get enabled():Boolean {
return _enabled;
}
public function set enabled(param:Boolean):void {
_enabled = param;
buttonMode = _enabled;
mouseEnabled = _enabled;
useHandCursor = _enabled;
if (_enabled) {
_up();
addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true);
addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true);
addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
addEventListener(MouseEvent.CLICK, click, false, 0, true);
} else {
_off();
removeEventListener(MouseEvent.MOUSE_OVER, rollOver);
removeEventListener(MouseEvent.MOUSE_OUT, rollOut);
removeEventListener(MouseEvent.MOUSE_DOWN, press);
removeEventListener(MouseEvent.MOUSE_UP, release);
removeEventListener(MouseEvent.CLICK, click);
}
}
private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void {
target.graphics.beginFill(color, alpha);
target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2);
target.graphics.endFill();
}
}