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

Billiards (1)

////////////////////////////////////////////////////////////////////////////////
// Billiards (1)
//
// ビリヤードもどき (4) [AS2.0]
// http://www.project-nya.jp/modules/weblog/details.php?blog_id=839
//
// TODO
// 1. 不具合(すり抜け)対策 2. 効果音
////////////////////////////////////////////////////////////////////////////////
Get Adobe Flash player
by ProjectNya 16 Sep 2010
  • Related works: 1
  • Talk

    ProjectNya at 16 Sep 2010 15:20
    ボールがボールをすり抜けちゃったりするわけですよ。
    ProjectNya at 16 Sep 2010 16:52
    ボールが壁を越えてからバウンドなんかもしちゃったりするわけですよ。

    Tags

    Embed
/**
 * Copyright ProjectNya ( http://wonderfl.net/user/ProjectNya )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/iZVg
 */

////////////////////////////////////////////////////////////////////////////////
// Billiards (1)
//
// ビリヤードもどき (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() {
            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;

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:Shape;
    private var balls: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 function Billiards(r:Rectangle) {
        rect = r;
        init();
    }

    private function init():void {
        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;
        setup();
    }
    private function setup():void {
        balls = new Array();
        for (var n:uint = 0; n <= max; n++) {
            var ball:Ball = new Ball(radius, colors[n]);
            addChild(ball);
            ball.x = area.x + Math.random()*area.width;
            ball.y = area.y + Math.random()*area.height;
            ball.setup(n);
            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();
        against();
        motion();
        manageDepths();
    }
    private function position():void {
        for (var n:uint = 0; n < max+1; n++) {
            var ball:Ball = balls[n];
            ball.position();
        }
    }
    private function checkHit():void {
        for (var n:uint = 0; n < max; n++) {
            var ball0:Ball = balls[n];
            for (var t:uint = n+1; t < max+1; t++) {
                var ball1:Ball = balls[t];
                repulsion(ball0, ball1);
            }
        }
    }
    private function motion():void {
        for (var n:uint = 0; n < max+1; n++) {
            var ball:Ball = balls[n];
            ball.motion();
        }
    }
    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 = (limit - 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 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 < max+1; 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 < max; n++) {
            var ball:Ball = balls[n];
            addChildAt(ball, n+2);
        }
    }
    private function draw():void {
        base = new Shape();
        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();
        addChild(base);
    }

}


//////////////////////////////////////////////////
// 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;

class Ball extends Sprite {
    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.5;
    private static var cueRange:Number = 1.6;
    private var line:Shape;

    public function Ball(r:uint, c:uint) {
        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 {
        parent.addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true);
        parent.addEventListener(MouseEvent.MOUSE_MOVE, track, false, 0, true);
        parent.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true);
    }
    private function press(evt:MouseEvent):void {
        xTarget = px + mouseX*cueRange;
        yTarget = py + mouseY*cueRange;
    }
    private function release(evt:MouseEvent):void {
        line.graphics.clear();
    }
    private function setCueLine():void {
        line = new Shape();
        parent.addChildAt(line, 1);
    }
    private function track(evt:MouseEvent):void {
        line.graphics.clear();
        line.graphics.lineStyle(40, bColor, 0.2);
        line.graphics.moveTo(px, py);
        line.graphics.lineTo(px + mouseX, py + mouseY);
        line.graphics.lineStyle(40, bColor, 0.1);
        line.graphics.lineTo(px + mouseX*cueRange, py + mouseY*cueRange);
        evt.updateAfterEvent();
    }
    public function repulsion(dx:Number, dy:Number):void {
        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;
    }
    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];
    }

}


//////////////////////////////////////////////////
// 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();
    }

}