はじめに
本資料は、やぎりが作成した、C++初学者向け資料です。
C++とSiv3Dで実際にシューティングゲームを作り、「C++の機能(クラス, vector, ポリモーフィズム)をゲームを作るにあたって実際にどう使うか何となく理解」することが目的になっています。
これまでC、C++の本やサイトを読み、配列や関数は何となく使えるが、ゲームを作るにあたってクラスをどう使えばいいのかわからない、といった人向けです。そのため、Siv3Dの機能をフルで使わない面がありますが(初心者にはプログラムの見た目が難しくなりすぎるため)、ご了承ください。もちろんわかっている方は、適宜C++の闇の力や、Siv3Dの神の力を使って頂いて構いません。逆に、Siv3D自体の知識は適宜説明していくため、完全なSiv3D初心者でも大丈夫です。
開発環境
開発環境はWindows, Visual Studio 2015、Siv3DのバージョンはSiv3D August 2016 v2を想定しています。
Siv3Dの導入
インストール - Play Siv3D!参照。VisualStudio2015がインストールされていれば、インストーラーを実行するだけで導入が完了します。
謝辞
本資料の一部は、いかろちゃんのサークル用C++講座資料を参考に作られました。ありがとうございました。
本資料のやり方
基本的にコードをコピペして自分で動かして確認、少し書き換えて思った通りになるか確認しながら進んでください。たまにC++の闇が顕現することがありますが、その場合は次の項目に進んで、後で戻ってきて考えるといいと思います。また、概要だけ説明するため、いろいろな話が割愛されているので、詳細が気になる場合はとりあえず無視して進むか、気になる場合はネットでC++の各機能を調べながら進むといいです。
あと、全体的に難しい(※人による)ので、途中で心が折れても気にしないほうがいいです。気が向いたら戻ってきてください。
演習問題について
Siv3D.hppをインクルードしているプログラムはSiv3Dを使ったアプリケーションを、そうでないプログラムはコンソールアプリケーション(文字だけ出てくる黒画面のやつ)で解くことを想定しています。
演習問題(コンソール)の解答は、vol_12_演習問題(コンソール)の解答の解答に書いてあります。
演習問題(Siv3D)の解答例は添付資料内に入っています。
添付資料内のファイルについて
-
演習問題(Siv3D)解答例コード
演習問題(Siv3D)の解答例です。 -
サンプルゲーム.exe
前半課題、最終課題ではこれに似たゲームを作ってもらいます。
今回やること
今回は本資料でよく使うSiv3Dの関数、クラスの解説を行います。
各回の資料について
-
クラスの基本
クラスの基本的な書き方を学ぶ。Siv3Dを用いた演習では、上下左右に移動するプレイヤーを作成する。 -
ファイル分け・コンポジション
クラスのファイル分けの方法を学ぶ。また、クラスの中にクラスを持つコンポジションに関しても学ぶ。「クラスの基本」で作成したSiv3Dのプロジェクトのプログラムを実際分割する。 -
vectorの基本
要素数を変更可能な動的配列"vector"を用いて、敵を複数生成・表示する。 -
参照・クラスのポインタ
オブジェクトから他のオブジェクトの情報を得るための参照・ポインタについて学び、Siv3Dの実例ではEnemyからPlayerの情報を参照する。以降の章で学ぶイテレータはポインタを模して作られているので、そのための予備知識としての位置づけでもある。 -
関数オーバーロード・コンストラクタ・デストラクタ
クラスを生成したときと破棄したときに呼ばれる、コンストラクタとデストラクタについて学ぶ。 -
イテレータ・vector要素の削除
vector要素を削除するやり方を学ぶ。敵を削除できるようになる。 -
remove_if・ラムダ式
前回とは別の方法で、vectorの要素を削除する。remove_if・ラムダ式を用いる。 -
GameManagerクラス・前半課題
実際にシューティングもどきを作るためのファイル分け、相互インクルードを学ぶ。また、ゲーム中全てのオブジェクトを要素に持つManagerクラスを作る。
前半課題は、これまで習得した知識でサンプルゲーム.exeと同じシューティングもどきを作成する。(正直インクルードなどややこしく、引っかかると詰む可能性があるので、詰んだら敵だけなど作れる部分だけ作った上で、解答を見て飛ばしてもいいかもしれない。) -
new・delete・基底・派生クラス
動的にメモリを確保・開放する機能new, deleteについて学ぶ。また、基底・派生クラスについて書き方を説明する。 -
仮想関数・ポリモーフィズム
本編
EnemyA,EnemyB,EnemyCを継承を用いて書き、まとめて扱う。 -
スマートポインタ・最終課題
使わなくなったら自動的にメモリを開放してくれるスマートポインタについて学ぶ。
最終課題では、前半課題を後半やった内容で書き直し、ポリモーフィズムの有用性を確認する。 -
演習問題(コンソール)の解答
すべての回の演習問題(コンソール)の解答例を示す。
本資料でよく使うSiv3Dの関数、クラス解説
以下では、本資料でよく使うSiv3Dの関数、クラスに関して解説している。クラスなど、Vol1以降で説明する内容も多分に含んでいるため、わからないところがあったらある程度理解して飛ばし読みしておき、後で戻ってきて理解したほうがよい。
マウス座標を描画、マウス座標に円を描画する例
以下の例では、マウス座標を取得し、画面に文字として描画している。また、マウス座標の位置にオレンジの円を描画している。
Main.cpp
# include <Siv3D.hpp>
void Main()
{
// Fontクラスのインスタンスを生成。フォントサイズは18を指定
const Font font(18);
while (System::Update())
{
// マウス座標を取得
int mouseX = Mouse::Pos().x;
int mouseY = Mouse::Pos().y;
// マウスの座標を文字として描画
font(L"MouseX:", mouseX, L" MouseY:", mouseY).draw();
// マウスのある位置にオレンジの円を描画
Circle(mouseX, mouseY, 50).draw(Color(255, 128, 0));
}
}
以上の例では、while内が約1/60秒に一回実行される。つまり、1/60秒ごとにパラパラ漫画のように画面の更新、再計算が行われている。一回の更新時間のことをフレームと呼ぶ。
また、実行してマウスの位置の座標を見るとわかると思うが、y座標は下側が正で、画面の左上が(0,0)画面の右下が(640,480)である。
文字を描画
while外でFontのインスタンスを生成const Font font(FontSize);
した後に以下を実行
内容:(a, b, c...) 複数の引数、型を指定可能
font(a, b, c...).draw();
円を描画
座標:(x,y), 半径:radius, 色:(r,g,b)
Circle(x, y, radius).draw(Color(r, g, b));
キー入力に応じて数字を増加する例
以下の例では、Zキーを押している間、毎フレームnumが1ずつ増えていき、Xキーを押したフレームにnumが100増え、Cキーを押したフレームにnumが0~100のランダムな値になる例を示している。
1秒あたり約60フレーム経過するので、Zキーを押している間numは1秒あたり約60ずつ増加する。
# include <Siv3D.hpp>
void Main()
{
// Fontクラスのインスタンスを生成。フォントサイズは18を指定
const Font font(18);
int num = 0;
while (System::Update())
{
// zキーを押している間numが1ずつ増加
if(Input::KeyZ.pressed){
num += 1;
}
// xキーを押すとnumが100増加
if (Input::KeyX.clicked) {
num += 100;
}
// cキーを押すとnumが0~100の間のランダムな数に
if (Input::KeyC.clicked) {
num = Random(0, 100);
}
font(L"Num:", num).draw();
}
}
キーを押しているか取得(押しているフレーム中true)
Input::KeyXXX.pressed
キーが押されたか取得(押されたフレームのみtrue)
Input::KeyXXX.clicked
主要キー
キー | 名称 |
---|---|
Z | KeyZ |
← | KeyLeft |
↓ | KeyDown |
↑ | KeyUp |
→ | KeyRight |
Enter | KeyEnter |
ランダムな値を取得
最小値:a, 最大値:b
Random(a, b);
演習問題(Siv3D)
-
double型の変数x, yを用意し、Circleクラスのdraw関数を用いてx,yに半径20pxの赤い円を描画せよ。(ヒント:赤=(r:255, g:0, b:0))
-
矢印キーを押したとき上記で描画した円が動くようにせよ。(x、yに数字を足せばよい)
-
Zキーを押しているフレームにx座標にRandom(-30.0, 30.0)を加算し、円が荒ぶる姿を観測せよ。