forked from: Checkmate Vol.6 Amatuerx(スライムな●と★)
2009/12/20 frameRate 調整、およびそれに伴う物理定数調整
/**
* Copyright Aquioux ( http://wonderfl.net/user/Aquioux )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/o4UL
*/
// forked from checkmate's Checkmate Vol.6 Amatuer
// 2009/12/20 frameRate 調整、およびそれに伴う物理定数調整
package {
import flash.display.Sprite;
import flash.events.Event;
[SWF(width = "465", height = "465", frameRate = "60", backgroundColor = "0xFFFFFF")]
public class CheckmateAmatuer extends Sprite {
private var circle1:LiquidCircle;
private var circle2:LiquidCircle;
private var star1:LiquidStar;
private var star2:LiquidStar;
public function CheckmateAmatuer() {
/*
コードでエッチなものごとを描写してください。
公序良俗は守ってください。
Represent something sexual by codes.
DO NOT be offensive to public order and morals.
*/
const SIZE_CIRCLE:Number = 50.0;
const SCALE_CIRCLE:Number = 2.0;
const COLOR_CIRCLE:uint = 0xFFCC99;
const SIZE_STAR:Number = 10.0;
const SCALE_STAR:Number = 12.5;
const COLOR_STAR:uint = 0xFFFF66;
const DIST:uint = 50;
const centerX:Number = stage.stageWidth / 2;
const centerY:Number = stage.stageHeight / 2;
circle1 = new LiquidCircle(SIZE_CIRCLE, SCALE_CIRCLE);
circle1.x = centerX - DIST;
circle1.y = centerY;
addChild(circle1);
circle2 = new LiquidCircle(SIZE_CIRCLE, SCALE_CIRCLE);
circle2.x = centerX + DIST;
circle2.y = centerY;
addChild(circle2);
star1 = new LiquidStar(SIZE_STAR, SCALE_STAR);
star1.x = centerX - DIST;
star1.y = centerY;
addChild(star1);
star2 = new LiquidStar(SIZE_STAR, SCALE_STAR);
star2.x = centerX + DIST;
star2.y = centerY;
addChild(star2);
var facadeCurveTo:FacadeCurveTo = new FacadeCurveTo();
facadeCurveTo.defineFill(COLOR_CIRCLE);
circle1.drawFacade = facadeCurveTo;
circle2.drawFacade = facadeCurveTo;
var facadeLineTo:FacadeLineTo = new FacadeLineTo();
facadeLineTo.defineFill(COLOR_STAR);
star1.drawFacade = facadeLineTo;
star2.drawFacade = facadeLineTo;
addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
private function enterFrameHandler(event:Event):void {
circle1.update();
circle2.update();
star1.update();
star2.update();
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
/**
* 流動的な図形を描く(抽象クラス)
* @author YOSHIDA, Akio (Aquioux)
*/
class Liquid extends Sprite {
// DrawAPI ファサード
public function set drawFacade(value:FacadeDraw):void {
_drawFacade = value;
_drawFacade.definePath(numOfPoint);
_drawFacade.build();
}
protected var _drawFacade:FacadeDraw;
// ドローポイントの数
protected var numOfPoint:uint;
// ドローポイントを格納する配列
protected var drawPoints:Array;
function Liquid() {}
// ドローポイントの座標を計算して、一時的な Vector に格納する
protected function createCoordinate(radius:Number):Vector.<Number> {
// サブクラスで定義
return null;
}
// drawPoint の生成
protected function createDrawPoints(vector:Vector.<Number>, length:Number, distOfReaction:Number):void {
var first:DrawPoint;
var prev:DrawPoint;
var n:uint = numOfPoint;
drawPoints = [];
for (var i:int = 0; i < n; i++) {
var drawPoint:DrawPoint = new DrawPoint(vector[i * 2], vector[i * 2 + 1], length, distOfReaction);
drawPoints.push(drawPoint);
prev = (i == 0) ? first = drawPoint : prev.next = drawPoint;
}
// 最後の drawPoint の next を最初の drawPoint に設定
drawPoint.next = first;
// 配列の一番最初に、最後の drawPointl を追加
drawPoints.unshift(drawPoint);
}
// 更新
public function update():void {
updatePosition(); // drawPoint の位置更新
updateData(); // 描画のための座標 Vector の更新
updateDraw(); // 描画
}
// DrawPoint の位置更新
private function updatePosition():void {
var posX:Number = this.mouseX;
var posY:Number = this.mouseY;
var dist:Number = Math.sqrt(posX * posX + posY * posY);
const N:uint = numOfPoint;
for (var i:int = 0; i < N; i++) {
var drawPoint:DrawPoint = drawPoints[i];
drawPoint.update(posX, posY, dist);
}
}
// 描画のための座標 Vector の更新
protected function updateData():void {
// サブクラスで定義
}
// 描画
private function updateDraw():void {
var g:Graphics = this.graphics;
g.clear();
g.drawGraphicsData(_drawFacade.graphicsData);
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
/**
* 流動的な円を描く
* @author YOSHIDA, Akio (Aquioux)
*/
class LiquidCircle extends Liquid {
function LiquidCircle(radius:Number = 50.0, rate:Number = 2.0) {
numOfPoint = 8;
createDrawPoints(createCoordinate(radius), radius * rate, radius * 0.9);
}
// ドローポイントの座標を計算して、一時的な Vector に格納する
override protected function createCoordinate(radius:Number):Vector.<Number> {
const RADIAN:Number = Math.PI * 2 / numOfPoint;
var vector:Vector.<Number> = new Vector.<Number>();
var n:uint = numOfPoint;
for (var i:int = 0; i < n; i++) {
var p:Point = Point.polar(radius, RADIAN * i);
vector.push(p.x, p.y);
}
vector.fixed = true;
return vector;
}
// 描画のための座標 Vector の更新
override protected function updateData():void {
var data:Vector.<Number> = _drawFacade.data;
// moveTo
var drawPoint:DrawPoint = drawPoints[0];
var anchorX:Number = (drawPoint.x + drawPoint.next.x) / 2;
var anchorY:Number = (drawPoint.y + drawPoint.next.y) / 2;
var idx:uint = 0;
data[idx++] = anchorX;
data[idx++] = anchorY;
// curveTo
var n:uint = drawPoints.length;
for (var i:int = 0; i < n; i++) {
drawPoint = drawPoint.next;
anchorX = (drawPoint.x + drawPoint.next.x) / 2;
anchorY = (drawPoint.y + drawPoint.next.y) / 2;
data[idx++] = drawPoint.x;
data[idx++] = drawPoint.y;
data[idx++] = anchorX;
data[idx++] = anchorY;
}
}
}
import flash.display.Graphics;
import flash.display.Sprite;
import flash.geom.Point;
/**
* 流動的な☆を描く
* @author YOSHIDA, Akio (Aquioux)
*/
class LiquidStar extends Liquid {
function LiquidStar(radius:Number = 50.0, rate:Number = 2.0) {
numOfPoint = 10;
createDrawPoints(createCoordinate(radius), radius * rate, radius * 4.9);
var n:uint = drawPoints.length;
for (var i:int = 0; i < n; i++) {
if (i % 2) {
drawPoints[i].convex = true;
}
}
}
// ドローポイントの座標を計算して、一時的な Vector に格納する
override protected function createCoordinate(radius:Number):Vector.<Number> {
const RADIAN:Number = Math.PI * 2 / numOfPoint;
const OFFSETRADIAN:Number = Math.PI / 2;
var vector:Vector.<Number> = new Vector.<Number>();
var n:uint = numOfPoint;
for (var i:int = 0; i < n; i++) {
var radius2:Number = (i % 2) ? radius / 2 : radius;
var p:Point = Point.polar(radius2, RADIAN * i + OFFSETRADIAN);
vector.push(p.x, p.y);
}
vector.fixed = true;
return vector;
}
// 描画のための座標 Vector の更新
override protected function updateData():void {
var data:Vector.<Number> = _drawFacade.data;
// moveTo
var idx:uint = 0;
var drawPoint:DrawPoint = drawPoints[0];
data[idx++] = drawPoint.x;
data[idx++] = drawPoint.y;
// lineTo
var n:uint = drawPoints.length;
for (var i:int = 0; i < n; i++) {
drawPoint = drawPoint.next;
data[idx++] = drawPoint.x;
data[idx++] = drawPoint.y;
}
}
}
/**
* ドローポイント
* LinkedList になっている
* マウスの位置に応じて動く
* @author YOSHIDA, Akio (Aquioux)
*/
class DrawPoint {
// LinkedList
public function get next():DrawPoint { return _next; }
public function set next(value:DrawPoint):void {
_next = value;
}
private var _next:DrawPoint;
// 現在のX座標
public function get x():Number { return _x; }
private var _x:Number;
// 現在のY座標
public function get y():Number { return _y; }
private var _y:Number;
// 凸フラグ
public function set convex(value:Boolean):void {
_convex = value;
}
private var _convex:Boolean = false;
private const SPRING:Number = 0.059; // 弾性
private const FRICTION:Number = 0.82; // 抵抗
private var vx:Number = 0; // ヴェロシティX座標
private var vy:Number = 0; // ヴェロシティY座標
private var localY:Number; // 既定X座標
private var localX:Number; // 既定Y座標
private var length:Number; // マウス反応時の伸長距離
private var distOfReaction:Number; // マウス反応距離
public function DrawPoint(x:Number, y:Number, length:Number, distOfReaction:Number) {
_x = localX = x;
_y = localY = y;
this.length = length;
this.distOfReaction = distOfReaction;
}
public function update(targetX:Number, targetY:Number, dist:Number):void {
var flg:uint = (dist > distOfReaction) ? 1 : 0;
var radian:Number = Math.atan2(targetY * flg - localY , targetX * flg - localX);
var length2:Number = (_convex && flg == 0) ? length / 2 : length;
var tx:Number = localX - Math.cos(radian) * length2;
var ty:Number = localY - Math.sin(radian) * length2;
vx += (tx - _x) * SPRING;
vy += (ty - _y) * SPRING;
vx *= FRICTION;
vy *= FRICTION;
_x += vx;
_y += vy;
}
}
import flash.display.GraphicsEndFill;
import flash.display.GraphicsPath;
import flash.display.GraphicsPathCommand;
import flash.display.GraphicsSolidFill;
import flash.display.GraphicsStroke;
import flash.display.IGraphicsData;
/**
* GraphicsAPI Facade(抽象クラス)
* @author YOSHIDA, Akio (Aquioux)
*/
class FacadeDraw{
// Graphics.drawGraphicsData の引数
public function get graphicsData():Vector.<IGraphicsData> { return _graphicsData; }
protected var _graphicsData:Vector.<IGraphicsData>;
// GraphicsPath の command
public function get data():Vector.<Number> { return _data; }
protected var _data:Vector.<Number>;
protected var fill:GraphicsSolidFill; // 塗り
protected var stroke:GraphicsStroke; // 線
protected var commands:Vector.<int>; // GraphicsPath の command
public function FacadeDraw() {}
// 塗りの定義
public function defineFill(color:uint, alpha:Number = 1.0):void {
fill = new GraphicsSolidFill(color, alpha);
}
// 線の定義
public function defineStroke(thickness:Number, color:uint, alpha:Number):void {
stroke = new GraphicsStroke();
stroke.thickness = thickness;
stroke.fill = new GraphicsSolidFill(color, alpha);
}
// パスの定義
public function definePath(num:uint):void {
// サブクラスで定義
}
public function build():void {
_graphicsData = new Vector.<IGraphicsData>();
_graphicsData.push(fill);
//_graphicsData.push(stroke);
_graphicsData.push(new GraphicsPath(commands, _data));
_graphicsData.push(new GraphicsEndFill());
}
}
import flash.display.GraphicsPathCommand;
/**
* Graphics.curveTo Facade
* @author YOSHIDA, Akio (Aquioux)
*/
class FacadeCurveTo extends FacadeDraw {
public function FacadeCurveTo() {}
// パスの定義
override public function definePath(num:uint):void {
// コマンド
commands = new Vector.<int>();
commands.push(GraphicsPathCommand.MOVE_TO);
for (var i:int = 0; i < num; i++) {
commands.push(GraphicsPathCommand.CURVE_TO);
}
commands.fixed = true;
// 座標
var len:uint = (num + 1) * 4 + 2;
_data = new Vector.<Number>(len, true);
}
}
import flash.display.GraphicsPathCommand;
/**
* Graphics.lineTo Facade
* @author YOSHIDA, Akio (Aquioux)
*/
class FacadeLineTo extends FacadeDraw {
public function FacadeLineTo() {}
// パスの定義
override public function definePath(num:uint):void {
// コマンド
commands = new Vector.<int>();
commands.push(GraphicsPathCommand.MOVE_TO);
for (var i:int = 0; i < num; i++) {
commands.push(GraphicsPathCommand.LINE_TO);
}
commands.fixed = true;
// 座標
var len:uint = (num + 1) * 2 + 2;
_data = new Vector.<Number>(len, true);
}
}