DxLibでの個人製作について質問

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

DxLibでの個人製作について質問

#1

投稿記事 by KokuryuKaruma » 1年前

現在、RPGのバトル画面風のものをDxLibにて制作してみているのですが、選択肢を選択するようにコードを書いてみているのですがうまく反応してくれません。

やりたいこと:UNDERTALEのようにメニューの選択をできるようにしたい。

現状:選択肢が表示され、現在選択されているものの確認はできるもののほかの選択肢を選ぶことができない。

初歩的なところと存じますが、ご助力願えたら幸いです。
よろしくお願いします。

メインスクリプト

コード:

#include "DxLib.h"
#include "MainCode.h"
#include "GameSystem.h"

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

	ChangeWindowMode(TRUE); // ウインドウモードに変更
	SetWindowText("ゲームを作ってみたよ"); // ウィンドウのタイトルを指定
	SetGraphMode(Window::WIDTH, Window::HEIGHT, Window::COLOR_BIT); // 解像度とカラービット数を設定
	if (DxLib_Init() == -1) { return EXIT_FAILURE; } // 初期化に失敗したらやめる (EXIT_FAILURE: -1)
	/*
		ここで変数の初期化, 画像のロードなど
	*/
	SetDrawScreen(DX_SCREEN_BACK);

	/*******************GAME LOOP********************************/
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {
		
		/*ここで, パラメータをいろいろいじる.*/
		ChooseTime();

		ClearDrawScreen(); //画面の内容を消去
		
		/*ここで, いろいろ描画する.*/
		ScreenCreate();
		
		ScreenFlip();
	}
	/*******************GAME LOOP END***************************/

	DxLib_End(); // DXライブラリ使用の終了処理
	return EXIT_SUCCESS; // プログラムの終了 (EXIT_SUCCESS: 0)
}
システム関連スクリプト

コード:

#include "DxLib.h"
#include "GameSystem.h"

/*文字カラー指定*/
unsigned int WhiteColor = GetColor(255, 255, 255);

/*選択肢分岐*/
int Choose; //0=攻撃,1=防御,2=回復,3=観察

int ScreenCreate() {

	/*テキストボックスの設置*/
	DrawBox(250, 450, 1030, 650, WhiteColor, FALSE);

	/*敵(みたいなの)の設置*/
	DrawCircle(640, 300, 50, WhiteColor, TRUE);
	DrawFormatString(620, 225, WhiteColor, "敵です"); //自己紹介

	/*コマンドの配置*/
	DrawFormatString(375, 500, WhiteColor, "攻撃"); //攻撃
	DrawFormatString(875, 500, WhiteColor, "防御"); //防御
	DrawFormatString(375, 585, WhiteColor, "回復"); //回復
	DrawFormatString(875, 585, WhiteColor, "観察"); //観察

	ChooseSystem();

	return 0;
}

int ChooseTime() {

	if (Choose == 0) {
		if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose += 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose += 1;
		}
	}

	if (Choose == 1) {
		if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			Choose += 2;
		}
	}

	if (Choose == 2) {
		if (CheckHitKey(KEY_INPUT_UP)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose += 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose += 1;
		}
	}

	if (Choose == 3) {
		if (CheckHitKey(KEY_INPUT_UP)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose -= 1;
		}
	}

	return Choose;
}

int ChooseSystem() {

	switch (Choose) {
	case 0:
		DrawFormatString(350, 500, WhiteColor, "→");
		break;
	case 1:
		DrawFormatString(850, 500, WhiteColor, "→");
		break;
	case 2:
		DrawFormatString(350, 585, WhiteColor, "→");
		break;
	case 3:
		DrawFormatString(850, 585, WhiteColor, "→");
		break;
	}

	return 0;
}
メインヘッダーファイル

コード:

#pragma once

struct Window {
	const static int WIDTH = 1280; // 横幅[px]
	const static int HEIGHT = 720; // 縦幅[px]
	const static int COLOR_BIT = 32;  // カラービット[bit]
};
システム関連ヘッダーファイル

コード:

#pragma once

/*プレイヤーステータス関数*/
static int PlayerHP = 0;
static int PlayerATK = 0;
static int PlayerDef = 0;

/*エネミーステータス関数*/
static int EnemyHP = 0;
static int EnemyATK = 0;
static int EnemyDef = 0;

int ScreenCreate();
int ChooseTime();
int ChooseSystem();

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

Re: DxLibでの個人製作について質問

#2

投稿記事 by あたっしゅ » 1年前

東上☆海美☆「
とりあえず直してみました。

コード:

//
// https://dixq.net/forum/viewtopic.php?f=3&t=21403&sid=1594ae3f6b8f2b2b06a7ebb1def2e477
//DxLibでの個人製作について質問 - ミクプラ(ja)
//
#include "DxLib.h"

//#include "MainCode.h"
//#pragma once

struct Window {
	const static int WIDTH = 1280; // 横幅[px]
	const static int HEIGHT = 720; // 縦幅[px]
	const static int COLOR_BIT = 32;  // カラービット[bit]
};

//#include "GameSystem.h"
//#pragma once

/*プレイヤーステータス関数*/
static int PlayerHP = 0;
static int PlayerATK = 0;
static int PlayerDef = 0;

/*エネミーステータス関数*/
static int EnemyHP = 0;
static int EnemyATK = 0;
static int EnemyDef = 0;

int ScreenCreate();
int ChooseTime();
int ChooseSystem();


//
//
//
int WINAPI
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{

	ChangeWindowMode(TRUE); // ウインドウモードに変更
	SetWindowText("ゲームを作ってみたよ"); // ウィンドウのタイトルを指定
	SetGraphMode(Window::WIDTH, Window::HEIGHT, Window::COLOR_BIT); // 解像度とカラービット数を設定

	if (DxLib_Init() == -1) { return EXIT_FAILURE; } // 初期化に失敗したらやめる (EXIT_FAILURE: -1)
	/*
		ここで変数の初期化, 画像のロードなど
	*/
	SetDrawScreen(DX_SCREEN_BACK);

	/*******************GAME LOOP********************************/
	while (ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0) {

		/*ここで, パラメータをいろいろいじる.*/
		ChooseTime();

		ClearDrawScreen(); //画面の内容を消去

		/*ここで, いろいろ描画する.*/
		ScreenCreate();

		ScreenFlip();
	}
	/*******************GAME LOOP END***************************/

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

	return EXIT_SUCCESS; // プログラムの終了 (EXIT_SUCCESS: 0)
}


//#include "DxLib.h"
//#include "GameSystem.h"

/*文字カラー指定*/
unsigned int WhiteColor = GetColor(255, 255, 255);
unsigned int RedColor   = GetColor(255,   0,   0); // 新規

/*選択肢分岐*/
int Choose; //0=攻撃,1=防御,2=回復,3=観察


int
ScreenCreate()
{

	/*テキストボックスの設置*/
	DrawBox(250, 450, 1030, 650, WhiteColor, FALSE);

	/*敵(みたいなの)の設置*/
	DrawCircle(640, 300, 50, WhiteColor, TRUE);
	DrawFormatString(620, 225, WhiteColor, "敵です"); //自己紹介

	/*コマンドの配置*/
	DrawFormatString(375, 500, WhiteColor, "攻撃"); //攻撃
	DrawFormatString(875, 500, WhiteColor, "防御"); //防御
	DrawFormatString(375, 585, WhiteColor, "回復"); //回復
	DrawFormatString(875, 585, WhiteColor, "観察"); //観察

	ChooseSystem();

	return 0;
}


int
ChooseTime()
{
	if (Choose == 0) {
		if (CheckHitKey(KEY_INPUT_RIGHT)) {
			//Choose += 1;
			Choose = 1;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			//Choose += 2;
			Choose = 2;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			//Choose += 2;
			Choose = 0;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			//Choose += 1;
			Choose = 0;

			return Choose;
		}
	}

	if (Choose == 1) {
		if (CheckHitKey(KEY_INPUT_LEFT)) {
			//Choose -= 1;
			Choose = 0;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			//Choose += 2;
			Choose = 3;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			//Choose -= 1;
			Choose = 1;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			//Choose += 2;
			Choose = 1;

			return Choose;
		}
	}

	if (Choose == 2) {
		if (CheckHitKey(KEY_INPUT_UP)) {
			//Choose -= 2;
			Choose = 0;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			//Choose += 1;
			Choose = 3;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			//Choose -= 2;
			Choose = 2;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			//Choose += 1;
			Choose = 2;

			return Choose;
		}
	}

	if (Choose == 3) {
		if (CheckHitKey(KEY_INPUT_UP)) {
			//Choose -= 2;
			Choose = 1;

			return Choose;

		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			//Choose -= 1;
			Choose = 2;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			//Choose -= 2;
			Choose = 3;

			return Choose;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			//Choose -= 1;
			Choose = 3;

			return Choose;
		}
	}

	return Choose;
}


int
ChooseSystem() 
{
	DrawFormatString(0, 0, WhiteColor, "           ");

	switch (Choose) {
	case 0:
		DrawFormatString(350, 500, WhiteColor, "→");
		break;

	case 1:
		DrawFormatString(850, 500, WhiteColor, "→");
		break;

	case 2:
		DrawFormatString(350, 585, WhiteColor, "→");
		break;

	case 3:
		DrawFormatString(850, 585, WhiteColor, "→");
		break;

	default:
		DrawFormatString( 0, 0, RedColor, "Choose 異常");
		break;
    }

	return 0;
}


// 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, 電子ブロック 持ち。

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: DxLibでの個人製作について質問

#3

投稿記事 by みけCAT » 1年前

関数 ChooseTime において、例えば最初 Choose == 0 で右キーを押した時
1. Choose == 0 なので、 Choose += 1; により Choose = 1 となる
2. Choose == 1 なので、 Choose == 1; により Choose = 0 となる
となり、結局Chooseの値が変わらないことがあります。

以下のように、1回のChooseTimeの実行につき1組のキー判定のみ実行するようにすると改善するでしょう。
(この例ではswitchを使いましたが、else ifなどでもいいでしょう)

コード:

int ChooseTime() {

	switch (Choose) {
	case 0:
		if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose += 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose += 1;
		}
		break;
	case 1:
		if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose += 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_UP)) {
			Choose += 2;
		}
		break;
	case 2:
		if (CheckHitKey(KEY_INPUT_UP)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose += 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose += 1;
		}
		break;
	case 3:
		if (CheckHitKey(KEY_INPUT_UP)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_LEFT)) {
			Choose -= 1;
		}
		else if (CheckHitKey(KEY_INPUT_DOWN)) {
			Choose -= 2;
		}
		else if (CheckHitKey(KEY_INPUT_RIGHT)) {
			Choose -= 1;
		}
		break;
	}

	return Choose;
}
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

KokuryuKaruma
記事: 2
登録日時: 1年前

Re: DxLibでの個人製作について質問

#4

投稿記事 by KokuryuKaruma » 1年前

皆さま回答ありがとうございます。

頂いた回答をもとにコードの修正を行い、→の部分が正常に左上、右上、左下、右下に移動することができました。

もう一点質問になってしまうのですが、→の移動判定が高速になってしまい、キーを押し続けると高速で移動することで選択が困難な状態になってしまいます。

原因としては、毎フレームキーの入力判定を取っているため高速で移動し、選択が困難になっていると思うのですが、適切に処理をするにはどうすればいいでしょうか。

よろしくお願いします。

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

Re: DxLibでの個人製作について質問

#5

投稿記事 by あたっしゅ » 1年前

東上☆海美☆「
> もう一点質問になってしまうのですが、→の移動判定が高速になってしまい、
> キーを押し続けると高速で移動することで選択が困難な状態になってしまいます。

#3 のコードのことですよね。

#2 ☆海美☆のコードなら、『キーを押し続けると高速で移動することで選択が困難な状態』には、
ならないと思いますが、試されましたか ?
VTuber:
東上☆海美☆(とうじょう・うみみ)
http://atassyu.php.xdomain.jp/vtuber/index.html
レスがついていないものを優先して、レスするみみ。時々、見当外れなレスしみみ。

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

アバター
みけCAT
記事: 6734
登録日時: 13年前
住所: 千葉県
連絡を取る:

Re: DxLibでの個人製作について質問

#6

投稿記事 by みけCAT » 1年前

KokuryuKaruma さんが書きました:
1年前
もう一点質問になってしまうのですが、→の移動判定が高速になってしまい、キーを押し続けると高速で移動することで選択が困難な状態になってしまいます。

原因としては、毎フレームキーの入力判定を取っているため高速で移動し、選択が困難になっていると思うのですが、適切に処理をするにはどうすればいいでしょうか。
例えば、CheckHitKey関数のかわりに
グローバル変数の扱いに気を使ってみよう (龍神録プログラミングの館)で紹介されているCheckStateKey関数を用い、
戻り値が1 (キーが押され始めた直後のフレームである) のときだけカーソルを移動するようにするといいと思います。
あたっしゅ さんが書きました:
1年前
#2 ☆海美☆のコードなら、『キーを押し続けると高速で移動することで選択が困難な状態』には、
ならないと思いますが、試されましたか ?
なるほど、選択位置がループする仕様を犠牲にしたのですね。
選択肢が例えば6個になったらどうしますか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

返信

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