練習問題
練習問題+α
Player クラス
次のようなクラスを作りなさい。
- 名前
- cplayer
- メンバ変数
- 実数 x, y (自キャラの座標)
- 実数 speed (1フレーム当たりの移動スピード)
- 実数 dx, dy (speedから計算された1フレーム当たりのx,y座標方向の移動量)
- コンストラクタ
- 引数あり(x,y,speedを初期化)
- 引数無し
- デストラクタ
- 作るだけ作るけど、特に何もしなくいいかな?
- メンバ変数
- (各変数のゲッタ,セッタはいったん作らないでおいてください)
- MoveUp() (上移動量(y軸マイナス方向)を計算)
- MoveDown() (下移動量(y軸プラス方向)を計算)
- MoveLeft() (左移動量(x軸マイナス方向)を計算)
- MoveRight()(右移動量(x軸プラス方向)を計算)
- Update() (座標を更新)
- PrintMe() (自分の座標と、移動スピードを表示)
実行結果
- "main.cpp"
#include <iostream> #include "cplayer.h" int main() { cplayer *ppl = new cplayer(0,0, 10); ppl->MoveUP(); //上方向に移動量を設定 ppl->Update(); //座標を更新 ppl->PrintMe(); //座標を表示 ppl->MoveRight(); //右に移動量設定 ppl->MoveUP(); //上に移動量設定 ppl->PrintMe(); //表示 => Updateを呼ばないと移動量を設定しただけで実際には動かない ppl->Update(); //設定された移動量をx, yに実際に適用、これでやっと動くよ //移動した後は、dx, dy移動予定量はリセットしておく(しないと次回の移動に影響しちゃうよ) ppl->PrintMe(); //座標を表示 }
実行結果
my position => (0, -10) my position => (0, -10) my position => (10, -20)
+αをごにょごにょしてみるよ
さっきのソースコードを実際にゲームなどで使うとどんな感じになるか見てみましょう!
まず、OpenSiv3Dのプロジェクトを作ります。(プロジェクト名は何でもいいよ)
さっき作ったクラスを追加します。
ファイル(cplayer.h, cplayer.cpp)がある人は、
- プロジェクトフォルダに、cplayer.h, cplayer.cpp をコピーします。
- ソリューションエクスプローラー ⇒ プロジェクト名右クリック ⇒ 追加 ⇒ 既存の項目
- cplayer.h, cplayer.cppを選択
ファイル(cplayer.h, cplayer.cpp)がない人は、クラスの追加で作ります!
- クラスの追加を起動(ソリューションエクスプローラー ⇒ 追加 ⇒ クラス
- 以下のように入力してOKを押す
- 途中まで入力するとありがたみがわかる!
Main関数内でcplayerのインスタンスを作成
こんな感じで読み込めます!
せっかく、Siv3Dで実行しているのに結果をコンソール画面(STDOUT)に出力しているのが残念な感じですね。
- "Main.cpp"
# include <Siv3D.hpp> // OpenSiv3D v0.6.2 # include "cplayer.h" void Main() { cplayer* player1 = new cplayer(0, 0, 1.0); Console << U"Open STD CONSOLE"; player1->MoveRight(); while (System::Update()) { player1->Update(); player1->PrintMe(); } }
Siv3Dに対応させる!
クラスを改造して、グラフィックを表示して動かしてみるよ!
とりあえず、今までのx,yを自機の位置として、自機を表示するメンバ関数を追加してみます。
自機はただの円であらわします。
円はこんな感じで書けたよね?
- "円の描画"
// 中心座標 (400, 300), 半径 20 の円を描く Circle{ 400, 300, 20 }.draw();
これを、クラスのメンバにDraw()関数として組み込みます。
- "cplayer.h"
#include <iostream> using std::cout; using std::endl; using std::cin; class cplayer { private: double x,y; double speed; double dx, dy; public: cplayer(double _x, double _y, double _speed) :x(_x),y(_y),speed(_speed),dx(0),dy(0){} cplayer() :x(0),y(0),speed(0),dx(0),dy(0){} void MoveUP(); void MoveDown(); void MoveLeft(); void MoveRight(); void Update(); void PrintMe(); void Draw(); //これを追加 };
- "cplayer.cpp"
void cplayer::Draw() { const double radius = 15.0; //これもパラメータとして設定できるようにしたいね。今のところ定数 Circle(x座標, y座用, 半径).draw(お好きな色); }
これで、Update()の後にDraw()を呼ぶと、移動後の座標に自機を表示できるので、毎フレーム呼ぶと?
追加の問題
- その1
各アローキーのキーボード入力は以下の様に取得できる。
これらを使って、コンソール画面に、入力したらspeed分対応した方向へ移動した座標を表示しなさい。
各フレームに1回自分の位置を表示すること。(coutでそのまま表示できるよ!)
if (KeyUp.up()) { //上キー↑を押したときの処理 } if (KeyLeft.up()) { //左キー←を押したときの処理 } if (KeyDown.up()) { //下キー↓を押したときの処理 } if (KeyRight.up()) { //右キー→を押したときの処理 }
- その2
- 今度は、アローキーを押したときに先ほどはcout出力だったのをやめて、Circle().draw()を使って対応する位置に、自機(ただの円盤)を表示させてみよう!(動くよ!)
- その3
- 次は、画面の端まで行ったときは、それ以上動かないように自機をストップさせよう!
- 画面の外に出ないようにするには、どこで止まればいいかな?
- 上下左右の画面境界の条件をそれぞれ考えて、条件分岐してみよう!
自機の大きさは、今は固定で半径15だったよね?
- "cplayer.cpp"
void cplayer::Draw() { const double radius = 15.0; //これもパラメータとして設定できるようにしたいね。今のところ定数 Circle(x座標, y座用, 半径).draw(お好きな色); }
- その4(ちょっとむずかしいかな?)
- 現在、自機はお下方向へ押した分だけ動くようになっている。それを以下の様に変更しなさい。
- 初期状態では、画面右方向へ進み続ける
- その後は、押した方向へ進行方向を変え進み続ける。
- 画面の境界にぶつかったら、進行方向から見て右回り(時計回り方向)へ90度角度を変えて進み続ける
ちょっと始めるのが楽なテンプレートを作ってみたよって話
今までSiv3Dのプロジェクトを作ると、めっちゃいろいろ書かれたMain.cppが作成されて、それを毎回消してからソースコードを記述してました。
正直めんどくさいよね。
そのお悩み、私が解決しましょう ⇒ このテンプレートを、
ドキュメント → Visual Studio 2019 → Templates → ProjectTemplates → Visual C++ の下にコピー
新しいプロジェクトを作るときに、 OpenSiv3D_0_6_3 陽悦版(要らんとこけしたやつ) を選択



