これも基本的な、ステージ境界での跳ね返りです。
Sprite の座標とステージサイズを比較して、ステージ外にはみ出す場合に移動量を反転するだけです。
private function moveCircle_handler( event:Event ):void
{
for ( var i:Number = 0; i < circleNum; i++ )
{
// 円 移動
circles[i].x += circles[i].vx;
circles[i].y += circles[i].vy;
// 境界判定
checkWalls( circles[i] );
}
}
private function checkWalls( _circle:Circle ):void
{
// 左
if ( _circle.x - _circle.radius < 0 )
{
_circle.x = _circle.radius;
_circle.vx *= -1;
}
// 右
else if ( _circle.x + _circle.radius > stage.stageWidth )
{
_circle.x = stage.stageWidth - _circle.radius;
_circle.vx *= -1;
}
// 上
if ( _circle.y - _circle.radius < 0 )
{
_circle.y = _circle.radius;
_circle.vy *= -1;
}
// 下
else if ( _circle.y + _circle.radius > stage.stageHeight )
{
_circle.y = stage.stageHeight - _circle.radius;
_circle.vy *= -1;
}
}
ムダに Sprite を増やすとこうなります。
これだけだと全く意味がありませんが、動きを統制するとパーティクル表現が可能になります。そのあたりは追い追い・・・
動いている円にドラッグ&ドロップ機能を追加すると、ボールを投げているような表現が可能になります。
このサンプルでは、より"らしさ"を表現するために、擬似重力と跳ね返り係数(?)を設定しています。この値を盛り込むと、前述の移動・跳ね返り処理が若干変更されます。
private var gravity:Number = 0.5; // 重力
private var bounce:Number = -0.8; // 跳ね返り係数
private function moveCircle_handler( event:Event ):void
{
var _circle:Circle = event.target as Circle;
// 円 移動
_circle.vy += gravity;
_circle.x += _circle.vx;
_circle.y += _circle.vy;
// 境界判定
checkWalls( _circle );
}
private function checkWalls( _circle:Circle ):void
{
// 左
if ( _circle.x - _circle.radius < 0 )
{
_circle.x = _circle.radius;
_circle.vx *= bounce;
}
// 右
else if ( _circle.x + _circle.radius > stage.stageWidth )
{
_circle.x = stage.stageWidth - _circle.radius;
_circle.vx *= bounce;
}
// 上
if ( _circle.y - _circle.radius < 0 )
{
_circle.y = _circle.radius;
_circle.vy *= bounce;
}
// 下
else if ( _circle.y + _circle.radius > stage.stageHeight )
{
_circle.y = stage.stageHeight - _circle.radius;
_circle.vy *= bounce;
}
}
で、メインのドラッグ&ドロップ処理。
AS3 では onReleaseOutside イベントハンドラがなくなったので、対象 Sprite のMouseEvent.MOUSE_DOWN 発生時に、stage に対して MouseEvent.MOUSE_UP を追加してドラッグ&ドロップを実現します。
/**
* ドラッグ&ドロップ サンプル
*/
_sprite.addEventListener( MouseEvent.MOUSE_DOWN, mousedown_handler );
private function mousedown_handler( event:MouseEvent ):void
{
// ドラッグ 開始
stage.addEventListener( MouseEvent.MOUSE_UP, mouseup_handler );
_sprite.startDrag();
}
private function mouseup_handler( event:MouseEvent ):void
{
// ドラッグ 終了
_sprite.stopDrag();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseup_handler );
}
ボールを投げる表現のために、ドラッグ中は前フレームの Sprite 座標を一時的に保存し、現在の座標との差分を取ることでドロップ時の移動量を設定します。
そのあたりも含めたドラッグ&ドロップ処理はこんな感じになります。
private function mousedownCircle_handler( event:MouseEvent ):void
{
var _circle:Circle = event.target as Circle;
// 円位置 保存
_circle.tx = _circle.x;
_circle.ty = _circle.y;
// 円 移動停止
_circle.removeEventListener( Event.ENTER_FRAME, moveCircle_handler );
// ドラッグ 開始
_circle.addEventListener( Event.ENTER_FRAME, trackVelocity );
stage.addEventListener( MouseEvent.MOUSE_UP, mouseupCircle_handler );
_circle.startDrag();
}
private function mouseupCircle_handler( event:MouseEvent ):void
{
var _circle:Circle = event.target as Circle;
// ドラッグ 終了
_circle.stopDrag();
stage.removeEventListener( MouseEvent.MOUSE_UP, mouseupCircle_handler );
_circle.removeEventListener( Event.ENTER_FRAME, trackVelocity );
// 円 移動再開
_circle.addEventListener( Event.ENTER_FRAME, moveCircle_handler );
}
private function trackVelocity( event:Event ):void
{
var _circle:Circle = event.target as Circle;
// 移動量 算出
_circle.vx = _circle.x - _circle.tx;
_circle.vy = _circle.y - _circle.ty;
// 円位置 保存
_circle.tx = _circle.x;
_circle.ty = _circle.y;
}
今回、イベントハンドラ内でループ処理するのではなく、各 Sprite にイベント登録しています。Event.target / MouseEvent.target を取得しているのはそのためです。
あとは円同士の衝突処理を追加すれば、ってトコでしょうか?
Trackbacks (0)
http://www.nloc-web.com/mt/mt-tb.cgi/27
Comment(1)
Commented by portable air conditioning (2012年1月 7日 00:29)
But it is this: in the event you and I could enumerate up in a year those on whom our sights will rest and understand the situations of their lives, some of us can be moved to conclude that nine-tenths of that range could have had a finer everyday life as Americans than they would have in their spheres as Englishmen.