前回のサンプルを少し発展させてみました。今回は配列の中身を回転させ、その情報を元にレンダリングしています。
前回のサンプルは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)
twitterでつぶやく
コメントが存在しません。