ついに動くCostco Man
割とあっさりと、ステージの表示までできたと思う。
それってやっぱり、Console版を一回作ってどんな動作をするものを作ろうかというイメージと設計ができているのが大きいんだよね。
つまり、
ただ何も書かずに考えて、何もまとめずソースコードそのまま書こうとするやつは、一生ゲーム作れません
何事も、小さなことの積み重ねと、次を考えて行動することが大事ってことだね。
それでは次に行ってみよう。
次は、実際に荷物押して運べるようにしていこう
Console版では、プレイ画面では以下のようにゲームのループを回していた。
- Mapの初期化
- Updateで入力受付
- Updateでプレイヤーの位置を取得
- Updateでプレイヤーの移動
- Updateでプレイヤーの移動に伴う荷物の移動の処理
- UpdateでClear判定
- Clearしていたら状態を変更
- それ以外は次へ
- すべて更新し終わったらDraw関数で更新後のStageを表示
- 入力受付に戻る
大体こんな感じだった(と思う)
この処理はSiv3Dでも大体同じように書いていくことができる(っていうか、できそうな感じにConsole版書いておいたんだ)
しかも、今回のグラフィック表示は、コンソール版のマップをグラフィカルに表示しているだけなので、コンソール版が裏で動いてさえくれれば表示を更新していくだけになる。(とりあえずはね)
入力部分は、コンソール版はstdin(標準入力)を使っていたが、Siv3D版ではSiv3Dの機能を使って入力をゲットしていく
その辺も含めて、必要な機能をConsole版から移植していこう(ほとんどはコピペで済むYO!)
ソースを追加していく
まずは、宣言部。つまり、gameSequence.hの修正をしていこう
- gameSequence.h
//Mainから呼ぶやつ void UpdateTitle(GAME_STATE& _state); void DrawTitle(); void UpdatePlay(GAME_STATE& _state); void DrawPlay(); void UpdateClear(GAME_STATE& _state); void DrawClear(); //Mainからは呼ばず、gameSequenceのほうでだけ呼ぶやつ void DrawStage(Map& _map); //ちょっと引数を変えたのでこっちに書く direction GetDirection(); //Console版から持ってきたやつ OBJNAME GetObjectNum(Point _pos, Map& _map); void SetObjtoMap(OBJNAME _obj, Point _pos, Map& _map); Point GetPlayerPos(Map& _map); void MoveObject(direction _dir, Map& _map); bool CheckClear(Map& _map);
実際に入力を受け取る関数GetDirectionの引数はコンソール版ではint cでとってきていたが、関数内でSiv3Dの機能を使って入力を受け取るので引数はいらなくなる
その他は、ほとんどそのまま使える(はず)
次に、それを踏まえて、定義部(gameSequence.cpp)を修正していく
- gameSequence.cpp
//Mainから呼ぶやつ void UpdateTitle(GAME_STATE& _state) から void DrawClear() { } まで追加なしなので省略 //Mainからは呼ばず、gameSequenceのほうでだけ呼ぶやつ void DrawStage(Map& _map) { 変更なしで省略 } //ちょっと引数を変えたのでこっちに書く direction GetDirection() { //後で直すので省略 } //Console版から持ってきたやつ OBJNAME GetObjectNum(Point _pos, Map& _map) { //コンソール版そのままコピペ } void SetObjtoMap(OBJNAME _obj, Point _pos, Map& _map) { //コンソール版そのままでいいよ } Point GetPlayerPos(Map& _map) { //コンソール版そのまま } void MoveObject(direction _dir, Map& _map) { //ここだけ変更 Point dirVector[5] = { { 0, -1 },{ -1, 0 },{ 0, +1 },{ +1, 0 },{ 0, 0 } }; //Console版は、これが外に出ていたが(ほかでも使う気がしてたんだよねぇ)この関数でしか使わないので関数ローカルで宣言 //あとは、コンソール版と同じ! } bool CheckClear(Map& _map) { //コンソール版と同じでOK //ここだけ、coutは使わないのでコメントにしておこう(グラフィック表示だもんね) //cout << "おかたずけ完了!" << endl; return true; }
ここまで変更したら、最後に、入力を取得する関数direction GetDirection()を修正していく
Siv3D使っているので、キー入力は
- Key○○.Down()
- Key○○.Up()
とかで取得することができる。
コンソール版では、アロー(方向)キーの取得がちょいめんどくさかったのでスルーしたけど(できないわけじゃないんだからね)、
今回は簡単なので、アローキーでもwasdでも動くようにしよう
方向は、globals.hで、
- globals.h
//direction方向を表すenum enum direction { UP, LEFT, DOWN, RIGHT, NONE };
- 'w'または上キー
- direction::UPまたは、単にUPを返す
- 'a'または左キー
- direction::LEFTまたは、単にLEFTを返す
- 's'また下キー
- direction::DOWNまたは、単にDOWNを返す
- 'd'または右キー
- direction::RIGHTまたは、単にRIGHTを返す
Siv3Dで複数キーの入力を取得するには、ここを見てほしい。
- gameSequence.cpp
direction GetDirection() { if ('w'または上キー) { return UP; } else if ('a'または左キー) { return LEFT; } else if ('s'または下キー) { return DOWN; } else if ('d'または右キー) { return RIGHT; } else //その他の場合 return NONE; }
実際に動かしていく
あとは、UpdatePlay内で、GetDirectionを呼び出してプレイヤーの移動方向を取得し、
コンソール版のMoveObjectにぶっこんでやればいいと思う。
使うマップは、さっきincludeで読み込んだmaps[0]を使おう
void UpdatePlay(GAME_STATE& _state)
{
direction nextDir = 方向を取得
MoveObjectを使ってmaps[0]上のプレイヤーをnextDirに動かす!;
//if (MouseL.down())
//{
// _state = GAME_STATE::CLEAR;
//}
}
これで、入力があるとmaps[0]のDat[][]にあるデータが書き換えられるので、DrawPlayでは今まで通り書き換えられたデータをマップ表示すればいいだけである。(変更なし)