DxLib使用時におけるボタンの使用

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
baby

DxLib使用時におけるボタンの使用

#1

投稿記事 by baby » 8年前

初投稿です。

質問は、Dxlib使用時にC++に標準で用意されているボタンなどを使うことはできるのでしょうか?
また、DxLibに同等の機能はあるのでしょうか?

よろしくお願いします。

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

Re: DxLib使用時におけるボタンの使用

#2

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

baby さんが書きました:Dxlib使用時にC++に標準で用意されているボタンなどを使うことはできるのでしょうか?
C++に標準でボタンは用意されていないはずなので、使うことはできません。
C++標準のSTLは使えると思います。
baby さんが書きました:また、DxLibに同等の機能はあるのでしょうか?
無いものと同等の機能は無いと思います。
また、現状のDXライブラリに「ボタン」を自動で用意する機能は無いと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#3

投稿記事 by softya(ソフト屋) » 8年前

C++の規格・標準ライブラリにはGUIの仕組みは存在しません。GUIの仕組みがない以上はボタンも標準では存在しません。
GUIのボタンは何らかのライブラリやOSのAPIに依存しています。
DXライブラリの場合はGUIのライブラリではないので、GUIを自前で作成する必要があります。

【補足】
書籍『超本格!サンプルで覚えるC言語 3Dゲームプログラミング教室』のサンプルゲームSword Boutのソースコードには
ボタンを含めたGUIのサンプルコードが掲載されているので参考になるのでは?
http://dxlib.o.oo7.jp/SwordBout/
私は、ちゃんとソースを読んでないので利用しやすいかは断言はできませんが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

baby

Re: DxLib使用時におけるボタンの使用

#4

投稿記事 by baby » 8年前

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

Windowsフォームアプリケーションというのがあり、それから作ることができたのでどうかなと思ったのですが。。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#5

投稿記事 by softya(ソフト屋) » 8年前

「Windowsフォームアプリケーション」は、ピュアなC++ではなくマイクロソフトが規格を作ったC++/CLIと言う別言語で作る事になります。
C++とすごく似てますが、上級者向けの別言語です。
また、「Windowsフォームアプリケーション」は.NetFrameWorkを使いますので.NetFrameWorkの環境にも依存しています。
それに対してDXライブラリはピュアC++用として開発されているので、同時に使うことは上級者レベルの技術が必要です。

【補足】
なお、マイクロソフト自身がVC++による「Windowsフォームアプリケーション」は今後推奨しないと言う方針を取っていますので、使う事自体がリスキーです。
C#の「Windowsフォームアプリケーション」を使えと言うことらしいです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

baby

Re: DxLib使用時におけるボタンの使用

#6

投稿記事 by baby » 8年前

softyaさんみけCAT、ありがとうございます!

やはりキーボードによる入力のみでいくほうが良いのでしょうか?。

マウスで指定の範囲をクリックしたらスタート(次のところに進む)ということにしたいのですが。

よろしくお願いします!

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#7

投稿記事 by softya(ソフト屋) » 8年前

独自でDXライブラリで実装すれば良いんです。
ゲームならみんな自前でやるのが基本です。
私の紹介したSword BoutのGUI機能を自分で作るか移植するかです。

>マウスで指定の範囲をクリックしたらスタート(次のところに進む)ということにしたいのですが。

それを実装した人はたくさんいますよ。
これが作れない技術レベルだとゲーム自体を作るのが困難ですから。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

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

Re: DxLib使用時におけるボタンの使用

#8

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

baby さんが書きました:やはりキーボードによる入力のみでいくほうが良いのでしょうか?。
作りたいプログラムの仕様やデザインによります。
baby さんが書きました:マウスで指定の範囲をクリックしたらスタート(次のところに進む)ということにしたいのですが。
マウスカーソルが指定の範囲にあり(GetMousePoint関数などで調べられる)、かつマウスのボタンが押されたら(GetMouseInput関数などで調べられる)スタート(次のところに進む)ということにすればいいと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

baby

Re: DxLib使用時におけるボタンの使用

#9

投稿記事 by baby » 8年前

わかりました。

ありがとうございます!

またわからないことがあれば質問することがあるかもしれませんが、その時はよろしくお願いします。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#10

投稿記事 by Dixq (管理人) » 8年前

DXライブラリで使えるボタンが欲しいということだったので汎用的に使えるボタンを作ってみました。
んーちょっと大がかりになってしまいました・・。
何とか簡素化できないものか。

[youtube][/youtube]

プロジェクト一式(VC++2012)
http://dixq.net/zip/Button.zip
サンプル.exeを実行してみてください。
DxLib本体は重いので入っていません。

ソースコードの説明

●main.cpp

コード:

#include <DxLib.h>
#include "GameMgr.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	GameMgr mgr;
	mgr.Main();
	return 0;
}
●GameMgr.h

コード:

#pragma once

#include "OnClickListener.h"

class GameMgr : public OnClickListener {
public:
	void Main();
	void OnClick(View* view)override;
};
●GameMgr.cpp

コード:

#include <DxLib.h>
#include "GameMgr.h"
#include "Button.h"
#include "Mouse.h"

void GameMgr::Main(){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	Button *button = new Button(320,200,100,50,"ボタン");
	button->SetOnClickListener(this);

	while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()){
		Mouse::Instance()->Update();
		button->Update();
		button->Draw();
	}

	delete button;

	DxLib_End();
}

void GameMgr::OnClick(View* view){
	printfDx("ボタンが押されました\n");
}
このクラスにはOnClickListenerを実装させてボタンのクリックイベントを拾えるようにします。
OnClickListenrとは?

●OnClickListener.h

コード:

#pragma once

#include "View.h"

class OnClickListener {
public:
	virtual ~OnClickListener(){}
	virtual void OnClick(View* view){}
};
インターフェイスクラス(ライク)として定義します。
クリックイベントを感知したらOnClickをコールバックするためのものです。

●View.h

コード:

#pragma once

class View {
public:
	virtual ~View(){}
	virtual void Update(){}
	virtual void Draw(){}
};
Viewパーツの大元になる基底クラスです。

●.Singleton.h

コード:

/***** Singleton.h ******/

#pragma once

template <typename _T>
class Singleton {

protected:
	Singleton() {}
	virtual ~Singleton() {}	
	Singleton(const Singleton& r){}
  	Singleton& operator=(const Singleton& r){}

public:
	static _T* Instance() {
		static _T inst;
		return &inst;
	};

};
●Mouse.h

コード:

#pragma once

#include "Singleton.h"

class Mouse : public Singleton<Mouse> {

	Mouse();
	friend Singleton<Mouse>;

public:
	bool Update();	//更新
	int GetPressingCount(int keyCode);//keyCodeのキーが押されているフレーム数を取得
	int GetReleasingCount(int keyCode);//keyCodeのキーが離されているフレーム数を取得
	int GetX();
	int GetY();
	const static int LEFT   = 0;
	const static int RIGHT  = 1;
	const static int MIDDLE = 2;

private:
	const static int BUTTON_NUM = 8;
	int mKeyPressingCount [BUTTON_NUM];//押されカウンタ
	int mKeyReleasingCount[BUTTON_NUM];//離されカウンタ
	int mX, mY;

	bool IsAvailableCode(int keyCode);//keyCodeが有効なキー番号か問う
};
マウス管理クラスが居ないとボタンイベントが取れないので、
Buttonクラスだけ追加して動くようには作れません。
よってMouseクラスも一緒に入れて下さい。

●Mouse.cpp

コード:

#include "Mouse.h"
#include <DxLib.h>

Mouse::Mouse():
 mX(0)
,mY(0)
{
    memset(mKeyPressingCount,  0, sizeof(mKeyPressingCount) );
    memset(mKeyReleasingCount, 0, sizeof(mKeyReleasingCount));
}

//更新
bool Mouse::Update(){
	int nowInput = GetMouseInput() ;      //今のキーの入力状態を取得
    for(int i=0; i<BUTTON_NUM; i++){ 
        if((nowInput>>i)&0x01){    //i番のキーが押されていたら
            if(mKeyReleasingCount[i] > 0){//離されカウンタが0より大きければ
                mKeyReleasingCount[i] = 0;   //0に戻す
            }
            mKeyPressingCount[i]++;          //押されカウンタを増やす
        } else {                             //i番のキーが離されていたら
            if(mKeyPressingCount[i] > 0){ //押されカウンタが0より大きければ
                mKeyPressingCount[i] = 0;    //0に戻す
            }
            mKeyReleasingCount[i]++;         //離されカウンタを増やす
        }
    }
	GetMousePoint(&mX, &mY);
    return true;
}

//keyCodeのキーが押されているフレーム数を返す
int Mouse::GetPressingCount(int keyCode){
    if(!Mouse::IsAvailableCode(keyCode)){
        return -1;
    }
    return mKeyPressingCount[keyCode];
}

//keyCodeのキーが離されているフレーム数を返す
int Mouse::GetReleasingCount(int keyCode){
    if(!Mouse::IsAvailableCode(keyCode)){
        return -1;
    }
    return mKeyReleasingCount[keyCode];
}

//keyCodeが有効な値かチェックする
bool Mouse::IsAvailableCode(int keyCode){
    if(0<=keyCode && keyCode<BUTTON_NUM){
        return true;
    }
    return false;
}

int Mouse::GetX(){
	return mX;
}

int Mouse::GetY(){
	return mY;
}
●Button.h

コード:

#pragma once

#include "View.h"
#include "OnClickListener.h"

class Button : public View {

public:
	Button(int x, int y, int w, int h, const char* str);
	void Update() override;
	void Draw() override;
	void SetOnClickListener(OnClickListener* listener);

private:
	int mX, mY, mW, mH;
	const char *mStr;
	bool IsPressed;
	OnClickListener* mListener;

};
ボタンクラスは基本的に作ったらいじらないです。SDKに入っているパーツのイメージです。
本来であればXMLなどでレイアウト情報や色情報等を取ってくるとよいでしょう。

●Button.cpp

コード:

#include <DxLib.h>
#include "Button.h"
#include "Mouse.h"

Button::Button(int x, int y, int w, int h, const char* str) : 
 mListener(NULL)
,IsPressed(false)
{
	mX = x;
	mY = y;
	mW = w;
	mH = h;
	mStr = str;
}

void Button::Update(){
	int x = Mouse::Instance()->GetX();
	int y = Mouse::Instance()->GetY();
	if(Mouse::Instance()->GetPressingCount(Mouse::LEFT)==0){
		IsPressed = false;
	}
	if(Mouse::Instance()->GetPressingCount(Mouse::LEFT)==1){
		if(mX<=x && x<=mX+mW && mY<=y && y<=mY+mH){
			mListener->OnClick(this);
			IsPressed =true;
		}
	}
	if(!(mX<=x && x<=mX+mW && mY<=y && y<=mY+mH)){
		IsPressed = false;
	}
}

void Button::Draw(){
	int sub=0;
	if(IsPressed){
		sub = 2;
	}
	int strW = GetDrawStringWidth(mStr, strlen(mStr));
	DrawBox(mX+sub, mY+sub, mX+mW-sub, mY+mH-sub, GetColor(100,255,255),TRUE);
	DrawBox(mX+sub, mY+sub, mX+mW-sub, mY+mH-sub, GetColor(255,100,100),FALSE);
	int strX = mX+mW/2-strW/2;
	int strY = mY+mH/2-DEFAULT_FONT_SIZE/2;
	DrawString(strX,strY,mStr,GetColor(0,0,0)); 
}

void Button::SetOnClickListener(OnClickListener* listener){
	mListener = listener;
}
Update()ではあたり判定の計算をし、クリックを検出したら登録されているリスナーのOnClickをコールバックします。




このようにしたら作れると思いますがいかがでしょうか。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#11

投稿記事 by Dixq (管理人) » 8年前

押したボタンを識別できる仕組みが入っていることもご紹介。
さっきのGameMgrを以下のように書き換えると

コード:

#include <DxLib.h>
#include "GameMgr.h"
#include "Button.h"
#include "Mouse.h"

void GameMgr::Main(){
	ChangeWindowMode(TRUE),DxLib_Init(),SetDrawScreen(DX_SCREEN_BACK);

	mPrevButton = new Button(320,200,100,50,"前へ");
	mPrevButton->SetOnClickListener(this);

	mNextButton = new Button(440,200,100,50,"次へ");
	mNextButton->SetOnClickListener(this);

	while(!ScreenFlip()&&!ProcessMessage()&&!ClearDrawScreen()){
		Mouse::Instance()->Update();
		mPrevButton->Update();
		mNextButton->Update();
		mPrevButton->Draw();
		mNextButton->Draw();
	}

	delete mPrevButton;
	delete mNextButton;
	DxLib_End();
}

void GameMgr::OnClick(View* view){
	if(view==mPrevButton){
		printfDx("「前へ」が押されました\n");
	}
	if(view==mNextButton){
		printfDx("「次へ」が押されました\n");
	}
}
こうなります。
[youtube][/youtube]

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: DxLib使用時におけるボタンの使用

#12

投稿記事 by baby2478nishi » 8年前

おはようございます。垢を作りましたがbabyです

今から学校ですので、帰ってから試してみたいと思います。

ところで、調べてみたのですが、ヘッダファイルというものがいまいちわかりません。メインプログラムに書くのはダメなのでしょうか?

よろしくおねがいします。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#13

投稿記事 by Dixq (管理人) » 8年前

あららまだCの基礎を学ばれてない状態でしたか、、ではせっかく作ったサンプルコードもさっぱりって感じでしょうか・・。
windowsプログラミングをされていたようなのである程度ご存知かと思っていました。

ヘッダファイルは必要です。
全部一つのファイルに書いてしまうと可読性が下がってしまいます。
オブジェクトのクラス単位に記述することで内容の理解が飛躍的に高まります。
C++をある程度ご存じかと思っていたのですが、クラスを書く時ヘッダファイル使いますよね?

baby2478nishi
記事: 52
登録日時: 8年前
住所: 兵庫県姫路市

Re: DxLib使用時におけるボタンの使用

#14

投稿記事 by baby2478nishi » 8年前

こんにちは。

自分の環境(部活)ではC言語(borland)をして、慣れたらDxLibに移行という感じです。

また、自分の周りの人もゲーム(例えばブロック崩しとか)をつくっていますが、.hファイルは使っていませんでしたので。

最初に書いておけばよかったですね。申し訳ございません。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 13年前
住所: 東海地方
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#15

投稿記事 by softya(ソフト屋) » 8年前

極めて小規模なものなら.hが無くても問題はありません。
ある程度以上の規模なら.hなしでモジュール分割せずに作るのは逆に開発の効率が悪くなります。
少なくとも私は、そのプログラムを読みたくありません。

このサイトに有る、「ゲームプログラミングの館」に分割の仕方や理由の解説があります。
「龍神録の館」ではシューティングでの実例がありますが、あまり良い分割の例とはいえません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
Dixq (管理人)
管理人
記事: 1661
登録日時: 13年前
住所: 北海道札幌市
連絡を取る:

Re: DxLib使用時におけるボタンの使用

#16

投稿記事 by Dixq (管理人) » 8年前

まずちゃんとしたプログラムの設計の方法を学んだ方が良さそうです。
まぁある程度試行錯誤して何故示された設計の方法が良いのかその利点を理解してからの方が良いかもしれませんが。
とにかくプログラムはどれだけ書いたかが勝負です。
沢山コードを書き、沢山壁にぶち当たってください。その分成長できるはずです。
その上で設計方法を学びたければ
ゲームプログラミングの館の
d.x章 ゲームプログラミング設計
にて基本を紹介しているので参考にしてください。
なお、ある程度CになれたらC++に移行した方が生産性は上がります。

閉鎖

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