ゲーム作り基本

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

ゲーム作り基本

#1

投稿記事 by 隠蔽 » 8年前

前にここで質問させてもらったのですが、また初心者疑問が湧いたので質問させてもらいます


1.ロード関数を使って画像をロードするには時間がかかると聞きました
プログラムは上から順に実行されると思うのですがロードしているときに
処理が止まってしまうということはないのでしょうか?

2.当たり判定関数を作って矩形当たり判定をするときにたくさんの座標情報が必要になりますよね
引数に座標値を書きまくったらすごい数になるのですが
やり方が間違ってそうで仕方ありません 正しいやり方というか効率的なというかありますか?

3.構造体にえむあろっくを使っているコードがあったのですが
エムアロックは要素数を確保?する使い方しか知らないのですが
構造体に使ってどうするのですか?

4.画像の大きさが様々な画面でスクロール処理をしたいのですが
マップチップのときと同じやり方でできますか?
(画像の端の座標を使えばできるかなぁと思っているのですが)


質問が多すぎますが答えられるだけでいいですのでどうかお願いいたします

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: ゲーム作り基本

#2

投稿記事 by へろりくしょん » 8年前

隠蔽 さんが書きました:1.ロード関数を使って画像をロードするには時間がかかると聞きました
プログラムは上から順に実行されると思うのですがロードしているときに
処理が止まってしまうということはないのでしょうか?
小さな画像1枚程度なら、0.1秒もかからないと思いますが、体感できるかどうかは別として、基本的にロード中は処理が止まります。
ですから、この手の処理はタイミングを見極める必要があります。
例えば、画面が暗転して新しい画面に切り替わる時。 とか。
隠蔽 さんが書きました:2.当たり判定関数を作って矩形当たり判定をするときにたくさんの座標情報が必要になりますよね
引数に座標値を書きまくったらすごい数になるのですが
やり方が間違ってそうで仕方ありません 正しいやり方というか効率的なというかありますか?
関数の引数がやたらと増えてしまう場合は、構造体にまとめてしまうのが、セオリーじゃないでしょうか。
呼び出し側の処理が若干煩雑になりがちなので、嫌う人もいるようですが。
隠蔽 さんが書きました:3.構造体にえむあろっくを使っているコードがあったのですが
エムアロックは要素数を確保?する使い方しか知らないのですが
構造体に使ってどうするのですか?
malloc() 関数は、ヒープ領域から任意のサイズのメモリを確保するものです。
int *hoge = (int*)malloc(sizeof(int[10])); というコードは、int[10] 型のサイズ分の領域を確保しているだけです。
sizeof(int) == 4 の時、int *hoge = (int*)malloc(40); と書いたコードと全く同じ結果が期待出来ます。

struct HOGE *hoge = (struct *HOGE)malloc(sizeof(struct HOGE)); というコードは、構造体 struct HOGE の大きさの領域をヒープに確保しますよって事です。
隠蔽 さんが書きました:4.画像の大きさが様々な画面でスクロール処理をしたいのですが
マップチップのときと同じやり方でできますか?
(画像の端の座標を使えばできるかなぁと思っているのですが)
画像の端の座標というのが分かりませんが、できますよ。
いわゆる多重スクロールって奴と同じ方法ですね。 この場合は、大きさの違う画像毎にレイヤー化します。
質問が多すぎますが答えられるだけでいいですのでどうかお願いいたします[/quote]

隠蔽

Re: ゲーム作り基本

#3

投稿記事 by 隠蔽 » 8年前

ありがとうございます 4っつとも答えていただき、また疑問が出たのですが
へろりーな さんが書きました:struct HOGE *hoge = (struct *HOGE)malloc(sizeof(struct HOGE)); というコードは、構造体 struct HOGE の大きさの領域をヒープに確保しますよって事です。
ヒープ領域ってプログラムが終わるまで消えない値でしたっけ?
staticと何が違うのですか?
へろりーな さんが書きました:いわゆる多重スクロールって奴と同じ方法ですね。 この場合は、大きさの違う画像毎にレイヤー化します。
多重スクロールとレイヤー化ってなんでしょうか?
調べてみたのですが用語?ばっかりでさっぱりだったので
素人にも分かるように教えていただけたら幸いです

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: ゲーム作り基本

#4

投稿記事 by へろりくしょん » 8年前

隠蔽 さんが書きました:ヒープ領域ってプログラムが終わるまで消えない値でしたっけ?
staticと何が違うのですか?
ちょっと乱暴な言い方になりますが。
ヒープ領域というのは、OSが管理している領域です。 アプリケーションでは、malloc() 関数等を呼び出す事で、OSの持つ領域を一時的に借り受けます。

OSはアプリケーションが起動されると、アプリケーションに必要なメモリ領域(コードセグメントや、データセグメント等)を確保し、ここへアプリケーションをロードします。
これがいわゆるプロセス空間と呼ばれるものです。

原則として、アプリケーションはこのプロセス空間で作業する事になりますが、必ずしもアプリケーションが作業するに必要な大きさを持つわけではありません。
そこで、アプリケーションからOSに対し、メモリをもちょっと頂戴。 とお伺いを立てるわけです。
そうすることで、より大きなメモリを扱う事が出来るようになります。 これがヒープ領域です。

static な変数は、一般にデータセグメント(プロセス空間)に配置されます。

隠蔽 さんが書きました:多重スクロールとレイヤー化ってなんでしょうか?
調べてみたのですが用語?ばっかりでさっぱりだったので
素人にも分かるように教えていただけたら幸いです
一般にマップチップは2次元配列で表現されると思いますが、この2次元配列を2個用意して、別に管理する事で重ねて表示しましょう。 というのがレイヤー化です。
例えば、街の中を考えた場合、地面だけの配列・建物だけの配列を用意して重ねるとすれば、地面レイヤー・建物レイヤーと呼ぶ事が出来ます。

1つの2次元配列で地面・建物表現した場合、右に100ピクセルスクロールさせてしまうと、地面と建物が同じようにスクロールしますね。
レイヤー化した場合、地面が右に100ピクセルスクロールする間に、建物を50ピクセルだけスクロールさせる。 といった事が容易になります。 これが多重スクロールです。

#あまりいい例が思いつきませんでしたが、地面と建物が別々にスクロールする事が現実にあり得ないという事はスルーしてください。

隠蔽

Re: ゲーム作り基本

#5

投稿記事 by 隠蔽 » 8年前

エムアロックの説明が分かったつもりです
どんだけメモリがほしいか設定できるのは分かりましたが(配列を使うときのは)
struct HOGE *hoge = (struct *HOGE)malloc(sizeof(struct HOGE));
これは何をしているのでしょうか? どんな使い方をするのか教えてください

M

Re: ゲーム作り基本

#6

投稿記事 by M » 8年前

隠蔽 さんが書きました:前にここで質問させてもらったのですが、また初心者疑問が湧いたので質問させてもらいます
1.ロード関数を使って画像をロードするには時間がかかると聞きました
プログラムは上から順に実行されると思うのですがロードしているときに
処理が止まってしまうということはないのでしょうか?
非同期の読み込み関数を使用するかロード関数をスレッドに投げれば、読み込み中でも他の処理(Now Loading...等)を動作させられますよ。
読み込み終了もしくはスレッドの終了を監視する枠組みを自前で構築する必要がありますが、いちど構築すれば応用範囲が広いです。

アバター
へろりくしょん
記事: 92
登録日時: 9年前
住所: 福岡

Re: ゲーム作り基本

#7

投稿記事 by へろりくしょん » 8年前

隠蔽 さんが書きました:struct HOGE *hoge = (struct *HOGE)malloc(sizeof(struct HOGE));
これは何をしているのでしょうか? どんな使い方をするのか教えてください
構造体 struct HOGE に必要なメモリをヒープ領域から確保しているだけです。

使い方は、普通の変数と変わりません。

ヒープ領域を利用する理由は色々とありますが、自動変数・静的変数が確保するメモリ領域にはいくつか不都合があります。

自動変数では、一般にスタックへ詰まれるため、変数の値を永続的に保持する事は出来ません。
静的変数では、その寿命はプログラムの終了までですが、逆に言えばプログラムの実行中は常に確保されていて、時に無駄とさえ言えます。
また、自動変数・静的変数はコンパイル時にそのサイズが決定されていなければなりません。
例えば、100MBもある動画ファイルを再生するために読み込むとして、静的領域にあらかじめ100MB確保しておく。 なんて行為はとても馬鹿らしいですね。

ヒープ領域に確保したメモリの寿命は、確保してから解放するまでで、これはプログラマが任意のタイミングで行う事ができ、またそのサイズも動的に決定する事ができます。
これにより、大容量のメモリを効率よく捌く事が可能です。

ただ、ヒープ領域へ配置される変数の宣言は出来ませんので、malloc() 関数等を通じて、OSにおねだりする必要があります。
そして、確保した領域へのアクセスは、領域へのアドレスを保持するポインタを経由して行います。
それ以外は、普通の変数(構造体)となんら変わりませんよ。

隠蔽

Re: ゲーム作り基本

#8

投稿記事 by 隠蔽 » 8年前

へろりーな さんが書きました:非同期の読み込み関数を使用するかロード関数をスレッドに投げれば、読み込み中でも他の処理(Now Loading...等)を動作させられますよ。
読み込み終了もしくはスレッドの終了を監視する枠組みを自前で構築する必要がありますが、いちど構築すれば応用範囲が広いです。
非同期の読み込み関数ってのがあるんですか!?自分はあまり詳しくないのですが・・・
後者については意味は一切わかりません すんまそん


〉〉へろりーなさん
じゃあ、この構造体の例の場合、普通に宣言するのと違うことは寿命の点だけってことですかね?
staticと違うことはサイズを指定できないってことでしょうか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: ゲーム作り基本

#9

投稿記事 by h2so5 » 8年前

隠蔽 さんが書きました: 非同期の読み込み関数ってのがあるんですか!?自分はあまり詳しくないのですが・・・
後者については意味は一切わかりません すんまそん
DXライブラリに非同期の読み込み関数は無いので、スレッドを使用して自作する必要があります。

今の段階で良く分からないのであれば、無理に非同期の読み込みをする必要はないと思います。
静止画のロード画面でも何とかなるかと。
隠蔽 さんが書きました: じゃあ、この構造体の例の場合、普通に宣言するのと違うことは寿命の点だけってことですかね?
staticと違うことはサイズを指定できないってことでしょうか?
サイズ指定はできますよ。mallocの引数がサイズです。
sizeof(struct HOGE) の部分が構造体1つ分のサイズを表していますから例えば、

struct HOGE *hoge = (struct *HOGE)malloc(sizeof(struct HOGE) * 2);
であれば構造体2つ分(つまり HOGE[2] ですね)のメモリを確保することになります。

隠蔽

Re: ゲーム作り基本

#10

投稿記事 by 隠蔽 » 8年前

すいません 前に書いたことは誤記でした

まとめると
・エムアロックやstaticを使うと値を保持できる
・エムアロックとstaticの違うところはメモリを指定できるかできないかである
これであってますかね?

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: ゲーム作り基本

#11

投稿記事 by h2so5 » 8年前

隠蔽 さんが書きました: ・エムアロックやstaticを使うと値を保持できる
値を保持するのは通常の変数でもできます。
違うのはいつまで値を保持するのか(=寿命)です。
隠蔽 さんが書きました: ・エムアロックとstaticの違うところはメモリを指定できるかできないかである
mallocによる動的確保ではメモリを確保・解放するタイミングが指定できます。
static変数については必ずプログラム実行・終了時に確保・開放されます。

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

Re: ゲーム作り基本

#12

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

スレッド非同期読み込みは読み込みにトンデモなく時間がかかる(十数秒)のでミニゲームで遊ばせたいとか、ステージ間の読み込みレスに見えるゲームを作りたいなど特別な意図がない限りやらなくて良いと思います。ちゃんとメモリ関係を理解していない人が組むと確実にバグりますので。それも超厄介なバグを産みます。
ただし、常に描画しながら読み込むと言うのはロードの使い方として大きな間違い(フレームレートが落ちる。メモリリークする)ですので、暗転中やステージ間で読むのが正しい使い方です。

それと関係ない指摘で申し訳ないですが「エムアロック」は口頭でやり取りする分には良いのですが文章中にあると違和感があるのでmallocと書いていただけると助かります。英語のカタカナ表記は基本的に口頭で会話する時用と思っていただいた方が良いかもしれません。

>・エムアロックとstaticの違うところはメモリを指定できるかできないかである

mallocの特徴
・動的なサイズを指定できる。 ⇒ メリット
・不要になれば好きなタイミングで開放できる。 ⇒ メリット
・解放(free)を忘れるとメモリに溜まっていく。 ⇒ デメリット(これをメモリリークと言う)
・確保忘れやサイズを間違うといとも簡単にメモリ保護例外が発生する。 ⇒ デメリット
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

隠蔽

Re: ゲーム作り基本

#13

投稿記事 by 隠蔽 » 8年前

なるほどそうゆう違いでしたか
とゆうことはstaticでもメモリが確保できない場合の処理を考えてやる必要があるのでしょうか?


#define MACRO_ASSERT(cond) { if( !(cond) ) DebugBreak(); }
違った質問になって申し訳ないのですが↑これはどういう意味でしょうか?
たくさん記号があって意味が分かりません(defineの置換ぐらいは知っています)


あと、もう一つはソフト屋さんのRPG講座のコードなんですが
ヘッダーに記述されているものはインクルードされた場所に展開されるのでしたよね
でも、その考え方だと構造体の実体の宣言?が構造体の定義よりも前に来ているのですが

コード:

typedef struct tag_CharObject *CHAR_OBJECT;//これはchar.hに記述されている

//ここからchar.cpp
#include "char.h"

struct tag_CharObject {
	int xnum;		//横方向の数。
	int ynum;		//縦方向の数。
	int animPtn;	//アニメーションのパターン
	int muki;		//向き
	int *images;	//プレーヤーキャラクタのイメージ配列
};

CHAR_OBJECT CharObj = NULL;
CharObj = (CHAR_OBJECT)malloc( sizeof(struct tag_CharObject) );
それとわざわざポインタを使って間接参照をしないといけない理由ってなんでしょうか?
処理のスピードが速くなるとかそういうことですか?

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

Re: ゲーム作り基本

#14

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

隠蔽 さんが書きました:なるほどそうゆう違いでしたか
とゆうことはstaticでもメモリが確保できない場合の処理を考えてやる必要があるのでしょうか?
staticで確保できない場合は、プロセス自体が起動しません。
つまりOSがエラーを出すのでプログラムは何も出来ないって事です。
隠蔽 さんが書きました:#define MACRO_ASSERT(cond) { if( !(cond) ) DebugBreak(); }
違った質問になって申し訳ないのですが↑これはどういう意味でしょうか?
たくさん記号があって意味が分かりません(defineの置換ぐらいは知っています)
もし条件(cond)が偽ならDebugBreak();を実行しますというマクロです。
分解すると

コード:

{	← ブロックの開始
	if( !(cond) ) 	← 条件(cond)を!(条件演算子)で否定。つまり逆の意味になる。
		DebugBreak(); ← デバッガで停止する関数。
}
← ブロックの終わり
隠蔽 さんが書きました:あと、もう一つはソフト屋さんのRPG講座のコードなんですが
ヘッダーに記述されているものはインクルードされた場所に展開されるのでしたよね
でも、その考え方だと構造体の実体の宣言?が構造体の定義よりも前に来ているのですが
これがあるので大丈夫ですよ。
typedef struct tag_CharObject *CHAR_OBJECT;
これも実体ではなくtypedefの定義に過ぎませんし、ポインタです。
構造体の実体が発生するのはmallocの時ですね。
隠蔽 さんが書きました:それとわざわざポインタを使って間接参照をしないといけない理由ってなんでしょうか?
処理のスピードが速くなるとかそういうことですか?
渡した関数の先で内容が書き換えられることです。
構造体を普通に引数で渡したら内容がコピーされてしまうので、書き換えても呼び出し元には反映されません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

隠蔽

Re: ゲーム作り基本

#15

投稿記事 by 隠蔽 » 8年前

softya(ソフト屋) さんが書きました:{ ← ブロックの開始
if( !(cond) ) ← 条件(cond)を!(条件演算子)で否定。つまり逆の意味になる。
DebugBreak(); ← デバッガで停止する関数。
}
えっと、condっていうのは変数でしょうか?condが定義されているかという意味でしょうか?
それとデバッカで停止する関数と書かれていますが
ほとんどのサイトはexit関数が使われています 
使い分けとかがあるのでしょうか?

softya(ソフト屋) さんが書きました:typedef struct tag_CharObject *CHAR_OBJECT;
これも実体ではなくtypedefの定義に過ぎませんし、ポインタです。
すいませんでした typedefの意味を復習してよくわかりました
それで定義する必要性はありますか?
とゆうか
typedef struct{
 メンバ変数
}CHAR_OBJECT;

CHAR_OBJECT *charobj
これと同じ意味でしょうか?どちらが効率的かって言われたら知りませんが

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

Re: ゲーム作り基本

#16

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

隠蔽 さんが書きました:えっと、condっていうのは変数でしょうか?condが定義されているかという意味でしょうか?
それとデバッカで停止する関数と書かれていますが
ほとんどのサイトはexit関数が使われています 
使い分けとかがあるのでしょうか?
マクロの引数は理解されていますか?
「C言語編 第39章 マクロ」
http://www.geocities.jp/ky_webid/c/039.html

それとexit関数ではプログラムは完全に停止しますが、DebugBreak();ではデバッガを利用していれば一時停止しますので変数の値などをデバッガで確認できます。
bccならTurbo Debugger があります。
「Turbo Debugger for Win32を使ってみる」
http://rakasaka.fc2web.com/delphi/td32.html
隠蔽 さんが書きました:すいませんでした typedefの意味を復習してよくわかりました
それで定義する必要性はありますか?
プログラム全体の設計コンセプトの問題です。
どうすれば便利か、書き間違い、バグが減るかって事が重要ですので、こういう手もありますよって事ですね。
どうするかは自分で考えてみてください。
自分で考えないと、そもそも意味が無いですから。
隠蔽 さんが書きました: とゆうか
typedef struct{
 メンバ変数
}CHAR_OBJECT;

CHAR_OBJECT *charobj
これと同じ意味でしょうか?どちらが効率的かって言われたら知りませんが
どっちでもかまいませんが、*を書く手間を減らしただけです。
手間を減らすのはバグを減らための基本ですので。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

隠蔽

Re: ゲーム作り基本

#17

投稿記事 by 隠蔽 » 8年前

サイトを見てきました それで置換のことなんですけど
(cond)って書かなくてはならないのでしょうか?
if文とかを省いて直接、DebugBreakに置換することはできないのでしょうか?

それと、ソフト屋さんのRPGコードでmallocを使っているのは
「保持した画像情報を忘れないようにするため」であっていますか?

アバター
h2so5
副管理人
記事: 2212
登録日時: 9年前
住所: 東京
連絡を取る:

Re: ゲーム作り基本

#18

投稿記事 by h2so5 » 8年前

MACRO_ASSERTは指定された条件が満たされない時にプログラムを停止するマクロです。
if文を省いたら無条件で停止してしまうので意味がありません。

もし無条件で停止させたいならブレークポイントを使ってください。

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

Re: ゲーム作り基本

#19

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

隠蔽 さんが書きました:サイトを見てきました それで置換のことなんですけど
(cond)って書かなくてはならないのでしょうか?
マクロ引数で(cond)と書くのはトラブル防止です。
先ほどの
「C言語編 第39章 マクロ」
http://www.geocities.jp/ky_webid/c/039.html
でも説明されています。
隠蔽 さんが書きました: if文とかを省いて直接、DebugBreakに置換することはできないのでしょうか?
そうしたら無条件に停止しますけど?

[追記]
こういうのは頭だけで考えずに実際に動作を試していただくと理解できると思います。
ちょっとテストプログラム書いて見る時間を惜しまないでください。
隠蔽 さんが書きました:それと、ソフト屋さんのRPGコードでmallocを使っているのは
「保持した画像情報を忘れないようにするため」であっていますか?
可変個数のデータを扱うからとCHAR_OBJECTであれば自キャラ以外も扱うのでCHAR_OBJECTが最終的に何個になるか分からないからです。
あとはマップだとマップファイルのサイズが不定だからだとか、可変要素・不定要素のためのmallocです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

隠蔽

Re: ゲーム作り基本

#20

投稿記事 by 隠蔽 » 8年前

申し訳ないです 
都合により今は自宅の外のパソコンから書き込んでいますのでCが手元にないです

difineの話は間違いで
#define MACRO_ASSERT { if( !(cond) ) DebugBreak(); }
このように書くことはできないかということです
完全に置換されるならcondなんて書く必要ないのではと思ったものですので
softya(ソフト屋) さんが書きました:可変個数のデータを扱うからとCHAR_OBJECTであれば自キャラ以外も扱うのでCHAR_OBJECTが最終的に何個になるか分からないからです。
メモリの大きさを指定するときは
CharObj = (CHAR_OBJECT)malloc( sizeof(struct tag_CharObject) * 2);
と書くと思っていたのですがRPG講座コードの場合
CharObj = (CHAR_OBJECT)malloc( sizeof(struct tag_CharObject) );
こんな風に書かれていました 
これじゃあ可変個数とか関係ない気がするのですがどうでしょうか?

それと*2と書きましたがその部分を*iにしたりできませんかね
reallocの存在は知っていますがわざわざ呼び出すのも面倒くさいので

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

Re: ゲーム作り基本

#21

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

隠蔽 さんが書きました:申し訳ないです 
都合により今は自宅の外のパソコンから書き込んでいますのでCが手元にないです
ここのサイトを使えば、どこからでも確認できますよ。
「Ideone.com | Online IDE & Debugging Tool >> C/C++, Java, PHP, Python, Perl and 40+ compilers and intepreters」
http://ideone.com/
隠蔽 さんが書きました:difineの話は間違いで
#define MACRO_ASSERT { if( !(cond) ) DebugBreak(); }
このように書くことはできないかということです
完全に置換されるならcondなんて書く必要ないのではと思ったものですので
そうすると、そのcondはマクロ置換されないので条件式ではなくint cond;などの変数にしないと行けないと思いますがどうするのでしょうか?
コンパイルするとこうなります。当然ながらエラー。
http://ideone.com/wfJI6

コード:

#define MACRO_ASSERT { if( !(cond) ) DebugBreak(); }
extern void DebugBreak(); //Linuxには無いので仮のものとして定義。
 
int main(void)
{
        MACRO_ASSERT;
        return 0;
}
隠蔽 さんが書きました:メモリの大きさを指定するときは
CharObj = (CHAR_OBJECT)malloc( sizeof(struct tag_CharObject) * 2);
と書くと思っていたのですがRPG講座コードの場合
CharObj = (CHAR_OBJECT)malloc( sizeof(struct tag_CharObject) );
こんな風に書かれていました 
これじゃあ可変個数とか関係ない気がするのですがどうでしょうか?

それと*2と書きましたがその部分を*iにしたりできませんかね
reallocの存在は知っていますがわざわざ呼び出すのも面倒くさいので
mallocする時点で個数が決まっていれば良いですが、char_Load()は不定期に複数回呼び出される前提ですので、一度に必要な分を全部確保する事はできません。
つまり、char_Load()は一度に指定個数を確保するのではなく呼び出される回数で不定個数を確保するのです。
個数が決まっているのなら、*iとすることは可能です。
ちなみに前提が全く違うので、2つの方法のどちらが良いかは比較する意味はありません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

隠蔽

Re: ゲーム作り基本

#22

投稿記事 by 隠蔽 » 8年前

softya(ソフト屋) さんが書きました:int cond;などの変数にしないと行けないと思いますが
はい、その通り変数にすればいいと思っていましたが
わざわざcondの値をいじって、置換で呼び出すなんて
よく考えたら、いやよく考えなくても二度手間ですよね
よく考えもしないで質問してしまい、謝罪します
softya(ソフト屋) さんが書きました:mallocする時点で個数が決まっていれば良いですが、char_Load()は不定期に複数回呼び出される前提ですので、一度に必要な分を全部確保する事はできません。
つまり、char_Load()は一度に指定個数を確保するのではなく呼び出される回数で不定個数を確保するのです。
このことについてはまだ分かってないんです 物わかりが悪く申し訳ないです
うまく言えませんがメモリを確保する理由が分かりません
可変個数って仰っていますがロードされた後、リターンされて違う構造体に代入されていますよね
だからメモリに確保しないで普通に返せばいい気がしてなりません

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

Re: ゲーム作り基本

#23

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

隠蔽 さんが書きました:このことについてはまだ分かってないんです 物わかりが悪く申し訳ないです
うまく言えませんがメモリを確保する理由が分かりません
可変個数って仰っていますがロードされた後、リターンされて違う構造体に代入されていますよね
だからメモリに確保しないで普通に返せばいい気がしてなりません
何度も書いてますがCHAR_OBJECTは構造体ではありません。構造体ポインタです。ポインタなのでポインタ値はmallocされたヒープメモリを指しています。
それに、char.cpp以外のプログラムは構造体の内部構造が分からないのでサイズ不明の構造体は実体宣言できません。宣言できるのは構造体のポインタの実体だけです。

これも納得できるまでプログラムで実験してみください。
char.cpp外から構造体のメンバにアクセス出来ません。

例えば私のヘッダの宣言
typedef struct tag_CharObject *CHAR_OBJECT;

typedef struct tag_CharObject CHAR_OBJECT_STRUCT;
として実体を確保する
CHAR_OBJECT_STRUCT CharObjStruct;
としてみてください。エラーになりますから。
こうすることで安易にメンバに触れない用にガードしています。

コンパイル例。
「Ideone.com | Online C Compiler & Debugging Tool」
http://ideone.com/N9rs8

[追記]
自分で一度関数を作ってみるとわかります。
・Loadで呼び出すとき引数を変えるだけで違うキャラクタをロードできる。
・複数のキャラクタをロードしておける。
・別々にキャラクタの描画タイミングが制御できる。
・ロードしたキャラクタを個別に開放できる。
・ロードした画像イメージの値にchar.cpp以外は直接触ることは出来ない。
これを満たす関数を書いてみてください。

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

隠蔽

Re: ゲーム作り基本

#24

投稿記事 by 隠蔽 » 8年前

エムアロックとポインタを復習して何度も読み返してみたのですが・・・

普通に構造体ポインタに引数で受けた情報を入れて返したらどうなりますか?
エムアロックを呼び出さずに返したら

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

Re: ゲーム作り基本

#25

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

隠蔽 さんが書きました:普通に構造体ポインタに引数で受けた情報を入れて返したらどうなりますか?
エムアロックを呼び出さずに返したら
構造体ポインタですので、構造体の実体が何処かに必要です。
構造体の実体は何処で実体宣言するのでしょうか?
想定していると違うというのであれば、隠蔽さんの考える擬似的なソースコードを書いてみてくださいね。

あと前に書きましたがエムアロックは口語用なので書き文字としてはmallocをお使いください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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