Ks-Product.com

指定された軸を基準にオブジェクトを回転させるサンプル【part 2】

前回のサンプルを少し発展させてみました。今回は配列の中身を回転させ、その情報を元にレンダリングしています。

前回のサンプルはrotateメソッドにバグ(Flashの仕様上、三角関数に誤差が出る為)があり時間経過とともに位置が微妙にずれてしまうのですが、fladdict.netさんの記事を参考に対策を施してみました。また、このサンプルのように90度単位の回転を前提としたシステムであれば、sin、cosの値は決め打ちの方がよいかも知れませんね。


package  
{
    import flash.display.MovieClip;
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.events.MouseEvent;
    import flash.geom.Point;
    import flash.text.TextField;
    /**
     * ...
     * @author Ks-Product.com
     */
    public class TestMatrix2 extends Sprite
    {
        public var axis:Sprite;
        public var axisX:Number;
        public var axisY:Number;
        public var TBlockArray:Array;
        public var spriteArray:Array;
        public var board:Array;
        //debug
        public var output:TextField;
        
        public function TestMatrix2() 
        {
            init();
        }
        
        private function init():void
        {                        
            axisX = 0;
            axisY = 0;

            board = [[0, 0, 0, 0],
                     [0, 0, 0, 0],
                     [0, 0, 0, 0],
                     [0, 0, 0, 0]];
            
            //ボードとマス目と同じ数だけスプライトを生成
            spriteArray = [];
            var offset:uint = 20;
            var margin:uint = 5;
            for (var i:uint = 0; i < board.length; i++) {
                spriteArray[i] = [];
                for (var j:uint = 0; j < board[i].length; j++ ) {
                    var b:Block = new Block();
                    b.x = j * (b.width + margin) + offset;
                    b.y = i * (b.height + margin) + offset;
                    addChild(b);
                    spriteArray[i][j] = b;
                }
            }
            
            //T字ブロックを定義
            TBlockArray = [[0, 0], [0, 1], [ -1, 0], [1, 0]];

            //debug
            output = new TextField();
            output.x = 130;
            output.y = 20;
            addChild(output);
        
            render();
            stage.addEventListener(MouseEvent.CLICK, onClick);
        }
        
        private function onClick(e:MouseEvent):void 
        {
            rotate(90);
        }
        
        /**
         * ブロックをレンダリングする
         */
        private function render():void
        {
            var posX:uint = 2;
            var posY:uint = 2;
            var i:uint;
            var j:uint;
            
            //ボードをリセット
            for ( i = 0; i < board.length; i++) {
                for (j = 0; j < board[i].length; j++ ) {
                    board[i][j] = 0;
                }
            }
            
            //ブロックの情報をボードに書き込む
            for ( i = 0; i < TBlockArray.length; i++) {
                var mx = TBlockArray[i][0];
                var my = TBlockArray[i][1];
                
                board[posY - my][posX + mx] = 1;
            }
            
            //ボードの情報をスプライトに反映
            for ( i = 0; i < board.length; i++) {
                for (j = 0; j < board[i].length; j++ ) {
                    spriteArray[i][j].activate(board[i][j]);
                }
            }
            
            //debug
            //配列の中身を出力
            output.text = "";
            for ( i = 0; i < board.length; i++) {
                for ( j = 0; j < board.length; j++) {
                    output.appendText(board[i][j] + "  ");
                }
                output.appendText("\n");
            }
        }
        
        /**
         * 指定された軸を中心に回転する
         * @param angle
         */
        public function rotate(angle:Number):void
        {
            /* cos -sin | x
             * sin cos  | y
             * 
             * cos*x - sin*y
             * sin*x + cos*y
             * 
             * */
            
             var r:Number = angle * Math.PI / 180;
             //var cos:Number = Math.cos(r); //三角関数は誤差が出る為、下記の方法で誤差を吸収する。
             //var sin:Number = Math.sin(r);
             var cos:Number =  Math.round( Math.cos(r) * 1000000000000000 ) / 1000000000000000;
             var sin:Number =  Math.round( Math.sin(r) * 1000000000000000 ) / 1000000000000000;

             for (var i:uint = 0; i < TBlockArray.length; i++) {
                 var tx:Number = TBlockArray[i][0] - axisX;
                 var ty:Number = TBlockArray[i][1] - axisY;
                 
                 var nx = cos * tx - sin * ty;
                 var ny = sin * tx + cos * ty;
                 
                 TBlockArray[i][0] = nx + axisX;
                 TBlockArray[i][1] = ny + axisY;
             }
             
             render();
        }
        
    }

}

import flash.display.Sprite;
/**
 * ...
 * @author ...
 */
class Block extends Sprite
{
    public function Block() 
    {
        activate(false);
    }
    
    public function activate(flg:Boolean):void
    {
        if (flg) {
            graphics.beginFill(0xFF0000);
            graphics.drawRect(0, 0, 20, 20);
            graphics.endFill();
        }else {
            graphics.beginFill(0xCCCCCC);
            graphics.drawRect(0, 0, 20, 20);
            graphics.endFill();
        }
    }
}

コメント(0)

コメントが存在しません。

コメントを投稿する

※投稿されたコメントは管理人が承認するまで反映されません。
またHTMLタグはご利用できません。コメント上にHTMLタグを表示させたい場合は全角でご入力ください。

お名前
サイトURL
コメント
  • Home
  • > 指定された軸を基準にオブジェクトを回転させるサンプル【part 2】
名前:
kakeruニコ動twitter
職業:
neet(転職活動中)
生年月日:
1983年4月19日

Flash(ActionScript)で食っていけたらなと思う今日この頃…とりあえず、年末年始にかけて転職活動できるようにごにょごにょ…

Powered by Movable Type.

ご覧の環境ではこのコンテンツはご利用できません。
最新のFlashPlayerをダウンロードしてからご利用ください。
Get Adobe Flash player