マウスカーソル ゲームメニュー選択画面

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Ken2929
記事: 6
登録日時: 11ヶ月前

マウスカーソル ゲームメニュー選択画面

#1

投稿記事 by Ken2929 » 11ヶ月前

はじめまして
とある課題で、ゲームのメニュー画面を制作しているものです。

現在矢印キーとw、s、マウスのホイールで上下のメニュー選択はきちんと出来ているのですが、最近のゲームみたいにマウスカーソルでマウスの指したところでもメニュー選択出来ればなと思い色々試行錯誤しているのですがなかなかできなくて困っています。

色々考えを巡らしているのですが、途方に暮れています。
何かアドバイス、良い案があればご提示ください、お願いいたします。

動作環境は
OS: Windows 11 バージョン 22H2
開発環境は
Visual stdio 2022
です。

一部にはなりますが、ソースコードはっておきます。

コード:

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

//更新
void Menu_Update() {
    int x, y, Mouse, Wheel;
    int MouseX, MouseY;
    Mouse = GetMouseInput();                //マウスの入力状態取得
    Wheel = GetMouseWheelRotVol();  //ホイールの回転量取得

    if (Keyboard_Get(KEY_INPUT_DOWN) == 1 || Keyboard_Get(KEY_INPUT_S) == 1 || Wheel < 0 ) {//下キーが押されているかつホイールが-方向に回転していたら
        NowSelect = (NowSelect + 1) % eMenu_Num;//選択状態を一つ下げる
    }   
    if (Keyboard_Get(KEY_INPUT_UP) == 1 || Keyboard_Get(KEY_INPUT_W) == 1 ||Wheel > 0 ) {//上キーが押されているかつホイールが+方向に回転していたら
        NowSelect = (NowSelect + (eMenu_Num - 1)) % eMenu_Num;//選択状態を一つ上げる
    }

    if (Keyboard_Get(KEY_INPUT_RETURN) == 1 || (GetMouseInput() & MOUSE_INPUT_LEFT) != 0) {//エンターキーが押されたら
        switch (NowSelect) {//現在選択中の状態によって処理を分岐
        case eMenu_Game://ゲーム選択中なら
            SceneMgr_ChangeScene(eScene_Game);//シーンをゲーム画面に変更
            break;
        case eMenu_Conf://設定選択中なら
            SceneMgr_ChangeScene(eScene_Config);//シーンを設定画面に変更
            break;
        case eMenu_Help://設定選択中なら
            SceneMgr_ChangeScene(eScene_Help);//シーンを設定画面に変更
            break;
        case eMenu_Exit://やめる選択中なら
            DxLib_End();
        }
    }
}

//描画
void Menu_Draw() {
    DrawString(180, 60, "メニュー画面", GetColor(255, 255, 255));
    DrawString(10, 170, "※上下キー又はw、s、ホイールを動かし、エンターか左クリックを押して下さい。", GetColor(255, 255, 255));
    DrawString(280, GAME_Y, "ゲーム", GetColor(255, 255, 255));
    DrawString(280, CONF_Y, "設定", GetColor(255, 255, 255));
    DrawString(280, HELP_Y, "説明", GetColor(255, 255, 255));
    DrawString(280, EXIT_Y, "やめる", GetColor(255, 255, 255));
    int y = 0;
    switch (NowSelect) {//現在の選択状態に従って処理を分岐
    case eMenu_Game://ゲーム選択中なら
        DrawString(280, GAME_Y, "ゲーム", GetColor(0, 255, 0));//緑にさせる
        y = GAME_Y;    //ゲームの座標を格納
        break;
    case eMenu_Conf://設定選択中なら
        DrawString(280, CONF_Y, "設定", GetColor(0, 255, 0));//緑にさせる
        y = CONF_Y;    //設定の座標を格納
        break;
    case eMenu_Help://設定選択中なら
        DrawString(280, HELP_Y, "説明", GetColor(0, 255, 0));//緑にさせる
        y = HELP_Y;    //説明の座標を格納
        break;
    case eMenu_Exit://やめる選択中なら
        DrawString(280, EXIT_Y, "やめる", GetColor(0, 255, 0));//緑にさせる
        y = EXIT_Y;
    }
    DrawString(250, y, "■", GetColor(0, 255, 0));//緑の■
}

アバター
usao
記事: 1887
登録日時: 10年前

Re: マウスカーソル ゲームメニュー選択画面

#2

投稿記事 by usao » 11ヶ月前

既存のキー操作とマウスカーソルとで簡単に喧嘩になりそうだから,仕様を決める(説明する)のが先だと思う.

個人的には,カーソル位置で選べるなら

・ホイールは要らない
・キーは各項目をダイレクトに選択決定するショートカット(例えば S キーで設定画面に直行,Hキーで説明画面に直行,みたいな)

とかにするかなぁ.

アバター
あたっしゅ
記事: 663
登録日時: 13年前
住所: 東京23区
連絡を取る:

Re: マウスカーソル ゲームメニュー選択画面

#3

投稿記事 by あたっしゅ » 11ヶ月前

東上☆海美☆「
とりあえず、作ってみたみみ。

コード:

//
// https://dixq.net/forum/viewtopic.php?f=3&t=21545
// マウスカーソル ゲームメニュー選択画面 - ミクプラ(ja)
//
// for Visual Studio 2022
//
#include "DxLib.h"

#include <vector>

#define _USE_MATH_DEFINES
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>


//
//
//
enum eMenu {
    eMenu_Game,
    eMenu_Conf,
    eMenu_Help,
    eMenu_Exit,
    eMenu_Num,
};
static int NowSelect = eMenu_Game;    //現在の選択状態(初期はゲーム選択中)


const int OX = 280;
const int DX = 100;
const int DX2 = DX/2;

const int DY = 64;
const int DY2    = DY/2;
const int GAME_Y = 100;
const int CONF_Y = GAME_Y + DY*1;
const int HELP_Y = GAME_Y + DY*2;
const int EXIT_Y = GAME_Y + DY*3;
const int Ytable[eMenu_Num] = {
    GAME_Y,
    CONF_Y,
    HELP_Y,
    EXIT_Y,
};


enum eScene {
    eScene_Game,
    eScene_Config,
    eScene_Help,
};
static int sceneSelect = eScene_Game;


void
SceneMgr_ChangeScene(enum eScene a )
{
    sceneSelect = a;
}


int
Keyboard_Get(int KeyCode )
{
    return CheckHitKey(KeyCode);
}


//更新
void
Menu_Update() 
{
    static int pushed = 0;

    int x, y;
    int MouseX, MouseY;
    int Mouse = GetMouseInput();                //マウスの入力状態取得
    int Wheel = GetMouseWheelRotVol();  //ホイールの回転量取得

    if (pushed == 0) {
        if (Keyboard_Get(KEY_INPUT_DOWN) == 1 || Keyboard_Get(KEY_INPUT_S) == 1 || Wheel < 0) {//下キーが押されているかつホイールが-方向に回転していたら
            NowSelect = (NowSelect + 1) % eMenu_Num;//選択状態を一つ下げる
            pushed = 10;
        }
        if (Keyboard_Get(KEY_INPUT_UP) == 1 || Keyboard_Get(KEY_INPUT_W) == 1 || Wheel > 0) {//上キーが押されているかつホイールが+方向に回転していたら
            NowSelect = (NowSelect + (eMenu_Num - 1)) % eMenu_Num;//選択状態を一つ上げる
            pushed = 10;
        }
    } else {
        pushed--;
    }

    if ((GetMouseInput() & MOUSE_INPUT_LEFT)) {
        GetMousePoint(&MouseX, &MouseY);

        for (int i = 0; i < eMenu_Num; i++) {
            if (MouseX > OX-20 && MouseX < OX + DX && MouseY > Ytable[i] && MouseY < Ytable[i] + DY2 ) {
                NowSelect = i;
            }
        }
    }

    if (Keyboard_Get(KEY_INPUT_RETURN) == 1 || (GetMouseInput() & MOUSE_INPUT_LEFT) != 0) {//エンターキーが押されたら
        switch (NowSelect) {//現在選択中の状態によって処理を分岐
            case eMenu_Game://ゲーム選択中なら
                SceneMgr_ChangeScene(eScene_Game);//シーンをゲーム画面に変更
                break;

            case eMenu_Conf://設定選択中なら
                SceneMgr_ChangeScene(eScene_Config);//シーンを設定画面に変更
                break;

            case eMenu_Help://設定選択中なら
                SceneMgr_ChangeScene(eScene_Help);//シーンを設定画面に変更
                break;

            case eMenu_Exit://やめる選択中なら
                DxLib_End();
        }
    }
}


//描画
void
Menu_Draw()
{
    DrawString(180, 60, "メニュー画面", GetColor(255, 255, 255));
    DrawString(10,  GAME_Y + DY * 4, "※上下キー又はw、s、ホイールを動かし、エンターか左クリックを押して下さい。",
        GetColor(255, 255, 255));
    DrawString(280, GAME_Y, "ゲーム", GetColor(255, 255, 255));
    DrawString(280, CONF_Y, "設定", GetColor(255, 255, 255));
    DrawString(280, HELP_Y, "説明", GetColor(255, 255, 255));
    DrawString(280, EXIT_Y, "やめる", GetColor(255, 255, 255));

    int y = 0;

    switch (NowSelect) {//現在の選択状態に従って処理を分岐
        case eMenu_Game://ゲーム選択中なら
            DrawString( OX, GAME_Y, "ゲーム", GetColor(0, 255, 0));//緑にさせる
            y = GAME_Y;    //ゲームの座標を格納
            break;

        case eMenu_Conf://設定選択中なら
            DrawString( OX, CONF_Y, "設定", GetColor(0, 255, 0));//緑にさせる
            y = CONF_Y;    //設定の座標を格納
            break;

        case eMenu_Help://設定選択中なら
            DrawString( OX, HELP_Y, "説明", GetColor(0, 255, 0));//緑にさせる
            y = HELP_Y;    //説明の座標を格納
            break;

        case eMenu_Exit://やめる選択中なら
            DrawString( OX, EXIT_Y, "やめる", GetColor(0, 255, 0));//緑にさせる
            y = EXIT_Y;
    }

    DrawString(250, y, "■", GetColor(0, 255, 0));//緑の■
}


//
//
//
int WINAPI
WinMain(HINSTANCE, HINSTANCE, LPSTR, int) try
{
    srand((unsigned)time(NULL)); // 乱数の仕組みを初期化

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

    // while(裏画面を表画面に反映, メッセージ処理, 画面クリア)
    while (
        ScreenFlip() == 0
        && ProcessMessage() == 0
        && ClearDrawScreen() == 0
    ) {
        //if (CheckHitKey(KEY_INPUT_ESCAPE)) {
        //    break;
        //}
        Menu_Update();
        Menu_Draw();
    }

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

    return EXIT_SUCCESS;
}
catch(...)
{
    return EXIT_FAILURE;
}


// end.
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

中の人:
手提鞄あたッしュ、[MrAtassyu] 手提鞄屋魚有店
http://ameblo.jp/mratassyu/
Pixiv: 666303
Windows, Mac, Linux, Haiku, Raspbery Pi, Jetson Nano, 電子ブロック 持ち。

Ken2929
記事: 6
登録日時: 11ヶ月前

Re: マウスカーソル ゲームメニュー選択画面

#4

投稿記事 by Ken2929 » 11ヶ月前

返事遅れました。

おっしゃる通り、仕様は漠然としているのですが、まずメニュー画面の骨組み、試作品を作ってからどういう風にしようかなと考えてました。
作るにあたり出来る限り一つや二つではなくなるべく多機能なほうがいいかなと思い、色々試していました。

アドバイスありがとございました!
usao さんが書きました:
11ヶ月前
既存のキー操作とマウスカーソルとで簡単に喧嘩になりそうだから,仕様を決める(説明する)のが先だと思う.

個人的には,カーソル位置で選べるなら

・ホイールは要らない
・キーは各項目をダイレクトに選択決定するショートカット(例えば S キーで設定画面に直行,Hキーで説明画面に直行,みたいな)

とかにするかなぁ.

返信

“C言語何でも質問掲示板” へ戻る