新ゲームプログラムの館1.4章のとこ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
LEMO
記事: 23
登録日時: 7年前
住所: 関東地方ですね

新ゲームプログラムの館1.4章のとこ

#1

投稿記事 by LEMO » 7年前

http://dixq.net/g/01_04.html
ここの

コード:

#include "DxLib.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
        ChangeWindowMode( TRUE ); // ウィンドウモードに設定
        DxLib_Init();   // DXライブラリ初期化処理

        int Handle;     // データハンドル格納用変数
        Handle = LoadGraph( "画像/キャラクタ00.png" ); // 画像をロード
        DrawGraph( 50, 100, Handle, TRUE ); // データハンドルを使って画像を描画

        WaitKey();     // キー入力があるまで待機
        DxLib_End();   // DXライブラリ終了処理
        return 0;
} 
のコードなのですが
int Handleで格納用変数を作ってそれをすぐHandle = LoadGraphで指定してますが
もし、[画像A][画像B][画像C][画像D][画像E][画像F][画像G]という7枚の画像をロードするときは
int HandleA
int HandleB
のようにロードしたい画像文格納変数を作るってことでしょうか?
なんとか簡略化できないのでしょうか?

Egg

Re: 新ゲームプログラムの館1.4章のとこ

#2

投稿記事 by Egg » 7年前

これでどうぞ。

コード:

// 初級:配列にする
int Handle[32];
// 中級:可変配列もしくはリストにする
std::List<int> ListHandle;
// 上級:人間に分かりやすい文字列エイリアスを付けてMapに保存する
std::Map<char*, int> ListMap;
リファレンス見ずに書いたので、ミスがあればハッカーの方よろしくお願いします。

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

Re: 新ゲームプログラムの館1.4章のとこ

#3

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

Egg さんが書きました:

コード:

// 中級:可変配列もしくはリストにする
std::List<int> ListHandle;
// 上級:人間に分かりやすい文字列エイリアスを付けてMapに保存する
std::Map<char*, int> ListMap;
STLを使うなら、Listではなくlist、Mapではなくmapですね。
また、どうしてstd::stringではなくchar*を用いたのですか?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Egg

Re: 新ゲームプログラムの館1.4章のとこ

#4

投稿記事 by Egg » 7年前

>>どうしてstd::stringではなくchar*を用いたのですか?
リテラルで比較したほうが速そうだなと思いまして
比較演算子をオーバーロードできるならばstd::stringのほうがよろしいかと
std::stringを普段余り使わないので

あんどーなつ
記事: 171
登録日時: 7年前
連絡を取る:

Re: 新ゲームプログラムの館1.4章のとこ

#5

投稿記事 by あんどーなつ » 7年前

ハッカーじゃないけど面白そうなので、色々考えました。

案1 最近のC++は日本語識別子が使える→enumかconst intにする

結論:あまりうれしくない。enumはC#と違って名前が被りやすいのでウザくなる可能性大

案2 マクロを使う

結論:ファイル構成が分かりづらくなる。自己満足の誰得システムになると思われる。

案3 配列とmapとchar*とstringを全部使う。

この案は割と気に入っています。コード例を以下に載せておきます。

コード:

#include <iostream>
#include <map>
#include <string>
using namespace std;

#define TRUE 1
#define FALSE 0

typedef struct { const char *key; const char *filename; } IMAGE_DATA;

const IMAGE_DATA IMAGE_LIST[] = {
	{"主人公"		, "画像/キャラクタ00.png"},
	{"ヒロイン"		, "画像/キャラクタ01.png"},
	{"雑魚敵1"		, "画像/キャラクタ02.png"},
	{"雑魚敵2"		, "画像/キャラクタ03.png"},
	{"雑魚敵3"		, "画像/キャラクタ04.png"},
	{"ラスボス"		, "画像/キャラクタ05.png"},
};

const int MAX_IMAGE = sizeof(IMAGE_LIST) / sizeof(IMAGE_DATA);

map<string, int> images;

// スタブのための関数
int LoadGraph(string fn) {
	static int cnt = 100;
	cout << "LoadGraph(" << fn << ")がロードされました.\n";
	return cnt++;
}
void DrawGraph(int i, int j, int h, int b) {
	cout << "DrawGraph: " << IMAGE_LIST[h-100].filename << "を表示しています.\n";
}

int main() {
	// 初期化
	for (int i = 0; i < MAX_IMAGE; ++i)
		images[IMAGE_LIST[i].key] = LoadGraph(IMAGE_LIST[i].filename);

	// 表示
	cout << "シーン1" << endl;
	DrawGraph(0, 0, images["主人公"], TRUE);
	DrawGraph(0, 0, images["雑魚敵1"], TRUE);
	DrawGraph(0, 0, images["雑魚敵2"], TRUE);
	cout << "シーン2" << endl;
	DrawGraph(0, 0, images["主人公"], TRUE);
	DrawGraph(0, 0, images["ラスボス"], TRUE);
	DrawGraph(0, 0, images["雑魚敵3"], TRUE);
	cout << "シーン3" << endl;
	DrawGraph(0, 0, images["主人公"], TRUE);
	DrawGraph(0, 0, images["ヒロイン"], TRUE);

	return 0;
}
実行結果

コード:

$ ./a.exe
LoadGraph(画像/キャラクタ00.png)がロードされました.
LoadGraph(画像/キャラクタ01.png)がロードされました.
LoadGraph(画像/キャラクタ02.png)がロードされました.
LoadGraph(画像/キャラクタ03.png)がロードされました.
LoadGraph(画像/キャラクタ04.png)がロードされました.
LoadGraph(画像/キャラクタ05.png)がロードされました.
シーン1
DrawGraph: 画像/キャラクタ00.pngを表示しています.
DrawGraph: 画像/キャラクタ02.pngを表示しています.
DrawGraph: 画像/キャラクタ03.pngを表示しています.
シーン2
DrawGraph: 画像/キャラクタ00.pngを表示しています.
DrawGraph: 画像/キャラクタ05.pngを表示しています.
DrawGraph: 画像/キャラクタ04.pngを表示しています.
シーン3
DrawGraph: 画像/キャラクタ00.pngを表示しています.
DrawGraph: 画像/キャラクタ01.pngを表示しています.

アバター
amehirune
記事: 181
登録日時: 10年前
住所: どっか
連絡を取る:

Re: 新ゲームプログラムの館1.4章のとこ

#6

投稿記事 by amehirune » 7年前

オフトピック
なんか勝手にC++という形で話が進んでいるけど、果たしてそれでいいのだろうか?
#初心者にわかるように話しているので、厳密にいえば違う部分もあります

基本的なところだけ言いますと、他の方もおっしゃっているように、
簡単なのはint型の配列を使う方法です。
int graph[7]で7枚分の画像データを保存できるようになります。

また、それらの画像に何らかの関連性がある場合、さらに省略が可能です。
①7枚全ての画像が統合されて、1枚の画像になっているとき
 この場合はLoadDivGraph関数が使えます。詳しくはググりましょう。もしくはリファレンスへ。
②ファイル名に規則性がある場合
 例えば、下記のサンプルでは「img00.jpg」「img01.jpg」「img02.jpg」…というように、
 imgの後に2桁の番号が続く画像ファイルたちを読み込んでいます。

コード:

for(int i=0;i<7;i++){
        sprintf(buf,"img%2d.jpg",i);
        graph[i] = LoadGraph(buf);
}
追記:みけCATさん>本当だ、iが落ちてました。すみません(汗)
最後に編集したユーザー amehirune on 2016年12月06日(火) 14:18 [ 編集 1 回目 ]
ほら、来いよ!! 誤字や矛盾を指摘したい奴から、前に出てこいよぉおおおおおおおッ!!!
※都合により、不定期でしか現れません。即返などはできませんのでご了承ください※

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

Re: 新ゲームプログラムの館1.4章のとこ

#7

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

amehirune さんが書きました: 例えば、下記のサンプルでは「img00.jpg」「img01.jpg」「img02.jpg」…というように、
 imgの後に2桁の番号が続く画像ファイルたちを読み込んでいます。
読み込んでいません。
sprintfの書式に対してデータが足りないので、未定義動作です。
また、%2dでは例えば1を渡すと01のような0埋めではなく 1のようなスペース埋めになります。

正しくは

コード:

for(int i=0;i<7;i++){
        sprintf(buf,"img%02d.jpg", i);
        graph[i] = LoadGraph(buf);
}
ですね。
オフトピック
amehirune さんが書きました:#初心者にわかるように話しているので、厳密にいえば違う部分もあります
変に本物のプログラムに似た擬似コードを使うと混乱させ、わかりにくいのでは…?
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
usao
記事: 1887
登録日時: 11年前

Re: 新ゲームプログラムの館1.4章のとこ

#8

投稿記事 by usao » 7年前

「配列」について調べるとよいでしょう.
オフトピック
>初級,中級,上級

という言葉を使うのは語弊があるのではないでしょうか.
それぞれ異なるデータ構造であり,適材適所で使うべきものと思うのですが.

LEMO
記事: 23
登録日時: 7年前
住所: 関東地方ですね

Re: 新ゲームプログラムの館1.4章のとこ

#9

投稿記事 by LEMO » 7年前

みなさんいろいろありがとうございます
では、初心者の僕が変にいろいろやるのではなく
おとなしく
int graphhandle[10];などで用意したほうが速いのですね....
ありがとうございました!

アバター
usao
記事: 1887
登録日時: 11年前

Re: 新ゲームプログラムの館1.4章のとこ

#10

投稿記事 by usao » 7年前

初心者だから…,とか,おとなしく…,とかいう変な話ではなく,
あなたの質問文を普通に読めば
「状況に最も適した手段」の第一候補は配列であると思います.

閉鎖

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