Home > Flash > NDS : NintendoDSをFlashで使う(その5) - Flashと連携

NDS : NintendoDSをFlashで使う(その5) - Flashと連携

  • Posted at: 2008年2月18日 00:25
  • Update: 2008年6月11日 13:21

080218_paintapp1.gif

ええかげん書ききらないと。出力側のFlashも作る。動作の動画だけ撮って、できた!ってことでいいかなぁ。。 えーと。。ソース嫁。

このエントリは書きかけの内容が含まれます。気がむいたら随時更新されます。

実装するよ

Serverとの通信

/**
 * 初期設定
 */
public private var socket:Socket;


// 通信の準備
publib function init():void {

    socket = new Socket();
    // ボタンは配置しといて
    buttonConnect.addEventListener(MouseEvent.CLICK, buttonConnect_click);

    // 通信状態に対するイベント

    // データを受信した時
    socket.addEventListener(ProgressEvent.SOCKET_DATA, onRecvData);
    // 接続できた時
    socket.addEventListener(Event.CONNECT, function():void {
        trace("connected!");
        buttonConnect.label = "DisConnect?";
    });
    // サーバー側から切断された時
    socket.addEventListener(Event.CLOSE, function():void {
        trace("closed from server");
        buttonConnect.label = "Connect!";
    });
}

/**
 * 通信処理
 */

// 接続する/切断する
private function buttonConnect_click(e:Event):void {
    if(!socket.connected){ // 接続していない時
        trace("connecting...");
        socket.connect(talk.labelHost.text, new int(talk.labelPort.text)); // 接続する
    }
    else{ // 接続している時
        socket.close(); // 閉じる
        debug("closed");
        buttonConnect.label = "Connect!";
    }
}

// データを受信した時の処理
private function onRecvData(e:Event):void{
    if(!socket.connected) return;
    if(socket.bytesAvailable > 0){
        var bytes:ByteArray = new ByteArray();
        socket.readBytes(bytes);
        var recvStr:Object = JSON.decode(bytes.toString()); // JSON形式のデータをパース

        DS2Action1(recvStr.p, recvStr.x, recvStr.y); // 何ぞ処理
    }
}

ソケット通信でServerに繋ぐよ。通信周りはshokaiさんのソケット通信のサンプルを拝借しました(元の記事はわかんなくなった。。)。Serverとテキストをやりとりするだけのもんです。繋いだらデータが来るのをずっと待ちます。

var recvStr:Object = JSON.decode(bytes.toString());
trace(recvStr.p, recvStr.x, recvStr.y,recvStr.m);

JSON形式のデータをAS3でパースするにはas3corelibを使います。Objectにしてくれます。べんりだねー。

ペン入力を反映

// ペン入力を反映
private function DS2Action1(penDown:Number, drawX:Number, drawY:Number):void {

    // ペンが接触した座標に点を移動
    if (penDown == 1) {
        g.moveTo(drawX, drawY);
    // ペンが降りている間は点間の線を描画
    } else if (penDown == 2) {
        g.lineTo(drawX, drawY);
    }
}

ペンの状態と、X、Yが送られてくるので、何か反映させます。
とりあえず線でも引いてみたよ。

できたもの

package {
  import com.adobe.serialization.json.JSON;
  
  import fl.controls.Button;
  
  import flash.display.Bitmap;
  import flash.display.BitmapData;
  import flash.display.BlendMode;
  import flash.display.Graphics;
  import flash.display.MovieClip;
  import flash.display.PixelSnapping;
  import flash.display.Sprite;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.events.ProgressEvent;
  import flash.geom.Matrix;
  import flash.net.Socket;
  import flash.utils.ByteArray;
  
  [SWF(width='800',height='500',backgroundColor='0x000000',frameRate='60')]

  public class Paint07 extends Sprite
  {
    private var _canvas:BitmapData;
    private var _sketch:Sprite;
    private var _stage2:BitmapData;
    private var _glow:BitmapData;
    private var _particles:Array;
    private var _pen:Graphics;
    private var _penSizeB:Boolean;
    private var _penSize:Number;
    private var _penColor:uint;
    private var _btnSpark:Button;
    private var penDown:Boolean = false;
    private var penState:Boolean = false;
    private var socket:Socket;
    private var talk:MovieClip;
    
    public function Paint07()
    {
      setCanvas();
    }
    
    /**
     * 初期設定
     */
    private function setCanvas():void {
      this._canvas = new BitmapData(640, 480, false, 0x0);
      this.addChild(new Bitmap(this._canvas)) as  Bitmap;
      
      this._glow = new BitmapData(640/4, 480/4, false, 0x0);
      var bm:Bitmap = this.addChild(new Bitmap(this._glow, PixelSnapping.NEVER, true)) as Bitmap;
      bm.scaleX = bm.scaleY = 4;
      bm.blendMode = BlendMode.ADD;
      
      this._particles = [];

      this._sketch = new Sprite();
      this.addChild(_sketch);
      
      setPen();
      
      addEventListener(Event.ENTER_FRAME, loop);
            stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownDraw);
            stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpDraw);
            stage.addEventListener(Event.MOUSE_LEAVE,onMouseLeaveDraw);

      // 起爆ボタン
      _btnSpark = new Button();
      _btnSpark.label = "SMAAAASH!!";
      _btnSpark.x = 200;
      _btnSpark.y = 400;
      addChild(_btnSpark);
      _btnSpark.addEventListener(MouseEvent.MOUSE_DOWN, _onBtnDown);
      
      // 通信パネル
      talk = new ChatObj();
      talk.x = 500;
      talk.y = 30;
      addChild(talk);

      // 通信の準備
      socket = new Socket();

      talk.buttonConnect.addEventListener(MouseEvent.CLICK, buttonConnect_click);
      talk.buttonSend.addEventListener(MouseEvent.CLICK, sendText);

      socket.addEventListener(ProgressEvent.SOCKET_DATA, onRecvData); // データ受信した時
      socket.addEventListener(Event.CONNECT, function():void { // 接続できた時
        debug("connected!");
        talk.buttonConnect.label = "DisConnect?";
      });
      socket.addEventListener(Event.CLOSE, function():void { // サーバー側から閉じられた時
        debug("closed from server");
        talk.buttonConnect.label = "Connect!";
      });
    }
    
    private function _onBtnDown(e:Event):void {
      drawBitmap();
    }
    
    // 描いた画像をスキャンしてパーティクルを生成
    private function drawBitmap():void
    {
      _canvas.draw(_sketch);
      _sketch.graphics.clear();
      var cx:Number = this._canvas.width / 2;
      var cy:Number = this._canvas.height / 2;
      var a:Number;
      var v:Number;
      var c:uint;
      for (var ey:Number = 0; ey < _canvas.height; ey += 2) {
        for (var ex:Number = 0; ex < _canvas.width; ex += 2) {
          a = Math.atan2(ey - cy, ex - cy) + Math.random() * Math.PI * 0.1; // 中心から外に向かって飛ばしたいので、その角度を計算
          v = Math.random() * 2 + 0.5;
          c = this._canvas.getPixel(ex, ey);
          if( c > 0 ) {
            this.emitParticle( // パーティクルを生成
              ex + Math.random() * 2, ey + Math.random() * 2,
              Math.random() + 0.5,
              c,
              Math.cos(a) * v, Math.sin(a) * v);
          }
        }
      }
      this.addEventListener(Event.ENTER_FRAME, this.update); // パーティクルを動かす
    }
    
    
    // パーティクルを配列に登録
    public function emitParticle(ex:Number, ey:Number, s:Number = 1, c:int = 0xffffff, vx:Number = 0, vy:Number = 0):void 
    {
      var p:Paticle = new Paticle();
      p.x = ex; // xの位置
      p.y = ey; // yの位置
      p.vx = vx; // x方向に動く量
      p.vy = vy; // y方向に動く量
      p.s = 10; // スピード「
      p.c = c; // 色
      this._particles.push(p); // 保存
    }
    
    
    // パーティクルを動かす
    public function update(e:Event):void 
    {
      this._canvas.lock(); // いっぱい setPixel するときは必ず lock しよう
      this._canvas.fillRect(this._canvas.rect, 0x0); // カンバスをクリア
      var n:int = this._particles.length;
      if (n == 0) {
          this._canvas.unlock();
          this.removeEventListener(Event.ENTER_FRAME, this.update);
      }
      while (n--) {
        var p:Paticle = this._particles[n];
        p.vy += 0.02 * p.s; // 重力を加える
        p.vx *= 0.99; // 空気抵抗
        p.vy *= 0.99; // y 方向にも
        p.x += p.vx; // 動かす
        p.y += p.vy;
        this._canvas.setPixel(p.x, p.y, p.c); // パーティクルを1つ描く
        if (p.y > this.stage.stageHeight) { // もし画面外にでちゃったら
          this._particles.splice(n, 1); // とりのぞく
        }
      }
      this._canvas.unlock(); // lock したやつは必ず unlock
      this._glow.draw(this._canvas, new Matrix(0.25, 0, 0, 0.25)); // キラキラを描く
    }
    
    
    
    /**
     * ペン入力処理
     */
    
    // ペン入力を待つ
    private function loop(e:Event):void 
    {
      if (penDown) draw();
        }
        
    // ペン入力描画
    private function draw():void 
    {
      if (this._penSize < 8) { this._penSizeB = false }
      if (this._penSize > 30) { this._penSizeB = true }
      this._penSize -= (this._penSizeB) ? 2 : -1;
      _pen.lineStyle(this._penSize,this._penColor,1,false,"normal","ROUND","ROOUND",3);
      _pen.lineTo(mouseX, mouseY);
      
    }
    
    private function drawDS(penDown:Number, drawX:Number, drawY:Number):void {
      if (penDown == 1) {
        setPen();
        _pen.moveTo(drawX*2, drawY*2);
      } else if (penDown == 2)  { 
        if (this._penSize < 8) { this._penSizeB = false }
        if (this._penSize > 30) { this._penSizeB = true }
        this._penSize -= (this._penSizeB) ? 2 : -1;
        _pen.lineStyle(this._penSize,this._penColor,1,false,"normal","ROUND","ROOUND",3);
        _pen.lineTo(drawX*2, drawY*2);
      }
    }
    
    private function onMouseDownDraw(e:Event):void {
      penDown = true;
      setPen();
      _pen.moveTo(mouseX,mouseY);
    }
    
    private function onMouseUpDraw(e:Event):void {
      penDown = false;
    }

    private function onMouseLeaveDraw(e:Event):void {
      penDown = false;
    }
    
    // ペンの設定
    private function setPen():void {
      this._penSizeB = true;
      this._penSize = 30;
      this._penColor = Math.random()*0xFFFFFF;
      this._pen = _sketch.graphics;
      this._pen.lineStyle(this._penSize,this._penColor,1,false,"normal","ROUND","ROOUND",3);
    }
    
    
    
    /**
     * 通信処理
     */
    
    private function buttonConnect_click(e:Event):void {
      if(!socket.connected){ // 接続していない時
        debug("connecting...");
        socket.connect(talk.labelHost.text, new int(talk.labelPort.text)); // 接続する
      }
      else{ // 接続している時
        socket.close(); // 閉じる
        debug("closed");
        talk.buttonConnect.label = "Connect!";
      }
    }
    
    private function sendText(e:Event):void{
      if(!socket.connected) return;
      var bytes:ByteArray = new ByteArray();
      bytes.writeUTFBytes(talk.labelSend.text);
      socket.writeBytes(bytes);
      socket.flush();
      debug("送信 :"+bytes.toString());
    }
    
    private function onRecvData(e:Event):void{
      if(!socket.connected) return;
      if(socket.bytesAvailable > 0){
        var bytes:ByteArray = new ByteArray();
        socket.readBytes(bytes);
        var recvStr:Object = JSON.decode(bytes.toString());
        //draw(recvStr.x, recvStr.y);
        
        debug("受信: p:"+recvStr.pp+" x:"+recvStr.px+" y:"+recvStr.py);
        if (recvStr.bb == 1) drawBitmap();
        drawDS(recvStr.pp, recvStr.px, recvStr.py);
      }
    }
    
    private function debug(message:String):void{
      trace("debug: "+message);
      talk.textAreaLog.text = message + "\n" + talk.textAreaLog.text;
    }
  }
}


/**
 * パーティクルの定義
 */
class Paticle {
  public var x:Number;
  public var y:Number;
  public var vx:Number;
  public var vy:Number;
  public var s:Number;
  public var c:int;
  
  public function Paticle() 
  {
    this.x = 0;
    this.y = 0;
    this.vx = 0;
    this.vy = 0;
    this.s = 1;
    this.c = 0xffffff;
  }
}

動かしてみる。

ボタン入力とかいろいろ加えるとこんな感じ。

080218_paintapp1.gif

Bボタンを押すと爆発します。てら子11のあれを拝借しました。

080218_paintapp2.gif

うん。できたできた。でも通信がなんだか不安定。Wi-Fiのタイマーがちゃんと動いてないのか、メモリ使いすぎてるのか。デバックはちゃんとしないといけないです。

関連エントリ:

関連タグ: AS3, Flash, NintendoDS

Comments:0

Comment Form

Home > Flash > NDS : NintendoDSをFlashで使う(その5) - Flashと連携

Auther
hoehoe3 : おおさか方面でWebとかやってますよ。
What am I doing...
    Search
    Feeds

    Return to page top