====== 練習問題 ====== [[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|}}