Dxライブラリについて

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

Dxライブラリについて

#1

投稿記事 by mi_l » 11年前

私は、C++を勉強していて、DXライブラリで簡単なゲームを作ろうとしています。

C要素が多い、竜神録の館はほとんど理解できました(できたと思っています)ので、C++用のソースをダウンロードして開いたのですが、まったくわかりませんでした・・・

とりあえず、背景のスクロール(背景クラス)だけ、書きました・・

コード:

#include"Back.h"
#include"DxLib.h"

Back::Back(void)
{
  count = 0
}

Back::~Back(void)
{
}

void Back::setPos()
{
	posX = 100;
	posY = 100+count;
}

void Back::calc()
{
	count++;
}

void Back::Draw()
{
	setPos();
	calc();

	DrawGraph( posX , posY , b_img , FALSE );
}

コード:

#ifndef BACK_H_
#define BACK_H_

class Back
{
private:
	float posX;
	float posY;
	int count;
protected:
public:
	Back(void);
	~Back(void);

	void setPos();

	void calc();

	void Draw();
};

#endif //BACK_H_
ここに、あとは、Loadクラスでも作って、画像をロードして、背景クラスにインクルードすればいいのだと思いますが、その後、下記のメイン関数にどのように書いていけばいいのかわかりません。

今は、背景だけですが、これから様々な要素(敵、自機、エフェクト、障害物など)を取り入れていくとき、竜神録みたいに「func_state」たる変数を用意してcase文で分けていくのでしょうか?

コード:

int Key[256];

int GetHitKeyStateAll_2(int GetHitKeyStateAll_InputKey[]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key[i]==1) GetHitKeyStateAll_InputKey[i]++;
        else                            GetHitKeyStateAll_InputKey[i]=0;
    }
    return 0;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    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が押されていない


        //ココ!!



        ScreenFlip();
    }

    DxLib_End();
    return 0;
}
今は休み時間で、書いたのでスペルミスなどあるかもしれません・・・

メインはコピペしたものです。

上に、背景のヘッダーなどインクルードします(している設定で・・・)

お願いします。



※管理人さん、副管理人さんへ・・

私は結構前から残っているアンドロイドアプリのトピックがあります。
現在も忘れないように勉強していますが、それは忘れないようにするためであり、トピックの答えを出そうというのではありません。

Cを勉強して、C++に入って更に当然他にもやることがありますので、そのトピックは、このまま長い間放置になってしまいます・・
要するに、C++で何かを作ろうとしており、プログラムの授業なんて学校ではないので他のことも疎かにできません。
よって、Javaでの製作はストップしている状況です、ですので、そのトピックは削除してください。

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

Re: Dxライブラリについて

#2

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

> よって、Javaでの製作はストップしている状況です、ですので、そのトピックは削除してください。

申し訳ないですが、フォーラムルールを読んで頂くと分かりますが原則として削除をお受けすることはできません。
解決していないトピックでも何らかのヒントに成る可能性があることと、第一に回答してくれた回答者に失礼になるからです。
他の掲示板でもそうですが、削除はできるだけ避けていただきたいと思います。

さて内容ですが、オブジェクト指向をちゃんとやるのか、手続き指向なのか(ベターC?)なのかスタンスを明確にしてもらったほうが良さそうです。
今のままだと、手続き指向をただクラスの形にしただけって印象なので勿体無いです。
それとクラスはインスタンスを生成しないと始まりません。そういう部分も勉強されていないように見えますが如何なのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

mi_l

Re: Dxライブラリについて

#3

投稿記事 by mi_l » 11年前

返信ありがとうございます。
softya(ソフト屋) さんが書きました:
申し訳ないですが、フォーラムルールを読んで頂くと分かりますが原則として削除をお受けすることはできません。
解決していないトピックでも何らかのヒントに成る可能性があることと、第一に回答してくれた回答者に失礼になるからです。
他の掲示板でもそうですが、削除はできるだけ避けていただきたいと思います。
おっしゃる通り、削除というのは回答者様にものすごい失礼な事ではあります。ですが、放置して、違うトピックを立て続けるのも失礼なので一応けじめとして書きました。
フォーラムルールに則り、削除はしない方向でお願いします。
softya(ソフト屋) さんが書きました: さて内容ですが、オブジェクト指向をちゃんとやるのか、手続き指向なのか(ベターC?)なのかスタンスを明確にしてもらったほうが良さそうです。
今のままだと、手続き指向をただクラスの形にしただけって印象なので勿体無いです。
それとクラスはインスタンスを生成しないと始まりません。そういう部分も勉強されていないように見えますが如何なのでしょうか?
方向としては、「オブジェクト指向をちゃんとやる」の方向です。

そして、ここの、指摘していただいた個所なのですけど、最初の私の質問にもあります通り、プログラミングの館では、まずmainに骨格をコピペ、そこから始めるようになっております・・・

ですが、私がどうしてもmain.cppを作ると以下のようになります・・・

コード:

#ifndef MAIN_H_
#define MAIN_H_

class Main
{
private:
	Back bg;
protected:
public:

	Main(void);
	~Main(void);

	void calc();//なんとなく・・
	void draw();
}
#endif //MAIN_H_

コード:

#include "Back.h"
#include "main.h"
#include "DxLib.h"

Main::Main()
{
}

Main::~Main()
{
}

void Main::calc()
{
}

void Main::draw()
{
	bg.Draw();
}

これですと、ウィンドウの生成など、骨格に含まれていたことを何処に書けばいいのかわかりません。

竜神録のC++のコードにもmainに骨格は書いてありせんでした・・・

どこにウィンドウ生成、つまり、コピペする「必ず書く骨格」は書けばいいのでしょうか?

そもそもmainの記述に誤りがあればそれもお願いします。

KORYUOH
記事: 44
登録日時: 12年前

Re: Dxライブラリについて

#4

投稿記事 by KORYUOH » 11年前

C++でもmainはmain関数で書きます。

なのでこの場合main.cppは

コード:

//インクルードは省略
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{

	//実装(省略)

	return 0;
}
の形で大丈夫です。

骨格に関しては別のクラスで用意し
実行メソッドを呼び出すだけの実装にするのがスマートだと思います。
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

mi_l

Re: Dxライブラリについて

#5

投稿記事 by mi_l » 11年前

返信ありがとうございます。

ウィンドウ生成は、他クラスに骨格のウィンドウ生成を記述したメソッドを用意して、メインで実装すればよいというのはわかりました。


しかし、ループはどのように表現すればいいのでしょうか?

mainのなかに描画などを実装するならそこはループ内でないといけないのですが・・・

コード:

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
 
        //ココ!!
        ScreenFlip();
    }
はmain内に書かなくて大丈夫なのでしょうか?

KORYUOH
記事: 44
登録日時: 12年前

Re: Dxライブラリについて

#6

投稿記事 by KORYUOH » 11年前

mi_l さんが書きました: mainのなかに描画などを実装するならそこはループ内でないといけないのですが・・・

コード:

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない
 
        //ココ!!
        ScreenFlip();
    }
はmain内に書かなくて大丈夫なのでしょうか?
考え方によりますがmainが描画、更新などをする必要性はないのでそれも別のクラスに任せてしまうとよいでしょう。
ざっくりとしたクラスですが

コード:

class Runner{
public:
	Runner();
	virtual ~Runner(){}
	
	void run();
	
private:
	//実装(省略)
}
このようなクラスを用意することでメイン関数内でインスタンスをつくりrun()を呼び出すだけになります。
run()ではウィンドウの作成からメインループを行う感じです。
C言語を使うと自分の足を誤って撃ち抜いてしまうことがある。 C++を使えばそのような間違いを犯しにくくなる。しかし、やってしまったときには足全体が無くなる。

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

Re: Dxライブラリについて

#7

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

私はMain専用のクラスは別に用意しなくても大丈夫だと思います。
WinMainで最低限のインスタンスを用意して、メソッドを呼び出したら良いのではないでしょうか?
クラスを用意すれば、オブジェクト指向が出来ていると言うわけでもないですから。

最初のBackクラスの
setPos();
calc();
がDrawメソッドに有る方がよほど問題だと思います。

気になる点。
1.メソッドの機能がメソッド名から逸脱している所。
2.外部公開する必要性があるか疑問なsetPos();メソッドが有る所。
3.setPos();の存在意義自体が疑わしい所。
4.Loadクラスが本当に必要なのか?と言う点。
オブジェクトして考えた時に画像ハンドルの保持はどのクラスがすべきなのか?
Loadクラスは何をするためのオブジェクトなのか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

mi_l

Re: Dxライブラリについて

#8

投稿記事 by mi_l » 11年前

返信ありがとうございます。


>>KORYUOHさん

mainにはループ処理(その他描画などの処理)が入っているメソッドを渡すってことですか?

例えば、Backの描画処理(Draw)はRunnerクラスのrunの中のループ内に実装するってことでしょうか?

runの中にwhile文(骨格で記述さているループ文)を書き、その中に描画などの処理を書いて、最後にmainに持ってきて・・・という感じなのでしょうか?


>>softya(ソフト屋) さん

一応Back.cppを直してみました

コード:

#include"Back.h"
#include"DxLib.h"

Back::Back(void)
{
	posX = 100;
	posY = 100;
	count = 0;
}

Back::~Back(void)
{
}

void Back::Draw()
{
	DrawGraph( posX , posY+count , b_img , FALSE );
	count++;
}
そして、Loadクラスは、すべての画像、音楽などのファイルをロードして、そこからそれぞれのクラスが必要なのをとっていく・・というような感じです・・

mi_l

Re: Dxライブラリについて

#9

投稿記事 by mi_l » 11年前

>>KORYUOHさん

KORYUOHさんのおっしゃっていることは、

main

コード:

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

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
	CSystemMgr SystemMgr;
	if( SystemMgr.Initialize() == false ){
		goto FIN;
	}
	SystemMgr.MainLoop();
FIN:
	SystemMgr.Finalize();
	return 0;
}
 

Runnerがいわゆる↓

コード:

#include <DxLib.h>

#include "Key.h"
#include "SystemMgr.h"
#include "Macro.h"
#include "CommonDefine.h"

#define WINDOW_TITLE "東方龍神録"

/*
*	@brief	コンストラクタ
*/
CSystemMgr::CSystemMgr(){
	m_pGameMgr = NULL;
	m_pFpsCtrl = NULL;
	SetGraphMode( WIN_W, WIN_H, WIN_BITS ) ;	//解像度設定
	SetMainWindowText(WINDOW_TITLE);			//ウィンドウタイトルをセット
	ChangeWindowMode( TRUE );					//ウィンドウモードに変更
	DxLib_Init();								//DXライブラリ初期化
	SetDrawScreen( DX_SCREEN_BACK );			//描画先を裏画面に設定
	SetOutApplicationLogValidFlag(FALSE);		//ログ出力しない
	SetAlwaysRunFlag(TRUE);						//ウィンドウがノンアクティブでも実行
	SetWindowSizeChangeEnableFlag(TRUE);		//ウィンドウサイズを自由に変更できる
}

/*
*	@brief	デストラクタ
*/
CSystemMgr::~CSystemMgr(){
	delete m_pGameMgr;	m_pGameMgr=NULL;
	delete m_pFpsCtrl;	m_pFpsCtrl=NULL;
	DxLib_End();							//DXライブラリ終了処理
}

/*
*	@brief	初期化
*/
bool CSystemMgr::Initialize(){
	if( m_pGameMgr == NULL ){
		m_pGameMgr = new CGameMgr();
	}
	if( m_pFpsCtrl == NULL ){
		m_pFpsCtrl = new CFpsCtrl();
	}
	m_pGameMgr->Initialize();
	return true;
}

void CSystemMgr::Finalize(){
	m_pGameMgr->Finalize();
}

/*
*	@brief	ゲームのメインループ部
*/
void CSystemMgr::MainLoop(){
	int t=0;
	while( !ScreenFlip() && !ProcessMessage() && !ClearDrawScreen() && !clsDx() ){

		CKey::Inst()->Update();					//UIの状態更新
		
		if( m_pGameMgr->Process() == false ){	//ゲーム処理
			break;
		}

		m_pGameMgr->Draw();						//ゲーム描画

		m_pFpsCtrl->Draw();	//FPS表示
		m_pFpsCtrl->Wait();	//指定FSPを保つための待機

		printfDx("Totl %2d[ms]\n", GetNowCount() - t );	t=GetNowCount();//1周の時間を処理表示

	}
}
の役割をしているということです・・よね・・?

上記コードは竜神録C++版のダウンロードしたものです。

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

Re: Dxライブラリについて

#10

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

mainの構造は、龍神録の方法でも良いですし、KORYUOHさんの方法でも良いですし、どちらを選んでもの良いと思います。

>そして、Loadクラスは、すべての画像、音楽などのファイルをロードして、そこからそれぞれのクラスが必要なのをとっていく・・というような感じです・・

資源を管理するクラスを作ると言うことですね。
であれば、Loadクラスをシングルトンにしてどこからも見えるようにしてしまうのがひとつの手です。
龍神録C++は、画像管理クラスとサウンド管理クラスがシングルトンで公開されていたはずです。

BGクラスは、STGを本格的に作るのならステージ毎の背景を処理する必要が出てくるでしょうし、ステージごとに背景サイズが違うとか、3Dを扱うクラスに成るかもしれないとか色々と考えて設計しておいた方が良いと思います。あとボス時の背景のループとかメソッドは色々必要だと思われます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

peot

Re: Dxライブラリについて

#11

投稿記事 by peot » 11年前

すみません、つまらない揚げ足とりかもしれないのですが、
こういうものだと定型で覚えてしまうとまずいのではないかと
思うので書き込ませてください。

エラーを出すことはほぼないとはいえ、DXライブラリの初期化を
コンストラクタ内で行うのはよくないです。
最低限、 DxLib_Init()だけでもエラーチェックは行っておいたほうが
よいと思います。

ですから、もしmain.cppつくるのであれば

コード:

 
class Main
{
 public:
 
	Main();
	~Main();
	int run;//又はRunnerでもmainLoopでもスキに

 private:

    Back bg;

	void calc();
	void draw();
};

/////////////////////////////////////////////////////////////////////
 
Main::Main()
{
	//エラーチェックをしないならこっちでもいい
	ChangeWindowMode( TRUE );
}

Main::~Main(){ DxLib_End(); }

int Main::run()
{
	//DXライブラリ初期化
	if( DxLib_Init() == -1 ){ return -1; }// ここ重要!
	//描画先を裏画面に設定
	SetDrawScreen( DX_SCREEN_BACK );

	while(
		!ScreenFlip() && 
		!ProcessMessage() && 
		!ClearDrawScreen() )
	{
		calc();
		draw();
	}
	return 0;
}
 
void Main::calc(){} 

void Main::draw(){ bg.Draw(); }
このようなカタチにしたほうがよいのではないでしょうか。
そんな細かいこと気にしねーわーと言うならば、忘れてもらって結構ですが・・・。

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

Re: Dxライブラリについて

#12

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

異常処理なら、龍神録C++でデストラクタが呼ばれない問題を適切に処理した上でですが、コンストラクタであるCSystemMgr::CSystemMgr(){から、throwしても良い気がします。
当然、インスタンス生成元であるWinMainでtry~catchしないとダメですけど。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

mi_l

Re: Dxライブラリについて

#13

投稿記事 by mi_l » 11年前

皆様、返信ありがとうございます。

また、ほかのやり方も教えていただき、ありがとうございます

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

Re: Dxライブラリについて

#14

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

良かったら、背景を動かすところまでは続けてはどうでしょうか?
ここで終わるのは中途半端な気がするのですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

mi_l

Re: Dxライブラリについて

#15

投稿記事 by mi_l » 11年前

解決後なのに返信ありがとうございます。


もちろんそのつもりです。

背景をスクロールさせて、キャラを出すところまでとりあえずやるつもりです!

おそらくそのことで新たなトピックを立てるとは思います・・・・自分の書いたコードをどれだけきれいにできるかとかで・・・

閉鎖

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