[ゲーム制作] しゃべりながらゲーム製作やってみます #04 キャラアニメとメニュー

今回は、前回作ったキャラクターの移動にアニメーションをつけるのと、各画面用の汎用的なメニューの作りについてしゃべっています。

]]>

[ゲーム制作] しゃべりながらゲーム製作やってみます #03 カメラとかキャラを動かす

カメラ制御とプレイヤー操作によるキャラクターの動きを制御します。まとまった時間がほしい・・・。

]]>

[ゲーム制作] しゃべりながらゲーム製作やってみます #02 とりあえずなんか動かす

第2回をアップしました。15分ぐらいでまとめたかったのですが、少し長くなってしまいましたね。

]]>

[ゲーム制作] しゃべりながらゲーム製作やってみます #01(.1) 仕切り直し回

前回ゲーム制作動画を上げましたが、VOICEROID を使って動画を製作するとかなり時間がかかることが判明したので、実況形式として撮り直しました。実況は初めてなのでうまくしゃべれていないのですが、今後も継続してやっていきたいと思いますのでよろしくお願いします。

初回はゲーム制作についての概要と、テキスト表示を行っています。

]]>

Windows フォームカラーデザイナー Ver 0.01 公開

ひさびさのちーたんつ~るず第2弾を公開しました。

Windows フォームカラーデザイナーは Windows フォームのコントロールの色を編集するためのツールです。元々は ToolStripManager の Renderer に設定する ProfessionalColorTable の色を作成するために作っていたのですが、そこからいくつか昨日を拡張したツールになります。

基本的な機能は各コントロールの色を編集して XML や CSV, プログラムコードなどにエクスポートするものとなっています。そんなに機能はないので使ってみたほうが分かりやすいかと思います。

WinFormColorTop_0001

ちーたんタッチボードの公開のときにも書きましたが、ちーたんつ~るずは「これ作ればたくさん使ってくれるだとう」とか「これは絶対ものすごく役に立つツールだ」というような考えて作ったツールではなく、「自分でたまたま欲しかった」とか「さすがにこれは使う人あんまりいないんじゃないか」的なものになっています。直感的に作ってみて、それなりに使えそうだったら公開してしまおうか、というような感じで作ったツールの集まりになるかと思います。

Windows フォームカラーデザイナーも利用者は「開発者」に限定されていますし、さらにその中でも「Windows フォームアプリケーション開発者」に絞られるかと思います (独自に色は作成できるのでその限りではないのですが)。それでも使いたい人が1人でも2人でもいるのであれば公開して使っていただくのもいいかなーと思ってます。

Windows フォームカラーデザイナーは以下のページで公開しています。細かくはないですが使い方とか概要なども載せましたので、使ってみたい方はダウンロードしてみてください。

]]>

私の C# においての Region ディレクティブのつけ方

完全に私個人の考えにおいての内容なのであんまり参考にはしてほしくなかったりするのですが、こういうつけ方もあるよー、的なものとして書いておきます。

通常 Region ディレクティブの使い方としては複数のプロパティやメソッドを特定のグループとしてまとめて折りたためるようにしてコード全体を見やすくするために使います。一例としては下のような感じですかね。

#region プロパティ
public int X { get; set; }
public int Y { get; set; }
#endregion

こういう使い方は私も割と普通にします。しかし、特定のグループとして region でまとめあったとして、どのグループにいれるか判断が難しいメソッドを作成した時にどっちの region に入れるべきか迷うことが多々あります。

仮に文字列処理を「変換系」「検索系」の region でまとめたとします。そこに「Dictionary から特定のキーの値を探し出し、テキストを HTML に出力できるように変換し文字列を返す。」というメソッドを作成した場合「変換系」なのか「検索系」なのかかなり迷うことがあります。

まあこれは一例なのでほかにももっとバリエーションがあったりするのですが、そんなこんなで最近はグループのまとめとしての region はあまり使いません。

でも可視化するコードの量は減らしたいので、別案としてよくあるのが「メソッド単位で囲む」になると思います。例としては

#region " ToRadian : Degree から Radian に変換 "
/// <summary>
/// 角度を Degree から Radian に変換します。
/// </summary>
/// <param name="degree">Degree 単位の角度。</param>
/// <returns>Radian 単位の角度。</returns>
public static float ToRadian(float degree)
{
  return degree * (float)Math.PI / 180.0f;
}
#endregion

これでメソッドを1行にまとめることができます。しかし、これにはデメリットがあり、折りたたんだ場合にそのメソッドがどんなものなのかを示す情報が region の行1行にしかありません。さらに XML コメントとは別に起こさないといけないので、書くのが2度手間になり、修正も2度手間です。説明や引数が多かった場合でもなんとかして1行に収めないといけないです。

上記のような諸々の事情を解決するため、私は region を下のようにつけるようにしました。

/// <summary>
/// 角度を Degree から Radian に変換します。
/// </summary>
/// <param name="degree">Degree 単位の角度。</param>
/// <returns>Radian 単位の角度。</returns>
public static float ToRadian(float degree)
#region
{
  return degree * (float)Math.PI / 180.0f;
}
#endregion

例は1行しかないので全然メリットはないんですが、こうすることによって概要や引数、戻り値の情報が見れる状態でコードを折りたたむことができます。別途 region 用のコメントを書かなくていいのもメリットですね。もちろん1行regionよりは行数が増えてしまいますが、まあ、ここら辺はどうしようもないでしょう。増えすぎたらグループをregionでまとめて(最初に戻る)

ちなみにこの region のまとめ方は正規法でもなんでもないので、VB.NET で同じやり方をすると構文エラーで怒られます。こんなやり方もあるよー程度にしておいてください・・・。

]]>

Entity Framework にて文字列の部分一致検索を行う

メモ書きです。

using (var entities = new xxxxxxEntities())
{
  var persons = from item in entities.Person
                where item.Name.Contains(keyword)
                select item;
}
// xxxxxxEntities は .edmx ファイルから生成されたエンティティクラス
// entities.Person はデータベースのテーブルから取得、生成されたクラス・プロパティ
// keyword は検索文字列

]]>

[.NET] 他のコントロールに押下キーの情報を渡す

アクティブでないウィンドウやコントロールに対してキーボードのキーを押したかのように情報を送るには、対象コントロールなどにフォーカスを当てて「SendKeys.Send」メソッド(または SendKeys.SendWait メソッド)を使うことによって送ることができます。

例えば、以下の例ではフォームがアクティブになっている状態でキーを押したときにテキストボックスに押したキー情報を送ってテキストを入力することができます。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  SendKeys.SendWait(e.KeyChar.ToString());
}

フォームでキーが押されたときに Focus メソッドでテキストボックスにフォーカスを当て、SendKeys で押されたキーを送っています。送ったあとフォーカスを戻すのがベストだとは思いますが、必要に応じて入れてください。

基本的なコードはこれで OK なのですが、SendKeys では一部のコードが特殊な用途に使用されるキーであるため、このままでは送ることができません。対象キー、用途については以下の MSDN の SendKeys を参照してください。

特殊キーを通常の入力キーとして送るには中括弧({})で囲む必要があります。これを踏まえるとコードは以下のようになります。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}

これで一見完成のように見えるのですが、実は動かしてみると「^(カレット)」キーを押したときになぜか「&(アンパサンド)」で送られてしまいます。.NET Framework のバグかはわかりませんが、これでは完全とは言えないため別案を使います。

WSH (Windows Script Host) にも同様に SendKeys の仕組みがあり、こちらは正常にカレットが送るのでこれを使います。WSH を使うには以下の手順を行う必要がります。

  1. 参照設定の追加で、COM タブから「Windows Script Host Object Model」を追加する。
  2. 参照設定に追加された「IWshRuntimeLibrary」のプロパティを開き、「相互運用機能型の埋め込み」を False に設定する。

そのうえで以下のようにコードを修正します。#if の条件を入れていますが、WSH を使うか使わないかで分けているだけなので不要であれば消してください。

private void form1_KeyPress(object sender, KeyPressEventArgs e)
{
  // アクティブなコントロールにキーを送るためフォーカスを当てる
  textBox1.Focus();
  switch (e.KeyChar)
  {
    case '^':
#if true // Interop.IWshRuntimeLibrary を使ってよい場合
      (new IWshRuntimeLibrary.WshShellClass()).SendKeys("{^}");
      break;
#endif
    case '+':
    case '%':
    case '~':
    case '(':
    case ')':
    case '{':
    case '}':
    case '[':
    case ']':
      // 特殊記号は中かっこで囲って送る
      SendKeys.SendWait("{" + e.KeyChar + "}");
      break;
    default:
      SendKeys.SendWait(e.KeyChar.ToString());
      break;
  }
}
]]>

[C#]Visual Studioにおけるステートメントのコードスニペット

実はいままで知らなかったんですが if 文や for 文を入力する際にコードスニペットを使って定型文を入力できたんですね。今までちまちま鍵かっこと書いていました。^^;

コードスニペットは Tab キーを押して入力できます。まず、if 文を例として、if 文を入力したい箇所にカーソルを置きます。

image

続いて「if」と入力します。インテリセンスが表示されるので途中で Tab キーを押して確定しても構いません。

image

下のように「if」の後ろにカーソルがある状態で Tab キーを押します。

image

下図のように必要なかっこが自動的に作られます。あとはオレンジ色になっている個所を修正していきます。

image

else 文が必要な場合は同様に else と入力した後に Tab キーを押せば鍵かっこが追加されます。これ以外の for や while, switch などにも使えるので試してみてください。

試していませんが、VB.NET とかもできるのではないかと思います。

]]>

Type クラス同士の比較結果 [.NET Framework]

サンプルコード

namespace TypeFullName
{
    class Program
    {
        static void Main(string[] args)
        {
            Type t1 = typeof(TypeFullName.Test1.ClassSample);
            Type t2 = typeof(TypeFullName.Test1.ClassSample);
            TypeFullName.Test1.ClassSample samp1 = new Test1.ClassSample();
            TypeFullName.Test1.ClassSample samp2 = new Test1.ClassSample();
            Type t3 = samp1.GetType();
            Type t4 = samp2.GetType();
            System.Diagnostics.Trace.WriteLine("t1 == t2      : " + (t1 == t2));
            System.Diagnostics.Trace.WriteLine("t3 == t4      : " + (t3 == t4));
            System.Diagnostics.Trace.WriteLine("t3.Equals(t4) : " + t3.Equals(t4));
        }
    }
    namespace Test1
    {
        public class ClassSample
        {
            public int A;
        }
    }
}

結果

t1 == t2      : True
t3 == t4      : True
t3.Equals(t4) : True
]]>