NDS : NintendoDSをFlashで使う(その5) - Flashと連携
- Posted at: 2008年2月18日 00:25
- Update: 2008年6月11日 13:21

ええかげん書ききらないと。出力側の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;
}
}
動かしてみる。
ボタン入力とかいろいろ加えるとこんな感じ。

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

うん。できたできた。でも通信がなんだか不安定。Wi-Fiのタイマーがちゃんと動いてないのか、メモリ使いすぎてるのか。デバックはちゃんとしないといけないです。
関連エントリ:
- (その1) - 概要とWiFi環境
- (その2) - DSとFlashをMIDIで繋げる
- (その3) - DSの勝手アプリを作るお
- (その4) - Serverの準備
- (その5) - Flashと連携