— boreal-kiss.com

Archive
2008年10月 Monthly archive

ブログパーツコレクション
ブログパーツコレクション

この本のどこかにうちのブログパーツが載っているはず。しかし随分とまあファンシーな表紙ですこと。

Read More

16×16ピクセルのドット絵はドラクエの顔しか描けないとずっと思っていたので感動しっぱなし。キャラクターかわいい、BGM秀逸、操作性良好。難易度も適切で個人制作でここまでバランス調整できるの?と感動しつつ現在洞窟物語 for MacOSXをプレイ中。そんな洞窟物語 for Wiiウェアのサイト(海外。日本国内での販売は未定)が2008/10/06に始動したのだけどすごい雰囲気でてる(BGMはつきのうた)。Aboutに開発室Pixel本人のコメントもあってびっくり。この人のことちょっと調べたんだけど全然メディアに出てないのなあ。壁紙のダウンロードもできるようになるらしいので定期的にチェックせねば。

» Cave Story for WiiWare

関連Link:
洞窟物語 – Wikipedia
国内発フリーゲームの傑作「洞窟物語」 Wiiウェアで登場 – Engadget Japanese

追記2008/10/11

壁紙一発目来た。ちとキモイ。

Read More

カスタムクラスオブジェクトをAIRのファイル読み書きで使用する方法(Flex環境)と注意点について。AMFのserialize/deserializeの話なのでNetConnectionなどにも応用可能だと思う。

使い方

  1. 保存したいクラスに[RemoteClass]メタタグを付ける(aliasの設定は必須ではない)。例えばcom.borealkiss.UserNameクラスを使いたい場合は以下のとおり。
    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
        }
    }
  2. ローカルで保持されるのはクラスのパブリックプロパティ(or getters/setters)のみ。例えば以下の場合だとUserName.firstNameの情報を保持したままクラスオブジェクトがローカルに保存できるようになる。publicプロパティを使う場合は以下のとおり。
    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            public var firstName:String;
        }
    }

    getters/settersを使用する場合は以下のとおり。この場合setとget両方が定義されていないとローカル保存できない。

    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            private var _firstName:String;
    
            public function set firstName(value:String):void{
                _firstName = value;
            }
            public function get firstName():String{
                return _firstName;
            }
        }
    }
  3. publicまたはsetters/getters定義されているクラスプロパティは全て保存される。保存したくないプロパティには[Transient]メタタグを付ける。例えばUserName.firstNameはローカル保存したいが、UserName.lastNameプロパティは保存したくない場合は以下ように記述する。
    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            public var firstName:String;
            
            [Transient]
            public var lastName:String;
        }
    }

    getters/settersを使う場合は、get/setの定義直前に記述する。(privateプロパティ直前の記述は無効)

    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            private var _firstName:String;
            private var _lastName:String;
            
            public function set firstName(value:String):void{
                _firstName = value;
            }
            public function get firstName():String{
                return _firstName;
            }
            
            [Transient]
            public function set lastName(value:String):void{
                _lastName = value;
            }
            public function get lastName():String{
                return _lastName;
            }
        }
    }
  4. FileStream.writeObject()でローカルファイルに保存する。以下の例ではApplicationStorageDirectory (MacだとUsers/USERNAME/Library/Preferences/APPLICATION_ID/Local_Store/)の”username.data”ファイルに書き出される(UserName.lastNameは[Transient]タグがあるので保存されない)。
    import flash.filesystem.File;
    import flash.filesystem.FileMode;
    import flash.filesystem.FileStream;
    import com.borealkiss.UserName;
    
    var user:UserName = new UserName();
    user.firstName = "Colin";
    user.lastname = "Moock";
    
    var f:File = File.applicationStorageDirectory.resolvePath("username.dat");
    var fs:FileStream = new FileStream();
    fs.open(f,FileMode.WRITE);
    fs.writeObject(user);
    fs.close();
  5. ローカルファイルからデータを取得する場合はFileStream.readObject()を使う。戻り値は型が指定されていないのでUserNameクラスにキャストする必要がある。
    var f:File = File.applicationStorageDirectory.resolvePath("username.dat");
    var result:UserName;
                
    if (f.exists){
        var fs:FileStream = new FileStream();
        fs.open(f,FileMode.READ);
        while (fs.bytesAvailable){
            result = fs.readObject() as UserName;
        }
        fs.close();
    }
    
    trace(result.firstName);//Colin
    trace(result.lastName);//null

注意点

  1. FileStream.readObject()でクラスオブジェクトを取得するとき、クラスオブジェクトのコンストラクタが(引数の設定ができないにも関わらず)必ず呼ばれる。そのためコンストラクタがデフォルト値を持たない引数を持つ場合はFileStream.readObject()を使うとエラーになる。例えば以下の場合、クラスオブジェクトはローカル保存はできるがローカルから呼び出すことができない。
    //FileStream.readObject()できない場合
    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            public var firstName:String;
            public var lastName:String;
            
            /**
             * Constructor
             */ 
            public function UserName(firstName:String,lastName:String){
                this.firstName = firstName;
                this.lastName = lastName;
            }
        }
    }

    コンストラクタが引数を持たないか、または引数にデフォルト値が設定されている場合は大丈夫。

    //FileStream.readObject()できる場合
    package com.borealkiss{
        
        [RemoteClass]
        public class UserName{
            public var firstName:String;
            public var lastName:String;
            
            /**
             * Constructor
             */ 
            public function UserName(firstName:String="",lastName:String=""){
                this.firstName = firstName;
                this.lastName = lastName;
            }
        }
    }
  2. FileStream.readObject()ではコンストラクタが呼ばれた後、ローカル保存されている値がプロパティに設定される。
Read More
  • 添削するのが意外とよい勉強になる

    日本人独特の外国語の言い回しミスがあるように、外国人にも独特の日本語の言い回しミスがある。このお国柄ミスは間違いなく母国語の骨格から来ている。そんな外国語の骨格(思考の順番)をわざわざ日本語訳して教えてくれていると考えると、外国人の日本語の添削をするのは非常に貴重な行為なんじゃないかと思う。外国語初学者だったら逆にそういう変な日本語を一旦あたまの中で真似て作ってみて、それを外国語に直訳していくとか。色々利用方法がある感じ。「ギャハハ変な日本語」で終わらせるのは非常にもったいない。

  • 日記タイトルは添削してもらいたい言語で簡潔に

    マイページに「あなたの添削を待っている日記一覧」という風に表示されるのだけど、タイトルからしか判断できないので、できるだけ添削してもらいたい言語でタイトルを書く方が相手に届きやすい。さらにタイトル文字数が10文字程度しか表示されないので(超えると以下…みたいになる)、できるだけ短く、可能ならインパクトのあるやつ。個人的には下ネタが万国共通で盛り上がると思っているのだけど、今のところ食いつきが悪い。

  • 添削してもらう文章であることを忘れない

    どんだけ高レベルに達していようと、少しでもネイティブに近づきたいと思って書くのであれば、謙虚な姿勢でいるべきだと思う。この辺はもうその人の人間性にかかわってくるのかもしれないけど。

  • 言語によって需要と供給の差がある

    当たり前と言えば当たり前だけど、例えば英語学習者より英語ネイティブの参加者が余裕で少ない。英語が使える人数をいれると多いのだろうけど、基本ネイティブ以外は添削しないからかな。日本語添削希望者で添削をされていない日記を見た事は無いけど、英語添削希望者の添削されていない日記はよく見かけるので体感的には正しい。

  • 日記の長短と添削率は関係ない

    意外だったけど、長い文章だと添削されないというわけではないっぽい。僕は三行以上は添削したくなくなるけど。

  • 添削する・される者同士共通言語を持っておくと楽

    なんでこの言い回しが変なのかとかセンシティブな内容が伝えやすいし伝わりやすい。文化に関わる部分だとなおさら。

  • らきすた好きな外国人が多い
Read More

NativeDragEvent.NATIVE_DRAG_DROPイベントで、ドロップされた画像ファイルのビットマップデータを取得したい。MacとWindowsともに動作する方法を模索した。

1. Clipboardデータから直接取得する

Macの場合以下の一行でJPG, GIF, PNG, BMP, ICOファイルのビットマップデータが直接取得できるが、Windowsだと取得できない。

//NativeDragEvent.NATIVE_DRAG_DROPのイベントリスナー
function onDragDrop(e:NativeDragEvent):void{
    var bmd:BitmapData = e.clipboard.getData(ClipboardFormats.BITMAP_FORMAT) 
                        as BitmapData;
}

2. Loader.load()を使用する

次にClipboard内のファイルパスをLoaderクラスに渡してLoaderクラスのプロパティ経由でビットマップデータを取得してみる。Macだと以下の方法で取得できるが、Windowsだと取得できない。

//NativeDragEvent.NATIVE_DRAG_DROPのイベントリスナー
function onDragDrop(e:NativeDragEvent):void{
    var path:String = e.clipboard.getData(ClipboardFormats.URL_FORMAT).toString();
    var loader:Loader = new Loader();
    loader.load(new URLRequest(path));
    loader.contentLoaderInfo.addEventListener(Event.INIT,onInit);
}

function onInit(e:Event):void{
    var bmd:BitmapData = e.target.content.bitmapData as BitmapData;
}

3. Loader.loadBytes()を使用する

結局Windows(とMac)でビットマップデータにアクセスするためにはどうすればよいかというと、一つの方法は(僕はこれしか成功していない)、ドロップされる画像ファイルに割り当てられたFileクラスオブジェクトのデータをByteArrayにしてからBitmapDataに変換してやることだ。この方法だとWindows、Macともにドロップされた画像ファイルのビットマップデータを取得できる。

//NativeDragEvent.NATIVE_DRAG_DROPのイベントリスナー
function onDragDrop(e:NativeDragEvent):void{
    var files:Array = e.clipboard.getData(ClipboardFormats.FILE_LIST_FORMAT)
                        as Array;
    var f:File = files[0];
    var fs:FileStream = new FileStream();
    var ba:ByteArray = new ByteArray();
    fs.open(f,FileMode.READ);
    fs.readBytes(ba,0,fs.bytesAvailable);
    fs.close();

    var loader:Loader = new Loader();
    loader.loadBytes(ba);
    loader.contentLoaderInfo.addEventListener(Event.INIT,onInit);
}

function onInit(e:Event):void{
    var bmd:BitmapData = e.target.content.bitmapData as BitmapData;
}

ただしLoaderクラスを使うのでJPG, GIF, PNGファイルしか扱えない。BMPやICOファイルを扱いたい場合は、別途BMPDecoder – Spark projectICODecoder – Spark projectを使うとよい。

Read More