ゲームを作る上でポインタを使用したファイル設計

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

ゲームを作る上でポインタを使用したファイル設計

#1

投稿記事 by LisetteLander » 13年前

本家管理人さんが公開してくださっている龍神録のソースコードは
"ポインタを使わずにシューティングゲームを作る"
とのことでした。

そこで、自分はポインタを使用した本格的なカプセル化したゲームを作ろうとしました。
とりあえず一つ目の目標として龍神録でのGV.hでのGLOBALと頭につけた変数をすべてカプセル化し、ポインタでの引渡しをします。
しかし、関数同士でスマートに値を受け渡すには、というところで躓きました。

具体的に言うと、画像です。
キー入力はmain関数から呼び出し→ファイル内スコープでのキー取得関数を利用して返り値を返す。
ということをすれば、まぁカプセル化になるのですが(実際にはクラス使ってないのでカプセル化も何もない)
画像だと
ロードされたハンドルを描画関数にまで持って行き、ゲーム中保持し続けるにはどうしたらいいのかわからないです。

ロードファイルによって割り当てられたハンドル変数は
それまでグローバル変数を前もって宣言しハンドルを代入し、描画関数によってハンドル変数に沿った画像を選択して描画していましたが
ポインタを使いグローバル変数を使わないとなるとロード関数から直接描画関数へハンドルの値を持っていくことになり、

①今までグローバル変数にハンドルを入れてきたので保持できていた変数が関数のスコープを抜けると同時に破棄されてしまうのでは?
というのと
②「mainループから(実際に)描画するための関数として呼び出される」用途と「描画するためにハンドルをロード関数から貰う」用途が両立せず
前者だとハンドルが未定義(保持していないため)、後者だと描画関数として役割を果たさないのではないか?
という疑問があります。
静的変数はできるだけ使わない方向です。

この場合、クラスメンバメソッドとして
1.ハンドルを受け取り、クラス変数として格納する関数と
2.別ファイルからの、例えばユニットの画像の種類番号を引数として貰い実際に描画する関数
として分けるのがいいのではないかと思うのですがコードが無駄に肥大化してたり、考え方が根本的に間違ってないかという質問です。




質問を簡潔にまとめると

コード:

void draw(){
	DrawRotaGraph(x,y, 1.0,0,handle[0],TRUE );
}

コード:

void load(){
	LoadDivGraph( "player.png", 16, 4, 4, 32, 48, handle ); // 3つに画像を分割してロード
}
グローバル変数"handle"を使っていた上記のコードを
ポインタを置き換えるためにはどうしたらいいのでしょうか?
「ハンドル変数を渡す・ロードする」のは一回のみです。
この場合

コード:

class draw{
   int handle;
   public:
   void come_on_handle(int tmp){
          handle=tmp;
   }
   void draw_unit{
      DrawRotaGraph(x,y, 1.0,0,handle[0],TRUE );
   }
}
というようにしたほうがいいのでしょうか?(C++は初めてなのでクラスの書き方間違ってるかも)

お粗末な長文を最後まで読んでくださってありがとうございます。
※↑のコードだとポインタ使ってません。ポインタは使いたいです。(幻想かもしれませんが)スマートになるため(´・ω・`)

naohiro19
記事: 256
登録日時: 15年前
住所: 愛知県

Re: ゲームを作る上でポインタを使用したファイル設計

#2

投稿記事 by naohiro19 » 13年前

キー入力と同じようにすればいいです。

コード:

static int m_Handle;
void  GraphLoad() {
    m_Handle = LoadGraph(...);
}

int GraphGet() {
    return m_Handle;
}
という感じになります。

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: ゲームを作る上でポインタを使用したファイル設計

#3

投稿記事 by beatle » 13年前

いまいち何をカプセル化したいのかよくわかりませんが、
C++でスマートに書きたいならポインタより参照を使った
方が良いような気がします。
それから、カプセル化すればコードが減るということはありません。
むしろその逆でしょう。

ぬっち
記事: 105
登録日時: 14年前
連絡を取る:

Re: ゲームを作る上でポインタを使用したファイル設計

#4

投稿記事 by ぬっち » 13年前

naohiro19 さんが書きました:そこで、自分はポインタを使用した本格的なカプセル化したゲームを作ろうとしました。
ここがよくわかりませんでした。

DXライブラリはかなり前に使用したのが最後でちょっとわからないのですが、私でしたら画像1つに対して1つオブジェクトを作成し、キーボードに対しても1つのオブジェクトを作成します。

画像を取り扱うクラス

コード:

class Image
{
private:
    int  m_Handle;
public:
    void Load( const char* fileName );
    void Draw( x, y );
    void Draw( x, y angle );
};
キーボードを取り扱うクラス

コード:

class Keyboard
{
private:
    int  m_Keys[ 256 ];
public:
    void Setup();
    bool IsPushed( int key );
};

質問の内容がよくわからなかったので、もしかしたら的外れな回答をしているかもしれません。

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

Re: ゲームを作る上でポインタを使用したファイル設計

#5

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

キーボードに関してはシングルトンにすると思います。2つインスタンスがあっても意味無いですし。
あと敵ごとにクラス化でインスタンスを持ちprivateなメンバ変数でハンドルを持つでしょう。それが一番のカプセル化です。
ただ、敵の画像が同じデータを持つ可能性が高いので画像を管理するクラスは別にするかも知れません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: ゲームを作る上でポインタを使用したファイル設計

#6

投稿記事 by LisetteLander » 13年前

ファイルスコープ内でのローカル変数、もしくは画像に関与する関数をまとめたクラスを作るということでしょうか?
loadファイルとdrawファイルを分けたいなんて言ったら前述と矛盾しますしc++の概念というかコンセプトに反しますよね・・・('A`;)

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

Re: ゲームを作る上でポインタを使用したファイル設計

#7

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

sood さんが書きました:ファイルスコープ内でのローカル変数、もしくは画像に関与する関数をまとめたクラスを作るということでしょうか?
loadファイルとdrawファイルを分けたいなんて言ったら前述と矛盾しますしc++の概念というかコンセプトに反しますよね・・・('A`;)
すいません、誰に対するコメントでしょうか?
naohiro19さんの物だったらC言語的カプセル化ですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: ゲームを作る上でポインタを使用したファイル設計

#8

投稿記事 by LisetteLander » 13年前

これで最後です。。

コード:

class graph_common{
private:
	int handle;
public:
	void handle_load(const TCHAR *FileName,int allnum,int xnum,int ynum,int xsize,int ysize){//handleがローカルで唯一のものになったからclassをコピペで大量に作ることになる?
	    LoadDivGraph(FileName,allnum,xnum,ynum,xsize,ysize,&handle); 
	}
	void handle_draw(int x,int y,double size,double angle){
		DrawRotaGraph(x,y,size,angle,handle,TRUE);
	}
};
こんなんなったんですが動きません・・・

追記

↑ココまで書いて、なんかこんな感じで行ける気がしました↓
class unit{
  int x,y,handle;
  double angle;
public:
  graph_draw(){
     DrawRotaGraph(x,y,1.0,angle,handle,TRUE);
  }
  graph_load(){
    LoadDivGraph(handle,?,?,?,?,?,?);
  }
}

が、handleはローカル変数でunitごとにロードするのはあまりにも効率的ではない気がします。
そうするとhandleをグローバル変数にするか画像機能をunitクラスの外に出すか・・・
画像機能をクラス化するとなるとこの[返信]の一番上のようなクラスになるのですが
画像ごとに枚数や大きさが違うのでhandle宣言時にうまく合致しません・・・
最後に編集したユーザー LisetteLander on 2011年11月30日(水) 01:42 [ 編集 4 回目 ]

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: ゲームを作る上でポインタを使用したファイル設計

#9

投稿記事 by LisetteLander » 13年前

softya(ソフト屋) さんが書きました: すいません、誰に対するコメントでしょうか?
naohiro19さんの物だったらC言語的カプセル化ですね。
naohiroさんに前半、句読点後はぬっちさんヘのコメントです。わかりづらくてすいません。

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

Re: ゲームを作る上でポインタを使用したファイル設計

#10

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

>画像ごとに枚数や大きさが違うのでhandle宣言時にうまく合致しません・・・

そういうのは、ハンドルを動的に必要個数だけ確保すれば解決します。
それとLoadDivGraphで
int handle;
は使い方を間違ってますよ。

>画像機能をクラス化するとなるとこの[返信]の一番上のようなクラスになるのですが
naohiro19さんのものをクラス化すると、それに近い形ですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: ゲームを作る上でポインタを使用したファイル設計

#11

投稿記事 by LisetteLander » 13年前

softya(ソフト屋) さんが書きました:>画像ごとに枚数や大きさが違うのでhandle宣言時にうまく合致しません・・・

そういうのは、ハンドルを動的に必要個数だけ確保すれば解決します。
それとLoadDivGraphで
int handle;
は使い方を間違ってますよ。

>画像機能をクラス化するとなるとこの[返信]の一番上のようなクラスになるのですが
naohiro19さんのものをクラス化すると、それに近い形ですね。
配列を動的に確保するにはどうしたらいいのでしょうか・・・
malloc()はややこしくなりそうで・・・

やはりunitはunitでクラスを作り
itemなどはitemなどでクラスを作りそれぞれ規格を統一して
定数でhandleを指定したほうがいいのでしょうか?
最後に編集したユーザー LisetteLander on 2011年11月30日(水) 13:05 [ 編集 1 回目 ]

beatle
記事: 1281
登録日時: 13年前
住所: 埼玉
連絡を取る:

Re: ゲームを作る上でポインタを使用したファイル設計

#12

投稿記事 by beatle » 13年前

C++では、普通の配列の要素数を可変にすることはできません。
int a[n];のnには定数式しか来れないのです。
C++をお使いなのですから、std::vectorなどを使いましょう。
参考:http://www.geocities.jp/ky_webid/cpp/library/002.html

ちなみに、C++では、通常はmallocではなくてnewを使います。

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

Re: ゲームを作る上でポインタを使用したファイル設計

#13

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

mallocを使わないにしてもちゃんと管理しないと行けませんよ。
int *handle;

int n=5
handle = new int[n];
です。
削除する時は
delete [] handle;
となります。デストラクタなどで削除して下さい。

管理で楽をしたいならSTLのvectorを使うのもひとつの手です。[補足]LoadDivGraph()用だとvectorだと問題ありますので、newかshared_arrayがおすすめです。

【追記】
あとboostのスマートポインタの配列版であるshared_arrayを使うのも方法です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
LisetteLander
記事: 147
登録日時: 14年前
住所: 東京

Re: ゲームを作る上でポインタを使用したファイル設計

#14

投稿記事 by LisetteLander » 13年前

ありがとうございました。
ひと通り疑問が解決したので解決とさせていただきます!

閉鎖

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