Help us understand the problem. What is going on with this article?

MATLAB でゲームを作る ~0. グラフィックス オブジェクト編~

More than 1 year has passed since last update.

MATLAB でゲーム制作シリーズ
- 0 章:グラフィックスオブジェクト(この記事)
- 1 章:コールバック
- 2 章:メインループ
- 3 章:アクションゲームでジャンプ

はじめに

人間はプログラミング言語を見るとゲームを作りたくなります。

「MATLAB ゲーム」と調べると MATLAB (Simulink で作ってるよくわからない人もいる) で作られたゲームが何個かヒットするので、MATLAB も例外ではありません。

ということで、MATLAB でゲームを作りたいという狂人至って正常な方々のために、MATLAB でどうやってゲームを作るのかについてまとめていきたいと思います。

 
今回は初めということで、準備編として「グラフィックス オブジェクト」に関する基礎知識をまとめていきたいと思います。

グラフィックス オブジェクトとは

 読んで字のごとく、グラフィックスを表示するためのオブジェクトのことです。
figureaxesplotsurfimage などなど、Figure ウィンドウ上に何かを描画する関数を使うと、
対応するグラフィックス オブジェクトが作成されます。

 グラフィックス オブジェクトを作成する関数は、基本的に返り値として作成したグラフィックス オブジェクトを指すハンドル(ポインタのようなもの)を返します。
例えば plot 関数だとこんな感じ。

>> t = 0:0.1:10;
>> p = plot(t,sin(t))

p = 

  Line のプロパティ:

              Color: [0 0.4470 0.7410]
          LineStyle: '-'
          LineWidth: 0.5000
             Marker: 'none'
         MarkerSize: 6
    MarkerFaceColor: 'none'
              XData: [1×101 double]
              YData: [1×101 double]
              ZData: [1×0 double]

  すべてのプロパティ を表示

この場合は "Line" という種類のグラフィックス オブジェクトが作成され、p という変数にそのハンドルが格納されています。
グラフィックス オブジェクトに関する詳しい情報はこのドキュメントに載っています。

 このようにして変数に格納したグラフィックス オブジェクトのハンドルをうまく使うと、MATLAB でもゲームっぽい動作を作れます。

グラフィックス オブジェクトのプロパティ

 グラフィックスオブジェクトは、色や位置などの情報をプロパティとして保持しています。上で plot 関数を実行したときに表示されていた "Color" や "LineWidth" などもプロパティです。

 グラフィックスオブジェクトの情報を取得したい、あるいは変更を加えたいときは、基本的に変数に格納したハンドルからプロパティにアクセスします。

プロパティ値の取得

 特定のプロパティ値を取得したい場合は、get 関数またはドット(.)を用います。例えば、上でプロットした Line オブジェクト p の線の太さを知りたい場合は以下の通りです。

>> width = get(p,'LineWidth')

width =

    0.5000

または

>> width = p.LineWidth
width =

    0.5000

私はプロパティを取得するときはほとんどドットを使用しています(こっちの方がシンプルに書けるので)。

プロパティ値の変更

 特定のプロパティ値を変更したい場合は、set 関数またはドットを用います。
例えば、Line オブジェクト p の色を赤に変更したい場合は以下の通りです。

>> set(p,'Color','r');

または

>> p.Color = 'r';

プロパティを変更するときもドットを使う場合が多いですが、
複数のプロパティを一度に変更したい場合は、set 関数を用いると 1 行でかけて便利です。

>> set(p,'LineWidth',2,'Color','r'); % 太さと色を一度に変更

よく使うグラフィックス オブジェクトまとめ

 ゲーム作りでよく使うグラフィックス オブジェクトをまとめておきます。各グラフィックス オブジェクトのプロパティ一覧は、「オブジェクト名 + プロパティ」で検索すれば、ドキュメントが出てきます。

Figure

 言わずもがな。ゲームウィンドウそのものになります。ゲームを作るときは、ゲームタイトルを付けたうえで、メニューバーや figure の番号などいらないものを消すことが多いです。

fig = figure('Name','My Game','MenuBar','none','ToolBar','none','NumberTitle','off');

どうでもいいですけど、タピオカミルクティーと Figure のプロパティって語感が似てますよね。

Axes

 座標軸です。ゲーム作りにおいてはゲーム内の世界そのもので、ここに他のオブジェクトをゲームのコンポーネントとして配置していきます。ゲーム作りでは Y 軸の向きを反対にすることが多いです(理由は次回以降の記事で説明するはずです)。ちなみに見出しは Axes ですが、axis コマンドが便利なので私は axes 関数はあまり使っていません。

ax = gca;
axis equal; %x 軸と y 軸の比率を合わせる
axis ij; %Y軸の向きを反転
axis([0 10 0 10]); %座標軸の範囲を指定
ax.Toolbar.Visible = 'off'; % 右上にマウスをかざすと出てくるメニューバーを非表示
set(ax,'XTIck',[],'YTick',[]); % 目盛りの非表示

個人的には目盛りを表示したままの方が MATLAB っぽくて好きです。

Image

 画像を表示します。すでに存在する figure 上に画像を表示するときは、XData, YData, CData を指定する必要があります。

imdata = imread('myImage.png');
im = image('XData',[0 1],'YData',[0 1],'CData',imdata);

Rectangle

 四角や丸を表示します。Position プロパティの指定の仕方が少し特殊なので注意

rec = rectangle('Position',[0 0 1 1]); % Position は [左下の点の x 座標, y 座標, 幅, 高さ] で指定
rec = rectangle('Position',[0 0 1 1]','Curvature',[1 1]) % 丸を作るときは Curvature プロパティを[1 1]に指定

Text

 文字を表示します。注意点として、デフォルトではフォントサイズは絶対サイズ(Figure のサイズによらない)扱いになっています。FontUnits プロパティを normalized に設定することで、Figure の大きさの変化に合わせて文字の大きさも変化するようになります。

text(1,1,'MATLAB','FontUnits','normalized','FontSize',0.1)

 
 
 とりあえずこれらのグラフィックス オブジェクトを使えば、マ〇オくらいだったら作れます。

便利なグラフィックス オブジェクト関連の関数

 グラフィックス オブジェクト用の便利な関数の紹介です。

gcf, gca コマンド

 それぞれアクティブになっている figure および axes のオブジェクトのハンドルを取得できます。

>> fig = gcf

fig = 

  Figure (1) のプロパティ:

      Number: 1
        Name: ''
       Color: [0.9400 0.9400 0.9400]
    Position: [680 678 560 420]
       Units: 'pixels'

  すべてのプロパティ を表示
>> ax = gca

ax = 

  Axes のプロパティ:

             XLim: [0 1]
             YLim: [0 1]
           XScale: 'linear'
           YScale: 'linear'
    GridLineStyle: '-'
         Position: [0.1300 0.1100 0.7750 0.8150]
            Units: 'normalized'

  すべてのプロパティ を表示

ゲーム起動中にうっかり別の Figure をクリックするととんでもないことになるので、
私はゲームのコード内では初期化処理以外で極力使わないようにしています。

delete 関数

 グラフィックス オブジェクト自体は変数を clear しても消えないので、消したい場合は delete 関数を使います。

>> delete(p);

当たり前ですが、一度 delete したグラフィックス オブジェクトのプロパティにはアクセスできません。

>> delete(p);
>> width = p.LineWidth
無効であるか削除されたオブジェクトです。

削除されたオブジェクトのハンドルが変数に残留思念のように残っていてそのプロパティを参照してしまう、
というのはゲームプログラムにおいて頻繁に生じるバグですので注意しましょう。

isgraphcs 関数

 グラフィックス オブジェクトが delete されているかを判別する関数です。残留思念のように変数に残っているオブジェクトから身を守ります。

>> fig = figure;
>> isgraphics(fig)

ans =

  logical

   1

>> delete(fig);
>> isgraphics(fig)

ans =

  logical

   0

途中で figure が閉じられたら処理を終了する、などの処理に使えます。

gobjects 関数

 グラフィックス オブジェクト配列の事前割り当ての関数です。マップチップのように同じタイプのオブジェクトを何個も作って行列や配列として保存しておく場合に便利です(セル配列でいい)

>> garray = gobjects(1,4);
for i = 1:4
garray(i) = rectangle('Position',[i 1 1 1]);
end
axis([0 5 0 5])
garray

garray = 

  1×4 Rectangle 配列:

    Rectangle    Rectangle    Rectangle    Rectangle

findobj 関数

 プロパティが特定の値となっているグラフィックス オブジェクトを検索できます。特定のオブジェクトにのみ何か操作を行いたい場合に非常に便利です。

>> objs = findobj('Type','Line','Color','r'); % 赤い Line オブジェクトのみを取得

まとめ

  • グラフィックス オブジェクトを作成する関数は返り値としてそのオブジェクトのハンドルを返す
  • グラフィックス オブジェクトの取得や変更を行う場合は、ハンドルに対してget,set,ドットなどを用いてプロパティにアクセスする
  • ゲーム作りに使えそうなオブジェクトは基本的な使い方を覚えておこう
  • ゲーム作りで便利な関数は存在だけでも抑えておこう

次回から本格的にゲームっぽい挙動を作っていく予定です。

 
 「いいね」が増えると次回の記事が豪華になるかも

macht
MATLAB でゲームを作りたい。 All comments and opinions expressed are mine alone and do not necessarily reflect those of my employers, past or present.
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした