Entries

Spriteを任意の座標で回転させる。これに移動が絡むときのプログラム研究(AS3.0+FlashDevelop)

Spriteを任意の座標で回転させる処理と、これに移動を絡めた動作を
実現しようとして色々と調べてみました。

まず任意の座標を中心に回転させる処理を考えてみました。
FlashDevelopだけだと回転処理に使うfl.motionパッケージが使えません。
これはFlashが入っていないと使えないので困りました。別の方法を使うしか
ありません。ネット上を探してみると幾つかの記事を見つけましたが、初心者の勉強に
適当なサンプルはあまりなく、結局自分でリファレンスを見て書くしかないのかな、と
パクるのは早々に諦めて1から調べてみました。

難しいと感じたのは、Spriteを回転している状態で移動するときにどう書くのか、
という点です。ローカル座標をグローバル座標に変換して、その座標を中心に
回転させると正しく動作することを知るのに、結構試行錯誤を重ねました。おそらく
同じような箇所でハマっている方がいるのではないでしょうか(って私だけ?)
Macの方には申し訳ないのですが、FlashDevelopで書いたサンプルを
アップします。動かしてみてください。


(あまり移動ボタンを押しすぎるとSpriteが画面から消えます。ほどほどに)




Main.as(動作させるための最低限の処理しか書いていません。ボタン処理はほぼ省略しています)

package
{
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.events.MouseEvent;

import GridSheet;

[SWF(width="500", height="400", backgroundColor="#FFFFFF", frameRate="10")]

/**
* IdoKaiten01
*
* 移動と回転を織り交ぜてSpriteを制御する実験
*
* 2012-01-21
*
* @author Matsushiro
*/

public class Main extends Sprite
{
private var sprec:Sprite;
private var buttonText1:TextField;
private var buttonText2:TextField;
private var button1:SimpleButton;
private var button2:SimpleButton;
private var button3:SimpleButton;
private var m0:Matrix;
private var l_pos:Point;

public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}

private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point

var gs:GridSheet = new GridSheet(stage);  // 方眼罫
gs.drawGridSheet(stage.stageWidth, stage.stageHeight); // 画面サイズを渡す

l_pos = new Point(110, 110); // 回転中心座標

sprec = new Sprite();
sprec.graphics.lineStyle(4, 0x0, 0.5);
sprec.graphics.drawRect(100, 100, 150, 20);
sprec.graphics.drawCircle(110, 110, 1);
addChild(sprec);

// 素材の情報表示
var tf1:TextField = new TextField();
tf1.text = "画面サイズ(500, 400) drawRect(100, 100, 150, 20) 回転中心(110,110) " ;
tf1.width = 600;
tf1.x = 5;
tf1.y = 5;
addChild(tf1);

var tf2:TextField = new TextField();
tf2.text = "回転角度45度  右下移動(+100, +100) 左上移動(-100, -100)";
tf2.width = 500;
tf2.x = 5;
tf2.y = 20;
addChild(tf2);

// 回転ボタンのラベルの作成
buttonText1 = new TextField();
buttonText1.text = "回転";
buttonText1.selectable = false;
buttonText1.width = 40;
buttonText1.height = 20;
buttonText1.x = 120;
buttonText1.y = 360;
addChild(buttonText1);

// 回転ボタンの作成
button1 = new SimpleButton();
button1.upState = makeRoundRect(0xDDDDDD, 100, 20, 10);
button1.overState = makeRoundRect(0xFFFFFF, 100, 20, 10);
button1.downState = makeRoundRect(0xBBBBBB, 100, 20, 10);
button1.hitTestState = button1.upState;
//button1.addEventListener(MouseEvent.MOUSE_DOWN, onButtonMouseDown);
button1.addEventListener(MouseEvent.MOUSE_UP, onButtonMouseUp);
//button1.addEventListener(MouseEvent.MOUSE_OVER, onButtonMouseOver);
//button1.addEventListener(MouseEvent.MOUSE_OUT, onButtonMouseOut);
button1.x = 85;
button1.y = 360;
addChild(button1);

// 右下移動ボタンラベル
buttonText1 = new TextField();
buttonText1.text = "右下移動";
buttonText1.selectable = false;
buttonText1.width = 60;
buttonText1.height = 20;
buttonText1.x = 220;
buttonText1.y = 360;
addChild(buttonText1);
// 右下移動ボタン
button2 = new SimpleButton();
button2.upState = makeRoundRect(0xDDDDDD, 100, 20, 10);
button2.overState = makeRoundRect(0xFFFFFF, 100, 20, 10);
button2.downState = makeRoundRect(0xBBBBBB, 100, 20, 10);
button2.hitTestState = button2.upState;
//button2.addEventListener(MouseEvent.MOUSE_DOWN, onButtonMouseDown);
button2.addEventListener(MouseEvent.MOUSE_UP, onButtonMouseUp_Move1);
//button2.addEventListener(MouseEvent.MOUSE_OVER, onButtonMouseOver);
//button2.addEventListener(MouseEvent.MOUSE_OUT, onButtonMouseOut);
button2.x = 200;
button2.y = 360;
addChild(button2);

// 左上移動ボタンラベル
buttonText2 = new TextField();
buttonText2.text = "左上移動";
buttonText2.selectable = false;
buttonText2.width = 60;
buttonText2.height = 20;
buttonText2.x = 340;
buttonText2.y = 360;
addChild(buttonText2);
// 左上移動ボタン
button3 = new SimpleButton();
button3.upState = makeRoundRect(0xDDDDDD, 100, 20, 10);
button3.overState = makeRoundRect(0xFFFFFF, 100, 20, 10);
button3.downState = makeRoundRect(0xBBBBBB, 100, 20, 10);
button3.hitTestState = button3.upState;
//button3.addEventListener(MouseEvent.MOUSE_DOWN, onButtonMouseDown);
button3.addEventListener(MouseEvent.MOUSE_UP, onButtonMouseUp_Move2);
//button3.addEventListener(MouseEvent.MOUSE_OVER, onButtonMouseOver);
//button3.addEventListener(MouseEvent.MOUSE_OUT, onButtonMouseOut);
button3.x = 315;
button3.y = 360;
addChild(button3);
}

private function onButtonMouseDown(event:MouseEvent):void
{
}

private function onButtonMouseUp(event:MouseEvent):void
{
var gpt:Point = new Point();
gpt = sprec.localToGlobal(l_pos); // ローカル座標からグローバル座標を求める

m0 = sprec.transform.matrix;
m0.tx -= gpt.x; // 回転させる中心の座標を画面左上(原点)に持っていく ってこと。
m0.ty -= gpt.y;
m0.rotate(45*Math.PI / 180);
m0.tx += gpt.x;
m0.ty += gpt.y;
sprec.transform.matrix = m0;
}

private function onButtonMouseOver(event:MouseEvent):void
{
}

private function onButtonMouseOut(event:MouseEvent):void
{
}

private function makeRoundRect(color:uint, width:int, height:int, round:int):Sprite
{
var s:Sprite = new Sprite();
s.graphics.lineStyle(2);
s.graphics.beginFill(color);
s.graphics.drawRoundRect(0, 0, width, height, round);
s.graphics.endFill();
s.alpha = 0.3;
return s;
}

private function onButtonMouseUp_Move1(event:MouseEvent):void
{
sprec.x += 100;
sprec.y += 100;
}

private function onButtonMouseUp_Move2(event:MouseEvent):void
{
sprec.x -= 100;
sprec.y -= 100;
}
}
}


GridSheet.as(方眼罫を表示させるための)

package
{
import flash.display.DisplayObjectContainer;
import flash.display.Sprite;

/**
* 方眼罫を描写する(2012-01-15)
*
* @author Matsushiro
*/

public class GridSheet
{
private var _stg:DisplayObjectContainer;

public function GridSheet(instg:DisplayObjectContainer):void {
_stg = instg;
}

// 方眼罫を描写する
public function drawGridSheet(m_width:int, m_height:int):void {

var linex:Sprite = new Sprite();
_stg.addChild(linex);

// 縦線(m_width)
for (var i1:int = 0; i1 <= m_width; i1 += 10) {
if (i1%100 == 0) linex.graphics.lineStyle(2, 0x0, 0.3); // 100pixel毎に太い線
else linex.graphics.lineStyle(1, 0x0, 0.3);

linex.graphics.moveTo(i1, 0);
linex.graphics.lineTo(i1, m_height);
}

// 横線(m_height)
for (var i2:int = 0; i2 <= m_height; i2 += 10) {
if (i2%100 == 0) linex.graphics.lineStyle(2, 0x0, 0.3);
else linex.graphics.lineStyle(1, 0x0, 0.3);

linex.graphics.moveTo(0, i2);
linex.graphics.lineTo(m_width, i2);
}
}
}
}

・・・とまあ、こんな感じです。
スポンサーサイト
この記事に対してトラックバックを送信する(FC2ブログユーザー)
http://tadpolizemedia.blog118.fc2.com/tb.php/170-d0e84d22

0件のトラックバック

0件のコメント

コメントの投稿

投稿フォーム
投稿した内容は管理者にだけ閲覧出来ます

Appendix

プロフィール

 二代目松四郎

Author: 二代目松四郎


「カメラと動画(+スチル写真)」
「音響と音楽」
「プログラミング」
を主なテーマに活動しています。
映画館と美術館と音楽ホールと
古い街並みが私の学校。

宮城県仙台市在住。

カテゴリー

ブログ内検索

ブロとも申請フォーム

この人とブロともになる

Counter