選択項目の実装サンプルです。もし参考になればどうぞ。
十字キーの上下で選択移動、Zキーを押すとその項目が選択された旨を2秒間表示して戻ります。
セレクト項目の最大数やその中身が変動する場合は、何かのデータから取ってくるような処理にするといいと思います。
ちょっと長いので、解読が面倒かもしれませんが・・。
#include "DxLib.h"
/* セレクト項目の最大数 */
#define SELECT_ELEMENT_MAX 10
/* セレクト項目の要素 */
typedef struct{
int iX, iY;
char cName[128];
}Element_t;
/* セレクト項目要素の親 */
typedef struct{
int iNum; //今選択されている番号
int iMax; //登録されている数
Element_t Element[ SELECT_ELEMENT_MAX ];
}Select_t;
/* キー状態格納変数 */
int Key[256];
/* キー入力管理関数 */
int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[/url]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++)
{
if(GetHitKeyStateAll_Key==1) GetHitKeyStateAll_InputKey++;
else GetHitKeyStateAll_InputKey=0;
}
return 0;
}
/* 呼ぶ関数を制御する変数 */
int FunctionState;
/* セレクト要素にメニュー情報を登録する */
void EnterSelectString( Select_t *Sel, int iX, int iY, char cStr[/url] ){
strcpy( Sel->Element[ Sel->iMax ].cName, cStr ); //文字列格納
Sel->Element[ Sel->iMax ].iX = iX; //座標格納
Sel->Element[ Sel->iMax ].iY = iY;
Sel->iMax++; //今いくつ要素が入っているかカウント
}
/* セレクト情報初期化 */
void SelectIni( Select_t *Sel ){
memset ( Sel, 0, sizeof(Select_t) ); //全て0に
EnterSelectString( Sel , 100, 100, "メニュー0" );
EnterSelectString( Sel , 100, 150, "メニュー1" );
EnterSelectString( Sel , 100, 200, "メニュー2" );
EnterSelectString( Sel , 100, 250, "メニュー3" );
EnterSelectString( Sel , 100, 300, "メニュー4" );
EnterSelectString( Sel , 400, 450, "メニューA" );
FunctionState=1; //次の関数を呼ぶ
}
/* キー入力などからセレクト状況を計算する */
void SelectCalc( Select_t *Sel){
/* 上下キーが押されたら現在選択されている番号を表す->iNumを変化させる */
if( Key[ KEY_INPUT_UP ] == 1 )
{
Sel->iNum--;
if( Sel->iNum < 0 )
{
Sel->iNum = Sel->iMax - 1 ;
}
}
if( Key[ KEY_INPUT_DOWN ] == 1 )
{
Sel->iNum = (++Sel->iNum) % Sel->iMax ;
}
}
/* セレクト項目と現在のセレクト状況描画 */
void SelectGraph( Select_t Sel){
int i, Col = GetColor(255,255,255) ;
for(i=0; i<Sel.iMax; i++)
{
DrawFormatString( Sel.Element[ i ].iX, Sel.Element[ i ].iY, Col, "%s", Sel.Element[ i ].cName );
}
DrawCircle( Sel.Element[ Sel.iNum ].iX-20, Sel.Element[ Sel.iNum ].iY+7, 7, Col, TRUE );
}
/* セレクトメイン */
void SelectMain( Select_t *Sel ){
SelectCalc( Sel ); //計算
SelectGraph( *Sel );//描画
if( Key[ KEY_INPUT_Z ] == 1 )
{
FunctionState = 2;//けって~
}
}
//決定されて2秒間その項目を表示する
void Decided( Select_t Sel ){
int Col = GetColor( 255, 255, 255 );
static int cnt=0;
DrawFormatString( 100, 100, Col, "%sが選択されました。", Sel.Element[ Sel.iNum ].cName );
cnt++;
if( cnt > 120 )//60FPSのモニタで2秒たったら
{
cnt = 0;
FunctionState = 0;
}
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
Select_t Select;
ChangeWindowMode(TRUE);//ウィンドウモード
if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理 ↑画面をクリア ↑入力状態を保存 ↑ESCが押されていない
switch(FunctionState){
case 0:
//初期化
SelectIni( &Select );
break;
case 1:
//メイン計算
SelectMain( &Select );
break;
case 2:
//決定した瞬間その項目を表示->0に戻る
Decided( Select );
break;
}
ScreenFlip();
}
DxLib_End();
return 0;
}