SoundBar
/**
* Copyright h_kamizono ( http://wonderfl.net/user/h_kamizono )
* MIT License ( http://www.opensource.org/licenses/mit-license.php )
* Downloaded from: http://wonderfl.net/c/vTZp
*/
/*
棒を別の棒に当てることで音を鳴らします。
当たった棒の色の組み合わせで鳴る音が違います。
それぞれの棒はマウスで移動できます。
*/
package {
import flash.display.*;
import flash.geom.*;
import flash.events.*;
import flash.filters.*;
import flash.media.Sound;
import flash.display.Sprite;
import flash.net.URLRequest;
import flash.utils.Timer;
import flash.events.TimerEvent;
import flash.trace.Trace;
[SWF(width="465", height="465", backgroundColor="0x000000")]
public class Main extends Sprite {
private var _sounds:Sounds = new Sounds();
private var _bmpds:Vector.<BitmapData> = new Vector.<BitmapData>();
private var _bmps:Vector.<Bitmap> = new Vector.<Bitmap>();
private var _barWidth:int = 10;
private var _barHeight:int = 100;
private var _barNum:int = 8;
private var _bars:Vector.<Bar> = new Vector.<Bar>();
private var _gf:GlowFilter = new GlowFilter(0xFFFFFF, 1, 16, 16, 2, 1, false, true);
// Barの初期位置
private var _posx:Array = [78, 238, 353, 149, 410, 73, 319, 249];
private var _posy:Array = [153, 226, 162, 129, 217, 246, 227, 147];
public function Main() {
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
_sounds.addEventListener("loadComplete", init);
}
private function init(e:Event):void
{
for (var i:int = 0; i < _barNum; i++)
{
_bars.push(new Bar(_posx[i], _posy[i],
_barWidth, _barHeight, (i % Bar.kinds) + 1));
addChild(_bars[_bars.length - 1]);
_bmpds.push(new BitmapData(stage.stageWidth, stage.stageHeight, true, 0))
}
var timer:Timer = new Timer(66);
timer.addEventListener(TimerEvent.TIMER, loop);
timer.start();
}
private function loop(e:TimerEvent):void
{
for (var i:int = 0; i < _barNum; i++)
{
_bars[i].rotation += _bars[i].degree;
_bmpds[i].fillRect(_bmpds[i].rect, 0);
_bmpds[i].draw(_bars[i], new Matrix(1, 0, 0, 1, _bars[i].x, _bars[i].y));
}
// Barが衝突したら音を鳴らす
for (i = 0; i < _barNum; i++)
{
for (var j:int = i + 1; j < _barNum; j++)
{
if (HitTest.complexHitTestObject(_bars[i], _bars[j], 1.2))
{
_bars[i].isLighted = true;
_bars[j].isLighted = true;
_bars[i].degree = -1*_bars[i].degree;
_bars[j].degree = -1*_bars[j].degree;
Sounds.plays(_bars[i].kind.toString() + _bars[j].kind.toString());
}
else
{
if (_bars[i].isLighted && !_bars[j].isLighted)
{
_bars[j].isLighted = false;
}
else if (!_bars[i].isLighted && _bars[j].isLighted)
{
_bars[i].isLighted = false;
}
else
{
_bars[i].isLighted = false;
_bars[j].isLighted = false;
}
}
}
}
// ぶつかった棒は光るように
/*
for (i = 0; i < _barNum; i++)
{
if (_bars[i].isLighted) _bars[i].filters = [gf];
else _bars[i].filters = [];
}
*/
// Barの移動
for (i = 0; i < _barNum; i++)
{
if (_bars[i].isPressed)
{
_bars[i].x = mouseX;
_bars[i].y = mouseY;
trace(_bars[i].x, _bars[i].y)
}
}
}
}
}
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
class Bar extends MovieClip {
//
private var _degree:int;
/*
* kindは1から4のInteger
* 1-1, 1-2, 1-3, 1-4がdrop1~4
* 2-2, 2-3, 2-4, がdrop5~7
* 3-3, 3-4 がdrop8-9
* 4-4 がdrop10
*/
private var _kind:int;
public static var kinds:int = 4;
// クリックされているかどうか
public var isPressed:Boolean = false;
// 光っているかどうか
public var isLighted:Boolean = false;
public function Bar(x:int, y:int, width:int, height:int, kind:int, degree:int = 10):void
{
var color:uint;
_kind = kind;
switch (kind)
{
case 1:
// green
color = Functions.hsbToRgb(100, 1, 1);
break;
case 2:
// blue
color = Functions.hsbToRgb(200, 1, 1);
break;
case 3:
// purple
color = Functions.hsbToRgb(300, 1, 1);
break;
case 4:
// red
color = Functions.hsbToRgb(350, 1, 1);
break;
}
graphics.clear();
graphics.lineStyle();
graphics.beginFill(color, 0.8);
graphics.drawRoundRect( -width / 2, -height / 2, width, height, 10, 10);
//centroid
this.x = x;
this.y = y;
this.width = width;
this.height = height;
_degree = degree;
addEventListener(MouseEvent.MOUSE_DOWN, onMDown);
addEventListener(MouseEvent.MOUSE_UP, onMUp);
}
public function onMDown(ev:MouseEvent):void
{
isPressed = true;
}
public function onMUp(ev:MouseEvent):void
{
isPressed = false;
}
public function get degree():int { return _degree; }
public function set degree(value:int):void
{
_degree = value;
}
public function get kind():int { return _kind; }
public function set kind(value:int):void
{
_kind = value;
}
}
// http://www.tink.ws/blog/as-30-hittest/
import flash.display.BitmapData;
import flash.display.BlendMode;
import flash.display.DisplayObject;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
class HitTest
{
public static function complexHitTestObject( target1:DisplayObject, target2:DisplayObject, accurracy:Number = 1 ):Boolean
{
return complexIntersectionRectangle( target1, target2, accurracy ).width != 0;
}
public static function intersectionRectangle( target1:DisplayObject, target2:DisplayObject ):Rectangle
{
// If either of the items don't have a reference to stage, then they are not in a display list
// or if a simple hitTestObject is false, they cannot be intersecting.
if( !target1.root || !target2.root || !target1.hitTestObject( target2 ) ) return new Rectangle();
// Get the bounds of each DisplayObject.
var bounds1:Rectangle = target1.getBounds( target1.root );
var bounds2:Rectangle = target2.getBounds( target2.root );
// Determine test area boundaries.
var intersection:Rectangle = new Rectangle();
intersection.x = Math.max( bounds1.x, bounds2.x );
intersection.y = Math.max( bounds1.y, bounds2.y );
intersection.width = Math.min( ( bounds1.x + bounds1.width ) - intersection.x, ( bounds2.x + bounds2.width ) - intersection.x );
intersection.height = Math.min( ( bounds1.y + bounds1.height ) - intersection.y, ( bounds2.y + bounds2.height ) - intersection.y );
return intersection;
}
public static function complexIntersectionRectangle( target1:DisplayObject, target2:DisplayObject, accurracy:Number = 1 ):Rectangle
{
if( accurracy <= 0 ) throw new Error( "ArgumentError: Error #5001: Invalid value for accurracy", 5001 );
// If a simple hitTestObject is false, they cannot be intersecting.
if( !target1.hitTestObject( target2 ) ) return new Rectangle();
var hitRectangle:Rectangle = intersectionRectangle( target1, target2 );
// If their boundaries are no interesecting, they cannot be intersecting.
if( hitRectangle.width * accurracy < 1 || hitRectangle.height * accurracy < 1 ) return new Rectangle();
var bitmapData:BitmapData = new BitmapData( hitRectangle.width * accurracy, hitRectangle.height * accurracy, false, 0x000000 );
// Draw the first target.
bitmapData.draw( target1, HitTest.getDrawMatrix( target1, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, -255, -255, 255 ) );
// Overlay the second target.
bitmapData.draw( target2, HitTest.getDrawMatrix( target2, hitRectangle, accurracy ), new ColorTransform( 1, 1, 1, 1, 255, 255, 255, 255 ), BlendMode.DIFFERENCE );
// Find the intersection.
var intersection:Rectangle = bitmapData.getColorBoundsRect( 0xFFFFFFFF,0xFF00FFFF );
bitmapData.dispose();
// Alter width and positions to compensate for accurracy
if( accurracy != 1 )
{
intersection.x /= accurracy;
intersection.y /= accurracy;
intersection.width /= accurracy;
intersection.height /= accurracy;
}
intersection.x += hitRectangle.x;
intersection.y += hitRectangle.y;
return intersection;
}
protected static function getDrawMatrix( target:DisplayObject, hitRectangle:Rectangle, accurracy:Number ):Matrix
{
var localToGlobal:Point;;
var matrix:Matrix;
var rootConcatenatedMatrix:Matrix = target.root.transform.concatenatedMatrix;
localToGlobal = target.localToGlobal( new Point( ) );
matrix = target.transform.concatenatedMatrix;
matrix.tx = localToGlobal.x - hitRectangle.x;
matrix.ty = localToGlobal.y - hitRectangle.y;
matrix.a = matrix.a / rootConcatenatedMatrix.a;
matrix.d = matrix.d / rootConcatenatedMatrix.d;
if( accurracy != 1 ) matrix.scale( accurracy, accurracy );
return matrix;
}
}
class Functions {
public static function hsbToRgb(h:Number,
s:Number,
b:Number) :uint {
while (h < 0) {
h+=360;
}
while (h >= 360) {
h -= 360;
}
var h2:Number = Math.floor(h/60);
var f:Number = h/60 - h2;
var parFull:Number = 255;
var parEmp:Number = 0;
var parZoka:Number = 255*f;
var parGensho:Number = 255*(1-f);
var red:Number = 0;
var green:Number = 0;
var blue:Number = 0;
switch (h2) {
case 0:
red = parFull; green = parZoka; blue = parEmp;
break;
case 1:
red = parGensho; green = parFull; blue = parEmp;
break;
case 2:
red = parEmp; green = parFull; blue = parZoka;
break;
case 3:
red = parEmp; green = parGensho; blue = parFull;
break;
case 4:
red = parZoka; green = parEmp; blue = parFull;
break;
case 5:
red = parFull; green = parEmp; blue = parGensho;
break;
}
var max:Number = Math.max(Math.max(red, green), blue);
red = max - (max - red)*s;
green = max - (max - green)*s;
blue = max - (max - blue)*s;
red *= b; green *= b; blue *= b;
var ret:uint = int(red) << 16 | int(green) << 8 | int(blue);
return ret;
}
}
import flash.events.Event;
import flash.events.EventDispatcher;
import flash.media.Sound;
import flash.net.URLRequest;
class Sounds extends EventDispatcher
{
private var _prefix:String = "http://assets.wonderfl.net/sounds/event/jam/drop";
private var _ext:String = ".mp3";
private static var _soundNum:int = 10;
private static var _sounds:Vector.<Sound> = new Vector.<Sound>();
private static var obj:Object = new Object();
public function Sounds()
{
/*
* ぶつかったBarの種類で出す音を変える、種類は4種
* 1-1, 1-2, 1-3, 1-4がdrop1~4
* 2-2, 2-3, 2-4, がdrop5~7
* 3-3, 3-4 がdrop8-9
* 4-4 がdrop10
*/
obj["11"] = 9;
obj["12"] = obj["21"] = 8;
obj["13"] = obj["31"] = 7;
obj["14"] = obj["41"] = 6;
obj["22"] = 5;
obj["23"] = obj["32"] = 4;
obj["24"] = obj["42"] = 3;
obj["33"] = 2;
obj["34"] = obj["43"] = 1;
obj["44"] = 0;
load();
}
private function load():void
{
var s:Sound = new Sound();
_sounds.push(s);
s.addEventListener(Event.COMPLETE, complete);
s.load(new URLRequest(_prefix + _soundNum.toString()+ _ext));
}
private function complete(e:Event):void
{
_soundNum -= 1;
if(_soundNum > 0) load();
else dispatchEvent(new Event("loadComplete"));
}
public static function play(i:int):void
{
_sounds[i].play(0,1);
}
public static function plays(s:String):void
{
_sounds[obj[s]].play(0,1);
}
static public function get soundNum():int { return _soundNum; }
}