ウェブフォントメモ

W3Cが規定したWOFF(Web Open Font Format)というのがあり、HTML5などではこれを使うようにしていく形で環境に縛られない形でFontを添付して使用するようにしていく模様。

Google Font
Google社が公開しているフォント類(使用条件などはそれぞれご確認ください)

Font Squirrel
フォントファイルとCSSなどを提供している
TTFをWOFFに変換する機能も提供しているが、すべてのフォントで行えるわけではなく、フォント作成者が拒否リストに登録している場合がある。

Nokia Imaging SDK

Nokia Imaging SDKというWinodwsPhone8用のフィルタ/エフェクトが公開されているようです。

さらっと流し読みですが、Nokia以外の端末でも使えるけど絶対使えるとは限らない、使う場合はCopyright表記を書くことという形のようです。

Nokia Lumia 1020が出たことでレンズ、カメラアプリが望まれるだろうからSDKで盛り上げてほしいという感じかな?

HTML5基本の覚書

<!DOCTYPE html>
<html lang="ja" class="no-js">
<head>
    <meta charset="UTF-8" />
    <title>html5基本</title>
    <!-- ブラウザ機能確認JS -->
    <script src="script/modernizr.js"></script>
    <!-- 高速CSSセレクタJS -->
    <script src="script/sizzle.js"></script>
    <!-- メイン用スタイルシートのリンク -->
    <link rel="stylesheet" href="styles/main.css" />
</head>

<body>
</body>
</html>

ここまでは定型文で使用可能
「!DOCTYPE html」でHTML5であることを宣言
「html lang=”ja”」使用言語の宣言、この場合は日本語で表記されていることを宣言している
「meta charset=”UTF-8″」使用している文字コードの宣言、UTF-8が一般的
「script src~」はJavaScriptの外部読み込み宣言
HTML5からType宣言(text/javascript)は必要なくなっている。

Modernizrを使用すると、ユーザーのブラウザで使用可能なHTML5、CSSの情報が取得できる
Modernizr HP
情報は、Modernizrを読み込むように指定しておくと「class=”no-js”」をIDとして情報が付加される。
ただし開発者ツールモードで見ないと見れないのでページソースを見るでは認識できない。

スタイルシートは「head」に記載する。
HTML5からType宣言(text/css)は必要なくなっている。

StreamSoketのSampleコード

非同期化していないところがあったりするのであまりいいサンプルではないですが、StreamSoketでの通信コードです。
WriteAsync、LoadAsyncで書き込み/読み込みを行うようにしてあります。
DataReader、DataWriterを使用した際にうまくいかなかったので、このような形で実装しています。

///////////////////////////////////////////////////////////////////////////////////////////////
// サーバへ接続等

        #region サーバへ接続
        /// <summary>
        /// TCPでサーバへ接続
        /// </summary>
        /// <param name="hostname"></param>
        /// <param name="serverport"></param>
        public async void TcpSocketConnect(string hostname, string serverport)
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            // 接続済み
            if (SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Already");
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                await Task.Run(() => { throw new PopClassException(SocketDatacontext.SocketMessage); });
                return;
            }

            if (SocketDatacontext.TcpSocket == null)
            {
                SocketDatacontext.TcpSocket = new Windows.Networking.Sockets.StreamSocket();

                bool currentSetting = SocketDatacontext.TcpSocket.Control.NoDelay;
                SocketDatacontext.TcpSocket.Control.KeepAlive = true;
                SocketDatacontext.TcpSocket.Control.NoDelay = false;
            }

            try
            {
                /// タイムアウト用
                CancellationTokenSource cts = new CancellationTokenSource();

                socketevent.SocketStatus = StringResourceLoader.GetString("Trying");

                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus); 
                
                var serverHost = new HostName(hostname);

                // タイムアウトの設定
                cts.CancelAfter(10000);

                await SocketDatacontext.TcpSocket.ConnectAsync(serverHost, serverport).AsTask(cts.Token);

                // DataReaderの作成
                SocketDatacontext.PeerReader = new DataReader(SocketDatacontext.TcpSocket.InputStream);
                SocketDatacontext.PeerReader.InputStreamOptions = InputStreamOptions.Partial;

                SocketDatacontext.Connected = true;
                SocketDatacontext.Closing = false;
                socketevent.SocketStatus = StringResourceLoader.GetString("Connection");
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
            }
            catch (Exception ex)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Connecterror") + ex.Message;
                OnSocketStatus(socketevent);

                SocketDatacontext.Closing = true;
                SocketDatacontext.TcpSocket.Dispose();
                SocketDatacontext.TcpSocket = null;
                SocketDatacontext.Connected = false;

                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                throw new PopClassException(SocketDatacontext.SocketMessage);
            }
        }
        #endregion

///////////////////////////////////////////////////////////////////////////////////////////////
// サーバへデータを送る

        #region サーバへデータを送る
        public async void ResultSend(string req)
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            if (!SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Mustbeconnectedtosend");
                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                return;
            }

            try
            {
                // サーバへリクエスト送信
                if (req != "")
                {
                    StreamSocketLib writeSokect = new StreamSocketLib();

                    socketevent.SocketStatus = StringResourceLoader.GetString("Tryingtosenddata");
                    OnSocketStatus(socketevent);

                    writeSokect.DataSend(SocketDatacontext.TcpSocket, req);

                    cryearthlib.DebugLoging.DebugPrint("Data Writer End");
                }
            }
            catch (Exception exception)
            {
                socketevent.SocketStatus = "Send data or receive failed with error: " + exception.Message;
                OnSocketStatus(socketevent);
            }
        }
        #endregion
        /// <summary>
        /// データ書き込みフロント
        /// </summary>
        /// <param name="socket"></param>
        /// <param name="senddata"></param>
        public void DataSend(StreamSocket socket, string req)
        {
            _socket = socket;

            Encoding encoding = Encoding.UTF8;

            byte[] bydata = encoding.GetBytes(req + Environment.NewLine);

            if (socket == null)
            {
                cryearthlib.DebugLoging.DebugPrint("socket Error : socket null");
                throw new Exception("socket Error : socket null");
            }

            try
            {
                var task = SocketDataWrite(bydata);
                if (!task.IsCompleted)
                {
                    var ret = task.Wait(timeout);
                    if (!ret)
                    {
                        cryearthlib.DebugLoging.DebugPrint("Write Time Out");
                    }
                }

                if (!task.Result)
                {
                    cryearthlib.DebugLoging.DebugPrint("Write Time Out");
                }
            }
            catch (Exception ex)
            {
                cryearthlib.DebugLoging.DebugPrint("DataWrite Error : " + ex.Message);
                throw new Exception("DataWrite Error : " + ex.Message);
            }
        }

        /// <summary>
        /// データ書き込み本体
        /// </summary>
        /// <param name="senddata"></param>
        /// <returns></returns>
        public async Task<bool> SocketDataWrite(byte[] senddata)
        {
            var writeTask = _socket.OutputStream.WriteAsync(senddata.AsBuffer()).AsTask();

            if (!writeTask.IsCompleted)
            {
                var writeret = writeTask.Wait(timeout);
                if (!writeret)
                {
                    return false;
                }
            }

            var flushTask = _socket.OutputStream.FlushAsync().AsTask();

            if (!flushTask.IsCompleted)
            {
                var flushret = flushTask.Wait(timeout);
                if (!flushret)
                {
                    return false;
                }
            }
            return true;
        }



///////////////////////////////////////////////////////////////////////////////////////////////
// サーバからのデータを読み込む

        #region サーバからのデータを読み込む
        public async Task<string> ResultRead()
        {
            SocketStatusEventArgs socketevent = new SocketStatusEventArgs();

            if (!SocketDatacontext.Connected)
            {
                socketevent.SocketStatus = StringResourceLoader.GetString("Mustbeconnectedtosend");
                OnSocketStatus(socketevent);

                return null;
            }

            try
            {
                var lastChar = string.Empty;
                var fullString = string.Empty;

                cryearthlib.Sleep(200);
                
                socketevent.SocketStatus = StringResourceLoader.GetString("Tryingtosenddata");
                OnSocketStatus(socketevent);

                CancellationTokenSource cts = new CancellationTokenSource(1000);
                cts.Token.ThrowIfCancellationRequested();
                var bytesRead = SocketDatacontext.PeerReader.LoadAsync(1024);

                Debug.WriteLine("StreamWriteAndRead : reader.LoadAsync : " + bytesRead.Status.ToString());

                if (bytesRead.Status != Windows.Foundation.AsyncStatus.Completed)
                {
                    cts.Cancel();

                    Debug.WriteLine("StreamWriteAndRead : cts.Cancel");
                    Debug.WriteLine("StreamWriteAndRead : " + bytesRead.Status.ToString());
                }
                else
                {
                    Debug.WriteLine("StreamWriteAndRead : ReadString : " + bytesRead.Status.ToString());

                    while (SocketDatacontext.PeerReader.UnconsumedBufferLength > 0)
                    {
                        fullString += SocketDatacontext.PeerReader.ReadString(SocketDatacontext.PeerReader.UnconsumedBufferLength);
                    }
                }

                SocketDatacontext.SocketMessage = socketevent.SocketStatus = fullString;
                OnSocketStatus(socketevent);

                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                cryearthlib.DebugLoging.DebugPrint("reader.End");
                return fullString;
            }
            catch (Exception exception)
            {
                socketevent.SocketStatus = "Receive failed with error: " + exception.Message;
                OnSocketStatus(socketevent);
                cryearthlib.DebugLoging.DebugPrint(socketevent.SocketStatus);
                return socketevent.SocketStatus;
            }
        }
#endregion

Unity4.2が出てた

学習用に入れてたんですが、Unity4.2が出ていました。
大きな違いとしては「WindowsStoa」と「WindowsPhone8」向けのbuildが可能になったようです。

unity

buildの際に、専用のフォルダを作成して指定しないとbuildされないような気配です。

作製すると、VS2012用のソリューションファイルが作成されているので、VSで開き、WindowsPhone8実機に転送実行になります。

吐き出したUnityPlayerがARMのみのようなため実機(デバイス)での実行に制限されるようです。

ストアアプリ向けbuildを試したところ、エラーが発生して作成できませんでした。
エラーが文字化けしているため何でエラーなのかがちょっと不明ですが、ArrayList、Hashtableで起きています。
WP8用にbuildした際は通っているので、何かしらの制限かとも思うのですが不明です。

Unity勉強しないとな、、、

GridのRow、Columnに合わせてドラッグ移動

とりあえずドラッグの方向に合わせて移動
これだけだと過敏すぎるので移動量か移動先のRow、Column数値をとって行うとかしないとだめだと思う。

GridViewItemでDragItemThemeAnimationなんかの組み合わせのほうがいいような気もする

またはこれで行ってる「SetValue(Grid.ColumnProperty,~)」を利用してオセロや囲碁などのほうが現実的かもしれない。

        private void MainChara_ManipulationDelta(object sender, Windows.UI.Xaml.Input.ManipulationDeltaRoutedEventArgs e)
        {
        	// TODO: ここにイベント ハンドラーのコードを追加します。
            // MainChara.SetValue(Grid.RowProperty, 3);
            var radian = Math.Atan2(e.Delta.Translation.Y, e.Delta.Translation.X);
            double degree = radian * 180.0 / 3.141592653589793;

            if (degree < 0)
            {
                degree += 360;
            }

            if (degree > 315 && degree < 380)
            { 
                // 右
                var value = (int)MainChara.GetValue(Grid.ColumnProperty);
                if (value != 6)
                {
                    value++;
                    MainChara.SetValue(Grid.ColumnProperty, value);
                }
            }
            else if (degree > 0 && degree < 45)
            {
                // 右
                var value = (int)MainChara.GetValue(Grid.ColumnProperty);
                if (value != 6)
                {
                    value++;
                    MainChara.SetValue(Grid.ColumnProperty, value++);
                }
            }
            else if (degree > 45 && degree < 135)
            { 
                // 下
                var value = (int)MainChara.GetValue(Grid.RowProperty);
                if (value != 6)
                {
                    value++;
                    MainChara.SetValue(Grid.RowProperty, value);
                }
            }
            else if (degree > 135 && degree < 225)
            {
                // 左
                var value = (int)MainChara.GetValue(Grid.ColumnProperty);
                if (value != 0)
                {
                    value--;
                    MainChara.SetValue(Grid.ColumnProperty, value);
                }
            }
            else
            {
                // 上
                var value = (int)MainChara.GetValue(Grid.RowProperty);
                if (value != 0)
                {
                    value--;
                    MainChara.SetValue(Grid.RowProperty, value);
                }
            }
        }

MediaErementでのサウンド再生の制限

MediaErementで複数のBGM再生やオンメモリ再生に関しては情報は各所にあるので、そちらをご覧ください。
自分がはまったのは、コードで制御を行ってたさいに、再生、停止などはできること、複数のページにまたがってもその再生、停止はできます。
出来ないのはそれ以外での、ボリューム変更、再生位置変更、イベントの発生は行われないようです。

フォーラムで質問したところ

MediaElementの各イベントが発火する前にVisualTreeにMediaElementが属していないと、イベントの発火が起きないのが原因とのことです。

所属させた場合、ページが遷移すればその時点で解放されてサウンドは停止するので、複数ページにまたがったサウンドの場合、Freamを工夫するか、XAudio2を使用する。
またはサウンドのボリューム変更などはあきらめるという形になるものと思われます。

個人的には正直この制限は残念なので、コード制御で実行されるようになるといいと思う次第

多言語対応アプリ提出時の注意点

Windowsストアアプリ/WindowsPhoneアプリを多言語に対応させてストアへ提出する場合の注意点。
・スクリーンショットは全言語用に同じだけ用意する。
・スクリーンショットの説明は全言語で共通の内容を翻訳して記載する。

プロモーション画像やタイトルアイコン、スプラッシュ画像はよほどでない限り共通でも行ける模様。
・タイトルに漢字を使って目立たせてるのでなどの理由は必要だと思いますが、可能でした。

後から言語を増やした場合は、すでに登録済みの言語に対しての更新内容に「対応言語を増やしました」という記載をしたほうがよい。
・追加した言語は「最初の公開」でも大丈夫でした。

Windowsストアアプリでの物理キーボードの有無

物理キーボードの有無を確認することで、「キーボード操作」とタブレットでの「コントローラーUI操作」の表示切替を実装することができる。

「KeyboardCapabilities Class」を使用して確認
「KeyboardPresent」が読み取り専用であるので、これを確認すること。

下記のページで確認したもの
http://msdn.microsoft.com/ja-jp/library/windows/apps/windows.devices.input.keyboardcapabilities.aspx

Windowsストアアプリで使用できるグラフコントロール

Modern UI (Metro) Charts for Windows 8, WPF, Silverlight
License:Microsoft Public License (Ms-PL)

・これから調べる

WinRT XAML Toolkit
License:The MIT License (MIT)
上記のチャートは「Windows 8 Toolkit – Charts and More(License:Common Development and Distribution License (CDDL))」からのポート
・これから調べる
・WinRT XAML ToolkitはどうやらWin8.1ベースでVS2013になっている模様

どちらもベータで、「Modern UI (Metro) Charts for Windows 8, WPF, Silverlight」には折れ線グラフはまだない

有料であれば、下記のようなものもあります。
NetAdvantage for Windows UI