<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
    <channel>
        <title>Black technology lab</title>
        <link>http://niisaka.s33.xrea.com/</link>
        <description>変な技術を研究するサイト</description>
        <language>ja</language>
        <copyright>Copyright 2008</copyright>
        <lastBuildDate>Fri, 21 Nov 2008 20:56:31 +0900</lastBuildDate>
        <generator>http://www.sixapart.com/movabletype/</generator>
        <docs>http://www.rssboard.org/rss-specification</docs>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その9 Storyboard構築</title>
            <description><![CDATA[<p><a href="http://niisaka.s33.xrea.com/2008/11/silverlight.html">前回</a>、XAMLを使用せずにプログラムコードからStoryboardを構築するのにちょっとつまづいたので、整理も兼ねて手順を書いておきます。</p>
<p>Storyboardを構築する主な流れは次のようになります。</p>
<ol>
<li>Storyboardクラスのインスタンスを作成</li>
<li>DoubleAnimation等のアニメーションクラスのインスタンスを作成</li>
<li>アニメーションをStoryboardの子に追加</li>
<li>2で作成したアニメーションの各種プロパティを設定</li>
<li>アニメーションを適用するターゲットとプロパティを設定</li>
<li>Storyboardをビジュアルツリー内のどこかのリソースに追加</li>
<li>Beginメソッドでアニメーションの開始</li></ol>
<p>(順番は多少前後してもかまいません)</p>
<p>2のアニメーションクラスですが、1つのプロパティに対しては1つしか適用できません。青→黒のような単純な色変化だけならColorAnimationクラスでいいのですが、青→赤→緑→青のように複雑な変化をする場合は、ColorAnimationUsingKeyFramesを使う必要があります。時間がかぶらないようにColorAnimationを複数作成して、同じターゲットに対して適用しようとしたら怒られました。</p>
<p>5のアニメーションを適用するターゲットですが、円の色を変化させるのでEllipseのインスタンスを設定してみたら駄目でした。正しくは、EllipseのFillプロパティに設定したSolidColorBrushをターゲットにします。</p>
<p>アニメーションを適用するプロパティは、<span id="nsrTitle">SolidColorBrush.ColorPropertyフィールドを使って指定します。今まで各クラスにある****Propertyフィールドが何のためにあるのか謎でしたが、やっと使い道が分かりました。</span></p>
<p><span>6のリソースに追加ですが、StoryboardはUIElementではないので、CanvasのChildrenに登録することはできません。Resourcesプロパティの子にする必要があります。また、リソースに登録する際にユニークな名前を付ける必要があり、同じオブジェクトのリソース内で名前が重複してはいけません。</span></p>
<p><span>実は前回はこのStoryboardを登録するリソースの場所がよく分かっておらず、描画領域のCanvasのリソースに登録しています。円のオブジェクトの数だけStoryboardも作成しているので、新しいStoryboardを作るたびにGuid.NewGuid()でユニークな名前を生成していました。しかし、よく見たらEllipseクラスにもResourcesプロパティはあったので、Ellipseのリソースに登録すれば名前で悩む必要はありませんでした。</span></p>
<p><span>EllipseごとにStoryboardを作成するのではなく、1つのStoryboardで全てのEllipseのアニメーションを管理することも試みましたが、これはとても面倒なのでやめました。まず、Storyboardに新しいアニメーションを登録するには、アニメーションの再生を止める必要があります。このときPauseでは駄目で、Stopさせる必要があります。また、1つのStoryboardには1つのタイムラインしかないので、各アニメーションのタイミングのズレは、アニメーションの設定で吸収する必要があります。</span></p>
<p><span>Ellipseを作成して色を変化させるサンプルは次のようになります。</span></p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight-9-storyboard.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight-9-storyboard.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Fri, 21 Nov 2008 20:56:31 +0900</pubDate>
        </item>
        
        <item>
            <title>Silverlightで出来ないこと</title>
            <description><![CDATA[<p>現在のSilverlight2では次のようなことができません。</p>
<p>1.ビットマップ画像操作</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p>ラスター画像のピクセル単位での読み書きができません。</p></blockquote>
<p>2.任意の音声出力</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p>実行時に音声を生成して出力はできません。</p></blockquote>
<p>3.3Dグラフィックス表示</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p>3D関係の描画機能は一切ありません。</p></blockquote>
<p>ビットマップが扱えないのは私としてはかなり致命的で、Silverlightを使ってやりたいと思っていたことの半分くらいは無理でした。短冊のように画像が並ぶお絵描き掲示板とか作りたかったんですけどね！一応、<a href="http://www.nokola.com/Raytracer/">Silverlight Raytracing Sample</a>のように自力でPNGエンコードすれば、ビットマップを表示することは可能ですが、これをリアルタイムで実行するのはキツそうです。</p>
<p>2の音声の動的生成は最初から出来るとは思っていませんでしたが、可能ならばFM音源シミュレータのような「音」を自分で作って遊ぶようなものを作ってみたかったです。</p>
<p>3Dグラフィックスは、機能としては提供されていませんが、テクスチャ無しのグーローシェーディングくらいなら自力描画でそこそこいけるでしょう。テクスチャ付きでQuakeを作っている人もいるので、初代プレイステーション程度の表現はいけるかもしれません。ちなみに来年リリース予定のSilverlight3では、3Dグラフィックス対応とのことです。</p>
<p>まっとうなペイントツールを作るのは厳しそうなので、ベンチマークも兼ねて動くペイントツールを作ってみました。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Thu, 20 Nov 2008 19:40:09 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その8 キーボード入力</title>
            <description><![CDATA[<p>Silverlightでのキーボード入力は、キーが押されたときに発生するKeyDownイベントと離されたときに発生するKeyUpイベントで処理します。</p>
<p>ゲーム等でキーを押しっぱなしにする操作を使用する場合は、あるキーが現在押されているのかの状態を知る必要がありますが、その情報を直接的に知ることはできません。(ShiftやCtrl等の修飾的に用いるキーのみ取得可能)</p>
<p>現在のキーの押下状態を取得するには、KeyDownイベントとKeyUpイベントでキー毎の押下状態フラグをON/OFFして、自分で管理する必要があります。</p>
<p>特にキーを限定しない、汎用的な押下状態チェックは次のようになります。</p><pre><span class="synType">public</span> <span class="synStatement">partial</span> <span class="synType">class</span> Page : UserControl
{
    Dictionary&lt;Key,DateTime&gt; KeyState = <span class="synStatement">new</span> Dictionary&lt;Key,DateTime&gt;();

    <span class="synType">public</span> Page()
    {
        InitializeComponent();

        <span class="synStatement">this</span>.KeyDown += <span class="synStatement">new</span> KeyEventHandler(Page_KeyDown);
        <span class="synStatement">this</span>.KeyUp += <span class="synStatement">new</span> KeyEventHandler(Page_KeyUp);
        <span class="synStatement">this</span>.LostFocus += <span class="synStatement">new</span> RoutedEventHandler(Page_LostFocus);
    }

    <span class="synType">bool</span> IsKeyDown(Key key)
    {
        <span class="synStatement">return</span> KeyState.ContainsKey(key);
    }

    <span class="synType">void</span> Page_KeyDown(<span class="synType">object</span> sender, KeyEventArgs e)
    {
        <span class="synStatement">if</span> (!KeyState.ContainsKey(e.Key))
        {
            KeyState[e.Key] = DateTime.Now;
        }
    }

    <span class="synType">void</span> Page_KeyUp(<span class="synType">object</span> sender, KeyEventArgs e)
    {
        KeyState.Remove(e.Key);
    }

    <span class="synType">void</span> Page_LostFocus(<span class="synType">object</span> sender, RoutedEventArgs e)
    {
        KeyState.Clear();
    }
}</pre>
<p>ここでは、KeyDownイベントで押されたキーをDictionaryに登録し、KeyUpイベントで削除しています。単純に押されたキーの記録だけならDictionaryはValueの部分が冗長ですが、そのような目的に最適なHashSetがSilverlightでは使えないので、DictionaryのKeyだけを利用してValueの部分は無視して代用します。しかし、せっかくValueがあるのに使わないのはもったいないので、ここでは押されたときの時刻をValueとして使っています。これを使って、キーが押されている時間を調べることもできます。(ゲームでは実時間よりもフレーム数で管理した方が便利かもしれません)</p>
<p>また、あるキーを長時間押し続けると、OSのオートリピート処理により、同じキーに対するKeyDownイベントが繰り返し発生します。このときKeyUpイベントはキーが離されるまで発生しないので、KeyDownイベントとKeyUpイベントの発生回数は非対称になります。</p>
<p>キーボード入力に関して3つ注意点があります。</p>
<p>1つ目の注意点ですが、KeyDownイベントもKeyUpイベントも、フォーカスを得ていないと発生しません。IEでウェブサイトを表示しているときにTabを押すとページ内のリンク等を点線の枠が移動しますが、これがフォーカスを表しています。キーボードからの操作は、このフォーカスに対して行われます。</p>
<p>フォーカスを得るには、Silverlightプラグインの画面内をユーザにクリックしてもらう必要があります。よくブラウザ上で動くゲームで、ゲーム内の操作は全てキーボードで行うのにタイトル画面のメニュー選択はマウスでしか行えないという、ユーザビリティの観点からは残念なゲームがありますが、これもフォーカスを得るための苦肉の策となっています。</p>
<p>2つ目は、フルスクリーンモードでは使用できるキーが著しく制限されます。フルスクリーンでも使えるキーは、矢印キー、スペース、Tab、PageUp、PageDown、Home、End、Enterだけとなっています。OSや特定アプリケーションそっくりの画面を出してパスワードを入力させるような悪用を避けるためだそうです。矢印とスペースが使えるので、なんとかゲームにも使えそうですが、矢印以外に2ボタン以上必要なゲームは厳しいでしょう。</p>
<p>3つ目の注意点は、各ブラウザの操作コマンドに設定されているショートカットキーは、ブラウザの操作が優先されるのでSilverlightでは使えません。ただし、Ctrl+C等は(IE上では)使えるので、どのキーが使えないのか各ブラウザで確認する必要があります。とりあえず、Ctrlキーやファンクションキー(F1～F12)は使用を避けた方がいいでしょう。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight-8.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight-8.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Tue, 18 Nov 2008 15:43:46 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その7 効果音再生</title>
            <description><![CDATA[<p>効果音も基本的にはBGMと同じで、MediaElementを使います。</p>
<p>ただし、常に1つの曲が流れているBGMとは違い、効果音は同時にいくつ鳴るのか実行時にならないと分からないので、画面構成用のXAMLに静的に登録してしまうのではなく、動的にMediaElementオブジェクトを作成します。(使用する効果音が非常に少なかったり同じ音が同時に複数鳴らなければ静的に登録する手も有り)</p>
<p>まずはPage.xamlに効果音を登録するための入れ物となるCanvasを作ります。効果音は実行時に頻繁に追加/削除を繰り返すので、効果音専用にCanvasを用意すると便利です。</p><pre><span class="synIdentifier">&lt;UserControl </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Class</span>=<span class="synConstant">"SoundTest.Page"</span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span class="synIdentifier"> </span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span><span class="synComment">:</span><span class="synType">x</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml"</span><span class="synIdentifier"> </span>
<span class="synIdentifier">    </span><span class="synType">Width</span>=<span class="synConstant">"400"</span><span class="synIdentifier"> </span><span class="synType">Height</span>=<span class="synConstant">"300"</span><span class="synIdentifier">&gt;</span>
    <span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"LayoutRoot"</span><span class="synIdentifier"> </span><span class="synType">Background</span>=<span class="synConstant">"White"</span><span class="synIdentifier">&gt;</span>
        <span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"SpriteCanvas"</span><span class="synIdentifier">/&gt;</span>
        <span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"SoundCanvas"</span><span class="synIdentifier">/&gt;</span>
        <span class="synIdentifier">&lt;MediaElement </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"Music"</span><span class="synIdentifier">/&gt;</span>
    <span class="synIdentifier">&lt;/Canvas&gt;</span>
<span class="synIdentifier">&lt;/UserControl&gt;</span></pre>
<p>UserControlは子要素としてコントロールを1つしか持てないので、まずは全体の入れ物となるCanvas(LayoutRoot)を作って、その中にスプライト用Canvas、サウンド用Canvas…と入れ子にします。</p>
<p>効果音に使うファイルは、リソースとして埋め込む方法やWebサイトにxapと一緒に置いて実行時にダウンロードさせる方法があります。ここでは実装が簡単なリソースに埋め込む方法を使います。</p>
<p>まず、プロジェクトに効果音として使いたいmp3(またはwma)を登録します。登録したファイルは、ソリューションエクスプローラで「ビルドアクション」を「埋め込まれたリソース」にします。(XAMLに直接MediaElementを書く場合は「埋め込まれたリソース」では駄目で「Resource」にする理由がよく分かっていません)</p>
<p>リソースとして埋め込んだmp3は、GetManifestResourceStreamで読み込みます。</p><pre><span class="synType">public</span> <span class="synStatement">partial</span> <span class="synType">class</span> Page : UserControl
{
    Stream Sound;
    <span class="synType">void</span> Page_Loaded(<span class="synType">object</span> sender, RoutedEventArgs e)
    {
        System.Reflection.Assembly asm = <span class="synStatement">this</span>.GetType().Assembly;
        Sound = asm.GetManifestResourceStream(<span class="synConstant">"SoundTest.Resources.sound.mp3"</span>);
    }</pre>
<p>GetManifestResourceStreamに指定するリソース名は、名前空間からフルネームで指定します。大文字と小文字は区別され、フォルダの区切りは.(ピリオド)を使用します。この例ではSoundTestプロジェクトにResourcesフォルダを作って、その中にsound.mp3を入れています。</p>
<p>音を鳴らすときは、MediaElementオブジェクトを作成し、先ほど取得したStreamをソースに指定してPlayメソッドを呼びます。</p><pre>    <span class="synType">private</span> <span class="synType">void</span> PlaySound()
    {
        MediaElement me = <span class="synStatement">new</span> MediaElement();
        me.SetSource(Sound);
        me.MediaEnded += <span class="synStatement">new</span> RoutedEventHandler(me_MediaEnded);
        SoundCanvas.Children.Add(me);
        me.Play();
    }

    <span class="synType">void</span> me_MediaEnded(<span class="synType">object</span> sender, RoutedEventArgs e)
    {
        MediaElement me = sender <span class="synStatement">as</span> MediaElement;
        SoundCanvas.Children.Remove(me);
    }</pre>
<p>実はMediaElementはビジュアルツリーに登録しなくても、オブジェクトの参照を保持してさえいれば、音声は再生されます。しかし、ビジュアルツリーに登録しないと、再生が終わってもMediaEndedイベントが発生しないようです。</p>
<p>私の環境では、SoundCanvas.Children.Countが120を超えたあたりでエラーが発生しました。正確に数えた人によると、123まではOKで124個目でエラーが発生したそうです。ドキュメントにはMediaElementが100を超えるようなら制限を設けるように書いてあるだけなので、この限界値が環境依存なのかは不明です。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight-7.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight-7.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Fri, 14 Nov 2008 13:51:03 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その6 BGM再生</title>
            <description><![CDATA[<p>Silverlightで扱えるオーディオデータは、MP3(.mp3)とWindows Media Audio(.wma)の2種類だけです。WAVE(.wav)やMIDI(.mid)等は使えません。</p>
<p>使い方はスプライトのときとほとんど一緒で、MediaElementコントロールをCanvasの子として登録するだけです。他のコントロール同様XAMLで登録できます。</p><pre><span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"LayoutRoot"</span><span class="synIdentifier">&gt;</span>
    <span class="synIdentifier">&lt;MediaElement </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"Music"</span><span class="synIdentifier"> </span><span class="synType">Source</span>=<span class="synConstant">"music.mp3"</span><span class="synIdentifier"> </span><span class="synType">AutoPlay</span>=<span class="synConstant">"True"</span><span class="synIdentifier">/&gt;</span>
<span class="synIdentifier">&lt;/Canvas&gt;</span></pre>
<p>Sourceで再生するファイルはリソースとしてプロジェクトに登録しておく必要があります。その際、ビルドアクションが「埋め込まれたリソース」では駄目で、「Resource」にする必要がありました。(日本語版 Silverlight tools RC0を使用)</p>
<p>AutoPlay="True"は、このページが読み込まれると同時に、自動的に再生を開始する設定です。</p>
<p>BGMとして使用する場合はループ再生させる必要がありますが、何故かMediaElementにはループ設定がなく、MediaEndedイベントを使って自分でループを実装する必要があります。</p><pre><span class="synType">public</span> Page()
{
    InitializeComponent();
    Music.MediaEnded += <span class="synStatement">new</span> RoutedEventHandler(Music_MediaEnded);
}

<span class="synType">void</span> Music_MediaEnded(<span class="synType">object</span> sender, EventArgs e)
{
    Music.Position = <span class="synStatement">new</span> TimeSpan(<span class="synConstant">0</span>);
    Music.Play();
}</pre>
<p>つなぎ目の無いシームレスなループは無理なようで、ループする際に一瞬音が途切れてしまいます。</p>
<p>MediaEndedイベントを使わずに、ループ終了位置の後ろにループ開始位置のデータを連結したファイルを用意し、Positionがループ終了位置を越えていたらループ開始位置+越えた分に設定しなおすという方法を試しましたが、これでも少し途切れてしまいました。こちらの方が、MediaEndedイベントよりは多少マシで無音部分は1/2～1/3程度に軽減されました。</p>
<p>短いフレーズをループで繰り返すようなBGMは諦めた方がいいかもしれません。これはBGMよりも、継続的に鳴り続ける効果音で致命的なので、何か対策があればいいのですが。</p>
<p>ところで、主に画像を定義するXAMLでBGMも指定できるというのは、意外と便利そうです。例えばゲームのシーン毎にBGMを指定するのに、従来ならばBGM設定を画像とは別に管理する必要がありましたが、画像と同時に扱えれば管理がとても楽になります。フラグによってBGMが変化するというような柔軟な対応は難しいかもしれませんが、MediaElementに付ける名前の命名規則である程度は対応可能だと思います。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight-5-bgm.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight-5-bgm.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Fri, 07 Nov 2008 10:31:01 +0900</pubDate>
        </item>
        
        <item>
            <title>Expression Blendが高いと思っていたら、実は恐ろしく安かった</title>
            <description><![CDATA[<p>元々私がSilverlightに興味を持ったのは、Adobe Flashの価格が高くて「遊びで使うのにこんなに出せねーよ」と思ったのがキッカケで(もっと安いFlexでいいと後から知った)、VisualStudioで開発できるSilverlightなら私にとってはタダも同然……という、実にセコい理由だったりします。</p>
<p>しかし、蓋を開けてみれば、Silverlightの開発にはVisualStudioだけでなくExpression Blendという別のツールも使うことが分かり、そのソフトの値段が63,203円(Amazonでの現在の価格)とFlashと大差ない値段で絶望。「なんでこんなに高いんだよ！この守銭奴！」と文句を言いつつ、「Microsoftにこれ以上1円も払わんぞ！」とVisualStudioオンリーで開発を進めることを心に決めていたのが、2時間前までの私。</p>
<p>よくよく調べて見ると、アップグレード版の対象商品にVisual Studioも含まれていることが判明。</p>
<p><a href="http://www.microsoft.com/japan/products/expression/products/Upgrade.aspx">Microsoft Expression アップグレード情報</a></p>
<p>これなら私は、13,986円のExpression Blend 2 アップグレード版でいいみたいです。</p><iframe class="amazon" style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm-jp.amazon.co.jp/e/cm?t=wtcha-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=B001AG23J4&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;m=amazon&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" scrolling="no"></iframe>
<p>さらによく調べてみると、なんとこのExpression Blend 2にはVisual Studio 2008 Standard Editionも含まれているそうです。</p>
<p>Visual Studio 2008 Standard Edition アップグレード版の現在のAmazonの価格は18,711円。Expression Blend 2の方が5000円も安くて同じ物が手にはいってしまいます。ようするに、Expression Blend 2の値段はマイナス5000円ということですねw</p>
<p>というわけで、Microsoftさんは守銭奴どころか、恐ろしいほど太っ腹なことが分かりました。</p>
<p>Expression Blend 2には全く興味ないけどVisual Studio 2008は欲しいという方にも、こちらがお勧めです。</p>
<p>ところで私は<a href="http://niisaka.s33.xrea.com/2008/05/visual-studio-2008-standard-ed.html">以前</a>書いたように、既にVisual Studio 2008 Standard Editionを買ってしまったのですが、これ返品するからExpression Blend 2＋5000円と交換してもらえませんか？orz</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/expression-blend.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/expression-blend.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
            
            
            <pubDate>Sat, 01 Nov 2008 20:46:44 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その5 ゲームループ</title>
            <description><![CDATA[<p>Silverlightはユーザの入力イベントに対してハンドラを記述するイベント駆動型プログラミングモデルが基本となっていますが、アクションゲームのようなプログラムではユーザからの入力が全くない場合でも常に動き続けなければいけないので、このプログラミングモデルとは相性が良くありません。</p>
<p>一般的にゲームプログラムは、メインの処理をループで回して常にゲーム処理を動かしておく構造にします。このときのメインループを、ゲームループと呼んだりします。通常のWindowsプログラムでは、メッセージループと呼ばれるメインループが存在するので、そこをメッセージがないときでも止まらないように作ればゲームループを簡単に実装することができます。</p>
<p>しかし、SilverlightではメインループはSilverlightプラグインの内部で処理されていて、我々の手の届かない場所にあります。そこでタイマ等の一定間隔で発生するイベントをゲームループのかわりに使います。</p>
<p>ゲームループの代用になるのは、主に次の3つです。</p>
<ol>
<li>System.Windows.Media.CompositionTarget.Renderingイベント</li>
<li>DispatcherTimer</li>
<li>StoryBoard</li></ol>
<p>1のCompositionTarget.Renderingイベントというのは、Silverlightの画面更新時に発生するイベントで、処理落ちがなければ一定間隔で常に発生しています。このイベントの発生間隔は、Application.Host.Settings.MaxFrameRateで設定可能で、デフォルトでは60fpsになっています。(ただし元となるタイマの分解能が1msなので、60fpsに設定しても16ms間隔の62.5fpsになる)</p>
<p>2のDispatcherTimerは、発生間隔を100ナノ秒単位で指定できるタイマイベントですが、Silverlightでは1のCompositionTarget.Renderingが呼ばれるタイミングが最小分解能となっています。デフォルトの60fps設定の場合、16msが最小分解能となっており、DispatcherTimerに17msを設定すると実際には32ms間隔でしかイベントが発生しません。</p>
<p>3のStoryBoardは空のStoryBoardを作成し、Completedイベントが発生するたびにBeginメソッドで繰り返し開始することで、タイマイベントのように動作します。これは、DispatcherTimerのIntervalを0に設定するのと実質的に同じことで、どちらを使っても大差ないと思います。</p>
<p>特に理由がなければ、1のRenderingイベントが一番いいと思います。このイベントの使い方は次のようになります。</p><pre><code class="cs">public partial class Page : UserControl
{
    public Page()
    {
        InitializeComponent();
        CompositionTarget.Rendering += new EventHandler(CompositionTarget_Rendering);
    }
    void CompositionTarget_Rendering(object sender, EventArgs e)
    {
        OnTimer();
    }</code></pre>
<p>フレームレートの設定はHTMLからSilverlightプラグインを呼び出すときのパラメータで与えることもできますが、Appクラスで明示的に設定してしまった方がいいでしょう。</p><pre><code class="cs">public partial class App : Application
{
    public App()
    {
        this.Startup += this.Application_Startup;
        this.Exit += this.Application_Exit;
        this.UnhandledException += this.Application_UnhandledException;

        this.Host.Settings.MaxFrameRate = 60;        // 60fps

        InitializeComponent();
    }</code></pre>
<p>デフォルト値が60なので60fpsなら何も指定しなくてもいいのですが、プラグインのパラメータでフレームレートを落としてゲームの速度を遅くするチートが可能になってしまうので、60fpsでも明示的に指定しておいた方がいいと思います。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/11/silverlight-5.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/11/silverlight-5.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Sat, 01 Nov 2008 03:30:45 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その4 XAMLでパラパラアニメ</title>
            <description><![CDATA[<p>XAMLは画像を定義するだけでなく、簡単なアニメーションも登録することができます。</p>
<p>XAMLアニメーションの解説の多くは、単純に図形の位置や向きが変化したり色や透明度が変化するだけのものが多いですが、ちょっと工夫するとXAMLだけでも、パラパラ漫画のように画像を順番に切り替えていくパラパラアニメーションも作ることができます。</p>
<p>私が試して成功した方法は以下の4つです。</p>
<ol>
<li>ObjectAnimationUsingKeyFramesを使ってImageのSourceプロパティを変更して画像を切り替え</li>
<li>アニメーションを1枚に連結した画像をImageBrushに登録し、Transformでブラシの位置をずらしながら、1コマ分の大きさのRectangleを表示</li>
<li>Canvas.clipに1コマ分の大きさのRectangleGeometryを登録し、その中でImageを移動させて連結画像の1コマ分をクリップ表示</li>
<li>Canvas上の同じ位置に全ての画像を重ねて配置し、1枚ずつ順番に表示されるようにObjectAnimationUsingKeyFramesでVisibilityプロパティを切り替え</li></ol>
<p>1は一番素直だと思いますが、Sourceプロパティを変更するたびにPNG画像の読み込みが発生するので、たぶん一番重いと思います。Image専用の手法で、ベクトル画像には使えない欠点もあります。また、VisualStudioでXAMLを編集しようとすると落ちたりして、扱いづらかったです。</p>
<p>2と3は考え方はほとんど一緒で、連結画像から1コマ分だけをどうやって抜き出すのかの実現方法が違います。2はラスター画像専用ですが、3はベクトル画像にも適用できます。</p>
<p>4はStoryboardの記述が複雑になりますが、もしかすると一番軽いかもしれません。ベクトル画像をアニメーションさせる場合は、これがベストではないかと思います。</p>
<p>3の方法で作ったパラパラアニメは以下のようになります。</p><pre><span class="synIdentifier">&lt;UserControl </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Class</span>=<span class="synConstant">"SilverlightAnimationTest.Walk"</span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span><span class="synComment">:</span><span class="synType">x</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml"</span>
<span class="synIdentifier">    </span><span class="synType">IsHitTestVisible</span>=<span class="synConstant">"False"</span><span class="synIdentifier">&gt;</span>
    <span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"LayoutRoot"</span><span class="synIdentifier">&gt;</span>
        <span class="synIdentifier">&lt;Canvas </span><span class="synType">Canvas</span><span class="synComment">.</span><span class="synType">Left</span>=<span class="synConstant">"-45"</span><span class="synIdentifier"> </span><span class="synType">Canvas</span><span class="synComment">.</span><span class="synType">Top</span>=<span class="synConstant">"-73"</span><span class="synIdentifier">&gt;</span>
            <span class="synIdentifier">&lt;Canvas</span><span class="synComment">.</span><span class="synIdentifier">Clip&gt;</span>
                <span class="synIdentifier">&lt;RectangleGeometry </span><span class="synType">Rect</span>=<span class="synConstant">"0,0,75,75"</span><span class="synIdentifier">/&gt;</span>
            <span class="synIdentifier">&lt;/Canvas</span><span class="synComment">.</span><span class="synIdentifier">Clip&gt;</span>
            <span class="synIdentifier">&lt;Image </span><span class="synType">Name</span>=<span class="synConstant">"walking"</span><span class="synIdentifier"> </span><span class="synType">Source</span>=<span class="synConstant">"walking.png"</span><span class="synIdentifier"> </span><span class="synType">Stretch</span>=<span class="synConstant">"None"</span><span class="synIdentifier">/&gt;</span>
        <span class="synIdentifier">&lt;/Canvas&gt;</span>
        <span class="synIdentifier">&lt;Canvas</span><span class="synComment">.</span><span class="synIdentifier">Triggers&gt;</span>
            <span class="synIdentifier">&lt;EventTrigger </span><span class="synType">RoutedEvent</span>=<span class="synConstant">"Canvas.Loaded"</span><span class="synIdentifier">&gt;</span>
                <span class="synIdentifier">&lt;BeginStoryboard&gt;</span>
                    <span class="synIdentifier">&lt;Storyboard&gt;</span>
                        <span class="synIdentifier">&lt;DoubleAnimationUsingKeyFrames </span><span class="synType">Storyboard</span><span class="synComment">.</span><span class="synType">TargetName</span>=<span class="synConstant">"walking"</span>
<span class="synIdentifier">                            </span><span class="synType">Storyboard</span><span class="synComment">.</span><span class="synType">TargetProperty</span>=<span class="synConstant">"(Canvas.Left)"</span>
<span class="synIdentifier">                            </span><span class="synType">Duration</span>=<span class="synConstant">"0:0:1.2"</span><span class="synIdentifier"> </span><span class="synType">RepeatBehavior</span>=<span class="synConstant">"Forever"</span><span class="synIdentifier">&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"0"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:0.0"</span><span class="synIdentifier">/&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"-75"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:0.2"</span><span class="synIdentifier">/&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"-150"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:0.4"</span><span class="synIdentifier">/&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"-225"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:0.6"</span><span class="synIdentifier">/&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"-300"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:0.8"</span><span class="synIdentifier">/&gt;</span>
                            <span class="synIdentifier">&lt;DiscreteDoubleKeyFrame </span><span class="synType">Value</span>=<span class="synConstant">"-375"</span><span class="synIdentifier"> </span><span class="synType">KeyTime</span>=<span class="synConstant">"0:0:1.0"</span><span class="synIdentifier">/&gt;</span>
                        <span class="synIdentifier">&lt;/DoubleAnimationUsingKeyFrames&gt;</span>
                    <span class="synIdentifier">&lt;/Storyboard&gt;</span>
                <span class="synIdentifier">&lt;/BeginStoryboard&gt;</span>
            <span class="synIdentifier">&lt;/EventTrigger&gt;</span>
        <span class="synIdentifier">&lt;/Canvas</span><span class="synComment">.</span><span class="synIdentifier">Triggers&gt;</span>
    <span class="synIdentifier">&lt;/Canvas&gt;</span>
<span class="synIdentifier">&lt;/UserControl&gt;</span></pre>
<p>ここで使用しているwalking.pngは以下のようにアニメーションを横に連結した画像で、1コマは75*75のサイズとなっています。</p>
<p>&nbsp;</p>
<p>
<form class="mt-enclosure mt-enclosure-image" mt:asset-id="123"><img class="mt-image-center" style="DISPLAY: block; MARGIN: 0px auto 20px; TEXT-ALIGN: center" height="75" alt="walking.png" src="http://niisaka.s33.xrea.com/images/walking.png" width="450" /></form>入れ子になっている内側のCanvasは、原点を人物の足元にするためにマイナスの座標を設定しています。また1コマ分を抜き出すためのクリップGeometryもここに設定してあります。</p>
<p>アニメーションの対象が添付プロパティの場合は、このようにTargetPropertyの引数に括弧を付ける必要があります。</p>
<p>これを組み込んだ実物のサンプルは続きで。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlight-4-xaml.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlight-4-xaml.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Thu, 30 Oct 2008 08:34:25 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その3 スプライト表示</title>
            <description><![CDATA[<p>Silverlightで画面上にキャラクタ(スプライト)を表示する方法は、DirectDrawやDirect3Dのようにバックバッファに対して自力で描画するのとは全く違った考え方で、表示したいオブジェクトをビジュアルツリーに登録するだけで、後はSilverlightが勝手に描画してくれます。一度登録したら明示的に削除しなければ、ずっと表示されたままになります。昔のハードウェアスプライトを知っている人には、馴染み深いと思います。</p>
<p>まず準備として、Page.xamlにCanvasを設置します。Silverlight2にはレイアウトコントロールとして、Canvas, Grid, StackPanelがありますが、GridやStackPanelは適当に子要素を登録すれば勝手に座標をいい感じに調節して表示してくれるのに対して、Canvasは自分で細かく座標を指定して使います。スプライト表示にはCanvasを使います。ウィザードが自動生成した初期状態のPage.xamlには空っぽのGridコントロールが配置されていますが、これは必要ないのでそのままCanvasに置き換えてしまいます。(Gridの子要素としてCanvasを設置してもいい)</p><pre><span class="synIdentifier">&lt;UserControl </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Class</span>=<span class="synConstant">"SpriteTest.Page"</span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml/presentation"</span><span class="synIdentifier"> </span>
<span class="synIdentifier">    </span><span class="synType">xmlns</span><span class="synComment">:</span><span class="synType">x</span>=<span class="synConstant">"http://schemas.microsoft.com/winfx/2006/xaml"</span><span class="synIdentifier"> </span>
<span class="synIdentifier">    </span><span class="synType">Width</span>=<span class="synConstant">"400"</span><span class="synIdentifier"> </span><span class="synType">Height</span>=<span class="synConstant">"300"</span><span class="synIdentifier">&gt;</span>
    <span class="synIdentifier">&lt;Canvas </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"LayoutRoot"</span><span class="synIdentifier"> </span><span class="synType">Background</span>=<span class="synConstant">"White"</span><span class="synIdentifier">&gt;</span>
    <span class="synIdentifier">&lt;/Canvas&gt;</span>
<span class="synIdentifier">&lt;/UserControl&gt;</span></pre>
<p>スプライトのパターンデータは、プログラム上でハードコーディングすることも可能ですが、通常はXAMLファイルとして用意します。XAMLは主にベクトル画像を表現するファイルですが、ImageオブジェクトとしてPNGを貼り付ければ、ラスター画像も簡単に扱えます。</p>
<p>XAMLファイルをSilverlightアプリケーションに組み込むには、SilverlightユーザーコントロールとしてC#のクラスにしてしまう方法と、リソースに登録する方法があります。</p>
<p>ユーザーコントロールにするには、[プロジェクト]-[新しい項目の追加]-[Silverlightユーザーコントロール]からプロジェクトに追加します。ここでMario.xamlを追加すると、Marioというクラスが自動的に定義されて、コード上でMario型のオブジェクトを扱うことができます。新しいMario型のインスタンスの作成も普通に Mario mario = new Mario() で作ることができます。XAML中に書かれている子要素もクラスのメンバとして定義されるので、簡単にアクセスできます。</p>
<p>リソースとして登録する場合は、外部のエディタ等でXAMLを予め用意しておいて、[プロジェクト]-[既存項目の追加]で加えます。また、加えたXAMLファイルのプロパティを開き、ビルドアクションを「埋め込まれたリソース」に変更します。</p>
<p>リソースの場合はC#のクラスが定義されないので、インスタンスの作成がちょっと面倒で、XamlReader.Load()にXAMLを読み込ませて作成してもらうことになります。</p><pre><code class="cs">Assembly asm = this.GetType().Assembly;
Stream s = asm.GetManifestResourceStream("SpriteTest.mario.xaml");
StreamReader reader = new StreamReader(s);
UIElement mario = XamlReader.Load(reader.ReadToEnd()) as UIElement;</code></pre>
<p>スプライトのインスタンスが作成できたら、CanvasのChildrenコレクションに追加します。Page.xamlを上記のように書いた場合、CanvasにLayoutRootという名前が付いているので、そのままLayoutRootでアクセスできます。</p><pre><code class="cs">LayoutRoot.Children.Add(mario);</code></pre>
<p>表示順(Zオーダー)は<strike>Childrenコレクション内の順番に依存していて、後から追加したものほど手前に表示されます。</strike>Canvas.ZIndex添付プロパティで制御でき、ZIndexが大きいほど手前に表示されます。ZIndexが等しい場合は、Childrenコレクション内の順番に依存し、後から追加したものほど手前に表示されます。(2008/11/05訂正)</p>
<p>スプライトを表示する座標はCanvasの添付プロパティを使って設定します。</p><pre><code class="cs">Canvas.SetLeft(mario, 100); // mario.SetValue(Canvas.LeftProperty, 100)でも可
Canvas.SetTop(mario, 80); // mario.SetValue(Canvas.TopProperty, 80)でも可</code></pre>
<p>普通のオブジェクト指向的な発想では mario.X = 100; mario.Y = 80; としたいところですが、Silverlight(WPF)では添付プロパティという方法を使います。添付プロパティのメリットはまだちゃんと理解していませんが、Canvasの子要素になったときにしか使わないLeft, Topを子に持たせるのは無駄だから、親が管理するといった感じでしょうか。(Gridの子要素になったときは、Gridの行と列を表すRow, Columnが添付プロパティになります)</p>
<p>スプライトを消去するときは、Childrenコレクションから削除します。</p><pre><code class="cs">LayoutRoot.Children.Remove(mario);</code></pre>
<p>同じスプライトを複数同時に表示する場合は、表示したい数だけMarioのインスタンスを作成します。ただし、既にあるオブジェクトからクローンを作成する機能がないようなので、必要な数だけXAMLを読み込む必要があります。毎回XAMLの解析が入って無駄な感じがしますが、我慢するしか無さそうです。</p>
<p>なお、表示する数が決まっているもの(自機、スコア、ゲームオーバーの文字…etc)は、Page.xamlに最初から登録しておいて、VisibilityプロパティやOpacityプロパティで表示のON/OFFを切り替えるのが一般的なようです。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlight-3.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlight-3.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Wed, 29 Oct 2008 12:25:20 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その2 XAMLのカラクリ</title>
            <description><![CDATA[<p>Page.xamlに何かUI要素を追加して、x:Name属性で名前を付けると、Pageクラス内でその名前でアクセスできます。</p>
<p>例えば次のようにPage.xamlにRectangleを加えると</p><pre><span class="synIdentifier">&lt;Rectangle </span><span class="synType">x</span><span class="synComment">:</span><span class="synType">Name</span>=<span class="synConstant">"hoge"</span><span class="synIdentifier"> </span><span class="synType">Fill</span>=<span class="synConstant">"Red"</span><span class="synIdentifier"> </span><span class="synType">Width</span>=<span class="synConstant">"50"</span><span class="synIdentifier"> </span><span class="synType">Height</span>=<span class="synConstant">"50"</span><span class="synIdentifier">/&gt;</span></pre>
<p>Page.xaml.csでhogeを介してRectangleを操作できます。</p><pre title="Page.xaml.cs"><code class="cs">hoge.Fill = new SolidColorBrush(Colors.Green);</code></pre>
<p>このときhogeはSystem.Windows.Shapes.Rectangleクラスのインスタンスで、Pageクラスのメンバとなっています。</p>
<p>C#はC++のように宣言にうるさい言語のはずなのに、突然hogeが使えるようになっているのが気持ち悪いですが、このカラクリの秘密はobjディレクトリの中にあります。</p>
<p>
<form class="mt-enclosure mt-enclosure-image" mt:asset-id="122">
<p><img class="mt-image-right" style="FLOAT: right; MARGIN: 0px 0px 20px 20px" height="356" alt="SilverlightProject2.gif" src="http://niisaka.s33.xrea.com/images/SilverlightProject2.gif" width="356" />ソリューションエクスプローラの「すべてのファイルを表示」を押すと、普段は表示されていないBinディレクトリやobjディレクトリもプロジェクトツリーに出てきます。</p>
<p>ここでobjディレクトリを覗いてみると、App.g.csとPage.g.csという2つのC#ソースファイルが見つかります。これが、Pageクラス内でhogeが使えるカラクリの正体で、VisualStudioのフォームデザイナがXAMLを解析してC#ソースファイルを自動生成しています。Page.g.csにもPageクラスの定義が書かれており、そこでhogeメンバが宣言されています。</p>
<p>このように1つのクラスの定義を複数のファイルに分けるために、C#のパーシャルクラスという機能が使われています。パーシャルクラスはクラスの完全な定義ではなく、部分的な定義を表し、1つのクラスの定義を離れた場所に分けて書くことができます。このとき、全ての定義にpartialの修飾子を付ける必要があります。</p>
<p>パーシャルクラスを使ってツールが自動生成するソースコードとプログラマが編集するソースコードを分離すると、誤って大事な部分を破壊してしまう事故が防げます。</p>
<p>乱用すると可読性を著しく悪化させそうなパーシャルクラスですが、VisualStudioの強力な入力支援機能のおかげで、細かい定義は気にしなくても簡単に扱うことができます。</p></form>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlight-2-xaml.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlight-2-xaml.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Tue, 28 Oct 2008 03:20:05 +0900</pubDate>
        </item>
        
        <item>
            <title>プログラム主体のSilverlightの勉強 その1 プロジェクトについて</title>
            <description><![CDATA[<p>私は自作プログラムを動かすためのプラットフォームとしてSilverlightを使いたいのですが、今のところ日本語でのSilverlight入門記事は、XAMLで画面をデザインしてそれに対するイベントハンドラとしてプログラムコードを書くという、XAMLが主でプログラムコードが従の関係のものばかりです。実際、Silverlightはそのような構造のアプリケーションに最も向いていて、ExpressionとVisualStudioの組み合わせで簡単に構築することができます。</p>
<p>しかし、私がやりたいのはプログラムコードが主で、XAMLはほとんど使わないか画像ファイル代わりに使うという構造のアプリケーションです。そのような構造のアプリケーション構築に関する記事が見当たらないので、自分で勉強しながら、学んだことを少しずつ書いていこうと思います。</p>
<p>
<form class="mt-enclosure mt-enclosure-image" mt:asset-id="121">
<p><img class="mt-image-right" style="FLOAT: right; MARGIN: 0px 0px 20px 20px" height="237" alt="SilverlightProject.gif" src="http://niisaka.s33.xrea.com/images/SilverlightProject.gif" width="356" />Silverlight Tools for Visual Studio 2008を導入してSilverlightアプリケーションプロジェクトを作成すると、右の図のようなプロジェクトが作成されます。</p>
<p>App.xamlはプロジェクト内すべてのXAMLから参照するスタイルやテンプレート(HTMLにおけるCSSのような存在)のようなリソースを格納するのに使われます。Page.xamlはアプリケーションの画面デザインの定義に使われます。App.xaml.csとPage.xaml.csは各XAMLに付随するプログラムコードで、主にイベントハンドラを定義します。このプロジェクト構造から見ても、XAMLが主でプログラムコードが従の関係であることがうかがえます。</p>
<p>さて、プログラムとして見た場合、このアプリケーションのエントリポイントがどこにあるのか分からないと動作を追うこともできません。エントリポイントはプロジェクト設定で変更することができますが、初期状態では、App.xaml.cs内で定義されているAppクラスとなっています。</p>
<p>AppクラスはSystem.Windows.Applicationを継承していて、このクラスのコンストラクタがエントリポイントとなっています。ウィザードの作成したコードでは、コンストラクタでStartupイベント等にイベントハンドラを登録しています。コンストラクタもStartupイベントハンドラも実行開始時に呼び出されるもので、この2つの違いはまだよく理解していません。想像では、コンストラクタはアプリケーション全体の初期化の途中で呼び出され、他のグローバルなオブジェクトが初期化されている保証がなく、Startupイベントでは初期化が完了しているという感じでしょうか？</p></p>
<p>Startupイベントハンドラでは、App.RootVisualプロパティにPageクラス(Page.xaml.csで定義されている)を設定しています。RootVisualプロパティは、Silverlightの画面を設定するもので、試しにこのコードをコメントアウトしてみると、Silverlightのローディング画面から何も変化しなくなりました。</p>
<p>
<p>シーン遷移のように画面を切り替えるときはRootVisualプロパティを変更すればいいのかと思いましたが、このプロパティは一度しか設定できないようです。スクリーンモードの設定のような感覚で使うみたいです。</p></form></p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlight-1.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlight-1.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">プログラミング</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Sun, 26 Oct 2008 18:45:30 +0900</pubDate>
        </item>
        
        <item>
            <title>BlueTrackは最強の光学式マウス？</title>
            <description><![CDATA[<p>レーザーマウスが出た頃の売り文句は「どこでも使える」でしたが、実際にはどこでもと言うには程遠く、満足に使えるサーフェスはそれほどありませんでしたが、Microsoftが「本当にどこでも使える」という売り文句でBlueTrack Technologyという新型センサを発表しました。</p>
<p><a href="http://www.microsoft.com/japan/hardware/mouse/bluetrack/special/">http://www.microsoft.com/japan/hardware/mouse/bluetrack/special/</a></p>
<p>新製品の売り文句なんて話半分くらいに受け取っているのですが、YouTubeで実際に操作している動画を見て驚愕。これは本当にどこでも使えますw</p><embed src="http://www.youtube.com/v/kgA1vS8rJ20&amp;hl=ja&amp;fs=1" width="425" height="344" type="application/x-shockwave-flash" allowfullscreen="true"></embed> 
<p>&nbsp;</p>
<p>国内では来週、ワイヤレスモデルが2機種発売予定です。</p>
<p><a id="static_txt_preview" href="http://www.amazon.co.jp/gp/product/B001GXQLLM?ie=UTF8&amp;tag=wtcha-22&amp;link_code=as3&amp;camp=767&amp;creative=3999&amp;creativeASIN=B001GXQLLM"><font color="#003399">Microsoft Explorer Mouse(5AA-00018)</font></a></p>
<p><a id="static_txt_preview" href="http://www.amazon.co.jp/gp/product/B001GXQLM6?ie=UTF8&amp;tag=wtcha-22&amp;link_code=as3&amp;camp=767&amp;creative=3999&amp;creativeASIN=B001GXQLM6"><font color="#003399">Microsoft Explorer Mini Mouse Dark Silver(5BA-00017)</font></a></p>
<p>来年2月にこのセンサーを使用したゲーミングマウスも発売予定になっています。</p>
<p>ただし、ゲーミングマウスとして見た場合に、このセンサにはいくつか問題と思われる点があります。</p>
<p>1つめはリフトオフディスタンスの長さ。リフトオフディスタンスとは、マウスを操作面から持ち上げて反応しなくなる距離のことです。マウスを右に動かし続ける場合、ある程度動かしたらマウスを持ち上げて左に戻すという使い方をしますが、リフトオフディスタンスが長いと左に戻す際に操作を切るためにたくさん持ち上げる必要があり、操作が大変になります。リフトオフディスタンスが長いと言われるレーザーマウスですら4mm程度ですが、上の動画の様子ではかなり離れていても反応してしまいそうです。</p>
<p>もう1つの問題はセンサーが斜め向きになっていること。レーザーマウスも斜めになっているのですが、マウスを持ち上げたときにマウスカーソルが上下に動いてしまう欠点があります。リフトオフディスタンスが長いほど上下に動く量も増えてしまうので、BlueTrackはかなり動くのではないかと思います。FPSのようにマウスで視点操作をするゲームでは、この上下のブレで画面全体が動いてしまうので、たんにマウスカーソルが上下に動く以上に不快に感じてしまいます。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/bluetrack.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/bluetrack.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">マウス</category>
            
                <category domain="http://www.sixapart.com/ns/types#tag">入力機器</category>
            
            <pubDate>Fri, 24 Oct 2008 21:45:03 +0900</pubDate>
        </item>
        
        <item>
            <title>簡単Silverlightアプリケーション開発ツールPopFly</title>
            <description><![CDATA[<p>Microsoftがブラウザ上でSilverlightアプリケーションを簡単に構築できる、PopFlyというサービスを提供しています。</p>
<p><a href="http://www.popfly.com/">http://www.popfly.com/</a></p>
<p>Yahoo!Pipesのような感じで、データソースと出力ツールを接続するだけで、コーディング無しで簡単にSilverlightアプリケーションを作ることができます。</p>
<p>試しにFlickrから富士山の写真を拾ってきて表示するアプリケーションを作ってみました。(製作時間2分)</p><iframe style="WIDTH: 500px; HEIGHT: 375px" src="http://www.popfly.com/users/niisaka/Mount%20Fuji%20Photo%20Viewer.small" frameborder="no" allowTransparency></iframe>
<p>Yahoo!Pipesのように、用意された道具を組み合わせるだけでなく、自分でJavaScriptを書いて入力ソースやデータ加工ツールを作ることもできるようです。</p>
<p>今回試したのはマッシュアップツールですが、簡単なゲームを作ることもできます。○○ツクールよりは汎用的で、Win95の頃にあったClick&amp;Playみたいな感じでしょうか。コーディング無しでも色々できそうな感じですが、自分でJavaScriptでコードを追加することもできるみたいです。さすがにマッシュアップほど簡単ではなかったので、ちょっと覗いてみた程度で、ゲーム製作にはまだ手をつけていません。そのうち何か簡単なものを作ってみたいと思います。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlightpopfly.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlightpopfly.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Sat, 18 Oct 2008 16:43:41 +0900</pubDate>
        </item>
        
        <item>
            <title>Silverlight2でました</title>
            <description><![CDATA[<p>ちょっとした小ネタの発表のためのプラットフォームとして期待していたMicrosoft版Flashモドキ「Silverlight」のバージョン2.0が、やっと正式リリースされました。</p>
<p>Silverlightは1.0の頃はプログラミング言語としてJavaScriptしか使えませんでしたが、2.0ではC#、VB.NET、IronPython、IronRuby、Managed JScriptも使えるようになりました。</p>
<p>さっそく、Silverlightのポテンシャルがどの程度が調べていたら、なんとSilverlight上で動くQuakeを作っている人がいました。</p><embed src="http://www.youtube.com/v/V2iS8LCAO8s&amp;hl=ja&amp;fs=1" width="425" height="344" type="application/x-shockwave-flash" allowfullscreen="true"></embed> 
<p>Quake in Silverlight (with texture mapping)</p>
<p>Silverlightに3D描画機能はないので、ポリゴン描画はもちろん自前実装です。テクスチャまで貼られていますが、これって1ピクセルずつ描画しているんですかね？ここまでやって60fps出るそうです。(作者のPCはPentium4 3.2GHzだったと思う)</p>
<p>テクスチャ無しの3Dで何かしようとしていた自分の志の低さを痛感させられましたw</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/10/silverlight2.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/10/silverlight2.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
            
            
                <category domain="http://www.sixapart.com/ns/types#tag">Silverlight</category>
            
            <pubDate>Thu, 16 Oct 2008 18:13:52 +0900</pubDate>
        </item>
        
        <item>
            <title>AHCIはじめました</title>
            <description><![CDATA[<p>現在PCのHDD接続インターフェースとしてはSerialATAが主流ですが、SerialATAには「IDE互換モード」と「AHCIモード」と呼ばれる2つの動作モードがあります。</p>
<p>IDE互換モードはSerialATA1.0で用意された規格で、まるでパラレルATAのように振る舞うことで従来のシステムとの互換性を高めています。</p>
<p>それに対してSerialATA2.0で用意されたAHCI(Advanced Host Controller Interface)モードでは、パラレルATAとの互換性を排除して、より高度な制御が可能となっています。</p>
<p>SerialATAのドライブ本来の性能を発揮するには、IDE互換モードではなくAHCIモードで使用する必要があります。しかし、AHCIモードを使用するにはOSやドライバの対応が必要で、XPで使うには面倒な手順でOSをインストールする必要がありました。</p>
<p>私が現在使っているPCは、OSはVista、チップセットはICH9R、HDDはもちろんSerialATAの最近の物で、AHCIはすぐにでも使える状態ですが、今まではIDE互換モードになっていました。</p>
<p>せっかく使えるのだから試しに使ってみようとBIOSでAHCIに切り替えてみると……はい、起動しなくなりましたorz</p>
<p>一瞬顔が青くなりましたが、Vistaのインストール時にIDE互換モードにしていると、AHCIドライバを読み込まないように自動的に設定されるのが原因でした。</p>
<blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
<p><a href="http://support.microsoft.com/default.aspx/kb/922976/ja">ブート ドライブの SATA モードを変更した後で Windows Vista ベースのコンピュータを起動すると、エラー メッセージ "STOP 0x0000007B INACCESSABLE_BOOT_DEVICE" が表示される</a>(Microsoftサポートオンライン)</p></blockquote>
<p>レジストリを書き換えてから改めてAHCIモードに変えてみると、無事に起動しました。</p>
<p>今回は「BIOSに設定があったからなんとなく試してみた」だけで、事前に何も情報を集めていなかったので、とりあえずAHCIモードで何か問題がないか２ち○んねるで情報収集しようとギ○ナビを起動したら……起動時のプログレスバーの進み方がめちゃくちゃ速い！！ギコナビ以外のアプリケーションも起動が速くなりました。</p>
<p>「体感できなかった」という報告もよく見るので全く期待していなかったのですが、これは嬉しい誤算。私の使っているHDDは、シーケンシャルアクセスは物凄く速いがランダムアクセスが遅い、直線番長なんて言われたりするドライブなので、特にNCQが効果的なのかもしれません。</p>]]></description>
            <link>http://niisaka.s33.xrea.com/2008/09/ahci.html</link>
            <guid>http://niisaka.s33.xrea.com/2008/09/ahci.html</guid>
            
                <category domain="http://www.sixapart.com/ns/types#category">雑記</category>
            
            
            <pubDate>Tue, 02 Sep 2008 11:40:45 +0900</pubDate>
        </item>
        
    </channel>
</rss>
