ホームへ戻る

 sp7章 メニュー画面の作り方 [選択項目編]

 今回紹介したメニュー画面はGキーやCキーを直接選択して画面を変える仕様でした。
しかしメニュー画面は普通、上下キーで選択状態を変え、エンターキー等で決定する仕様が普通でしょう。

(こんな感じ)

そこで、「メニュー画面の作り方.2」のコードを少しいじって上下キーで選択状態を変える仕様にしてみます。

今回キー入力を扱うので、「2.9章 全てのキーの入力状態を取得する」のコードをマージします。
利用の仕方は「d.4章 ゲームの設計と分割コンパイル(2) 」に従います。
まず、Keyboard.hとKeyboard.cppをソリューションに追加して、以下のコードを追加して下さい。
(d.4章と同じコードです)


↓Keyboard.h↓


#pragma once

// キーの入力状態を更新する
void Keyboard_Update();

// 引数のキーコードのキーの入力状態を返す
int Keyboard_Get( int KeyCode );

↓Keyboard.cpp↓


#include "DxLib.h"

static int m_Key[256];  // キーの入力状態格納用変数

// キーの入力状態更新
void Keyboard_Update(){
    char tmpKey[256];             // 現在のキーの入力状態を格納する
    GetHitKeyStateAll( tmpKey );  // 全てのキーの入力状態を得る
    for( int i=0; i<256; i++ ){ 
        if( tmpKey[i] != 0 ){ // i番のキーコードに対応するキーが押されていたら
            m_Key[i]++;   // 加算
        } else {              // 押されていなければ
            m_Key[i] = 0; // 0にする
        }
    }
}

// KeyCodeのキーの入力状態を取得する
int Keyboard_Get( int KeyCode ){
    return m_Key[ KeyCode ]; // KeyCodeの入力状態を返す
}

今回変更を加えるのは以下に示す Menu.cpp です。
列挙体でeMenuを定義し、現在ゲーム選択中なのか設定選択中なのかを示すNowSelect変数を用意します。
後のことは基本的に「3.4章 簡単な選択画面を作る (マイナス方向へのループ) 」と同じです。
Menu_Update関数内で状態を更新します。キーの入力によって現在の選択状態を変更します。
(今回は項目が2つしかないので、マイナス方向へのループは考えなくてもいいのですが)
エンターが押されると、SceneMgr_ChangeScene()をコールバックしてシーンを変更します。
Menu_Draw関数内では現在の選択状態によって「■」の表示位置を変更して表示しています。


↓Menu.cpp↓


#include "Menu.h"
#include "SceneMgr.h"
#include "DxLib.h"
#include "Keyboard.h"

const static int GAME_Y   = 240;    //「ゲーム」文字のy位置
const static int CONFIG_Y = 270;    //「設定」文字のy位置

typedef enum{
    eMenu_Game,        //ゲーム
    eMenu_Config,    //設定

    eMenu_Num,        //本項目の数
} eMenu ;

static int NowSelect = eMenu_Game;    //現在の選択状態(初期はゲーム選択中)

//更新
void Menu_Update(){
    if(Keyboard_Get(KEY_INPUT_DOWN)==1){//下キーが押されていたら
        NowSelect = (NowSelect+1)%eMenu_Num;//選択状態を一つ下げる
    }
    if(Keyboard_Get(KEY_INPUT_UP)==1){//上キーが押されていたら
        NowSelect = (NowSelect+(eMenu_Num-1))%eMenu_Num;//選択状態を一つ上げる
    }
    if(Keyboard_Get(KEY_INPUT_RETURN)==1){//エンターキーが押されたら
        switch(NowSelect){//現在選択中の状態によって処理を分岐
        case eMenu_Game://ゲーム選択中なら
            SceneMgr_ChangeScene(eScene_Game);//シーンをゲーム画面に変更
            break;
        case eMenu_Config://設定選択中なら
            SceneMgr_ChangeScene(eScene_Config);//シーンを設定画面に変更
            break;
        }
    }
}

//描画
void Menu_Draw(){
    DrawString(200, 150,     "メニュー画面です。",GetColor(255,255,255));
    DrawString(200, 170,     "上下キーを押し、エンターを押して下さい。",GetColor(255,255,255));
    DrawString(280, GAME_Y,  "ゲーム",GetColor(255,255,255));
    DrawString(280, CONFIG_Y,"設定",GetColor(255,255,255));
    int y=0;
    switch(NowSelect){//現在の選択状態に従って処理を分岐
    case eMenu_Game://ゲーム選択中なら
        y=GAME_Y;    //ゲームの座標を格納
        break;
    case eMenu_Config://設定選択中なら
        y=CONFIG_Y;    //設定の座標を格納
        break;
    }
    DrawString(250, y, "■", GetColor(255,255,255));
}

↓main.cpp(赤字部のみ修正)↓


#include "DxLib.h"
#include "SceneMgr.h"
#include "Keyboard.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
    ChangeWindowMode(TRUE), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

    while( ScreenFlip()==0 && ProcessMessage()==0 && ClearDrawScreen()==0 ){//画面更新 & メッセージ処理 & 画面消去

        Keyboard_Update();    //キーボードの更新

        SceneMgr_Update();  //更新
        SceneMgr_Draw();    //描画

    }
        
    DxLib_End(); // DXライブラリ終了処理
    return 0;
}

本プログラムのプロジェクト一式はこちらからDLできます。

実行結果

このように各モジュールのUpdate関数内に処理を追加していくことで機能が増えていきます。

それでは5節にわたって紹介してきたメニュー画面の作り方講座を終わります。

→分からないことがあれば掲示板で質問して下さい


- Remical Soft -