MosquitoAttack (to use the headphone)
MosquitoAttack
* (to use the headphone)
*
* 蚊叩き
* (ヘッドフォン推奨)
* 羽音を頼りに耳障りな蚊をクリックで潰しましょう。
*
*
* 羽音の生成のソースはseagirlさんのMosquito Noise 17k Hzを拝借しました。
* http://wonderfl.net/c/94k2
* (17kHzをヘッドフォンで聞いていると耳をやられそうなので1.7kHzにしてます)
*
* 蚊の描画のソースはnutsuさんのcheckmate作品より拝借しました。
* http://wonderfl.net/c/3OcH
*
* ※羽音リアル版
* http://wonderfl.net/c/6Ga1
*
*
/**
* Copyright sakusan393 ( http://wonderfl.net/user/sakusan393 )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/oAxD
*/
/*
* MosquitoAttack
* (to use the headphone)
*
* 蚊叩き
* (ヘッドフォン推奨)
* 羽音を頼りに耳障りな蚊をクリックで潰しましょう。
*
*
* 羽音の生成のソースはseagirlさんのMosquito Noise 17k Hzを拝借しました。
* http://wonderfl.net/c/94k2
* (17kHzをヘッドフォンで聞いていると耳をやられそうなので1.7kHzにしてます)
*
* 蚊の描画のソースはnutsuさんのcheckmate作品より拝借しました。
* http://wonderfl.net/c/3OcH
*
* ※羽音リアル版
* http://wonderfl.net/c/6Ga1
*
* */
package
{
import flash.display.BitmapData;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.SampleDataEvent;
import flash.events.TimerEvent;
import flash.media.Sound;
import flash.net.URLRequest;
import flash.utils.Timer;
import org.papervision3d.events.InteractiveScene3DEvent;
import org.papervision3d.materials.BitmapMaterial;
import org.papervision3d.materials.ColorMaterial;
import org.papervision3d.materials.utils.MaterialsList;
import org.papervision3d.materials.WireframeMaterial;
import org.papervision3d.objects.primitives.Cube;
import org.papervision3d.objects.primitives.Cylinder;
import org.papervision3d.objects.primitives.Plane;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.objects.special.Sound3D;
import org.papervision3d.view.BasicView;
[SWF(backgroundColor="0x0", frameRate="30", width="465", height="465")]
/**
* ...
* @author 393
*/
public class MosquitoAttack extends BasicView
{
private var _cylinder:Cylinder;
private var _cube:Cube;
private var _angle:Number = Math.random();
private var _mosquitoPlane:Plane;
private var _mosquitoGraArray:Vector.<BitmapMaterial> = new Vector.<BitmapMaterial>();
//羽音
private static const SAMPLING_RATE:int = 44100;
private static const SAMPLE_SIZE:int = 8192; // 2048 〜 8192
private var frequency:Number = 1700;
private var phase:Number = 0.0;
private var waveform:SineWave;
private var _sound:Sound;
private var _sound3D:Sound3D;
private var _count:int;
private var _timer:Timer;
private var _clapSound:Sound;
public function MosquitoAttack()
{
super(465, 465, true, true, "Free");
this.addEventListener(Event.ADDED_TO_STAGE , init);
}
private function init(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
_clapSound = new Sound(new URLRequest("http://393.bz/data/claphands.mp3"));
//カメラ位置初期化
camera.x = camera.z = 0;
camera.y = 1000;
camera.zoom = 40
camera.rotationX = 10;
camera.rotationY = 180;
// 地面を作成
var wireP:WireframeMaterial = new WireframeMaterial(0x666699);
var plane:Plane = new Plane(wireP, 10000, 10000, 10, 10);
plane.rotationX = 90;
plane.x = 10;
plane.y = 0;
plane.z = 10;
scene.addChild(plane);
//蚊を生成
//var colorMaterial:ColorMaterial = new ColorMaterial(0xFFFFFF);
_mosquitoGraArray[0] = new BitmapMaterial(fig1());
_mosquitoGraArray[1] = new BitmapMaterial(fig2());
_mosquitoGraArray[2] = new BitmapMaterial(fig3());
for (var i:int = 0; i < 2; i++)
{
_mosquitoGraArray[0].interactive = true;
}
_mosquitoPlane = new Plane(_mosquitoGraArray[0], 20, 20, 1);
_mosquitoPlane.addEventListener(InteractiveScene3DEvent.OBJECT_CLICK , clickHandler);
_mosquitoPlane.addEventListener(InteractiveScene3DEvent.OBJECT_OVER , overHandler);
_mosquitoPlane.addEventListener(InteractiveScene3DEvent.OBJECT_OUT , outHandler);
scene.addChild(_mosquitoPlane);
_mosquitoPlane.y = 900;
_mosquitoPlane.x = Math.sin(_angle) * 100;
_mosquitoPlane.z = Math.cos(_angle) * 100;
//蚊の羽音
waveform = new SineWave();
_sound = new Sound();
_sound.addEventListener(SampleDataEvent.SAMPLE_DATA, sampleDataHandler);
// サウンド3Dを作成
_sound3D = new Sound3D(_sound);
scene.addChild(_sound3D);
_sound3D.play();
addEventListener(Event.ENTER_FRAME , enterFrameHandler);
startRendering();
//蚊のグラフィック変化
_timer = new Timer(100);
_timer.addEventListener(TimerEvent.TIMER, timerHandler);
_timer.start();
stage.addEventListener(MouseEvent.MOUSE_DOWN, downHandler);
}
private function overHandler(e:InteractiveScene3DEvent):void
{
viewport.buttonMode = true;
}
private function outHandler(e:InteractiveScene3DEvent):void
{
viewport.buttonMode = false;
}
private function downHandler(e:MouseEvent):void
{
_clapSound.play();
}
private function timerHandler(e:TimerEvent):void
{
_count ++;
var bMat:BitmapMaterial;
if (_count % 2 == 0) bMat = _mosquitoGraArray[0];
else bMat = _mosquitoGraArray[1];
_mosquitoPlane.material = bMat;
}
public function fig1():BitmapData
{
return BitmapPatternBuilder.build(
[[1,0,0,1,0,0,1],
[1,0,1,1,1,0,1],
[1,1,1,1,1,1,1],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,0],
[0,1,0,1,0,1,0],
[1,0,0,1,0,0,1]],
[0x00000000, 0xFFFFFFFF]);
}
public function fig2():BitmapData
{
return BitmapPatternBuilder.build(
[[0,0,0,1,0,0,0],
[0,0,1,1,1,0,0],
[0,1,1,1,1,1,0],
[1,1,1,1,1,1,1],
[1,0,1,1,1,0,1],
[0,1,0,1,0,1,0],
[0,1,0,1,0,1,0]],
[0x00000000, 0xFFFFFFFF]);
}
public function fig3():BitmapData
{
return BitmapPatternBuilder.build(
[[1,0,0,1,0,0,1],
[0,1,0,1,1,1,0],
[1,1,1,1,1,0,0],
[0,1,1,1,1,1,0],
[0,0,1,1,1,0,1],
[0,1,0,1,1,1,0],
[1,0,0,0,1,0,1]],
[0x00000000, 0xFFFF0000]);
}
private function clickHandler(e:InteractiveScene3DEvent):void
{
trace("attack");
_sound3D.stop();
_timer.stop();
var bMat:BitmapMaterial = _mosquitoGraArray[2];
_mosquitoPlane.material = bMat;
stopRendering();
singleRender();
}
private function sampleDataHandler(e:SampleDataEvent):void
{
var sample:Number;
//dataに書き込む量は、8192(安定性を求めたmax値)
//ここは実際に何周期になるかは関係ない(1ループで1周期ではない)
for (var i:int = 0; i < SAMPLE_SIZE; i++)
{
//位相差を計算
//周波数/サンプリングレート(分解能は44.1khzじゃないとだめ?)
phase += frequency / SAMPLING_RATE;
//サインカーブでの位相角における値を返す
sample = waveform.exec(phase);
//すこしゲインを下げる
sample *= 0.1;
e.data.writeFloat(sample); // L
e.data.writeFloat(sample); // R
}
}
private function enterFrameHandler(e:Event):void
{
camera.rotationY += (((mouseX / stage.stageWidth) * 360)-camera.rotationY)*0.02;
camera.rotationX += ((((mouseY / stage.stageHeight) - 0.5) * 45) - camera.rotationX) * 0.02;
_mosquitoPlane.x = Math.sin(_angle) * 3500;
_mosquitoPlane.z = Math.cos(_angle*1.3) * 1000;
_mosquitoPlane.y = Math.cos(_angle * 5) * 500 + 1000;
_sound3D.copyPosition(_mosquitoPlane);
_mosquitoPlane.rotationY = camera.rotationY;
_angle -= 0.005;
}
}
}
//サイン波形データを返す
class SineWave
{
public function exec(phase:Number):Number
{
//位相差から位相角を計算(1周期からの割合算出)
var phaseAngle:Number = phase * Math.PI * 2;
var sample:Number = Math.sin(phaseAngle);
return sample;
}
}
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Graphics;
class BitmapPatternBuilder{
/**
* creates BitmapData filled with dot pattern.
* First parameter is 2d array that contains color index for each pixels;
* Second parameter contains color reference table.
*
* @parameter pattern:Array 2d array that contains color index for each pixel.
* @parameter colors:Array 1d array that contains color table.
* @returns BitmapData
*/
public static function build(pattern:Array, colors:Array):BitmapData{
var bitmapW:int = pattern[0].length;
var bitmapH:int = pattern.length;
var bmd:BitmapData = new BitmapData(bitmapW,bitmapH,true,0x000000);
for(var yy:int=0; yy<bitmapH; yy++){
for(var xx:int=0; xx<bitmapW; xx++){
var color:int = colors[pattern[yy][xx]];
bmd.setPixel32(xx, yy, color);
}
}
return bmd;
}
/**
* short cut function for Graphics.beginBitmapFill with pattern.
*/
public static function beginBitmapFill(pattern:Array, colors:Array, graphics:Graphics):void{
var bmd:BitmapData = build(pattern, colors);
graphics.beginBitmapFill(bmd);
bmd.dispose();
}
}