練習問題

練習問題+α

次のようなクラスを作りなさい。

名前
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)がある人は、

  1. プロジェクトフォルダに、cplayer.h, cplayer.cpp をコピーします。
  2. ソリューションエクスプローラー ⇒ プロジェクト名右クリック ⇒ 追加 ⇒ 既存の項目
  3. cplayer.h, cplayer.cppを選択

ファイル(cplayer.h, cplayer.cpp)がない人は、クラスの追加で作ります!

  1. クラスの追加を起動(ソリューションエクスプローラー ⇒ 追加 ⇒ クラス
  2. 以下のように入力してOKを押す
  3. 途中まで入力するとありがたみがわかる!

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に対応させる!

クラスを改造して、グラフィックを表示して動かしてみるよ!

Fig. 1: 自機(ただの円)の表示

とりあえず、今までの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 陽悦版(要らんとこけしたやつ) を選択

  • game-engineer/classes/2022/game-programing-1/second-term/11/11-09-2.txt
  • 最終更新: 3年前
  • by root