Cの標準ソート関数
Re: Cの標準ソート関数
-10,-15といった数字はどこから出てきたのですか?小心者 さんが書きました: iを基準にソートするとき20-10,30-15の数値でソートしたいのです
つまり結果は10と15になりその結果の数値でソートをしたいのです
Re: Cの標準ソート関数
すいません 誤記でした
20-10、40-35です
どこから出てきたということですがどれくらいの値を引くかはどうでもよいのです
今回の例で-10と-35をあげさせていただきました
20-10=10、40-35=5となり
計算結果の値の10と5を比べると5の方が小さいです
この値を元にiを昇順でソートすると20→40となります
そうゆうことがしたいのですができますか?
20-10、40-35です
どこから出てきたということですがどれくらいの値を引くかはどうでもよいのです
今回の例で-10と-35をあげさせていただきました
20-10=10、40-35=5となり
計算結果の値の10と5を比べると5の方が小さいです
この値を元にiを昇順でソートすると20→40となります
そうゆうことがしたいのですができますか?
Re: Cの標準ソート関数
どうでもいいと言っても、実際に引く数値は何か意味のある数値なんですよね?小心者 さんが書きました: どこから出てきたということですがどれくらいの値を引くかはどうでもよいのです
今回の例で-10と-35をあげさせていただきました
意味のない数字なら、最初から引いた後の数値を構造体に入れておけばいいのではないですか?
Re: Cの標準ソート関数
何度もすいません では、この技術を知って何をしたいかを書きますね
実は画像の描画順の並び替えをしたいのです
その際に画像の左下の座標を基準にソートしたいのですが
最初から引いた数値で構造体をつくってしまうと
その引いた数値の場所に画像が表示されますよね
そういうことはしたくないのです
ですのでソートするときだけ引いた数値を参照して表示する時は引いていない数値を使うということが
したいのです 少々、長くなってしまいましたができますか?
実は画像の描画順の並び替えをしたいのです
その際に画像の左下の座標を基準にソートしたいのですが
最初から引いた数値で構造体をつくってしまうと
その引いた数値の場所に画像が表示されますよね
そういうことはしたくないのです
ですのでソートするときだけ引いた数値を参照して表示する時は引いていない数値を使うということが
したいのです 少々、長くなってしまいましたができますか?
Re: Cの標準ソート関数
仰りたいことは分かりました。
比較関数を少しいじくれば実現できます。
今までiの数値で比較していたところを、単純に i - a での比較に置き換えればいいのです。
しかし疑問なんですが、
(i , a がそれぞれ x , y に対応すると仮定してですが)
変な描画順になると思われます。
比較関数を少しいじくれば実現できます。
今までiの数値で比較していたところを、単純に i - a での比較に置き換えればいいのです。
しかし疑問なんですが、
左下の座標を基準にと言っても、x座標とy座標の差でソートする意味はあるんでしょうか?小心者 さんが書きました: その際に画像の左下の座標を基準にソートしたいのですが
(i , a がそれぞれ x , y に対応すると仮定してですが)
変な描画順になると思われます。
Re: Cの標準ソート関数
元のデータと同じ形式を持つソート用の配列を用意し、
その配列に、あらかじめゲタをはかせた値を放り込んでからソートすればよいのでは?
その配列に、あらかじめゲタをはかせた値を放り込んでからソートすればよいのでは?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
単純にソートキーと実際の座標のメンバ変数を分ければ良い話だと思います。
[追記]
構造体に、元の画像の情報がないとソート後には配列の並びが変わるので元の情報との整合性が取れなくなります。
この構造体配列をソートして、[0]からindexで示す画像を表示処理すれば思う順番に描画されるはずです。
[追記]
構造体に、元の画像の情報がないとソート後には配列の並びが変わるので元の情報との整合性が取れなくなります。
この構造体配列をソートして、[0]からindexで示す画像を表示処理すれば思う順番に描画されるはずです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
申し訳ないのですがi-aではありませんh2so5 さんが書きました:左下の座標を基準にと言っても、x座標とy座標の差でソートする意味はあるんでしょうか?
(i , a がそれぞれ x , y に対応すると仮定してですが)
変な描画順になると思われます。
具体的に申しますとi-zとなっておりzに入る数字は画像の縦の長さになります
比較関数のいじり方も分からないのですがどのように実現できるのでしょうか?
馬鹿なので理解できませんbox さんが書きました:元のデータと同じ形式を持つソート用の配列を用意し、
その配列に、あらかじめゲタをはかせた値を放り込んでからソートすればよいのでは?
もう少し詳しくご教授願えませんか?
Re: Cの標準ソート関数
と同じ構造を持つTEST型の配列(仮に名前をaaaとでもします)を のように用意します。
次に、配列aaaの各要素に対して、配列sortの内容をもとに、
質問者さんの考えどおりに値をセットします。ここが、「ゲタをはかせる」って意味。
どういう値をセットするかは、こちらにはわかりません。質問者さんのプログラムしだい。
そして、配列aaaをソートします。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: Cの標準ソート関数
Cのqsort関数では、zの値が静的に決まらないのであれば非局所オブジェクトを使わざるを得ず、使用状況によってはリエントラント性の問題が生じるので手放しには推奨できません。小心者 さんが書きました:具体的に申しますとi-zとなっておりzに入る数字は画像の縦の長さになります
比較関数のいじり方も分からないのですがどのように実現できるのでしょうか?
非標準関数のqsort_sやqsort_rを使えるのであれば、それを使った方が楽に解決します。
実はCでなくC++であれば、関数オブジェクトを使えば簡単に問題が解決します。
最近は、たとえ部分的にでもC++0xに対応している処理系も普通に使えるようになってきたので、ラムダ式を使えば簡単に実装できたりもします。
Re: Cの標準ソート関数
提示されたものはこういうことでしょうか?
typedef struct{
int key;
int x;
int y;
char *image;
}test;
test test1[2] = {
{20,41,"あああ.bmp"},
{-20,40,"いいい.bmp"}
};
for (int i = 0; i < 2; i++) {
LoadGraphScreen( test1[i].x , test1[i].y , test1[i].image , TRUE ) ;
};
あってますでしょうか?初心者なもので
それとtest1の値の設定のところで
yから10を引いた数値でソートしようと思い
test test1[2] = {
{test1[1].y-10,20,41,"あああ.bmp"},
{-20,40,"いいい.bmp"}
};
このように書いたのですがエラーが出ます
どのように記述すればいいのでしょうか?
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
ちゃんと書くとしたら、表示座標はキャラが移動するので毎回かわりますよね。
だとしたら、ソートキーは毎回変わりますので毎回計算しないといけません。
キャラの移動
↓
ソートキー計算
↓
ソート
↓
表示
が毎フレーム必要です。
それとLoadGraphScreenはタイトル画面とかの表示用でゲーム中に使用するのは向きません。
ロード処理(LoadGraph)はまとめて初期化時とメインループの表示(DrawGraph)に分けて行います。
ゲームに関する基本的な組み方は、ここの管理人であるDixqさんが作っていらっしゃるコンテンツを一通り読まれることをお勧めします。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
[追記]
ちなみに、 は、自己参照で動的に変化するものが定数として書かれているのでNGです。
keyは、プログラム中に計算を書いてください。
だとしたら、ソートキーは毎回変わりますので毎回計算しないといけません。
キャラの移動
↓
ソートキー計算
↓
ソート
↓
表示
が毎フレーム必要です。
それとLoadGraphScreenはタイトル画面とかの表示用でゲーム中に使用するのは向きません。
ロード処理(LoadGraph)はまとめて初期化時とメインループの表示(DrawGraph)に分けて行います。
ゲームに関する基本的な組み方は、ここの管理人であるDixqさんが作っていらっしゃるコンテンツを一通り読まれることをお勧めします。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
[追記]
ちなみに、 は、自己参照で動的に変化するものが定数として書かれているのでNGです。
keyは、プログラム中に計算を書いてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
いわゆるバードビューで表示する画像の描画順を求めるためにソートしたいのかなと。勝手な想像ですけど。
もしそうなら画像の左上座標を基準にするのではなく、ベースライン上の座標を基準にしたほうが良いのでは。
描画するときに上にずらして描画するほうが余分な情報をたらい回ししなくて済むと思います。
キャラクタがジャンプしてたり空を飛んでいたりとか画像の縦サイズよりもさらに上にずらして描画しなくてはならないときでもベースラインは変わらないので。
もしそうなら画像の左上座標を基準にするのではなく、ベースライン上の座標を基準にしたほうが良いのでは。
描画するときに上にずらして描画するほうが余分な情報をたらい回ししなくて済むと思います。
キャラクタがジャンプしてたり空を飛んでいたりとか画像の縦サイズよりもさらに上にずらして描画しなくてはならないときでもベースラインは変わらないので。
Re: Cの標準ソート関数
>>ISleさん
はいその通りバードビューです ベースラインってのがよく分からないんですが
あらかじめ表示座標に縦の長さを足しておいてそこに表示しろってことですよね
なるほどそのような手法もありましたか・・・ どちらがいいのか考えて見ます
>>ソフト屋さん
構造体の中に式を書いちゃ駄目なんですね
メモリー読み込みのこともありがとうございました
それと、もうひとつ気になったんですがこの表示方法で表示フラグを導入するにはどうすればいいですかね
普通の表示方法なら
if(flag=1)DrawGraphScreen(画像A)
if(flag=2)DrawGraphScreen(画像B)
こんな風に記述できますがこのやり方だと効率のいい表示フラグ参照が思い浮かびません
教えてください すいません
はいその通りバードビューです ベースラインってのがよく分からないんですが
あらかじめ表示座標に縦の長さを足しておいてそこに表示しろってことですよね
なるほどそのような手法もありましたか・・・ どちらがいいのか考えて見ます
>>ソフト屋さん
構造体の中に式を書いちゃ駄目なんですね
メモリー読み込みのこともありがとうございました
それと、もうひとつ気になったんですがこの表示方法で表示フラグを導入するにはどうすればいいですかね
普通の表示方法なら
if(flag=1)DrawGraphScreen(画像A)
if(flag=2)DrawGraphScreen(画像B)
こんな風に記述できますがこのやり方だと効率のいい表示フラグ参照が思い浮かびません
教えてください すいません
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
どういう意味の表示フラグでしょうか?小心者 さんが書きました:それと、もうひとつ気になったんですがこの表示方法で表示フラグを導入するにはどうすればいいですかね
普通の表示方法なら
if(flag=1)DrawGraphScreen(画像A)
if(flag=2)DrawGraphScreen(画像B)
こんな風に記述できますがこのやり方だと効率のいい表示フラグ参照が思い浮かびません
教えてください すいません
キャラクタの存在・非存在ならそもそもソート配列に登録しなければ良いことです。
アニメーションパターンなら、パターン番号を構造体に持てばよいだけです。
[訂正]それとも私が勘違いしてますか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
ベースラインというのは地面との接点を含む水平線のことです。小心者 さんが書きました:はいその通りバードビューです ベースラインってのがよく分からないんですが
あらかじめ表示座標に縦の長さを足しておいてそこに表示しろってことですよね
空中に浮いているときは垂線を垂らして地面と交わる点を接点とします。
描画順を決めるのに表示座標と画像サイズだけでは上手くいかないパターンがありますし、ベースライン基準で管理したほうがあらかじめ何かしておくとか必要なくなってプログラムの構造がシンプルになると思います。
- 添付ファイル
-
- baseline.png (1.7 KiB) 閲覧数: 13465 回
Re: Cの標準ソート関数
>>ISLeさん
あーそれがベースラインって言うんですか!
自分は横座標をx、奥行きをy、そして高さをhにしてy+h=縦座標の表示位置にしております
(↑多分このことですよね・・・) ありがとうございます
わざわざ画像まで用意していただき、勉強になります
>>ソフト屋さん
いえいえ、勘違いなどされておりませんよ その通りです
配列に入れなければいいのかな~というのは浮かんだのですが比較関数と構造体をいくつも作るのは
面倒くさいな~と思ったもので・・・ いい考えはありませんかね(生意気言って申し訳ないです)
もう一つ質問なのですが画像の反転描写など様々な描画関数を使いたくなった場合、どうしましょう
あーそれがベースラインって言うんですか!
自分は横座標をx、奥行きをy、そして高さをhにしてy+h=縦座標の表示位置にしております
(↑多分このことですよね・・・) ありがとうございます
わざわざ画像まで用意していただき、勉強になります
>>ソフト屋さん
いえいえ、勘違いなどされておりませんよ その通りです
配列に入れなければいいのかな~というのは浮かんだのですが比較関数と構造体をいくつも作るのは
面倒くさいな~と思ったもので・・・ いい考えはありませんかね(生意気言って申し訳ないです)
もう一つ質問なのですが画像の反転描写など様々な描画関数を使いたくなった場合、どうしましょう
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
反転なら反転フラグで済む話ですね。小心者 さんが書きました:いえいえ、勘違いなどされておりませんよ その通りです
配列に入れなければいいのかな~というのは浮かんだのですが比較関数と構造体をいくつも作るのは
面倒くさいな~と思ったもので・・・ いい考えはありませんかね(生意気言って申し訳ないです)
もう一つ質問なのですが画像の反転描写など様々な描画関数を使いたくなった場合、どうしましょう
同時に起こるエフェクトの種類や組み合わせで必要なフラグ変数の数も変わると思います。
あとキャラクタの管理構造体とソート構造体は分けた方が後々良いでしょう。
最初の頃に書いたように、ソート構造体にはキャラクタの管理構造体の添字番号かポインタを持てば最低限のサイズの構造体に出来ます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
っていうか、そもそもこういうif文を書いている時点で「なんかまずいんじゃないかなぁ」小心者 さんが書きました: if(flag=1)DrawGraphScreen(画像A)
if(flag=2)DrawGraphScreen(画像B)
なんて思ったりしてます。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: Cの標準ソート関数
単文だからまずいということでしょうか?それともセミコロンがないとかエラー的なことでしょうか?box さんが書きました:っていうか、そもそもこういうif文を書いている時点で「なんかまずいんじゃないかなぁ」
なんて思ったりしてます。
まぁ、その辺は自分も短縮した形で書きましたし多分、心配無用・・・だと思います
フラグ変数が書けません(フラグ変数は分かりますが、どこに記述すればいいか・・・)softya(ソフト屋) さんが書きました:反転なら反転フラグで済む話ですね。
同時に起こるエフェクトの種類や組み合わせで必要なフラグ変数の数も変わると思います。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
こちらの意味は理解されていますか?小心者 さんが書きました:フラグ変数が書けません(フラグ変数は分かりますが、どこに記述すればいいか・・・)
とりあえず、小心者さんが考えている形の簡単な足元順のソートのサンプルコードを今の知識に範囲で書いてもらってよいでしょうか?softya(ソフト屋) さんが書きました:あとキャラクタの管理構造体とソート構造体は分けた方が後々良いでしょう。
最初の頃に書いたように、ソート構造体にはキャラクタの管理構造体の添字番号かポインタを持てば最低限のサイズの構造体に出来ます。
それをもとに改善点を書いたほうが分りやすいと思いますのでお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
おっと、そうきましたか。小心者 さんが書きました: 単文だからまずいということでしょうか?それともセミコロンがないとかエラー的なことでしょうか?
カッコの中に書いてある
flag=1
という式は、
flag
に
1
を代入して、その結果(1)を評価します。つまり、
if(flag=1)
っていうif文は、ぶっちゃけ
if(1)
って書いたのと同じです。
flag
と
1
とを比較「していません」。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。
プログラムは思ったとおりには動かない。書いたとおりに動く。
Re: Cの標準ソート関数
>>boxさん
あーーーやっちましました ごめんなさい 文法どころの話じゃなかったです、、、、ちゃっかりちゃっかり
if(flag==1)←こうですね
あーーーやっちましました ごめんなさい 文法どころの話じゃなかったです、、、、ちゃっかりちゃっかり
if(flag==1)←こうですね
Re: Cの標準ソート関数
#include "DxLib.h"
typedef struct{
int x;
int y;
char *image;
}test;
typedef struct{
int key;
int index;
}sort;
int comp( const void *c1, const void *c2);
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
test test1[2] = {
{20,41,"あああ.bmp"},
{-20,40,"いいい.bmp"}
};
sort sort1[2] = {
{test1[1].y-20,1},
{test1[2].y-20,2}
};
qsort(sort1,2,sizeof(sort),comp);
for (int i = 0; i < 2; i++) {
LoadGraphScreen( test1[i].x , test1[i].y , test1[i].image , TRUE ) ;
};
// 絵を打つ
WaitKey() ; // キー入力待ち
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
sort sort2 = *(sort *)c1;
sort sort3 = *(sort *)c2;
int tmp1 = sort2.key;
int tmp2 = sort3.key;
return tmp1 - tmp2;
}
これじゃあ、ソートされた値が使われてませんよね・・・ どうしましょう・・・
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
私の書いたことがほとんど反映されていませんので、実例で示します。
「C言語~ゲームプログラミングの館~」
http://dixq.net/g/14.html
をベースにしました。
まず、配列の添字の使い方が全面的に間違っています。2要素の配列の添字は0と1です1と2ではありませんでの注意してください。
それと次の指摘点も反映させています。ISLeさんの言うベースラインには対応させていません。
aka.pngとsiro.pngはこちらにあった32x32の画像です。
「C言語~ゲームプログラミングの館~」
http://dixq.net/g/14.html
をベースにしました。
まず、配列の添字の使い方が全面的に間違っています。2要素の配列の添字は0と1です1と2ではありませんでの注意してください。
それと次の指摘点も反映させています。ISLeさんの言うベースラインには対応させていません。
softya(ソフト屋) さんが書きました:ちゃんと書くとしたら、表示座標はキャラが移動するので毎回かわりますよね。
だとしたら、ソートキーは毎回変わりますので毎回計算しないといけません。
キャラの移動
↓
ソートキー計算
↓
ソート
↓
表示
が毎フレーム必要です。
それとLoadGraphScreenはタイトル画面とかの表示用でゲーム中に使用するのは向きません。
ロード処理(LoadGraph)はまとめて初期化時とメインループの表示(DrawGraph)に分けて行います。
ゲームに関する基本的な組み方は、ここの管理人であるDixqさんが作っていらっしゃるコンテンツを一通り読まれることをお勧めします。
「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」
http://dixq.net/g/
#include "DxLib.h"
typedef struct{
int x;
int y;
char* file;
int image;
}test;
typedef struct{
int key;
int index;
}sort;
int comp( const void *c1, const void *c2);
#define CHARS_MAX 2
char Key[256];
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
// 描画先を裏画面に設定
SetDrawScreen( DX_SCREEN_BACK );
test test1[CHARS_MAX] = {
{20,56,"aka.png"},
{21,40,"siro.png"}
};
// ロード
for( int i=0 ; i<CHARS_MAX ; i++ ) {
test1[i].image = LoadGraph(test1[i].file);
}
// ここからメインループ
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
sort sort1[CHARS_MAX];
if( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
test1[0].y-- ; //yの値を1減らす
if( Key[ KEY_INPUT_DOWN ] == 1 ) //下タンが押されたら
test1[0].y++ ; //yの値を1増やす
// ソートキーの作成
for( int i=0 ; i<CHARS_MAX ; i++ ) {
sort1[i].key = test1[i].y-20;
sort1[i].index = i;
}
// ソートを行う。
qsort(sort1,CHARS_MAX,sizeof(sort),comp);
// ソートされた順番に表示
for( int i=0 ; i<CHARS_MAX ; i++ ) {
int index = sort1[i].index;
DrawGraph( test1[index].x , test1[index].y , test1[index].image , TRUE ) ;
}
ScreenFlip();//裏画面を表画面に反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
sort sort2 = *(sort *)c1;
sort sort3 = *(sort *)c2;
int tmp1 = sort2.key;
int tmp2 = sort3.key;
return tmp1 - tmp2;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
ぴょうぴんぽぽさんと小心者さんは同一人物でしょうか?ぴょうぴんぽぽ さんが書きました:表示フラグはどこですか?
もし同じ方なら無用な混乱のもとなので名前の統一をお願いします。
フォーラムルールにも記載してありますので確認をお願いします。
同じか方だと仮定して答えると、小心者さんのコード自体が表示フラグ以前にゲームとしての仕組みが出来ていないので実装していません。
小心者さんが表示フラグやら、エフェクトフラグの仕様と言うかゲームプログラムの仕組みを理解した後でないと書くわけには行きませんので。
[補足]まず、ご自分で実装してみてください。
それと、「新・C言語 ~ゲームプログラミングの館~ [DXライブラリ]」 http://dixq.net/g/
は一通り読まれて理解されましたか?
この後に進むには基本・入門だけは読んで理解してる事を前提にしないと進めないと思います。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
あ、いえ自分も初心者でここのトピックを見ていて気になったもので・・・
「ぴょうぴんぽぽ」は小心者さんの名前を借りさせていただきました(ぱ行にした)
表示フラグのことで画像を持っていないので試すことが出来ないんですけど
多分、構造体の中にソート構造体にchar型のflag変数をつくって文字列を代入し
if(sort.flag)なんてことをすればできるのではないのでしょうか?
複数の関数を使いたい場合もfor文のなかで分岐をさせて関数を使い分けるのではないでしょうか?
あっている間違っている指摘ください 気になるので
それとキャラ構造体とソート構造体を分けているのはなぜですか?
ソート構造体のコピーなど、なんか手間があるように見えるので(初心者にはそう見える)
「ぴょうぴんぽぽ」は小心者さんの名前を借りさせていただきました(ぱ行にした)
表示フラグのことで画像を持っていないので試すことが出来ないんですけど
多分、構造体の中にソート構造体にchar型のflag変数をつくって文字列を代入し
if(sort.flag)なんてことをすればできるのではないのでしょうか?
複数の関数を使いたい場合もfor文のなかで分岐をさせて関数を使い分けるのではないでしょうか?
あっている間違っている指摘ください 気になるので
それとキャラ構造体とソート構造体を分けているのはなぜですか?
ソート構造体のコピーなど、なんか手間があるように見えるので(初心者にはそう見える)
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
ぴょうぴんぽぽさん、私にメールを頂けますか?お伝えしたいことがあります。
メールアドレスは、
です(すいません。アドレスを手で打ち込んでください)。
メールアドレスは、

by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
ぴょうぴんぽぽ さんが書きました:表示フラグのことで画像を持っていないので試すことが出来ないんですけど
多分、構造体の中にソート構造体にchar型のflag変数をつくって文字列を代入し
if(sort.flag)なんてことをすればできるのではないのでしょうか?
複数の関数を使いたい場合もfor文のなかで分岐をさせて関数を使い分けるのではないでしょうか?
文字列を持つのは効率的ではないです。「文字列を代入しif(sort.flag)なんてことを」はC言語の文法として問題があります。
int型で0がOFF、1がONで良いんじゃないでしょうか?
「for文のなかで分岐をってところが不明確」ですが、表示の中で行うならenumでパターン定義してswitchで分岐で良いんじゃないでしょうか?
ぴょうぴんぽぽ さんが書きました:それとキャラ構造体とソート構造体を分けているのはなぜですか?
ソート構造体のコピーなど、なんか手間があるように見えるので(初心者にはそう見える)
ソート対象の構造体が大きくなるとそれだけ遅くなるからです。
あとソート構造体とキャラクタ管理構造体で同じデータを持つのは無駄ですね。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
#include "DxLib.h"
typedef struct{
int x;
int y;
char* file;
int image;
}test;
typedef struct{
int key;
int index;
int flag;
}sort;
int comp( const void *c1, const void *c2);
char Key[256];
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
// 描画先を裏画面に設定
SetDrawScreen( DX_SCREEN_BACK );
test test1[2] = {
{20,56,"あああ.bmp"},
{21,40,"いいい.bmp"}
};
// ロード
for( int i=0 ; i<2 ; i++ ) {
test1[i].image = LoadGraph(test1[i].file);
}
// ここからメインループ
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
sort sort1[2];
if( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
test1[0].y-- ; //yの値を1減らす
if( Key[ KEY_INPUT_DOWN ] == 1 ) //下タンが押されたら
test1[0].y++ ; //yの値を1増やす
sort1[0].flag=1;
// ソートキーの作成
for( int i=0 ; i<2 ; i++ ) {
sort1[i].key = test1[i].y-20;
sort1[i].index = i;
}
// ソートを行う。
qsort(sort1,2,sizeof(sort),comp);
// ソートされた順番に表示
for( int i=0 ; i<2 ; i++ ) {
if(sort1[i].flag==1){
int index = sort1[i].index;
DrawGraph( test1[index].x , test1[index].y , test1[index].image , TRUE ) ;
}
}
ScreenFlip();//裏画面を表画面に反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
sort sort2 = *(sort *)c1;
sort sort3 = *(sort *)c2;
int tmp1 = sort2.key;
int tmp2 = sort3.key;
return tmp1 - tmp2;
}
いいい.bmpも表示されてしまいます なぜでしょうか?
(sort1[0].flagに1を代入していてsort[1].flagは0のままですのでいいいは表示されないと思うのですが)
for文の中で描画関数を使い分けなければ描画順を操作することが出来ないと思うのですが
この考えは間違っているのでしょうか? switch文のを一度、書いてみます
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
最初にsort1[1].flagが代入されていないので値が最初不定です。
sortの都合上、途中で値が1になるのでsort1[0].flag共々1になっていします。
かならず配列の中身を全部埋めてください。
代入するなら と明確に値を設定すれば直ります。
sortの都合上、途中で値が1になるのでsort1[0].flag共々1になっていします。
かならず配列の中身を全部埋めてください。
代入するなら と明確に値を設定すれば直ります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
ありがとうございます
最後に・・・
「enumでパターン定義して」と仰りましたがenumがよく分かりません
普通のswitch文じゃ駄目なんでしょうか?
aの値が設定されていなかったりしますが・・・
最後に・・・
「enumでパターン定義して」と仰りましたがenumがよく分かりません
普通のswitch文じゃ駄目なんでしょうか?
#include "DxLib.h"
typedef struct{
int x;
int y;
char* file;
int image;
}test;
typedef struct{
int key;
int index;
int flag;
int byouga;
}sort;
int comp( const void *c1, const void *c2);
char Key[256];
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
// 描画先を裏画面に設定
SetDrawScreen( DX_SCREEN_BACK );
test test1[3] = {
{20,56,"あああ.bmp"},
{21,40,"いいい.bmp"},
{22,52,"ううう.bmp"}
};
// ロード
for( int i=0 ; i<2 ; i++ ) {
test1[i].image = LoadGraph(test1[i].file);
}
LoadDivGraph(test[2].file, 10 , 4 , 3, 48 , 56 , test1[2].image);
// ここからメインループ
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
//↑メッセージ処理 ↑画面をクリア ↑キーボード入力状態取得 ↑ESCが押されていない
sort sort1[3] = {
{test[0]-20 , 0 , 1 , 1},
{test[1]-23 , 1 , 1 , 1},
{test[2]-32 , 2 , 1 , 2}
};
if( Key[ KEY_INPUT_UP ] == 1 )
sort1[2].byouga = 3
// ソートを行う。
qsort(sort1,3,sizeof(sort),comp);
// ソートされた順番に表示
for( int i=0 ; i<3 ; i++ ) {
if(sort1[i].flag==1){
int index = sort1[i].index;
switch(sort[i].byouga){
case 1;
DrawGraph( test1[index].x , test1[index].y , test1[index].image , TRUE ) ;
break;
case 2;
DrawGraph( test1[index].x , test1[index].y , test1[index].image[ a ] , TRUE ) ;
break;
case 3;
DrawTurnGraph( test1[index].x , test1[index].y , test1[index].image[ a ] , TRUE ) ;
break;
}
}
}
ScreenFlip();//裏画面を表画面に反映
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
sort sort2 = *(sort *)c1;
sort sort3 = *(sort *)c2;
int tmp1 = sort2.key;
int tmp2 = sort3.key;
return tmp1 - tmp2;
}
- softya(ソフト屋)
- 副管理人
- 記事: 11677
- 登録日時: 14年前
- 住所: 東海地方
- 連絡を取る:
Re: Cの標準ソート関数
enumで書くのがきれいな書き方ってだけです。
難しかったら、とりあえず使わなくてもOKです。
ところで、test1[index].image[ a ]が意味不明ですね。
あと、byougaはtest構造体にあった方が後々良い気もしますが、これ以上拡張しないなら無視して良いです。
難しかったら、とりあえず使わなくてもOKです。
ところで、test1[index].image[ a ]が意味不明ですね。
あと、byougaはtest構造体にあった方が後々良い気もしますが、これ以上拡張しないなら無視して良いです。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。
Re: Cの標準ソート関数
aは画像切り替えの為の変数のつもりだったのですが・・・
描画関数の使い方、間違っていましたかね ごめんなさい
とりあえず「構造体が大きすぎるとソートに時間がかかる」という
ソフト屋さんの助言に基づいてbyougaとflagはキャラ構造体に持っていくことにします
長い間、助けてくださりありがとうございました
他の皆さんも知恵を貸していただき感謝いたします
描画関数の使い方、間違っていましたかね ごめんなさい
とりあえず「構造体が大きすぎるとソートに時間がかかる」という
ソフト屋さんの助言に基づいてbyougaとflagはキャラ構造体に持っていくことにします
長い間、助けてくださりありがとうございました
他の皆さんも知恵を貸していただき感謝いたします