リングオシレータ
赤→青→緑→赤の順で、接触したときに隣の粒子の色を変えていく
/**
* Copyright Nao_u ( http://wonderfl.net/user/Nao_u )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/lX7B
*/
//
// 赤→青→緑→赤の順で、接触したときに隣の粒子の色を変えていく
//
//
package {
import flash.display.Sprite;
import flash.events.*;
[SWF(width="465", height="465", backgroundColor="0xFFFFFF", frameRate="30")]
public class FlashTest extends Sprite {
public function FlashTest() {
Main = this;
initialize();
stage.addEventListener(Event.ENTER_FRAME,update);
stage.addEventListener(KeyboardEvent.KEY_UP, keyCheckUp);
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyCheckDown);
stage.addEventListener(MouseEvent.MOUSE_UP, MouseCheckUp);
stage.addEventListener(MouseEvent.MOUSE_DOWN, MouseCheckDown);
}
}
}
import flash.display.Sprite;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.events.MouseEvent;
import flash.ui.Keyboard;
import flash.text.TextField;
import flash.geom.*;
import flash.utils.getTimer;
import frocessing.color.ColorHSV;
var Main:Sprite;
var SCREEN_W:Number = 465;
var SCREEN_H:Number = 465;
var Text0:TextField
var Text1:TextField
var Text2:TextField
var T:Number = 0.5;
var Mode:int = 0;
var AgentAry:Vector.<Agent> = new Vector.<Agent>;
var Grid:Vector.<Array>;
var GridSize:int = 16;
var GridLength:int = (SCREEN_W / GridSize)+2;
var Wall:Vector.<int>;
var GridVec:Vector.<Point>;
var GridVecDisp:Boolean = false;
var RedNum:int;
var GreenNum:int;
var BlueNum:int;
function initialize():void{
Text0 = new TextField();
Text0.text = "----";
Text0.autoSize = "left";
Main.addChild(Text0);
Text1 = new TextField();
Text1.y = 12;
Text1.text = "----";
Text1.autoSize = "left";
Main.addChild(Text1);
Text2 = new TextField();
Text2.y = 24;
Text2.text = "----";
Text2.autoSize = "left";
Main.addChild(Text2);
graphicClear();
updateGrid();
var num:int = 1500;
for( var i:int=0; i<num; i++ ){
var dir:Number;
var target:Point = new Point;
if( i < num/2 ) { dir =Math.PI; target.x = SCREEN_W/2-15; target.y = -SCREEN_H/4; }
else { dir =Math.PI/2; target.x = SCREEN_W*1.25; target.y = SCREEN_H/2+15;}
//dir =Math.PI*0.5;
AgentAry.push( new Agent( new Point(0+(i/120)*35, 50+((i%5)*75+(i%20)*3)), dir, target ) );
AgentAry[i].update();
}
}
function update(e :Event):void{
var time:int = getTimer();
RedNum=0;
GreenNum=0;
BlueNum=0;
graphicClear();
updateGrid();
for( var i:int=0; i<AgentAry.length; i++ ){
AgentAry[i].update();
}
updateClick();
if( KeyPrev == 0 && KeyData != 0 ){
if( GridVecDisp == true ) GridVecDisp = false;
else GridVecDisp = true;
}
KeyPrev = KeyData;
var endTime:int = getTimer() - time;
Text0.text = "R:" + RedNum;
Text1.text = "G:" + GreenNum;
Text2.text = "B:" + BlueNum;
var sx:Number = 60;
drawRect(sx, 6, sx+RedNum/3, 5, 0xff8080 );
drawRect(sx,18, sx+GreenNum/3, 5, 0x80ff80 );
drawRect(sx,30, sx+BlueNum/3, 5, 0x8080ff );
if( RedNum == 0 ) AgentAry[0].Type = 0;
if( GreenNum == 0 ) AgentAry[0].Type = 1;
if( BlueNum == 0 ) AgentAry[0].Type = 2;
// updateKey();
// MouseUpdate();
}
function updateClick():void{
var mx:Number = Main.stage.mouseX;
var my:Number = Main.stage.mouseY;
if( MouseData & MOUSE_LEFT_TRG ){
}
}
function updateGrid():void{
Grid = new Vector.<Array>
var idx:int;
for( var x:int=0; x<GridSize+2; x++ ){
for( var y:int=0; y<GridSize+2; y++ ){
idx = x + y*GridSize;
Grid.push( new Array() );
}
}
var agt:Agent;
for( var i:int=0; i<AgentAry.length; i++ ){
agt = AgentAry[i];
idx = agt.getIndex();
Grid[idx].push( agt );
}
}
var target:Point = new Point;
class Agent{
public var Sp:Sprite;
public var isEnable:Boolean = false;
public var Pos:Point = new Point;
public var SpdVec:Point = new Point;
public var Color:int;
public var Type:int;
public function Agent( p:Point, r:Number, t:Point ){
Sp=new Sprite();
Pos = p;
Sp.x = Pos.x;
Sp.y = Pos.y;
Main.stage.addChild(Sp);
var rnd:Number = Math.random();
Type = rnd*rnd*rnd*rnd*rnd*rnd * 3;
SpdVec.x = -1.0+Math.random()*2;
SpdVec.y = -1.0+Math.random()*2;
}
public function update( ):void{
var reset:Boolean = false;
Sp.x = Pos.x;
Sp.y = Pos.y;
checkNear();
Pos.x += SpdVec.x;
Pos.y += SpdVec.y;
if( Pos.x < 9 ) { Pos.x = 9; SpdVec.x *= -1 }
if( Pos.y < 50 ) { Pos.y = 50; SpdVec.y *= -1 }
if( Pos.x > SCREEN_W-9 ) { Pos.x = SCREEN_W-10; SpdVec.x *= -1 }
if( Pos.y > SCREEN_H-9 ) { Pos.y = SCREEN_H-10; SpdVec.y *= -1 }
if( Type == 0 ) { RedNum++; Color = 0xff8080;}
if( Type == 1 ) { GreenNum++; Color = 0x80ff80;}
if( Type == 2 ) { BlueNum++; Color = 0x8080ff;}
drawCircle( Pos.x, Pos.y, 5, Color );
}
public function checkNear():void{
var idx:int;
var lp:int;
var ar:Array;
var ag:Agent;
for( var x:int=-1; x<2; x++ ){
for( var y:int=-1; y<2; y++ ){
idx = getIndexOfs(x,y);
ar = Grid[idx];
lp = ar.length;
for( var i:int=0; i<lp; i++ ){
ag = ar[i];
if( ag != this ){
var dist:Number = getDist( this.Pos, ag.Pos );
if( dist < 9.0 ){
if(Math.random() < 0.75){
if( ag.Type == 2 && Type == 1 ) Type = 2;
if( ag.Type == 1 && Type == 0 ) Type = 1;
if( ag.Type == 0 && Type == 2 ) Type = 0;
}
var swapX:Number = SpdVec.x;
var swapY:Number = SpdVec.y;
SpdVec.x = ag.SpdVec.x;
SpdVec.y = ag.SpdVec.y;
ag.SpdVec.x = swapX;
ag.SpdVec.y = swapY;
var targetVec:Point = new Point;
targetVec.x = ag.Pos.x - this.Pos.x;
targetVec.y = ag.Pos.y - this.Pos.y;
ag.Pos.x += targetVec.x*0.05;
ag.Pos.y += targetVec.y*0.05;
}
}
}
}
}
}
public function getIndex():int{
var idx:int = int(Pos.x/GridLength)+1+ (int(Pos.y/GridLength)+1)*GridSize;
return idx;
}
public function getIndexOfs( ofsX:int, ofsY:int ):int{
var idx:int = int(Pos.x/GridLength)+1+ofsX + (int(Pos.y/GridLength)+1+ofsY)*GridSize;
return idx;
}
public function getIndexPos( px:Number, py:Number ):int{
var idx:int = int(px/GridLength)+1+ (int(py/GridLength)+1)*GridSize;
return idx;
}
public function setEnable( flg:Boolean ):void{
if( flg == true && isEnable == false ){
Sp.graphics.clear();
Sp.graphics.lineStyle(1.4,0x000000);
Sp.graphics.beginFill(0xe0d000,1);
Sp.graphics.drawCircle(0,0,8.0);
Sp.graphics.endFill();
}else if( flg == false && isEnable == true ){
Sp.graphics.clear();
}
isEnable = flg;
}
}
function graphicClear():void{
Main.graphics.clear();
}
function drawRect(sx:Number, sy:Number, ex:Number, ey:Number, col:int ):void{
Main.graphics.lineStyle( 0, col );
Main.graphics.beginFill( col );
Main.graphics.drawRect( sx, sy, ex, ey );
Main.graphics.endFill();
}
function drawLine( sx:Number, sy:Number, ex:Number, ey:Number, size:Number, col:int ):void{
Main.graphics.lineStyle(size,col);
Main.graphics.moveTo( sx, sy );
Main.graphics.lineTo( ex, ey );
}
function drawCircle( x:Number, y:Number, size:Number, col:int ):void{
Main.graphics.lineStyle(1.0,0x000000);
Main.graphics.beginFill( col, 1 );
Main.graphics.drawCircle( x, y, size );
Main.graphics.endFill();
}
function drawCircleLine( x:Number, y:Number, size:Number, col:int ):void{
Main.graphics.lineStyle(1.0,0x000000);
// Main.graphics.beginFill( col, 1 );
Main.graphics.drawCircle( x, y, size );
// Main.graphics.endFill();
}
var KEY_UP:int = 0x01;
var KEY_DOWN:int = 0x02;
var KEY_LEFT:int = 0x04;
var KEY_RIGHT:int = 0x08;
var KEY_UP_TRG:int = 0x10;
var KEY_DOWN_TRG:int = 0x20;
var KEY_LEFT_TRG:int = 0x40;
var KEY_RIGHT_TRG:int = 0x80;
var KeyData:int;
var KeyPrev:int;
function keyCheckDown(event:KeyboardEvent):void {
switch (event.keyCode){
case Keyboard.UP: KeyData |= KEY_UP|KEY_UP_TRG; break;
case Keyboard.DOWN: KeyData |= KEY_DOWN|KEY_DOWN_TRG; break;
case Keyboard.LEFT: KeyData |= KEY_LEFT|KEY_LEFT_TRG; break;
case Keyboard.RIGHT: KeyData |= KEY_RIGHT|KEY_RIGHT_TRG; break;
}
}
function keyCheckUp(event:KeyboardEvent):void {
switch (event.keyCode){
case Keyboard.UP: KeyData &= ~KEY_UP; break;
case Keyboard.DOWN: KeyData &= ~KEY_DOWN; break;
case Keyboard.LEFT: KeyData &= ~KEY_LEFT; break;
case Keyboard.RIGHT: KeyData &= ~KEY_RIGHT; break;
}
}
function updateKey():void{
KeyData &= ~(KEY_UP_TRG|KEY_DOWN_TRG|KEY_LEFT_TRG|KEY_RIGHT_TRG);
}
var MOUSE_LEFT:int = 0x01;
var MOUSE_LEFT_TRG:int = 0x02;
var MouseData:int;
function MouseCheckDown(event:MouseEvent):void{
MouseData |= MOUSE_LEFT;
MouseData |= MOUSE_LEFT_TRG;
}
function MouseCheckUp(event:MouseEvent):void{
MouseData &= ~MOUSE_LEFT;
}
function MouseUpdate():void{
MouseData &= ~MOUSE_LEFT_TRG;
}
function normalize( a:Point ):void {
var dist:Number = Math.sqrt( a.x * a.x + a.y*a.y );
a.x /= dist;
a.y /= dist;
}
// 2点間の距離を求める
function getDist( a:Point, b:Point ):Number {
var dx:Number = a.x-b.x;
var dy:Number = a.y-b.y;
return Math.sqrt(dx*dx + dy*dy);
}
// 内積 (dot product) : a⋅b = |a||b|cosθ
function dot( a:Point, b:Point ):Number {
return (a.x * b.x + a.y * b.y);
}
// 外積 (cross product) : a×b = |a||b|sinθ
function cross( a:Point, b:Point ):Number {
return (a.x * b.y - a.y * b.x);
}