2009年12月27日日曜日

今更DCプレイ環境を構築する。(VGAで

SEGA最新の家庭用ゲーム機「Dreamcast」をPCの液晶モニタでプレイしてみました。

まず必要なもの。
1. DC本体

私は既に1台所有してますが、ハードオフでケーブル、コントローラーなしの本体のみを500円で買ってきました。

2. 液晶モニタ
D-sub(15pin)とかVGA端子って表記があるものなら何でもいいかと。
付いてないの見たことないですけど。
それと、液晶ディスプレイがワイド(16:9もしくは16:10)の場合は、4:3での表示に対応したものが望ましいです。
ちなみに自分はLGのW2453Vってのを購入しました。

LGって韓国メーカーなので嫌う人もいますけど、安くて十分な性能があると思ってます。
お金があるならNANAOの液晶が欲しいです・・・
NANAOディスプレイ

3. DC VGA BOX
DCをVGAで出力するための周辺機器です。
SEGA純正のは現在高いらしいので、自分はAmazonで純正ではないDC VGAボックス
を購入しました。
VGAケーブルは付属してないので別途必要になります。PC持ってるなら普通はあります。
VGAケーブル

4. スピーカーもしくはヘッドフォン
上記の3つだと音が出ないので必要です。
モニタにスピーカーがついていて、そこから出力する場合は、VGAボックスと繋ぐケーブルが必要になります。

というわけで以下プレイ画像など。
ちなみに、全てのゲームがVGA出力対応というわけではないようです。
参照:DCソフトVGA出力対応表

キャプチャする環境がないので、携帯電話のカメラで撮った低画質画像です。
メニュー画面
秀瑛さんその1
秀瑛さんその2
綺麗どすなぁ。
ドブ板。これは一章ではなくWhat'sシェンムーのです。
ジャギーが目立つ気がします。
それなりに有名なサクラ大戦3のOP。
サクラ3はVGAでプレイすると綺麗な感じがします。
私はXbox360もVGAでプレイしていて、いちいちディスプレイの裏に行って付け替えるのが面倒なので、一回余計にケーブル噛ませてます。
手元で付け替えられるので便利。
上の灰色のが360VGA。

所感?
基本VGAの方が綺麗に映ると思うけど、このころ作られたゲームは、液晶ディスプレイを意識して作られたものではないと思うので、ブラウン管の方がいいかもしれません。
でもやっぱブラウン管でかいので、液晶でできた方がお手軽だよね。
というわけで、みんなもDCプレイしようよ!

2009年12月25日金曜日

げおやばい

先日(15日)たまたま見たブログの記事を読んで衝撃を受けた。それが下の記事。
ゲオのレトロゲー100円セールで色々買ってきました。 - げーまー的ダッシュ

          _,,,,,         ―― |_| |_| > 
         /川川ハ        | l ̄ | |    ノ   メ 
        ///川川lト、      |_| 匚. |   \   シ 
       (ゞ川从川/_,―' ̄ヽ    | |   ノ    食 
     __>ームヾ ̄(  _-、 |  |_|   \   っ 
    /   |       y-  ノ_|       <   て 
    '-,,_ |        |  ムkノ) l_ll_l ,-,    )  る 
       "|        |       // /   場 
        |         |     匚/   ̄ヽ   合 
       |     ___ |              ノ   じ 
       r―――"    ‐|  \\     \   ゃ 
       |          /     \\   <   ね 
       人     乂  /       \\ ノ   え 
ニヽ   /  |    ヾ /    ___―― ̄    っ 
__\ /  /|     l         ̄ ̄―――__  ! 
     / /  \\  ヾ                 ν、 
 ̄弋二/ ̄|   \\  \   \\            V⌒ 
 ̄ ̄\\\ ̄\  \\  \    \\ 
 ̄ ̄ ̄\\\ ̄|   "―_从从     \\ 
 ̄ ̄ ̄ ̄\\\ ̄\    |   ζ      \\ 
 ̄ ̄ ̄ ̄ ̄\\\ ̄|    ヾ  \\       \\ 
 ̄ ̄ ̄ ̄ ̄ ̄\\\\ ̄フ \\ \\
というわけで自分も市内のGEO2店舗に寄り、大量購入してきた。
その成果がこれ。
SSとDCのソフトしか購入してません。

・・・積みゲーリスト更新しなきゃな。。。

2009年12月20日日曜日

久しぶりにまたメモ

最近忙しいし、特に更新することもないのでブログは放置気味です。

窓の杜 - 【REVIEW】IE6/7/8でWebサイトの見栄えを見比べ「Microsoft Expression Web SuperPreview」
以前IETester紹介しましたけど、こっちのほうがいいかも。重ねて表示もできるし。日本語はないみたいだけど特別困らない。
正直MSがこんなソフトだしてくるとは思わんかった。

ギャルゲーブログ airの作画があまりにもひどいので俺が書き直してやったww

PSP版クイーンズブレイド 「セクシーシーンでもご安心!ママキタボタン」
なにこの神機能。ういんどみるのメモ帳偽装を思い出す。

Flex Builder 3 でブラウザを開かずにデバッグする方法 - hiru日記
自分のノートPCのFlexBuilderはなぜがブラウザだと「デバッガに接続できませんでした」ってエラーがでるので、この方法でデバッグしてます。

めざましTech - Canvas と SVG:それぞれをいつ使ったら良いでしょう?
HTML5のCanvasとSVGについてです。基本JavaScriptを使うんですね。

cssとHTMLのみで擬似的な3D表示を実現するCSS 3D Meninas - かちびと.net
無駄にすごい。実用性なさそう。

2009年11月29日日曜日

メモです。

ソーシャルブックマークでも使えって突っ込みは無しの方向で・・・

『龍が如く4 伝説を継ぐもの』は神室町がより立体的でリアルに
いいぞもっとやれ。こういう街を歩けるゲームって好きだったりします。
シェンムーとかアサクリとか。RPGは新しい街に行くのが楽しい。

「潮風の消える海に」舞台探訪
おーすごい。ついホームから飛び降りたくなる。実在する舞台があったんですね。
自分もたまに自転車でふらーっと出かけますが、こんな風に目的を持って出かけるのもいいかもしれない。

「fonthack.jp | フリーで使える日本語フォント」に使われている日本語フリーフォントをまとめてみた(漢字も使える)

[CSS]スタイルシートで実装する、アイデア溢れる画像ギャラリー
いつものことながらCSSplayはすごいなあ。

【86枚】PSPの壁紙ください
PSPは面倒なので壁紙使ってないですがメモ。

Valveってどんな所だろう?素敵なオフィス写真が公開、バールのような物が凄い!
ちょっと気持ち悪い。360でOrange Box一通りやりましたが、変な生物みたいなの気持ち悪い。ああいうの苦手。

[Flex]Buttonのiconを動的に変える

ダウンロードして使えるボタン素材いろいろ
一風変わったボタンも即席で作れてしまうボタン作成素材集
ボタン。

高品質なテクスチャをダウンロード&登録できるサイト -Textur.es
テクスチャ。

Fichier:Medico peste.jpg
以前NHKの世界ふれあい街歩きのエディンバラ(多分)で見たんだけど、ペストの医者らしい。名前は忘れた。
なんかシャイニングフォース3の敵教団ザコっぽいのでメモ。

そういえばXPとかで「¥」を連続で押すと半角に変わる理由、知ってる人いたら教えてください。

2009年11月23日月曜日

[Away3D]UV座標とれた。

最近投稿のタイトルが適当です。

にわからないって言ってたUV座標の取り方がわかりました。
わからないって言ってたのが馬鹿みたいに簡単にできました。

こんなん。
そういえばちょっと前から作ったものをGoogle App Engineのほうに上げるようにしたんですけど問題なく見られますかね?あまり動作確認とかしてないので・・・

ソースコードはこんな感じ。
package {
 import away3d.cameras.HoverCamera3D;
 import away3d.containers.ObjectContainer3D;
 import away3d.containers.Scene3D;
 import away3d.containers.View3D;
 import away3d.core.utils.Cast;
 import away3d.events.MouseEvent3D;
 import away3d.lights.DirectionalLight3D;
 import away3d.loaders.Collada;
 import away3d.materials.MovieMaterial;

 import flash.display.Bitmap;
 import flash.display.MovieClip;
 import flash.display.Sprite;
 import flash.display.StageQuality;
 import flash.events.Event;
 import flash.events.MouseEvent;

 public class away3 extends Sprite {
  private var scene:Scene3D;
  private var camera:HoverCamera3D;
  private var view:View3D;

  [Embed(source="mate.png")]
  public var materialImage:Class;
  [Embed(source="test.dae", mimeType="application/octet-stream")]
  public var colladaData:Class;

  private var material:MovieMaterial;
  private var collada:Collada;
  private var model:ObjectContainer3D;
  private var light:DirectionalLight3D;
  private var mc:MovieClip;

  private var isMouseDown:Boolean;
  //navigation variables
  private var lastPanAngle:Number;
  private var lastTiltAngle:Number;
  private var lastMouseX:Number;
  private var lastMouseY:Number;


  public function away3() {
   mc = new MovieClip();
   mc.base = mc.addChild(new Bitmap(Cast.bitmap(materialImage)));
   mc.surface = mc.addChild(new Sprite());
   initEngine();
   initLights();
   initMaterials();
   initObjects();
   initListeners();

   isMouseDown = false;
  }

  /**
   * Initialise the engine
   */
  private function initEngine():void {
   scene = new Scene3D();
   camera = new HoverCamera3D();
   camera.zoom = 1;
   camera.focus = 100;
   camera.distance = 50;
   camera.steps = 10;
   camera.targetpanangle = camera.panangle = 0;
   camera.targettiltangle = camera.tiltangle = 10;

   view = new View3D({camera: camera, scene: scene});
   addChild(view);

   stage.quality = StageQuality.HIGH;
  }

  /**
   * Initialise the lights
   */
  private function initLights():void {
   //light = new DirectionalLight3D({color:0xFFFFFF, ambient:0.25, diffuse:0.75, specular:0.9, x:40000, y:40000, z:40000});
   light = new DirectionalLight3D();
   light.color = 0xFFFFFF;
   light.ambient = 0.25;
   light.diffuse = 0.75;
   light.specular = 0.9;
   light.x = 0;
   light.y = 1000;
   light.z = 1000;

   scene.addChild(light);
  }

  /**
   * Initialise the materials
   */
  private function initMaterials():void {
   material = new MovieMaterial(mc);
   material.interactive = true;
  }

  /**
   * Initialise the scene objects
   */
  private function initObjects():void {
   //model1 = Collada.parse(Charmesh, {scaling:10, material:material, mouseEnabled:false});
   collada = new Collada();
   //collada.scaling = 0.1;
   model = collada.parse(colladaData) as ObjectContainer3D;
   model.materialLibrary.getMaterial("mat1").material = material;
   model.mouseEnabled = true;
   model.addOnMouseDown(onModelMouseDown);
   scene.addChild(model);
  }

  /**
   * Initialise the listeners
   */
  private function initListeners():void {
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
   stage.addEventListener(Event.RESIZE, onResize);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
   stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
   stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
   onResize();
  }

  /**
   * Navigation and render loop
   */
  private function onEnterFrame(event:Event):void {
   //update the camera position
   if(isMouseDown) {
    camera.targetpanangle = 0.35 * (stage.mouseX - lastMouseX) + lastPanAngle;
    camera.targettiltangle = 0.35 * (stage.mouseY - lastMouseY) + lastTiltAngle;
   }
   camera.hover();

   //render scene
   view.render();
  }

  private function onModelMouseDown(e:MouseEvent3D):void {
   mc.surface.graphics.beginFill(0xFFFFFF);
   mc.surface.graphics.drawCircle(e.uv.u * mc.width, mc.height - (e.uv.v * mc.height), 100);
   mc.surface.graphics.endFill();
  }

  private function onMouseDown(event:MouseEvent):void {
   lastPanAngle = camera.targetpanangle;
   lastTiltAngle = camera.targettiltangle;
   lastMouseX = stage.mouseX;
   lastMouseY = stage.mouseY;
   isMouseDown = true;
   stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }

  private function onMouseUp(event:MouseEvent):void {
   isMouseDown = false;
   stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }

  private function onMouseWheel(e:MouseEvent):void {
   camera.distance -= e.delta * 1.5;
   if(camera.distance < 0) {
    camera.distance = 0;
   } else if(camera.distance > 70) {
    camera.distance = 70;
   }
  }

  private function onStageMouseLeave(event:Event):void {
   isMouseDown = false;
   stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }

  /**
   * stage listener for resize events
   */
  private function onResize(event:Event = null):void {
   view.x = stage.stageWidth / 2;
   view.y = stage.stageHeight / 2;
  }
 }
}

UV座標は、
material = new MovieMaterial(mc);
material.interactive = true;
MovieMaterialを使ってinteractiveをtrueにして、
private function onModelMouseDown(e:MouseEvent3D):void {
 mc.surface.graphics.beginFill(0xFFFFFF);
 mc.surface.graphics.drawCircle(e.uv.u * mc.width, mc.height - (e.uv.v * mc.height), 100);
 mc.surface.graphics.endFill();
}
MouseEvent3Dのuvで取得できます。
Y座標は「e.uv.v * mc.height」かと思ったんですが、「mc.height - (e.uv.v * mc.height)」でした。
わかりづらいね。

参考サイト
blog.tartiflop » Blog Archive » First steps in Away3D : Part 3 - Texture mapping
Tutorials (category) > Tutorials > Flash Magazine

カメラの動きは相変わらずよくわからない。

2009年11月21日土曜日

[Away3D]ライトとか。

Away3DでCollada(DAE)オブジェクトにお絵かき、みたいなことをやろうとしたけどやり方がわからなかったので違うものを作ってみました。
Away3Dでクリックした座標をどうやってとってくるのかがよくわからないんだよなー。Pv3DだとVirtualMouseとか使ってたけどどうやるんだろ?

今回はライトの3つの値(ambient, diffuse, specular)をスライダーで変更してみました。
こちら。
いつものようにソースコードは右クリック→「ソースの表示」で見られます。
自分も大学のCG論のOpenGLで少しやったぐらいなのであまり詳しくないですが、ambientは環境光、diffuseは散乱光、specularは反射です。

次はまだよく理解していないカメラの動きを勉強する。

2009年11月11日水曜日

memo

メモです。いつもより多くメモしております。

Away3D関係
First steps in Away3D : Part 5 - Lighting and shading
Part1からソースコードが載ってるので勉強になります。
Flash 3D Basics
名前の通り3Dの基本です。英語のサイトですがサンプルがあってわかりやすい。
[Away3D] Collada Animation
アニメーションはやったことないですがとりあえずメモ。

ActionScript
配列コピー – ActionScript
slice()よりconcat()のほうが早いんですね。
そういえばこの間友達からArrayの初期化は「= new Array();」よりも「= [];」のほうが早いって聞きました。
FlexでObjectのvar_dump()を行う「Debug.dump」を試してみた
Objectの中身を表示してくれます。便利。

そうめん
ActionScript Thread Library 1.0 (そうめん) ドキュメント
そうめんです。非常に便利
そうめんをさわってみた その4
まだそうめん勉強中なので。
Thread(そうめん)× Away3D × Blenderで作成(僕がそうめんを使う理由的な)

jQuery, CSSとか
How To Create A Sexy Vertical Sliding Panel Using jQuery And CSS3
horinaja for scriptaculous or jQuery
[CSS]1ピクセルのラインを巧みに使用したドロップダウン型ナビゲーション


パッド派にとって格闘ゲームに最適なFightpad for Xbox 360
PCと360兼用として買おうかな。SSコンっぽいのでSSFでも使えそうだし。

2009年11月10日火曜日

[Away3D]Away3DでShader試してみた[AS3.0]

前回言ってた続きです。

Papervision3DでUVマッピングを使用したColladaがうまく読み込めなかったので、Away3Dで試してみました。
Away3Dは検索しても解説してくれているところがあまりないので、サンプルファイルを参考にしながら(というかコピーして)、UVマッピングを使用したColladaを表示してみました。
それでできたものがこれ

Pv3Dで表示されてた黒い線が消えてるじゃないですかー。
ぅわーい。

あ、Away3DはこちらにあるようにShaderの種類がPv3Dより少ないので、PhongShaderを使ったんですが、非常に重かったのでモデルデータを作り直しました。

というわけで全然完成してないけどソースコード公開するよ。
package {
 import away3d.cameras.HoverCamera3D;
 import away3d.containers.ObjectContainer3D;
 import away3d.containers.Scene3D;
 import away3d.containers.View3D;
 import away3d.core.base.Mesh;
 import away3d.core.utils.Cast;
 import away3d.lights.DirectionalLight3D;
 import away3d.loaders.Collada;
 import away3d.materials.PhongBitmapMaterial;
 
 import flash.display.Sprite;
 import flash.display.StageQuality;
 import flash.events.Event;
 import flash.events.MouseEvent;

 public class away3 extends Sprite {

  private var scene:Scene3D;
  private var camera:HoverCamera3D;
  private var view:View3D;

  //[Embed(source="mat.png")]
  //public var materialImage:Class;
  //[Embed(source="sample.dae", mimeType="application/octet-stream")]
  //public var colladaData:Class;
  [Embed(source="mate.png")]
  public var materialImage:Class;
  [Embed(source="test.dae", mimeType="application/octet-stream")]
  public var colladaData:Class;

  private var material:PhongBitmapMaterial;
  private var collada:Collada;
  private var model:ObjectContainer3D;
  private var mesh:Mesh;
  private var light:DirectionalLight3D;

  private var isMouseDown:Boolean;
  //navigation variables
  private var lastPanAngle:Number;
  private var lastTiltAngle:Number;
  private var lastMouseX:Number;
  private var lastMouseY:Number;

  public function away3() {
   initEngine();
   initLights();
   initMaterials();
   initObjects();
   initListeners();

   isMouseDown = false;
  }

  /**
   * Initialise the engine
   */
  private function initEngine():void {
   scene = new Scene3D();
   camera = new HoverCamera3D();
   camera.zoom = 1;
   camera.focus = 100;
   camera.distance = 80;
   camera.targetpanangle = camera.panangle = -10;
   camera.targettiltangle = camera.tiltangle = 20;

   view = new View3D({camera: camera, scene: scene});
   //view.session = new BitmapRenderSession(1);

   //view.mouseZeroMove = true;
   addChild(view);

   stage.quality = StageQuality.HIGH;
   //stage.quality = StageQuality.LOW;
  }

  /**
   * Initialise the lights
   */
  private function initLights():void {

   //light = new DirectionalLight3D({color:0xFFFFFF, ambient:0.25, diffuse:0.75, specular:0.9, x:40000, y:40000, z:40000});
   light = new DirectionalLight3D();
   light.color = 0xFFFFFF;
   light.ambient = 0.25;
   light.diffuse = 0.75;
   light.specular = 0.9;
   light.x = 0;
   light.y = 1000;
   light.z = 1000;

   scene.addChild(light);
  }

  /**
   * Initialise the materials
   */
  private function initMaterials():void {
   material = new PhongBitmapMaterial(Cast.bitmap(materialImage));
   material.specular = 0.5;
  }

  /**
   * Initialise the scene objects
   */
  private function initObjects():void {
   //model1 = Collada.parse(Charmesh, {scaling:10, material:material, mouseEnabled:false});
   collada = new Collada();
   //collada.scaling = 0.1;
   model = collada.parse(colladaData) as ObjectContainer3D;
   model.materialLibrary.getMaterial("mat1").material = material;
   model.mouseEnabled = false;

   scene.addChild(model);

   //mesh = model.getChildByName("obj1-node") as Mesh;
  }

  /**
   * Initialise the listeners
   */
  private function initListeners():void {
   addEventListener(Event.ENTER_FRAME, onEnterFrame);
   stage.addEventListener(Event.RESIZE, onResize);
   stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
   stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
   //stage.addEventListener(MouseEvent.MOUSE_WHEEL, onMouseWheel);
   onResize();
  }

  /**
   * Navigation and render loop
   */
  private function onEnterFrame(event:Event):void {
   //update the camera position
   //camera.moveTo(0, 70, -10);
   if(isMouseDown) {
    camera.targetpanangle = 0.3 * (stage.mouseX - lastMouseX) + lastPanAngle;
    camera.targettiltangle = 0.3 * (stage.mouseY - lastMouseY) + lastTiltAngle;
   }
   camera.hover();

   //render scene
   view.render();
  }

  private function onMouseDown(event:MouseEvent):void {
   lastPanAngle = camera.targetpanangle;
   lastTiltAngle = camera.targettiltangle;
   lastMouseX = stage.mouseX;
   lastMouseY = stage.mouseY;
   isMouseDown = true;
   stage.addEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }

  private function onMouseUp(event:MouseEvent):void {
   isMouseDown = false;
   stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }
  
  /*private function onMouseWheel(e:MouseEvent):void {
   if(camera.distance > 20) {
    camera.distance -= e.delta * 1.5;
   }
  }*/

  private function onStageMouseLeave(event:Event):void {
   isMouseDown = false;
   stage.removeEventListener(Event.MOUSE_LEAVE, onStageMouseLeave);
  }

  /**
   * stage listener for resize events
   */
  private function onResize(event:Event = null):void {
   view.x = stage.stageWidth / 2;
   view.y = stage.stageHeight / 2;
  }
 }
}

[Away3D]Away3Dにも手を出してみる。

ActionScriptの3Dライブラリは今までPapervision3Dを使ってきましたが、ここらでAway3Dにも手を出してみたいと思います。

自分の開発環境は、Flex Builder3(Flex SDK 3.3)です。

Away3Dに手を出そうと思ったきっかけは、これです。
Pv3Dだと解決方法わからなかったので、Away3Dならなんとかなるかも・・・と思った次第です。

Away3Dの導入方法を紹介します。
Away3Dはこちらの公式サイトから手に入れられます。
WindowsだとTortoiseSVNを使う方法が一般的かもしれませんが、svnチェックアウトするとファイルの量が大量にあるし、新しくソフトをインストールするのも面倒なので、個人的にダウンロードページから個別にDLする方法をお勧めします。

以下一部画像付きで解説。
1.Away3Dで手に入れたいバージョンをダウンロード。(とりあえず最新版)
  exampleも一緒にダウンロードしとくといいと思います。


2.zip解凍。

3.解凍したフォルダの中の「examples_3_4_0」にソースパスを通す。
プロジェクトのプロパティ
ActionScriptビルドパスの「フォルダを追加」でフォルダを指定。

4.プロパティのActionScriptコンパイラ、「必要な Flash Player バージョン」を10に。

設定はこれで完了です。

次回Away3Dで作ったものを載せようと思います。

2009年11月5日木曜日

CSS Nite in FUKUSHIMA, Vol.3に行ってきました。

10/30(土)に開催したCSS Nite in FUKUSHIMAに参加してきました。
CSS Niteに参加するのは前回のin FUKUSHIMA, Vol.2に次いで2回目です。
ちなみに記事の内容はCSS Niteにほとんど関係ありません。

当日の自分の行動。
車のタイヤの空気入れて出発

猪苗代でちょっと給油

郡山到着 ファミマで休憩

金がなかったので適当な郵便局で5千円おろす

コジマ

ヨドバシ

CSS Nite

サイゼリヤ

GEO

郡山でガソリン満タン給油

帰宅
折角郡山に行くので会津にないものにいくつか行ってきました。

郡山市内は意外と道路が入り組んでいて、一方通行が多かったです。ガソリンが会津に比べて安いので満タン入れてきました。
途中でヨドバシに寄ってるのはAcerのノートPCに触ってみたかったからです。会津で取り扱っている店がないので。

イベントは概ね満足。ただもう少し時間が短くて、参加費が安いほうが個人的にうれしいです。

フォクすけハンドタオルをいただきました。これは番号抽選ではなく、じゃんけんで残った人の自己申告で貰えたので本当に自分が当たったのか不安です。持って帰ってきてよかったのかなぁ・・・
ちなみに自分は普段ブラウザはOpera使ってます。

イベント終了後自宅に帰る前に、サイゼリヤで夕飯を食べてきました。
近くにサイゼリヤがないので、存在自体を最近まで知らなかったのですが、悪くないです。
ただピザはおいしくなかった。それと基本四人席だったので一人で入ると申し訳なくなります。
そして近くにあったゲオで、
バーニングレンジャーとバーチャコールSを購入。
暇ができたらこれらを是非プレイしたい。

2009年10月26日月曜日

間違い発見

さっきスペルミスを発見した。(2009/10/26現在)

OpenSocial API リファレンス
上のページのこの部分。
Object value - 更新する値です。有効な josn である必要があります。
josnじゃなくてjsonだと思ふ。他のところはjsonって書いてあるし。

それだけ。

2009年10月24日土曜日

[Pv3D]UVマッピングの問題


UVマッピングを使用したテクスチャに、Shaderを適用すると出てくる例の黒い線を消すべくいろいろやってみた。

日本語のページを探してもこの問題の解決策を見つけられなかったので、英語で調べてみるとこんなものを見つけました。
まさに自分と同じ現象、しかも解決策書いてある!というわけで早速試してみました。

解決方法が書いてあるのはこの一文。
a fix is to change the shadercomposition mode to per_tri on the shader. This will be slower but remove the seams.
意訳すると、「シェーダーのshadercomposition modeをper_triにすれば、重くなるけど線消えるよ。」って感じでしょうか?

shadercomposition modeってのは、ShadedMaterialのプロパティにshaderCompositeModeというのがあるので多分これのことでしょう。
shaderCompositeModeのデフォルトの値は0。
また、ShaderCompositeModesに次のような記述があります。
public static var PER_LAYER:int = 0;
public static var PER_TRIANGLE_IN_BITMAP:int = 1;
per_triというのは、おそらくこのPER_TRIANGLE_IN_BITMAPのこと。
というわけで、
var material:ShadedMaterial = new ShadedMaterial(bitmapmaterial, shader, 1);
という風に記述しました。3つ目の引数がshaderCompositeModeです。

こちらが作ったswfファイルです。重いので反応遅れます。
ソースコードは右クリックで見られます。
他の目的で作ったものをブログ用に適当に改変してるので非効率的な書き方になってます。

上のファイルを見てもらえればわかりますが、この方法を試しても駄目でした。
例の線は消えてはいるようですが、それとはまた別のものが表示されるようになってしまいました。
原因はよくわかりません。

自分は解決しませんでしたが、これで解決する場合もあるかもしれません。

2009年10月18日日曜日

反省とメモ

最近改めて以前公開したソースコードを見直したりしてますが、今見直すと修正したいものが結構あります。
ブログは他人にも見られるものなので一応修正しておきます。

この記事についての訂正です。

var myMaterials:Object = {
    material_2_1_8_image: new BitmapMaterial(material0.bitmapData),
    material_3_2_8_image: new BitmapMaterial(material1.bitmapData),
    material_4_3_8_image: new BitmapMaterial(material2.bitmapData),
中略
    material_28_37_8_image: new BitmapMaterial(material35.bitmapData),
    material_22_38_8_image: new BitmapMaterial(material36.bitmapData),
    material_0_23_8_image: new BitmapMaterial(material37.bitmapData)
}
var daeObject:DAE = new DAE();
daeObject.load(XML(new daeFile()), new MaterialsList(myMaterials));
scene.addChild(daeObject);
Object型は文字『-』を使うとエラーが出たので、Colladaファイルの『-image』を『_image』に置換してました。
これを今書き直すならこうします。
var myMaterials:MaterialsList = new MaterialsList();
myMaterials.addMaterial(new BitmapMaterial(material0.bitmapData), "material_2_1_8-image");
myMaterials.addMaterial(new BitmapMaterial(material1.bitmapData), "material_3_2_8-image");
myMaterials.addMaterial(new BitmapMaterial(material2.bitmapData), "material_4_3_8-image");
中略
myMaterials.addMaterial(new BitmapMaterial(material35.bitmapData), "material_28_37_8-image");
myMaterials.addMaterial(new BitmapMaterial(material36.bitmapData), "material_22_38_8-image");
myMaterials.addMaterial(new BitmapMaterial(material37.bitmapData), "material_0_23_8-image");

var daeObject:DAE = new DAE(false);
daeObject.load(XML(new daeFile()), myMaterials);
scene.addChild(daeObject);
訂正版はコンパイルしたわけではないので、もしかしたらエラーが出るかも・・・
MaterialsList.addMaterialを使えば、文字『-』を使っても問題ない(はず)ですので、こっちのほうがいいです。
ソースコードも多少わかりやすいと思います。


あと、気になった記事のメモ。
Papervision 3D Programming Tutorial - Blend Modes
いろいろあるんですね。

単調なウェブサイトのデザインに手を加えてクオリティをアップするチュートリアル

必ずモノにしたい! ウェブデザイン向け Photoshop チュートリアル16個

cssのテクニックなどを学びたい時に見ておきたい12サイト
未チェック。そのうち見る。

[JS]画像に見出しとキャプションをスライド表示させるチュートリアル
jQuery。

お前等ノートパソコンにステッカー貼らないよな?
ちょっと作ってみたいかも。

2009年10月12日月曜日

[Pv3D]Phong shadingとBump mapping[AS3.0]


久しぶりの更新です。
自転車で東京へ行くっていう馬鹿なことしてたので時間がありませんでした。

さて本題。
Papervision3DのPhongShaderを使ってバンプマッピングをしてみました。
バンプマッピングってのは白黒の画像で表面の凹凸を表現する方法のことらしいです。
こんな感じ。結構CPUに負荷かかるので気をつけてください。

クリックした場所のバンプマップを書き換えてます。
某アニメの最終話みたいに月に落書きします。
note.x | [PV3D2.0] BumpMapの動的書き換え
上の記事を参考に書きました。
月の画像はこちらのを使わせてもらいました。

あまりいい書き方ではないと思いますが、以下ソースコードです。
変数名とか関数名とかかなり適当。
package {
 import flash.display.Bitmap;
 import flash.events.Event;
 import flash.geom.Point;
 import flash.geom.Rectangle;

 import org.papervision3d.core.utils.InteractiveSceneManager;
 import org.papervision3d.core.utils.Mouse3D;
 import org.papervision3d.core.utils.virtualmouse.VirtualMouse;
 import org.papervision3d.lights.PointLight3D;
 import org.papervision3d.materials.BitmapMaterial;
 import org.papervision3d.materials.shaders.PhongShader;
 import org.papervision3d.materials.shaders.ShadedMaterial;
 import org.papervision3d.objects.primitives.Plane;
 import org.papervision3d.objects.primitives.Sphere;
 import org.papervision3d.view.BasicView;

 [SWF(backgroundColor="#ffffff")]
 public class sample_bump extends BasicView {
  // ヴァーチャルマウス
  private var vMouse:VirtualMouse;
  // 球(月)
  private var sphere:Sphere;
  // 月のバンプマップ埋め込み
  [Embed(source="moonbump1k.jpg")] private var bumpImage:Class;
  private var bumpMap:Bitmap = new bumpImage() as Bitmap;
  // シェーダー
  private var shader:PhongShader;

  /* constructor */
  public function sample_bump() {
   super(640, 480, true, true,"Target");

   // カメラ設定
   camera.x = 0;
   camera.y = 0;
   camera.z = 400;
   camera.focus = 1000;
   camera.zoom = 1;

   vMouse = viewport.interactiveSceneManager.virtualMouse;
   Mouse3D.enabled = true;

   /* 背景画像は画像を貼り付けたPlane(平面)を球(月)の奥に設置している */
   // 背景画像埋め込み
   [Embed(source="000191_m.jpg")] var wallpaper:Class;
   var wp:Bitmap = new wallpaper() as Bitmap;
   var star:BitmapMaterial = new BitmapMaterial(wp.bitmapData);
   star.doubleSided = true;
   star.smooth = true;
   var wall:Plane = new Plane(star, 1024, 681);
   wall.z = -200;
   scene.addChild(wall);

   // 月の画像埋め込み
   [Embed(source="moonmap1k.jpg")] var texture:Class;
   var tex:Bitmap = new texture() as Bitmap;
   // ライト設定
   var light:PointLight3D = new PointLight3D();
   light.x = 0;
   light.y = 200;
   light.z = 500;
   scene.addChild(light);

   var bmpMat:BitmapMaterial = new BitmapMaterial(tex.bitmapData);
   shader = new PhongShader(light, 0xFFFFFF, 0x666666, 50, bumpMap.bitmapData, tex.bitmapData);
   var material:ShadedMaterial = new ShadedMaterial(bmpMat, shader);
   material.smooth = true;
   material.interactive = true;

   sphere = new Sphere(material, 100, 16, 12);
   scene.addChild(sphere);

   startRendering();
  }

  // バンプマップ埋め込み
  [Embed(source="bump.png")] private var craterImage:Class;
  private var crater:Bitmap = new craterImage() as Bitmap;
  private function meteor():void {
   // バンプマップ合成
   bumpMap.bitmapData.merge(crater.bitmapData, new Rectangle(0, 0, crater.width, crater.height), new Point(vMouse.x*1000 - crater.width/2, vMouse.y*500 - crater.height/2), 128, 128, 128, 128);

   // バンプマップ更新
   shader.bumpmap = bumpMap.bitmapData;
  }

  override protected function onRenderTick(event:Event=null):void {
   // 回転
   sphere.yaw(0.25);
   if(InteractiveSceneManager.MOUSE_IS_DOWN) {
    meteor();
   }

   super.onRenderTick(event);
  }
 }
}

2009年9月17日木曜日

最近の買い物

最近財布の紐が緩んだのかいろいろ買い物をしてしまいました。

まずはDS

以前から欲しくてついに買ったって感じです。にしても高い。
中古屋で海外版の銀色を1万円で購入。これで兄に借りなくてもDSで遊べます。


カルドセプトDS
Sofmapで980円だったので。


ラブプラス
DS購入の理由の半分くらいはこれ。


MAPLUSポータブルナビ3
知り合いからGPSレシーバーを貰ったのでなんとなく買ってみた。
車に取り付けてみたら結構使えた。自転車にも取り付けてみたいが、どうやって取り付けようか考え中。


シャイニングフォース3 シナリオ2
シナリオ2は、シナリオ1,3と比べて品薄でなかなか手に入らなかったが、先日ついに入手。
これでシナリオ1を心置きなく進められる。


PSPでは主に2GBのを使ってたのですが、MAPLUS3のインストールなどをすると足りないということで、MAPLUS3用に新しく買った。
Sofmapでの送料調整の役割も兼ねて。

2009年9月15日火曜日

オカンとボクと、インターネット?

タイトルわけわかりませんね。

それはともあれ、フルフラッシュのサイトって多いですよね。
不便な点もいくつかありますが、幅広い表現ができるので企業のサイトには良く使われてますね。

一方で使いにくい、わかりづらいので嫌いって人も結構多い感じがします。
というか大好きって人は聞いたことないです。

http://www.ca4la.com/tsu4shi/
さっき母に上のサイトでどうしたらいいかわからずすっごいイライラしたって言われたんですよ。
たしかにこれはわかりづらい。というか全体的にイライラするw

どういう層の人をターゲットにしたサイトか知りませんが、万人に受けるものって難しいですね~。

-------------------------------

なんかついに我が地域にも光回線がくるらしい。11月から。
やったね。
ついでにプロバイダ変えてもらおうかな。

2009年9月11日金曜日

DC

北米でDreamcastが10周年を迎えたようですね。
名作がずらり並んだ「GTが選ぶドリームキャスト作品ベスト10」
上の記事にも書かれていますが、ゲーム動画サイト(?)のGameTrailers.comでDCのゲームベスト10を発表しています。

下がその動画。
http://www.gametrailers.com/player/55604.html

どういう基準で誰が選んだソフトかはよくわかりませんが、結構参考になるランキングだと思います。
でも1位が一番アテにならない、というか1位だけソフト複数とか卑怯だろそれw

1,7,9,10位以外は全部所持してたなー。
しかも結構やり込んでた。

エターナルアルカディア(北米だとSkies of Arcadia?)って海外でも評価高いんですね、ちょっと意外。
自分も購入しましたよ、@barai版。てか@baraiで購入した人ってどれくらいいるんだろう・・・

シェンムーが上位にあるので嬉しいです。
以下個人的意見ですが、今までで一番面白かったゲームは『シェンムーII』です。
シェンムー2を超えるゲームは今のところない。今後超えるゲームがあるとしたらシェンムー3しかない!
と考えているぐらいシェンムーが好きです。

というわけでシェンムー3をつくってくれ~。
でたら定価10万でも買う。

2009年9月10日木曜日

こまーしゃるめっせーじだっけ?

なんとなく思いついたので懐かしいCMでも紹介するよー。
多分福島県オンリー。


昔はこのCMよく流れてたのですが、最近は全然見ませんな。

2009年9月8日火曜日

[Flex]Flexでスライドパズル

以前作ったやつ(AIR)のFlex版です。

AIRだとインストールとか面倒だし、Flexのほうがブラウザで遊べていいと思ったので作ってみました。

こちら
ソースコードは右クリックで見られます。

あまり見やすいソースコードではないですねー。今後改善していきたいです。

今のところは4×4の15パズルしかできませんが、そのうち5×5とかにも対応させていく予定。

2009年9月3日木曜日

[Pv3D]Collada(.dae)にShader試してみた[AS3.0]

Papervision3DでShader試してみました。
Shaderってのは、3Dで光、それによって発生する影を表現するもの、と思っておけばいいです。自分も詳しくは知りません。
やはり影がないと3Dって感じがしないですよね。ベタ塗りだと奥行きとかわからないですし。

このようになりました。
ソースは右クリックで見てください。

おー、一気に3Dっぽくなったー。
PhongShaderだと重いので、今回はGouraudShaderを使用しました。マシンによっては重いかも。

まぁ見ればわかりますが、問題があります。
表面に黒い線のツギハギができてしまっています。

原因はテクスチャマッピング関係だと思います。

このサンプルのモデル、テクスチャ画像は下のようになっています。

つまりこの一枚の画像を、テクスチャマッピング(割り当て)をして、モデルに対応させて表示しています。

おそらく、この問題の原因は、テクスチャの継ぎ目のところに影を生成してしまってるからだと思います。

この問題を解決して綺麗に表示したいのですが方法がわかりません。
さてこれはどうしたものか・・・

--------------------------------------
追記
解決しませんでしたが、こちらで黒い線の問題を取り上げました。

さらに追記
別のライブラリを使って問題を解決してみました。
こちら

2009年8月25日火曜日

無料で3Dモデルデータを作成する-回転体 その3

前回の続きです。

その3 Google SketchUp

SketchUp(無料版)での回転体の作り方を紹介します。
他にもっといいやり方があるかもしれませんが、とりあえず自分がやった方法を紹介。

最初に起動したときの画面はこんな感じです。
まずはマウスのホイールを操作して、視点移動の操作に慣れます。難しくはないと思うのですぐに慣れると思います。


1.長方形ツールで適当な平面を描きます。


2.線ツールで線を描きます。これは回転軸なので、先ほど描いた四角形の辺と直角に交わるようにして下さい。


3.線ツール、円弧ツールなどを使い、断面図を描きます。
  断面図の画像データがあるのなら「ファイル>インポート」で読み込み、それをなぞるといいです。

画像の断面図は適当に描きました。


4.円ツールを使い、2.で描いた回転軸を中心に円を描きます。
  回転軸とは垂直に交わるようにして下さい。


5.先ほど描いた円と、断面図の面以外のものは選択ツールで選択し、Deleteしてしまいます。


6.選択ツールで円の面を選択。
  邪魔だったので定規みたいなのも削除しました。


7.「ツール>フォローミー」を選択。


8.フォローミーツールで断面図をクリックすると一瞬で回転体ができます。
  円を削除して、完成です。


書き出せる形式が少ないですが、SketchUpは使いやすいと思います。
単純な立体を扱うならSketchUpはちょうどいいんじゃないかな。
始める前に3Dギャラリーを覗いて他の人の作品を見ておくといいでしょう。


その4に続きます。

2009年8月21日金曜日

無料で3Dモデルデータを作成する-回転体 その1&2

その1 紹介

最近断面図から立体モデル、つまり2Dの画像データから3Dのモデルのデータを作成する作業を勉強してました。

メモついでにやり方を紹介します。
ちなみに私は3Dについて全然詳しくありません。専門用語はほとんどわからないレベルです。

そもそも3DCGソフトは値段が高く、操作が複雑なものが多いので敷居は低くありません。
お金もないので今回は無料のソフトを使用し、断面図から回転体を作成してみました。

自分が今回使ったソフトは、Blender、Google SketchUp、Metasequoiaの3つです。
Wikipediaから引用

Blender
特徴的で効率の良い独自のユーザインタフェース(UI)を持つ。
現在、急速な勢いで機能拡張・整備が進んでおり、まだまだ発展途上な部分はあるものの、商用のハイエンド3Dツールと肩を並べるほどの機能群を擁する。

Google SketchUp
米Google Inc.が開発・提供している3Dデザインツール。元々、SketchUpは米@Last Software社が開発と販売を行なっていたが、Googleが同社を2006年3月に買収して全ての権利を引き継いだ。

Metasequoia
3Dモデルの作成(モデリング)に特化した3DCGモデラーであり、トゥーンレンダリング・Pythonスクリプト・プラグイン等の機能を備える。

3DCGモデラーとしての高機能性、ユーザフレンドリーな操作性、フリーウェア版などの入手性の高さなど、日本における3DCGモデラーとして非常に人気が高く、参考書籍も多い。開発者用にライブラリやソースコードを公開しているため、シェアウェア版では多くの開発者によるプラグインを利用することができるようになっている。また、シェアウェア版ではフリーウェア版には無い三面図法を取り入れており操作性が非常に良い。



その2 Blender

まず自分がBlenderを使ってみてどうだったかを紹介します。

一言で言うと、操作性が悪すぎて操作が難し過ぎてまともに使えませんでした。
アニメーションも扱えたり、様々な形式の読み込み&書き出しに対応していて高機能なのは理解できますが、自分のような初心者には扱えません。
「それでもBlenderを勉強したい!」という方はこちらのサイトで勉強するといいと思います。
わかりやすく丁寧に説明されていると思います。


その3に続きます。

2009年8月20日木曜日

くおりてぃ・ふーどぱわーせんたー

携帯電話のカメラ機能、自分は結構使います。
多分電話より使用頻度高い。

気になったものはとりあえず撮っとくようにしています。



            ,..::::´:::::::::::::::::::::::::::::::::::::`::...、 _
            /:::::::::::::::::::::::::::::::::::::::::::::::::::/   \
           /::::::::::/::::::::::::::::::::::::::::::::::::::/       ヽ
        /::::::::::/|::::::::::::::l::::::::::::::::::::::::/  で 過   ヽ
        i::::|:::::/ |:::::::::::::l:::::l::::::::::::::::::|   す  多   ト、
       i:::::l:::∧ヽ|::::::::::::ハ::::|l::::::::::::::::|   よ  書   l:::::\
         l::r |::L{メi l|::::::::::l__l:::l_l::::::::::::::::!     き   /::::_::」
        l:::メV`ヽ.八::::::::l _V__l:::::::::::::::ヽ       /::::::|
       l::,' `ァ´ハ ヽ::::!'^ たj::::::::::::::::::::\__/::ト、:: ::|
          l::! i´  `\ヽ|ヽ  `¨l::::::::::::::::::::::::::::::::::::::|ヽ! \|
        l:ハ  _    `ー'′  |::|、:::::::::::::::::::::::::::::::l
        l′! \>       V,ム:::::::::::::::::l、:::::::l
             !     __,. - ´>―へ:::::::::::| \:::!
            ̄ |       |:::、:::::|\::::::!  `
             |       l:::| \|_ \!
                 |    ,..-‐ ´ ̄#   |



最近どうでもいい投稿ばっかだなー

2009年8月19日水曜日

ジーニアスはボクサー

新型のPS3が発表されたらしいですね。
http://japanese.engadget.com/2009/08/18/ps3-2-9980/

PS3大勝利!!!


とういわけで(?)、このニュースにも負けないような360にうれしい情報をご紹介。

英和辞典でそこそこポピュラーな大修館書店さんのジーニアス英和辞典
自分も高校生の時使ってました。自分が持っているのは第3版ですけど。

なんとこのジーニアス英和辞典の収録単語に、『Xbox』があります!
しかも『PlayStation』は載っていません。

Xbox勝利・・・?


------------------------------------------

まー、ぶっちゃけただ単に"X"から始まる単語が少ないから載せてみたってだけでしょう。
ゲーム機関係だと他には『NES』(Nintendo Entertainment System、ファミコンの海外での名前)が載ってました。これはさすが任天堂といったところでしょうか。

2009年8月14日金曜日

ちょっと遊び

Parpervision3Dの2.1が公開されてますね。
DAEまわりが改善されてるようで嬉しいです。
変えてみたら以前はエラーが出てたものが動くようになったりしました。

というわけでちょっと更新。
内容自体はのとほとんど変わりません。

初音ミクのモデルデータに落書きをできるようにしてみた。→
かなーり適当です。左右対称に描かれてしまうところが多いです。
ちなみに、このプログラムはPv3Dが2.0だとエラーが出て動きません。2.1だと動いたので公開してみました。

モデルのデータはこちらからいただきました。謝々。

2009年8月13日木曜日

背景

放置してるとそのうち更新する気になってくるNE

『夏のあらし!』第9話の客ネタがけいおんや咲などパロネタが満載だらけだった件を見て思い出したネタでも。。。

背景にネタを仕込むのは要らない気もしますが、気付くとちょっと嬉しいです。個人的に。
それで嬉しくてついキャプチャしてしまった画像があったので載せてみようかな、と。

明日君の一場面。たしか瑠璃子ルートの途中だったかな・・・?

これですよ、これ↓

これはどうみてもあのキャラにしか見えない・・・

------------------

ちなみにこの画像、キャプチャしたのは約1年前。
この記事を下書きしたのは約2ヶ月前なんですよね。

なんでそんな長い間公開してなかったかって言うと、著作権が怖かったからです。
なんというチキン。

というわけで問題があったら削除します。これ。

2009年7月16日木曜日

[Pv3D][Flex]Collada(.dae)にお絵かき[AS3.0]

これまた前回の続きです。

こんな感じです。
現時点で不具合は多いですが、基本の動作としてはこんな感じかな~と・・・
右下の「編集する」を選択すると編集モードに入ります。

[PV3D2.0] virtualMouse axis on DAE
Flash Player 10でPV3D上の落書きを保存してみる
↑2つを参考にし、matsu4512さんに助けてもらいながら作りました。

ソースコード
demo.mxml World3D.as

現時点でお絵かきが上手くいってない原因はここらへんが原因かなー。
material = new MovieMaterial(movieClip, false, true, false, new Rectangle(0, 0, bmpData.width, bmpData.height));


---
お絵かきをするにはクリックしたマテリアルの情報を得る必要があるのですが次のように行ってます。

private function modelComplete(e:FileLoadEvent):void {
var dae_rootNode:DisplayObject3D = dae.getChildByName("COLLADA_Scene");
var targetMesh:DisplayObject3D = dae_rootNode.getChildByName("Model").getChildByName("mesh1");
targetMesh.addEventListener(InteractiveScene3DEvent.OBJECT_MOVE, drawModel);
}

private function drawModel(e:InteractiveScene3DEvent):void {
if(isModelOver) {
targetMaterial = int(e.renderHitData.material.name);
}
}

mesh1っていうDisplayObject3Dからマテリアルの名前をどうやって取得するかわからなかったので、Flex Builderの補完機能をつかってそれっぽいのを片っ端から試してたら、
『e.renderHitData.material.name』で取得することができることが判明。
この"renderHitData"って調べてもあまり情報がないんですよね~。
まあ問題なく(?)動いてるので大丈夫かな。

ちなみに、「getChildByName("Model").getChildByName("mesh1")」の"Model"と"mesh1"は

<library_visual_scenes>
<visual_scene id="SketchUpScene" name="SketchUpScene">
<node id="Model" name="Model">
<node id="mesh1" name="mesh1">
<instance_geometry url="#mesh1-geometry">
<bind_material>
<technique_common>
<instance_material symbol="material0" target="#material0ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
<instance_material symbol="material1" target="#material1ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
中略
<instance_material symbol="material6" target="#material6ID">
<bind_vertex_input semantic="UVSET0" input_semantic="TEXCOORD" input_set="0"/>
</instance_material>
</technique_common>
</bind_material>
</instance_geometry>
</node>
<node id="mesh2" name="mesh2">
<instance_geometry url="#mesh2-geometry">
<bind_material>
<technique_common>
<instance_material symbol="ForegroundColor" target="#ForegroundColorID"/>
</technique_common>
</bind_material>
</instance_geometry>
</node>
中略
</visual_scene>
</library_visual_scenes>

daeファイルのこの部分の『node』の名前からきてます。
mesh1のほかにもmesh2とかがありますが、マテリアルが含まれてるのはmesh1のほうなのでそっちです。
書き出したソフトによって多少違いがあるとは思いますが他も同じようなもののはず。

2009年7月13日月曜日

雑記

ブログを全然更新してないのでたまには更新。
次あたりでプログラムのほう更新する予定。

この夏は福島へ! 福島県と「モンスターハンター3」がタイアップ
なんぞこれw
県知事からのメッセージもあるので結構ちゃんとした企画っぽい。

最後のタブを閉じてもFirefox3.5を開いたままにする方法
個人的に便利なのでメモ。「about:config」でいじります。
普段はOpera使ってるのでこのほうが使いやすいです。

2009年7月5日日曜日

雑記

今日エヴァ破見てきました。車で片道2時間かけて。
これだから田舎は。

プログラムのほうがあまり進んでないので気になった記事でも挙げていきます。
MorphController - Mighty Morphing Papervision3D
Papervision3D | DisplayObject3Dの頂点操作 geometry.vertices
Pv3D 2.0 Morphing geometry trough LERP
まだ詳しくソースコード見てないですが、Papervision3Dでの頂点操作などの記事です。
Papervision tutorials
チュートリアルです。いろいろあります。

[Computer Science] Web上の膨大な画像に基づく自動画像補完技術の威力
画像補完の記事です。

[CSS]テキストだけを使ってぱっと見、画像のようにみえるスタイルシート
すごい。ですけど実際には使えなさそう。

2009年7月3日金曜日

[Pv3D][Flex]Collada(.dae)のマテリアル張り替え

前回の続き?

前回3DギャラリーからとってきたCollada形式のデータはテクスチャの枚数が多かったので今回は自分でGoogle SketchUpを使ってモデルを作ってみました。形はかなり適当ですが・・・

動作サンプル
ソースコードは右クリックで表示できます。

背景が白いところでドラッグ&ドロップで視点移動、マウスホイールでズームイン&アウトします。
ズームは正確にはズームではなく、カメラごと対象に近づく(or遠ざける)ようになってます。
「ロード」ボタンを押してから、「はりかえ」ボタンを押すとテクスチャがランダムに変わります。
エラーが出ると思うので、「ロード」を押す前に「はりかえ」を押さないでください。

DAEに渡すマテリアルリストの作成は次のようにやってます。

var material0:BitmapMaterial = new BitmapFileMaterial("model3/images/texture0.jpg");
var material1:BitmapMaterial = new BitmapFileMaterial("model3/images/texture1.jpg");
var material2:BitmapMaterial = new BitmapFileMaterial("model3/images/texture2.jpg");
var material3:BitmapMaterial = new BitmapFileMaterial("model3/images/texture3.jpg");
var material4:BitmapMaterial = new BitmapFileMaterial("model3/images/texture4.jpg");
var material5:BitmapMaterial = new BitmapFileMaterial("model3/images/texture5.jpg");
var material6:BitmapMaterial = new BitmapFileMaterial("model3/images/texture6.jpg");
var material7:BitmapMaterial = new BitmapFileMaterial("model3/images/texture7.jpg");
var material8:BitmapMaterial = new BitmapFileMaterial("model3/images/texture8.jpg");
var material9:BitmapMaterial = new BitmapFileMaterial("model3/images/texture9.jpg");
var myMaterials:Object = {
material0: material0,
material1: material1,
material2: material2,
material3: material3,
material4: material4,
material5: material5,
material6: material6,
material7: material7,
material8: material8,
material9: material9
}
texture = new MaterialsList(myMaterials);

myMaterialsの中身の『material0: material0』ですが、
これは、『Colladaファイルのマテリアルの名前: 上で宣言しているBitmapMaterial型の変数material0』です。名前同じでわかりづらいですね、すみません。
で、「Colladaファイルのマテリアルの名前」はCollada(DAE)ファイルを調べればわかります。
ColladaってのはXMLで書かれているので、適当なテキストエディタで開くと、次のようになっています。

<library_images>
<image id="material0-image" name="material0-image">
<init_from>../images/texture0.jpg</init_from>
</image>
<image id="material1-image" name="material1-image">
<init_from>../images/texture1.jpg</init_from>
</image>
中略
<image id="material8-image" name="material8-image">
<init_from>../images/texture8.jpg</init_from>
</image>
<image id="material9-image" name="material9-image">
<init_from>../images/texture9.jpg</init_from>
</image>
</library_images>
<library_materials>
<material id="material0ID" name="material0">
<instance_effect url="#material0-effect"/>
</material>
<material id="FrontColorNoCullingID" name="FrontColorNoCulling">
<instance_effect url="#FrontColorNoCulling-effect"/>
</material>
<material id="material1ID" name="material1">
<instance_effect url="#material1-effect"/>
</material>
<material id="material2ID" name="material2">
<instance_effect url="#material2-effect"/>
</material>
中略
<material id="material8ID" name="material8">
<instance_effect url="#material8-effect"/>
</material>
<material id="material9ID" name="material9">
<instance_effect url="#material9-effect"/>
</material>
<material id="ForegroundColorID" name="ForegroundColor">
<instance_effect url="#ForegroundColor-effect"/>
</material>
</library_materials>

書き出したソフトによって記述に多少の違いはありますが、『<material id="material0ID" name="material0">』のnameがマテリアルの名前になります。

あとは、

dae.load("○○.dae", 作成したマテリアルリスト);

と書けばロードされます。
普通はCollada自体でもテクスチャを指定してありますが、これで渡したマテリアルリストのほうが優先されるっぽいです。

マテリアルの張り替えには「replaceMaterialByName」を使ってます。こんな感じで。

var material:BitmapMaterial = new BitmapFileMaterial("model3/images/texture" + Math.round(Math.random()*9) + ".jpg");
dae.replaceMaterialByName(material, "material0");



今回参考にさせてもらったサイト
http://pv3d.org/2008/12/26/switching-a-moviematerial-on-the-face-of-a-cube-replacematerialbyname/
http://d.hatena.ne.jp/matsu4512/20090701

2009年6月21日日曜日

雑記

週末を使って戦場のヴァルキュリアをクリアしました。
以前言ったとおりアニメ終了前にちゃんとクリアできました。
これで積みゲー1つ消化。
購入から約3ヶ月でのクリアでした。結構早いかも。

良ゲーでした。DLCも購入しました。
なんだかまだ出していないキャラがいるっぽいので売らずに2週目をする予定。

ところでエターナルアルカディアの続編って出ないんですかね・・・俺待ってんだけど。

2009年6月18日木曜日

[Pv3D]Papervision3Dをやってみた その3[AS3.0]


今回はCollada形式(DAE)のファイルをPv3Dで読み込んでみました。

完成品ソースコード

まずGoogleの3Dギャラリーから適当なファイルをダウンロード。
利用規約は読んだけど多分問題はないはず。

拡張子daeのファイルがあるので、それをソースフォルダに持っていき、あとは、
var dae:DAE = new DAE();
dae.load("model.dae");
scene.addChild(dae);

と書けば表示されます。
だたし、こちらで解説されているように"org/papervision3d/core/proto/MaterialObject3D.as"の"tiled"の値を"true"にしないと正しく表示されません。

これだけだったらあまり苦労はしません。
Flex Builder上で実行するのにはエラーはでません。しかし、生成したswfファイルを実行すると、「ローカルファイルシステムの SWF および信頼されているローカル SWF ファイルのみがローカルリソースにアクセスできます。」といったエラーが発生します。
これを解決するには、モデルとテクスチャのファイルの埋め込みが必要になります。
今回一番苦労したのがこれです。


テクスチャファイルの埋め込みと、そのマテリアルリストの作成はこんな感じです。
[Embed(source='model/images/texture0.jpg')]
private var texture0:Class;    // 画像埋め込み
var material0:Bitmap = new texture0() as Bitmap;
var myMaterials:Object = {
material_2_1_8_image: new BitmapMaterial(material0.bitmapData)
}

上の「material_2_1_8_image」の部分は、daeファイルをテキストエディタで開き、画像ファイル名を検索すると、このようになっています。
<image id="material_0_23_8_image" name="material_0_23_8_image">
<init_from>../images/texture0.png</init_from>
</image>

この"id"と"name"の値です。
自分が使用したdaeファイルは、この値が「material_0_23_8-image」というようになっていましたが、"-"を含むとASでエラーになるので、"_"に置換しています。


モデルデータの埋め込みとロードはこんな感じです。
[Embed(source="model/model.dae", mimeType="application/octet-stream")]
var daeFile:Class;
var daeObject:DAE = new DAE();
daeObject.load(XML(new daeFile()), new MaterialsList(myMaterials));


テクスチャの画像が多いと埋め込みが非常に面倒です。
鮭さんのほうで紹介されていたこちらを使わせてもらいました。便利便利。
今回の完成品ですが、一部のテクスチャの表示がうまくいってません。見逃してください。


今回の参考サイトはこちらです。
http://sakeprog.cocolog-nifty.com/sake/2008/08/papervision3d38_7285.html
http://blog.r3c7.net/?p=113
http://d.hatena.ne.jp/sakusan_net/20080702/1215003280


----------------------------------------
2009/10/18 追記
一部訂正しました。→こちら

2009年6月17日水曜日

昨日のお買い物。

近くのGEOでDVD返すついでに何本かゲームを買った。
当分プレイしないと思うけど。

まずはこれ。
スナッチャー
スナッチャー
メタルギアで有名な小島監督の作品だってことだけは知ってますが、内容は知らない。
てかコナミってSSでゲーム出してたんですね。アーケードではライバルでもあるのでセガとはあまり仲がよくなさそうだけど。

DESIRE デザイア

これはなんとなく買った。安かったし。(でもこの中では一番高い

そしてこれ。本日の目玉商品。
DIGITAL DANCE MIX 安室奈美恵
DIGITAL DANCE MIX 安室奈美恵
店頭で見て前々から気になっていた作品。
非常に気になります。これは近いうちにプレイするかも?
セガのAM2研の作品っぽいです。なにをしたいんだあそこは・・・

3本で約1000円でした。お買い得?

Vista SP2

家のデスクトップPCにVistaSP2をインストールしようとするとなぜか失敗するという現象が起きた。

再起動までさせておいて最後のところで「インストールされませんでした」というメッセージとともに変更を元に戻してしまう。
原因を調べていたらこれらしい。
デスクトップは家族共用だが、兄が以前Ramdiskを入れていたのが原因らしい。
上記サイトにあるように環境変数をいじったらインストールされました。

こういう事態が起きてしまうのでソフトを入れすぎるのも問題ですねー。

2009年6月4日木曜日

[Pv3D]Papervision3Dやってみた その2[AS3.0]

まだ途中だったりしますが、こんな感じです。
ソースコードはこちら

Cameraは結構複雑。まだ慣れてない。
本当はBitmapMaterialを貼り付けたかったんだけど、セキュリティエラーがでた。
なんで?

2009年6月2日火曜日

積みゲーリスト

メモ代わりに積みゲーリストでも作ってみる。
自分が忘れないためのものなんで面白くも何ともないですが。

PS3

  • 龍が如く3
     - 未クリア。8割ぐらい進んでる。そのうちクリアする。

  • 戦場のヴァルキュリア
     - 未クリア。8割ぐらい進んでる。アニメ終わる前に終わらせようかな。



Xbox360

  • ソニックワールドアドベンチャー
     - 未クリア。エッグマンランド。ストーリーよりもホットドッグ系を進めようかな。

  • HaloWars
     - 未クリア。5割程度?オンラインメインです。ストーリーはそのうちCoopで。

  • Halo3、COD4、怒首領蜂大往生、Orange Box、XBLA
     - クリア済み。暇だったら実績解除。



Wii

  • ウイニングイレブン プレーメーカー2009
     - たまにやるかも。とりあえず放置。



PS2

  • グランディアX
     - 未クリア。やる気ない。

  • ANUBIS ZONE OF THE ENDERS
     - 未クリア。現在7割程度。そのうちやります。

  • アマガミ
     - 2人クリア。気が向いたらやる。

  • サクラ対戦3
     - 未プレイ。

  • Fate/stay night
     - 未プレイ。限定版についてきたPSPの花札ゲーはやった。



DC

  • セガガガ
     - 未プレイ。そのうちやる?



SS

  • ルームメイト -井上涼子-
     - クリア済み。BADエンドだけど。夏休みにまたやるかも?

  • お嬢様特急
     - 未クリア。半分程度。

  • AZEL
     - 未クリア。まだ序盤。いつかやる。

  • パンツァードラグーンツヴァイ
     - 未プレイ。

  • シャイニング・ザ・ホーリィアーク
     - 未プレイ。

  • シャイニングフォースIII シナリオ3
     - 未プレイ。シナリオ2を持ってないのでシナリオ2手に入れたらやりたい。



PSP

  • グランディア
     - ゲームアーカイブス。昔SS版をクリア済み。

  • アイドルマスターSP ミッシングムーン
     - ババアはやった。疲れたので進めてない。ババアっていったやつ表出ろ。

  • もじぴったん
     - ボリュームありすぎ。



DS

  • ヴァルキリープロファイル 咎を背負う者
     - 序盤。



書くの疲れたのでPCはいいや。
なんか忘れてるのありそう・・・

昔に比べてクリアしないゲームが増えたなあ。

2009年5月27日水曜日

JavaScriptでのCSS指定

この間jQuery使ってたら、IEでだけエラーが出た。
「またか」と思いつつ原因を探してたらこちらのページを見つけました。

tableのtrタグを非表示にしたり、表示したりするのに「css("display", "none")」と「css("display", "table-row")」を使ってたのが原因っぽいです。
こういう時は「css("display", "none")」「css("display", "")」を使えばいいそうです。
あえて未指定にすることで各ブラウザの初期値になるらしい。

これは覚えてて損はないかも。

2009年5月26日火曜日

[Pv3D]Papervision3Dやってみた その1[AS3.0]

今回は球を表示させるだけの簡単なプログラム。
カメラを動かさないとなんだがなんだが3Dな感じがしませんね。

実行結果
ソースコードはすごい短いです。

package {
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.view.BasicView;

[SWF(backgroundColor="#ffffff")]
public class lets3d extends BasicView {
public function lets3d() {
var ball:Sphere = new Sphere(null, 500, 50, 50);
scene.addChild(ball);
startRendering();
}
}
}

今回はこちらを参考にさせてもらいました。
ソースコードが短いのは6行目の"extends BasicView"をしてるおかげみたいです。Pv3Dの便利機能の1つと考えていいんでしょうか。

BasicViewを使わない方もいらっしゃいます。鮭さんとかそうですね。
勉強がてら自分も"extends BasicView"をしないで挑戦してみました。

というわけで、まず動作を理解するためにBasicView.asの中身を見てみます。

package org.papervision3d.view
{
import org.papervision3d.cameras.SpringCamera3D;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.cameras.CameraType;
import org.papervision3d.cameras.DebugCamera3D;
import org.papervision3d.core.view.IView;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
/* @author Ralph Hauwert
* 中略 */
public class BasicView extends AbstractView implements IView
{
/* 中略 */
public function BasicView(viewportWidth:Number = 640, viewportHeight:Number = 480, scaleToStage:Boolean = true, interactive:Boolean = false, cameraType:String = "Target")
{
super();

scene = new Scene3D();
viewport = new Viewport3D(viewportWidth, viewportHeight, scaleToStage, interactive);
addChild(viewport);
renderer = new BasicRenderEngine();

switch(cameraType)
{
case CameraType.DEBUG:
_camera = new DebugCamera3D(viewport);
break;
case CameraType.TARGET:
_camera = new Camera3D(60);
_camera.target = DisplayObject3D.ZERO;
break;
case CameraType.SPRING:
_camera = new SpringCamera3D();
_camera.target = DisplayObject3D.ZERO;
break;
case CameraType.FREE:
default:
_camera = new Camera3D(60);
break;
}

cameraAsCamera3D.update(viewport.sizeRectangle);
}

/**
* Exposes the camera as a Camera3D
*/
public function get cameraAsCamera3D():Camera3D
{
return _camera as Camera3D;
}
/* 略 */
}
}

これも"extends AbstractView"となっているので、AbstractView.asの中身も覗いてみます。

package org.papervision3d.view
{
import flash.display.Sprite;
import flash.events.Event;

import org.papervision3d.core.proto.CameraObject3D;
import org.papervision3d.core.view.IView;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;

/**
* @Author Ralph Hauwert
*/
public class AbstractView extends Sprite implements IView
{
protected var _camera:CameraObject3D;
protected var _height:Number;
protected var _width:Number;

public var scene:Scene3D;
public var viewport:Viewport3D;
public var renderer:BasicRenderEngine;

public function AbstractView()
{
super();
}

public function startRendering():void
{
addEventListener(Event.ENTER_FRAME, onRenderTick);
viewport.containerSprite.cacheAsBitmap = false;
}

/* 中略 */
protected function onRenderTick(event:Event = null):void
{
renderer.renderScene(scene, _camera, viewport);
}

/* 略 */
}
}

今回使わなかった部分は略しました。
ところでこれって勝手に載せていいんですかね?問題はないと思うけど。

上2つを参考に最初のプログラムを書きなおします。

package {
import flash.display.Sprite;
import flash.events.Event;
import org.papervision3d.cameras.Camera3D;
import org.papervision3d.objects.DisplayObject3D;
import org.papervision3d.objects.primitives.Sphere;
import org.papervision3d.render.BasicRenderEngine;
import org.papervision3d.scenes.Scene3D;
import org.papervision3d.view.Viewport3D;

[SWF(backgroundColor="#ffffff")]
public class lets3d2 extends Sprite {
public var scene:Scene3D;
public var camera:Camera3D;
public var viewport:Viewport3D;
public var renderer:BasicRenderEngine;

public function lets3d2() {
scene = new Scene3D();
camera = new Camera3D(60);
viewport = new Viewport3D(0, 0, true, true);
renderer = new BasicRenderEngine();
addChild(viewport);

camera.target = DisplayObject3D.ZERO;
camera.update(viewport.sizeRectangle);

var ball:Sphere = new Sphere(null, 500, 50, 50);
scene.addChild(ball);

addEventListener(Event.ENTER_FRAME, renderTick);
viewport.containerSprite.cacheAsBitmap = false;
}

protected function renderTick(event:Event = null):void {
renderer.renderScene(scene, camera, viewport);
}
}
}

最初のに比べるとソースコードは長くなりました。
実行結果はこちら

見事同じものができました。

結論:
BasicViewがつかえるのなら、使ったほうがいいんでね?

2009年5月25日月曜日

[Pv3D]Papervision3Dをやろうかな

Papervision3Dって名前長いですね。
というわけでこれからは「Pv3D」とでも略そうかと思ふ。

とりあえずGoogle Codeからswcファイルをダウンロードして、Flex Builderで開発環境そろえました。

ちなみに、Papervision3D 2.0(Great White)です。
なんか2.0は結構違うらしいので、どうせ覚えるのなら新しいほうがいいかな、と。

http://rainyday.jp/blog/flash/pv3d/75.html
http://sakeprog.cocolog-nifty.com/sake/2008/05/papervision3d_c48d.html
http://labs.anthill.jp/2008/04/as30greatwhitepapervision3d_20.html
とりあえず↑を読んで勉強します。

2009年5月19日火曜日

IETester

Webページの制作をすると、ブラウザチェックなるものが必要になります。

自分は前までMultiple IEを使っていたんですが、
IE8にアップデートしてから動かなくなったので、今はIETesterを使っています。

なかなか使いやすいのでお勧めです。

2009年5月17日日曜日

[Flex][AIR]ポケベル暗号変換Ver.0.1

そろそろ更新しないとまずいと感じたので更新します。

今回は30分で書けるような楽なプログラムです。


ひらがなをポケベル暗号(?)っていうのに変換します。
なんか唐突に思いついたので作ってみました。
ちなみに私はポケベル触ったことすらありません。

変換できない文字は「?」になります。
見た目をもっとポケベルっぽくするといい感じなるかも。
↓Adobe AIRファイル


↓ソースコード


ソースコードを記事に書くと記事が縦に長くなってしまうので今回はSkyDriveのほうに上げました。
だれか他のいいやり方教えてください。

2009年5月4日月曜日

雑記

本日の雑記。

GWだし、明日ちょっと自転車で普段行かないとこ言ってみようと思う。
ところでBloggerって写真と動画以外のものってアップできないんですかね?
ちょっと不便。

適当に気になった記事とか便利だと思ったもの。
http://pxtoem.com/
pxをemに変換したい時に。

http://net.tutsplus.com/videos/screencasts/fun-with-css-shapes/
画像を使わないでCSSだけで吹きだしを表現できるらしい。エラスティックレイアウトだと利点がありそう。

http://kujirahand.com/tools/tougarasi/
ソースコードをhtmlで表示したい時に。
15パズルVer.0.1のときはこちらを使わせてもらいました。

http://www.4gamer.net/games/023/G002373/20090421011/
>■ゲスト:岩垂徳行 井上喜久子 伊瀬茉莉也
3番目の人グランディア関係あったっけ?ちなみに現在初代をPSPでプレイ中。

http://hatimaki.blog110.fc2.com/blog-entry-1018.html
>恋人になると彼女がプレイヤーの呼び方をボイスで呼んでくれる
>EVSでは無く、苗字、名前、あだ名のボイスは大量に用意されている

なんかバーチャコールSというゲームを思い出した。

2009年5月3日日曜日

[Flex][AIR]15パズルVer.0.15



前回の続きです。

Ver.0.1にエフェクトを追加しました。連打しまくるとおかしくなるかも?
それと、ピース(Piece)の綴りを間違えていたのを修正しました。
白く塗りつぶしていた最後のピースを横のほうに表示させるようにしました。
イメージとしては、おもちゃの「できるんです」をイメージ。


次回あたりに大きい画像を縮小して表示させるようにする予定。

ソースコード
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" nativeDragEnter="onDragEnter(event);" nativeDragDrop="onDragDrop(event);" width="600" height="500" viewSourceURL="srcview/index.html">
<mx:MenuBar labelField="@label" itemClick="useFile(event)" width="100%" id="myMenu">
<mx:dataProvider>
<mx:XMLList>
<Menu label="操作">
<MenuItem label="スタート" />
</Menu>
</mx:XMLList>
</mx:dataProvider>
</mx:MenuBar>
<mx:Image id="myImage" width="100%" height="100%" />
<mx:Move id="myMove" easingFunction="Back.easeInOut" duration="350" />
<mx:Script>
<![CDATA[
import mx.effects.easing.*;
import mx.controls.Alert;
import mx.events.MenuEvent;

// 画像のロード判定用
private var loadEnd:Boolean = false;
private var file_ary:Array;
// 1ピースの幅
private var pieceWidth:Number;
// 1ピースの高さ
private var pieceHeight:Number;
// 空ピースの番号
private var empty:uint;
// 完成確認用配列
private var order:Array = new Array();
private var base:Image;
// シャッフルしたかどうか
private var random:Boolean = false;

// メニュー用の関数
private function useFile(e:MenuEvent):void {
if(e.label == "スタート") {
shuffle();
}
}

// ドラッグ&ドロップでロード
private function onDragEnter(event:NativeDragEvent):void {
trace("entered");
var cb:Clipboard = event.clipboard;
if(cb.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)) {
// ドロップを許可
NativeDragManager.acceptDragDrop(this);
}
}

private function onDragDrop(event:NativeDragEvent):void {
if(loadEnd) {
for(var i:uint = 0; i <= 15; i++) {
myImage.removeChild(myImage.getChildByName(String(i)));
}
myImage.removeChild(myImage.getChildByName(String(16)));
}

var cb:Clipboard = event.clipboard;
file_ary = cb.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
trace("ファイル名:" + File(file_ary[0]).name);

LoaderRequest();
}

private function LoaderRequest():void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadCompleted);
var request:URLRequest = new URLRequest(File(file_ary[0]).url);
loader.load(request);
}

private function LoadCompleted(event:Event):void {
// 画像はBitmapでロード
var bitmapImage:Bitmap = Bitmap(event.target.loader.content);
empty = 15;
pieceWidth = bitmapImage.width / 4;
pieceHeight = bitmapImage.height / 4;

// ピース並べ
for(var i:uint = 0; i < 15; i++) {
// ピースと同じ大きさのビットマップをつくる
var newPieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth, pieceHeight));
// ロードした画像から新しく作ったビットマップにコピー
newPieceBitmap.bitmapData.copyPixels(bitmapImage.bitmapData, new Rectangle((i % 4) * pieceWidth, Math.floor(i / 4) * pieceHeight, pieceWidth, pieceHeight), new Point(0, 0));

// ピースの描画
var newPiece:Sprite = new Sprite();
newPiece.addChild(newPieceBitmap);
base = new Image();
base.addChild(newPiece);
base.width = pieceWidth;
base.height = pieceHeight;
base.x = (i % 4) * (pieceWidth + 3) + 20;
base.y = Math.floor(i / 4) * (pieceHeight + 3) + 30;
base.name = String(i);
base.addEventListener(MouseEvent.CLICK, click);
myImage.addChild(base);
}
// 空ピースは白い長方形
var emptyPiece:Sprite = new Sprite();
emptyPiece.graphics.beginFill(0xffffff);
emptyPiece.graphics.drawRect(0, 0, pieceWidth, pieceHeight);
emptyPiece.graphics.endFill();
base = new Image();
base.addChild(emptyPiece);
base.width = pieceWidth;
base.height = pieceHeight;
base.x = 3 * (pieceWidth + 3) + 20;
base.y = 3 * (pieceHeight + 3) + 30;
base.name = String(15);
myImage.addChild(base);

var lastPieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth, pieceHeight));
lastPieceBitmap.bitmapData.copyPixels(bitmapImage.bitmapData, new Rectangle(3 * pieceWidth, 3 * pieceHeight, pieceWidth, pieceHeight), new Point(0, 0));
var lastPiece:Sprite = new Sprite();
lastPiece.addChild(lastPieceBitmap);
base = new Image();
base.addChild(lastPiece);
base.width = pieceWidth;
base.height = pieceHeight;
base.x = 4 * (pieceWidth + 3) + 20;
base.y = 3 * (pieceHeight + 3) + 30;
base.name = String(16);
myImage.addChild(base);

// 完成判定のためIndexをセット
for(var j:uint = 0; j < 17; j++) {
myImage.setChildIndex(myImage.getChildByName(String(j)), j);
}

// ピクチャの大きさに合わせてウィンドウの大きさを変更
nativeWindow.width = bitmapImage.width + pieceWidth + 60;
nativeWindow.height = bitmapImage.height + 105;
loadEnd = true;
}

// ランダムシャッフル
private function shuffle():void {
var count:uint = 8888;
var pieceNumber:uint;
random = true;

for(var i:uint = 0; i < count; i++)
{
pieceNumber = Math.floor(Math.random() * 15);
if(checkMove(pieceNumber))
{
pieceMove(pieceNumber, random);
}
}
}

// ピースクリック時の処理
private function click(event:MouseEvent):void {
//ピースの番号
var pieceNumber:int = event.currentTarget.name;
trace("click:" + pieceNumber);
if(checkMove(pieceNumber)) {
pieceMove(pieceNumber, false);
}
}

// ピースが動かせるかチェック
private function checkMove(pieceNumber:int):Boolean {
var result:Boolean = false;

if((pieceNumber == (empty - 4)) || (pieceNumber == (empty + 4)))
result = true;
else if(((pieceNumber % 4) != 0) && ((pieceNumber - 1) == empty))
result = true;
else if(((pieceNumber % 4) != 3) && ((pieceNumber + 1) == empty))
result = true;

return result;
}

// ピース移動
private function pieceMove(pieceNumber:int, random:Boolean):void {
var oldEmpty:int = empty;
empty = pieceNumber;
if(!random) {
moveEffect(pieceNumber, oldEmpty);
} else {
myImage.getChildByName(String(oldEmpty)).x = (pieceWidth + 3) * (pieceNumber % 4) + 20;
myImage.getChildByName(String(oldEmpty)).y = (pieceHeight + 3) * Math.floor(pieceNumber / 4) + 30;
myImage.getChildByName(String(pieceNumber)).x = (pieceWidth + 3) * (oldEmpty % 4) + 20;
myImage.getChildByName(String(pieceNumber)).y = (pieceHeight + 3) * Math.floor(oldEmpty / 4) + 30;
}
myImage.getChildByName(String(oldEmpty)).name = String(pieceNumber);
myImage.getChildByName(String(pieceNumber)).name = String(oldEmpty);
indexExchange(pieceNumber);
}

private function moveEffect(fromNumber:int, toNumber:int):void {
myMove.target = myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(fromNumber))));
if(fromNumber == 16) {
myMove.duration = 800;
myMove.xFrom = (pieceWidth + 3) * 4 + 20;
myMove.yFrom = (pieceHeight + 3) * 3 + 30;
} else {
myMove.xFrom = (pieceWidth + 3) * (fromNumber % 4) + 20;
myMove.yFrom = (pieceHeight + 3) * Math.floor(fromNumber / 4) + 30;
}
myMove.xTo = (pieceWidth + 3) * (toNumber % 4) + 20;
myMove.yTo = (pieceHeight + 3) * Math.floor(toNumber / 4) + 30;
myMove.play();
if(fromNumber != 16) {
myMove.target = myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(toNumber))));
myMove.xFrom = (pieceWidth + 3) * (toNumber % 4) + 20;
myMove.yFrom = (pieceHeight + 3) * Math.floor(toNumber / 4) + 30;
myMove.xTo = (pieceWidth + 3) * (fromNumber % 4) + 20;
myMove.yTo = (pieceHeight + 3) * Math.floor(fromNumber / 4) + 30;
myMove.play();
}
}

// Index交換用関数
private function indexExchange(index:int):void {
var indexTemp:int;

indexTemp = myImage.getChildIndex(myImage.getChildByName(String(index)));
myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(index)))), myImage.getChildIndex(myImage.getChildByName(String(empty))));
myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(empty)))), indexTemp);
// ピース合わせ確認
checkComplete();
}

// 完成判定関数
private function checkComplete():void {
var complete:Boolean = true;
for(var i:uint = 0; i < 15; i++) {
if(!(i == myImage.getChildIndex(myImage.getChildByName(String(i))))) {
// 不一致があった場合
complete = false;
}
}
// 全て一致した場合
if(complete) {
trace("Complete!");
var alert:Alert = Alert.show("complete");
alert.isPopUp = false;
alert.cacheAsBitmap = true;
moveEffect(16, 15);
}
}
]]>
</mx:Script>
</mx:WindowedApplication>
↓前回のに上書きしてしまった。



------------------------------------------
2009/9/20 追記
Flex版作りました。
こちら

2009年4月29日水曜日

[Flex][AIR]15パズルVer.0.1


Flex Builder3でFlexとかActionScriptの勉強をしているわけですが、
15パズルを作りたくなったので作ってみました。
最低限の機能はできたのでVer.0.1としてあげます。

制作にあたっては、こちらの記事こちらの本を参考にさせてもらいました。

ドラッグ&ドロップで自動的に画像を16分割します。
画像ファイルそのままの大きさで16分割するので大きい画像はパズルに向かないかも。
今後そういうとこを直して機能を追加していこうと思ってます。

ソースコードは↓
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" nativeDragEnter="onDragEnter(event);" nativeDragDrop="onDragDrop(event);" width="500" height="400" viewSourceURL="srcview/index.html">
<mx:MenuBar labelField="@label" itemClick="useFile(event)" width="100%" id="myMenu">
<mx:dataProvider>
<mx:XMLList>
<Menu label="操作">
<MenuItem label="スタート" />
</Menu>
</mx:XMLList>
</mx:dataProvider>
</mx:MenuBar>
<mx:Image id="myImage" width="100%" height="100%" />
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.MenuEvent;

// 画像のロード判定用
private var loadEnd:Boolean = false;
private var file_ary:Array;
// 1ピースの幅
private var pieceWidth:Number;
// 1ピースの高さ
private var pieceHeight:Number;
// 空ピースの番号
private var empty:int;
// 完成確認用配列
private var order:Array = new Array();

// メニュー用の関数
private function useFile(e:MenuEvent):void {
if(e.label == "スタート") {
shuffle();
}
}

// ドラッグ&ドロップでロード
private function onDragEnter(event:NativeDragEvent):void {
trace("entered");
var cb:Clipboard = event.clipboard;
if(cb.hasFormat(ClipboardFormats.FILE_LIST_FORMAT)) {
// ドロップを許可
NativeDragManager.acceptDragDrop(this);
}
}

private function onDragDrop(event:NativeDragEvent):void {
if(loadEnd) {
for(var i:uint = 0; i <= 15; i++) {
myImage.removeChild(myImage.getChildByName(String(i)));
}
}

var cb:Clipboard = event.clipboard;
file_ary = cb.getData(ClipboardFormats.FILE_LIST_FORMAT) as Array;
trace("ファイル名:" + File(file_ary[0]).name);

LoaderRequest();
}

private function LoaderRequest():void {
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoadCompleted);
var request:URLRequest = new URLRequest(File(file_ary[0]).url);
loader.load(request);
}

private function LoadCompleted(event:Event):void {
// 画像はBitmapでロード
var bitmapImage:Bitmap = Bitmap(event.target.loader.content);

empty = 15;
pieceWidth = bitmapImage.width / 4;
pieceHeight = bitmapImage.height / 4;

//ピース並べ
for(var i:uint = 0; i < 15; i++) {
// ピースと同じ大きさのビットマップをつくる
var newPieceBitmap:Bitmap = new Bitmap(new BitmapData(pieceWidth, pieceHeight));
// ロードした画像から新しく作ったビットマップにコピー
newPieceBitmap.bitmapData.copyPixels(bitmapImage.bitmapData, new Rectangle((i % 4) * pieceWidth, Math.floor(i / 4) * pieceHeight, pieceWidth, pieceHeight), new Point(0, 0));

// ピースの描画
var newPiece:Sprite = new Sprite();
newPiece.addChild(newPieceBitmap);
newPiece.width = pieceWidth;
newPiece.height = pieceHeight;
newPiece.x = (i % 4) * (pieceWidth + 5) + 20;
newPiece.y = Math.floor(i / 4) * (pieceHeight + 5) + 30;
newPiece.name = String(i);
newPiece.addEventListener(MouseEvent.CLICK, click);
myImage.addChild(newPiece);
}
// 空ピースは白い長方形
var emptyPieace:Sprite = new Sprite();
emptyPieace.graphics.beginFill(0xffffff);
emptyPieace.x = 3 * (pieceWidth + 5) + 20;
emptyPieace.y = Math.floor(3) * (pieceHeight + 5) + 30;
emptyPieace.graphics.drawRect(0, 0, pieceWidth, pieceHeight);
emptyPieace.graphics.endFill();
emptyPieace.name = String(15);
myImage.addChild(emptyPieace);

// 完成判定のためIndexをセット
for(var j:uint = 0; j <= 15; j++) {
myImage.setChildIndex(myImage.getChildByName(String(j)), j);
}

// ピクチャの大きさに合わせてウィンドウの大きさを変更
nativeWindow.width = bitmapImage.width + 60;
nativeWindow.height = bitmapImage.height + 105;
loadEnd = true;
}

// ランダムシャッフル
private function shuffle():void {
var count:uint = 10000;
var imgNum:uint;

for(var i:uint = 0; i < count; i++) {
imgNum = Math.floor(Math.random() * 15);
if(checkMove(imgNum)) {
pieceMove(imgNum);
}
}
}

// ピースクリック時の処理
private function click(event:MouseEvent):void {
//ピースの番号
var pieaceNumber:int = event.currentTarget.name;
trace("click:" + pieaceNumber);
if(checkMove(pieaceNumber)) {
pieceMove(pieaceNumber);
}
}

// ピースが動かせるかチェック
private function checkMove(pieaceNumber:int):Boolean {
var result:Boolean = false;

if((pieaceNumber == (empty - 4)) || (pieaceNumber == (empty + 4)))
result = true;
else if(((pieaceNumber % 4) != 0) && ((pieaceNumber - 1) == empty))
result = true;
else if(((pieaceNumber % 4) != 3) && ((pieaceNumber + 1) == empty))
result = true;

return result;
}

// ピース移動
private function pieceMove(pieaceNumber:int):void {
var oldEmpty:int = empty;
empty = pieaceNumber;
myImage.getChildByName(String(oldEmpty)).x = (pieceWidth + 5) * (pieaceNumber % 4) + 20;
myImage.getChildByName(String(oldEmpty)).y = (pieceHeight + 5) * Math.floor(pieaceNumber / 4) + 30;
myImage.getChildByName(String(oldEmpty)).name = String(pieaceNumber);
myImage.getChildByName(String(pieaceNumber)).x = (pieceWidth + 5) * (oldEmpty % 4) + 20;
myImage.getChildByName(String(pieaceNumber)).y = (pieceHeight + 5) * Math.floor(oldEmpty / 4) + 30;
myImage.getChildByName(String(pieaceNumber)).name = String(oldEmpty);
indexExchange(pieaceNumber);
}

// Index交換用関数
private function indexExchange(index:int):void {
var indexTemp:int;

indexTemp = myImage.getChildIndex(myImage.getChildByName(String(index)));
myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(index)))), myImage.getChildIndex(myImage.getChildByName(String(empty))));
myImage.setChildIndex(myImage.getChildAt(myImage.getChildIndex(myImage.getChildByName(String(empty)))), indexTemp);

// ピース合わせ確認
checkComplete(); }

// 完成判定関数
private function checkComplete():void {
var complete:Boolean = true;
for(var i:uint = 0; i < 15; i++) {
if(!(i == myImage.getChildIndex(myImage.getChildByName(String(i))))) {
// 不一致があった場合
complete = false;
}
}
// 全て一致した場合
if(complete) {
trace("Complete!");
var alert:Alert = Alert.show("complete");
alert.isPopUp = false;
alert.cacheAsBitmap = true;
}
}
]]>
</mx:Script>
</mx:WindowedApplication>
AIRファイルのダウンロード

---------------------------------
2009/9/4 追記

AIRファイルのダウンロードは、Ver.0.1を間違えて消してしまったためVer.0.15のみです。
上のリンクからたどるか、こちらからDLできます。