表示位置を直して形も変えた
forked from 1つのSpriteに表示してhitAreaは別々 (diff: 128)
ActionScript3 source code
/**
* Copyright nabe ( http://wonderfl.net/user/nabe )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/88Fp
*/
// forked from nabe's 1つのSpriteに表示してhitAreaは別々
// forked from nabe's 別々のSpriteに描画
// forked from nabe's 1つのSpriteに描画
package {
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.SimpleButton;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.*;
[SWF(width="465", height="465", backgroundColor="0", frameRate="24")]
public class Main extends Sprite {
private var fx:Number;
private var fy:Number;
public function Main ():void {
addEventListener(Event.ADDED_TO_STAGE, init_);
}
private function init_(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init_);
var w_:int = stage.stageWidth * 0.5;
var h_:int = stage.stageHeight * 0.5;
x = w_;
y = h_;
append_(w_ * (Math.random() - 0.5), h_ * (Math.random() - 0.5));
addEventListener(Event.ENTER_FRAME, update_);
stage.addEventListener(MouseEvent.CLICK, click_);
}
private function click_(e:MouseEvent):void {
//クリックした位置に子を追加する。
append_(mouseX, mouseY);
}
private function append_(x_:Number, y_:Number):void {
//子を追加する。
const useMask_:Boolean = true;
//子SpriteにhitAreaを設定するか?
addChild(new Cube(x_, y_, useMask_));
}
private function update_(e:Event):void {
//アニメーション。
const split_:Boolean = false;
//子SpriteでBitmapFillするか?
var g_:Graphics
g_ = graphics;
g_.clear();
var n_:int = this.numChildren;
for (var i_:int = 0; i_ < n_; ++i_) {
var cube_:Cube = this.getChildAt(i_) as Cube;
if (!cube_) continue;
if (split_) {
g_ = cube_.graphics;
g_.clear();
}
cube_.update_(g_);
}
}
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.GradientType;
import flash.display.Graphics;
import flash.display.Shape;
import flash.display.TriangleCulling;
import flash.events.MouseEvent;
import flash.geom.Matrix;
import flash.geom.Matrix3D;
import flash.geom.PerspectiveProjection;
import flash.geom.Point;
import flash.geom.Utils3D;
import flash.geom.Vector3D;
import flash.display.Sprite;
import flash.events.Event;
class Cube extends Sprite {
private var vertices3D:Vector.<Number> = new Vector.<Number>;
private var vertices2D:Vector.<Number> = new Vector.<Number>;
private var indices:Vector.<int> = new Vector.<int>;
private var uvtData:Vector.<Number> = new Vector.<Number>;
private var texture_:BitmapData;
private var sum_rot:Matrix3D;
private var add_rot:Matrix3D;
private var trans_:Vector3D;
private var pers_:Matrix3D;
private var useMask_:Boolean;
public function Cube(x_:Number, y_:Number, useMask_:Boolean):void {
this.useMask_ = useMask_;
trans_ = new Vector3D(x_, y_, 1000);
addEventListener(Event.ADDED_TO_STAGE, init_);
}
private function init_(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init_);
var m_:Matrix3D = root.transform.perspectiveProjection.toMatrix3D();
var p_:Vector3D = m_.transformVector(new Vector3D(1, 1, 1000, 1));
trans_.x *= p_.z / p_.x;
trans_.y *= p_.z / p_.y;
data_();
addEventListener(MouseEvent.CLICK, remove_);
if (useMask_) {
var mask_:Sprite = new Sprite;
mask_.mouseEnabled = false;
hitArea = mask_;
mask_.visible = false;
addChild(mask_);
}
}
public function update_(g_:Graphics):void {
move_();
draw_(g_, true);
if (useMask_) {
var m_:Graphics = hitArea.graphics;
m_.clear();
draw_(m_, false);
}
}
private function data_():void {
//回転の用意。
sum_rot = new Matrix3D;
add_rot = new Matrix3D;
var axis_:Vector3D = new Vector3D(Math.random() - 0.5, Math.random() - 0.5, Math.random() - 0.5);
axis_.normalize();
add_rot.appendRotation((Math.random() - 0.5) * 10, axis_);
//投影の用意。
pers_ = root.transform.perspectiveProjection.toMatrix3D();
//テクスチャの用意。
texture_ = newTexture_(400, 300, 10);
//分割数
const unum:int = 8;
const vnum:int = 6;
const r_:int = 100;
var b0:int = 0;
var b1:int = 0;
for (var u_:int = 0; u_ <= unum; ++u_) {
var upos:Number = u_ / unum;
var urad:Number = Math.PI * 2 * upos;
var xpos:Number = r_ * Math.cos(urad);
var zpos:Number = r_ * Math.sin(urad);
for (var v_:int = 0; v_ <= vnum; ++v_) {
var vpos:Number = v_ / vnum;
var vrad:Number = -Math.PI * vpos;
var ypos:Number = r_ * Math.cos(vrad);
var ysin:Number = Math.sin(vrad);
uvtData.push(upos, vpos, 0);
vertices3D.push(xpos * ysin, ypos, zpos * ysin);
}
if (u_ == 0) continue;
b0 = b1;
b1 += vnum + 1;
for (var i_:int = 1; i_ < vnum; ++i_) {
indices.push(
b0 + i_ - 1, b1 + i_ + 0, b0 + i_ + 0,
b0 + i_ + 0, b1 + i_ + 0, b1 + i_ + 1
);
}
}
}
private function move_():void {
//座標を更新する。
sum_rot.append(add_rot);
var mat:Matrix3D = sum_rot.clone();
mat.appendTranslation(trans_.x, trans_.y, trans_.z);
mat.append(pers_);
Utils3D.projectVectors(mat, vertices3D, vertices2D, uvtData);
}
private function draw_(g_:Graphics, show_:Boolean):void {
//渡された画面に描画する。
if (show_) {
//表示用。
g_.beginBitmapFill(texture_, null, false, true);
g_.drawTriangles(vertices2D, indices, uvtData, TriangleCulling.POSITIVE);
} else {
//マスク用。
g_.beginFill(0xFFCCCC);
g_.drawTriangles(vertices2D, indices, null, TriangleCulling.POSITIVE);
}
g_.endFill();
}
private function remove_(e:Event):void {
//クリックすると消える。
parent.removeChild(this);
e.stopPropagation();
}
private function newTexture_ (width_:int, height_:int, size_:int):BitmapData {
//ピンク色の方眼紙。
var s_:Shape = new Shape;
var g_:Graphics = s_.graphics;
g_.clear();
g_.lineStyle(1, 0xFF0000);
//縦線。
for (var x_:int = 0; x_ < width_; x_ += size_) {
g_.moveTo(x_, 0);
g_.lineTo(x_, height_);
}
//横線。
for (var y_:int = 0; y_ < height_; y_ += size_) {
g_.moveTo(0, y_);
g_.lineTo(width_, y_);
}
//ビットマップに転記する。
var r_:BitmapData = new BitmapData(width_, height_, false, 0xFFCCCC);
r_.draw(s_);
return r_;
}
}
