Re: タイトル画面からゲーム画面へ ( No.1 ) |
- 名前:sereparu 日時:2020/04/12 22:34
メニュー画面で選択した項目によって画面を変更するには
まずは各画面を描画する関数を作っておいて
選択した項目ごとにそれぞれの画面の関数を呼び出す、というような作り方が一般的だと思います。
作り方については、下記サイトで紹介されている「メニュー画面の作り方」のページが参考になります。
(下記サイトではメニュー画面の作り方以外にも、ゲームを作るための基本的な知識が多数紹介されているので
初心者でしたら一通り御覧になることをおすすめします)
[新・ゲームプログラミングの館]
ttps://dixq.net/g/index.html
(URLの先頭に「h」を付けてください)
また、"Shutdown"を選んでZキーを押したときにプログラムを終了したい場合は
例えば、シャットダウンするかどうかのフラグの変数(shutdownFlag)を作って
while のループを続ける条件に「shutdownFlag == false」を加えておいて
"Shutdown"を選んでZキーを押したときだけ「shutdownFlag = true;」にすれば
while のループを抜けてプログラムを終了できると思います。
(他にも色々やり方はあると思いますが、私はこのやり方で作っています)
|
Re: タイトル画面からゲーム画面へ ( No.2 ) |
- 名前:らふれしあ 日時:2020/04/12 23:14
こんばんは!
わたしはこんな感じで書いてます。とりあえず変更した部分だけ。
参考程度にでもなれば幸いです(C言語は久々に書きました……)。
// メニュー系の関数を外に出してしまったので、参照できるように諸々の変数をグローバル変数にしてしまいました
int Handle = 0;
int Handle2 = 0;
int SelectNum = 0; //現在の選択番号
// 内容はほとんどコピペしただけです。決定キー(Zキー)を押したときの処理だけ変更してます
int UpdateManu()
{
//計算フェーズ
if (Key[KEY_INPUT_DOWN] == 1)
{ //したキーが押された瞬間だけの処理
SelectNum = (SelectNum + 1) % 2; //現在の選択項目を一つ下にずらす(ループする)
PlaySoundMem(Handle, DX_PLAYTYPE_BACK); //効果音をならす
}
if (Key[KEY_INPUT_UP] == 1)
{ //上キーが押された瞬間だけの処理
SelectNum = (SelectNum + 1) % 2; //現在の選択項目を一つ上にずらす(逆ループする)
PlaySoundMem(Handle, DX_PLAYTYPE_BACK); //効果音をならす
}
if (Key[KEY_INPUT_DOWN] == 1 || Key[KEY_INPUT_UP] == 1)
{ //下キーか上キーが押された瞬間
for (int i = 0; i < 2; i++)
{ //メニュー項目数である3個ループ処理
if (i == SelectNum)
{ //今処理しているのが、選択番号と同じ要素なら
MenuElement[i].x = 270; //座標xを260にする
}
else
{ //今処理しているのが、選択番号以外なら
MenuElement[i].x = 290; //座標をxを280にする
}
}
}
if (Key[KEY_INPUT_Z] == 1 || Key[KEY_INPUT_RETURN] == 1)
{
PlaySoundMem(Handle2, DX_PLAYTYPE_BACK);
if (SelectNum == 0) return 10; // ゲーム本編へ
else if (SelectNum == 1) return 100; // ゲーム終了処理へ
}
return 0; // メニューシーンから移動しない
}
// 内容はコピペしただけです
void DrawManu()
{
//描画フェーズ
for (int i = 0; i < 2; i++)
{ //メニュー項目を描画
DrawFormatString(MenuElement[i].x, MenuElement[i].y, GetColor(255, 255, 255), MenuElement[i].name);
}
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen(DX_SCREEN_BACK); //ウィンドウモード変更と初期化と裏画面設定
int SHandle;
SHandle = LoadSoundMem("Title_BGM.mp3");
Handle = LoadSoundMem("select.mp3");
Handle2 = LoadSoundMem("Button.mp3");
PlaySoundMem(SHandle, DX_PLAYTYPE_LOOP);
//メニュー項目要素を5つ作る
MenuElement_t MenuElement[2] = {
{270, 360, "New Game"}, //タグの中身の順番で格納
{290, 400, "ShutDown"},
};
int GameState = 0; // ゲームの遷移状態
bool GameEndFlag = false; // メインループを抜けるためのフラグ
//while(裏画面を表画面に反映、メッセージ処理、画面クリア、キー更新)
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0)
{
// GameStateの値に応じて処理分け
switch (GameState)
{
case 0: // メニュー
{
GameState = UpdateMenu();
DrawMenu();
break;
}
case 10: // ゲーム本編
{
// とりあえずダミーとして文字描画だけ
DrawFormatString(200, 200, GetColor(255, 255, 255), "ゲーム本編です");
break;
}
case 100: // ゲーム終了
{
// ゲーム終了フラグを立てる
GameEndFlag = true;
break;
}
}
//ループを抜ける
if (GameEndFlag) break;
}
DeleteSoundMem(SHandle);
DeleteSoundMem(Handle);
DeleteSoundMem(Handle2);
DxLib_End(); //DXライブラリ終了
return 0;
}
|
Re: タイトル画面からゲーム画面へ ( No.3 ) |
- 名前:codeΣ 日時:2020/04/13 10:20
返信してくれたsereparuさん、そしてらふれしあさん、ありがとうございます!
らふれしあさんが提案してくれたソースコードと、sereparuさんの処理の考え方を主に
やってみたら、処理に成功しました!
返信してくれたsereparuさん、らふれしあさん、本当にありがとうございます!
|
Re: タイトル画面からゲーム画面へ ( No.4 ) |
- 名前:kanamaru 日時:2020/04/13 11:44
最初に言っておきます。あくまでも以下は個人的な意見です。
今まで出てきた物を批判するつもりはありません。
実際質問者さんは解決にしていますし。
そのことを承知で読んでください。
なんか妙に複雑に考えているというか、無駄に長いというか。
例えばゲーム中どっかのキーを押すと開くメニューの話に聞こえます。
そこまでめんどくさく考える必要はないように思えます。
また、ゲームを丸ごと一つのWhile文に入れているように見えますが、
これって後が大変になると思います。
(少なくとも僕だったら探すのが大変)
だったらゲームの場面ごとに処理が分離していた方がいいと思います。
僕だったらタイトル画面、ゲーム本編(ゲームによってはリプレイか選択する画面も)
に分けて考えます。(僕はしませんがそれぞれ別の関数に分けてもいいかもしれない。)
できるだけ既に書かれているプログラムに変数名とか似せてみました
(キーの長押し防止とか選んでいる項目の強調の仕方とか普段使っている方法と違うので。)
#include "Dxlib.h"
int Key[256];
int gpUpdateKey() {
char tmpKey[256]; //現在のキー入力状態を格納する
GetHitKeyStateAll(tmpKey); //すべてのキー入力状態を得る
for (int i = 0; i < 256; i++) { //i番のキーコードに対応するキーが押されていたら
if (tmpKey[i] != 0) {
Key[i]++; //加算
}
else { //押されていなければ
Key[i] = 0;
}
}
return 0;
}
struct MenuElement_t {
int x, y; //座標格納用変数
char name[128]; //項目名格納用変数
} MenuElement;
int WINAPI WinMain(HINSTANCE h1,HINSTANCE hp,LPSTR lpC,int nC) {
ChangeWindowMode(true);
if (DxLib_Init() == -1) return -1;
MenuElement_t MenuElement[2] = {
{270, 360, "New Game"}, //タグの中身の順番で格納
{290, 400, "ShutDown"},
};
int SelectNum = 0;
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && gpUpdateKey() == 0) {
if ((Key[KEY_INPUT_DOWN] == 1)|| (Key[KEY_INPUT_UP] == 1)) {
SelectNum = 1 - SelectNum;
int dum = MenuElement[0].x;
MenuElement[0].x = MenuElement[1].x;
MenuElement[1].x = dum;
}
if ((Key[KEY_INPUT_Z] == 1) || (Key[KEY_INPUT_RETURN] == 1)) {
break;
}
for (int i = 0; i < 2; i++) { //メニュー項目を描画
DrawFormatString(MenuElement[i].x, MenuElement[i].y, GetColor(255, 255, 255), MenuElement[i].name);
}
}
if (SelectNum == 1) {
DxLib_End();
}
//ここにゲーム本編を書く。
ClearDrawScreen();
DrawFormatString(200, 200, GetColor(255, 255, 255), "ゲーム本編です");
WaitKey();
DxLib_End();
return 0;
}
音は自由につけてください
|
|