====== 練習問題 ======
[[game-engineer:classes:2021:game-programing-1:second-term:11:11-09-1|練習問題のページへのリンク]]
* [[https://paiza.io/ja|オンラインコンパイラ:paiza.io]]
* [[https://replit.com/|オンラインコンパイラ:replit.com]]
=== 練習問題+α ===
==== 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() (自分の座標と、移動スピードを表示)
== 実行結果 ==
#include
#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 をコピーします。
- {{:game-engineer:classes:2022:game-programing-1:second-term:11:copy_source.png?400|}}
- ソリューションエクスプローラー ⇒ プロジェクト名右クリック **⇒ 追加 ⇒ 既存の項目**
- {{:game-engineer:classes:2022:game-programing-1:second-term:11:追加.png?400|}}
- cplayer.h, cplayer.cppを選択
- {{:game-engineer:classes:2022:game-programing-1:second-term:11:copy_source.png?400|}}
ファイル(cplayer.h, cplayer.cpp)がない人は、クラスの追加で作ります!\\
- クラスの追加を起動(ソリューションエクスプローラー ⇒ 追加 ⇒ クラス
- {{:game-engineer:classes:2022:game-programing-1:second-term:11:class_add.png?400|}}
- 以下のように入力してOKを押す
- {{:game-engineer:classes:2022:game-programing-1:second-term:11:add_class_files.png?400|}}
- 途中まで入力するとありがたみがわかる!
=== Main関数内でcplayerのインスタンスを作成 ===
こんな感じで読み込めます!\\
せっかく、Siv3Dで実行しているのに結果をコンソール画面(STDOUT)に出力しているのが残念な感じですね。\\
# include // 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に対応させる! ===
クラスを改造して、グラフィックを表示して動かしてみるよ!\\
{{:game-engineer:classes:2022:game-programing-1:second-term:11:20221110-095007-871.png?400|}}
自機(ただの円)の表示
とりあえず、今までのx,yを自機の位置として、自機を表示するメンバ関数を追加してみます。\\
自機はただの円であらわします。\\
円はこんな感じで書けたよね?\\
// 中心座標 (400, 300), 半径 20 の円を描く
Circle{ 400, 300, 20 }.draw();
これを、クラスのメンバにDraw()関数として組み込みます。\\
#include
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(); //これを追加
};
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**だったよね?\\
void cplayer::Draw()
{
const double radius = 15.0; //これもパラメータとして設定できるようにしたいね。今のところ定数
Circle(x座標, y座用, 半径).draw(お好きな色);
}
* その4(ちょっとむずかしいかな?)
* 現在、自機はお下方向へ押した分だけ動くようになっている。それを以下の様に変更しなさい。
* 初期状態では、画面右方向へ進み続ける
* その後は、押した方向へ進行方向を変え進み続ける。
* 画面の境界にぶつかったら、進行方向から見て右回り(時計回り方向)へ90度角度を変えて進み続ける
=== ちょっと始めるのが楽なテンプレートを作ってみたよって話 ===
今までSiv3Dのプロジェクトを作ると、めっちゃいろいろ書かれたMain.cppが作成されて、それを毎回消してからソースコードを記述してました。\\
正直めんどくさいよね。\\
そのお悩み、私が解決しましょう ⇒ {{ :game-engineer:classes:2022:game-programing-1:second-term:11:opensiv3d_0.6.3_youetsu.zip |このテンプレート}}を、\\
ドキュメント → Visual Studio 2019 → Templates → ProjectTemplates → Visual C++ の下にコピー\\
新しいプロジェクトを作るときに、 __OpenSiv3D_0_6_3 陽悦版(要らんとこけしたやつ)__ を選択
\\
{{:game-engineer:classes:2022:game-programing-1:second-term:11:templ.png?400|}}