Murayama blog.

AIの民主化。

宇宙船


3本目。ここで5章おしまい。5章早い。5章ナイス。


5章の途中の加速度のところもコーディングしてみたんだけど、
たぶん、誰もサンプルを見たがらないと思ったので、省略。


なんで、5章の最後のサンプルに挑戦した。



宇宙船。



そう、宇宙船。シャトルっぽいやつな。


この本の前半のハイライトになるんじゃないかと思う。


で、早速実行結果。まずクリックしてね。
左キー、右キーで宇宙船の角度が変わります。そんで上キーで噴射と。
感動した?俺は感動したぜ。


そんでコードです。

package
{
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.KeyboardEvent;
  import flash.ui.Keyboard;
  
  public class ShipSim extends Sprite
  {
    private var ship:Ship;
    private var vr:Number = 0;
    private var thrust:Number = 0;
    private var vx:Number = 0;
    private var vy:Number = 0;
    
    public function ShipSim()
    {
      init();
    }
    
    private function init():void{
      ship = new Ship();
      addChild(ship);
      ship.x = 100;
      ship.y = 300;
      
      addEventListener(Event.ENTER_FRAME, onEnterFrame);
      stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown);
      stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
      
    }
  
    private function onKeyDown(evt:KeyboardEvent):void
    {
      if(evt.keyCode == Keyboard.LEFT){
        vr = -5;
      }else if(evt.keyCode == Keyboard.RIGHT){
        vr = 5;
      }else if(evt.keyCode == Keyboard.UP){
        thrust = 0.2;
        ship.draw(true);
      }
    }
 
    private function onKeyUp(evt:KeyboardEvent):void
    {
      vr = 0;
      thrust = 0;
      ship.draw(false);
    }
    
    private function onEnterFrame(evt:Event):void
    {
      ship.rotation += vr;
      var radians:Number = ship.rotation * Math.PI / 180;
      var ax:Number = Math.cos(radians) * thrust;
      var ay:Number = Math.sin(radians) * thrust;
      
      vx += ax;
      vy += ay;
      
      ship.x += vx;  
      ship.y += vy;
    }
 
  }
}
 
import flash.display.Sprite;
  
class Ship extends Sprite
{
  public function Ship()
  {
    draw(false);
  }
  
  public function draw(showFlame:Boolean):void{
    graphics.clear();
    graphics.lineStyle(1, 0xFFFFFF);
    graphics.moveTo(10, 0);
    graphics.lineTo(-10, 10);
    graphics.lineTo(-5, 0);
    graphics.lineTo(-10, -10);
    graphics.lineTo(10, 0);
    
    if(showFlame){
      graphics.beginFill(0x990000);
      graphics.lineStyle(1, 0xFF0000);
      graphics.moveTo(-7.5, -5);
      graphics.lineTo(-15, 0);
      graphics.lineTo(-7.5, 5);
      graphics.endFill();
    }
  }
}


まず、キーを押したときのイベントハンドラ
左キーを押したときはvr(角度に影響する変数)に-5が設定される。
右キーを押したときは+5。
上キーを押したときはthrust(加速度みたいなの)に0.2をセット。これで速度が生まれる。
ついでに噴射部分を描画している。

    private function onKeyDown(evt:KeyboardEvent):void
    {
      if(evt.keyCode == Keyboard.LEFT){
        vr = -5;
      }else if(evt.keyCode == Keyboard.RIGHT){
        vr = 5;
      }else if(evt.keyCode == Keyboard.UP){
        thrust = 0.2;
        ship.draw(true);
      }
    }


次にキーを離したときのイベントハンドラ
変数をデフォルトに戻してる、と。

    private function onKeyUp(evt:KeyboardEvent):void
    {
      vr = 0;
      thrust = 0;
      ship.draw(false);
    }


最後にEvent.ENTER_FRAMEイベント。ここでアニメーションっぽくなる。
宇宙船の表示角度を調整して、
その表示角度をラジアンに変換して、
Math.cos、Math.sinで縦、横成分にスピードを分解してる。
あとは加速度を速度に加算してる。

    private function onEnterFrame(evt:Event):void
    {
      ship.rotation += vr;
      var radians:Number = ship.rotation * Math.PI / 180;
      var ax:Number = Math.cos(radians) * thrust;
      var ay:Number = Math.sin(radians) * thrust;
      
      vx += ax;
      vy += ay;
      
      ship.x += vx;  
      ship.y += vy;
    }


説明は以上。


こんな短いコードでちょっとしたゲームっぽいのが作れるんすね。
こういうのが簡単に作れるなんて良い時代ですね。


てことで、みんなASやろう。