Murayama blog.

AIの民主化。

壁との跳ね返り

本日のラスト。跳ね返り。


あー、サンプルとしては、一番地味かも。


そいでコード。
実は、大事なポイントがある。


横方向のスピードvxがあるとして、20という数値が格納されている場合、
跳ね返ると20を-20に変換してやると良い。
普通の発想でもここまでは辿り着けると思う。

// スピードの逆転
vx *= -1


このパラメータを-1ではなくて、-0.7とかにすると、
跳ね返るごとに減速させることができる。


でもこれだけじゃちゃんと動かない。
アニメーションは、言うなれば、紙芝居を超高速にしたようなもの。
例えば、ボールと壁までの距離が93センチだとして、
1コマあたり、10センチ壁に近寄るとしたら、
10コマ目では7センチめり込んでしまう。
Flashではそういうことが起きてしまう。


そのような場合を考慮して、壁にぶつかったら(範囲外に出てしまったら)、
ボールを壁際に再配置する必要がある。

// これが肝。壁際に再配置する。
ball.x = right - ball.radious;


ちなみにrightは範囲の右端の値。
radiousは半径。


詳しくはこちら。

package
{
  import flash.display.Sprite;
  import flash.display.StageAlign;
  import flash.display.StageScaleMode;
  import flash.events.Event;
  
  public class Bouncing extends Sprite
  {
    private var ball:Ball;
    private var vx:Number;
    private var vy:Number;
    private var bounce:Number = -0.7
    
    public function Bouncing()
    {
      init();
    }
    
    private function init():void
    {
      stage.scaleMode = StageScaleMode.NO_SCALE;
      stage.align = StageAlign.TOP_LEFT;
      ball = new Ball();
      ball.x = stage.stageWidth / 2;
      ball.y = stage.stageHeight / 2;
      
      vx = Math.random() * 40 - 20;
      vy = Math.random() * 40 - 20;
      
      addChild(ball);
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
    }
 
    private function onEnterFrame(evt:Event):void
    {
      ball.x += vx;
      ball.y += vy;
      
      var left:Number = 0;
      var right:Number = stage.stageWidth
      var top:Number = 0;
      var bottom:Number = stage.stageHeight;
      
      if(ball.x + ball.radious > right){
        // これが肝。壁際に再配置する。
        ball.x = right - ball.radious;
        // スピードの逆転
        vx *= bounce;
      }else if(ball.x - ball.radious < left){
        // これが肝。壁際に再配置する。
        ball.x = left + ball.radious;
        // スピードの逆転        
        vx *= bounce;
      }
 
      if(ball.y + ball.radious > bottom){
        // これが肝。壁際に再配置する。        
        ball.y = bottom - ball.radious;
        // スピードの逆転
        vy *= bounce;
      }else if(ball.y - ball.radious < top){
        // これが肝。壁際に再配置する。        
        ball.y = top + ball.radious;
        // スピードの逆転
        vy *= bounce;
      }
    }
  }
}
 
import flash.display.Sprite;
 
class Ball extends Sprite
{
  public var radious:Number;
  public var color:uint;
  public var vx:Number;
  public var vy:Number;
 
  public function Ball(radius:Number = 40, color:uint = 0xff0000)
  {
    this.radious = radius;
    this.color = color;
    init();
  }
 
  private function init():void{
    graphics.beginFill(color);
    graphics.drawCircle(0, 0, radious);
    graphics.endFill();
  }
}


おしまい。