ページ 1 / 1
qsortの使い方
Posted: 2011年4月23日(土) 14:22
by ららら
とある場所で提示されていた問題なのですがその場では質問できそうでなかったので
こちらの掲示板で質問をさせていただきます
確か問題はLoadGraphScreen関数の入れ替えだったかな?
その関数をy座標を基準にqsortで入れ替えるといものでした
コード:
typedef struct{
int x;//x座標の値
int y;//y座標の値
char *name;//画像の名前
}TEST;
TEST base[2];
for( i=0; i<10; i++ ){
LoadGraphScreen( base[i].x , base[i]y ,*base[i].name , TRUE ) ;
}
といったのがヒントとして提示されていたのですがqsortの比較関数がつくれません
誰か詳しい方、教えていただけませんか? お願いします
Re: qsortの使い方
Posted: 2011年4月23日(土) 14:29
by へろりくしょん
だから、y を比較すればいいだけだと思いますが。
とりあえず、比較関数の中身は
int hikaku(const void *a, const void *b)
{
return ((TEST*)a)->y - ((TEST*)b)->y;
}
とでもすればいいかと。
Re: qsortの使い方
Posted: 2011年4月23日(土) 14:33
by みけCAT
とある場所ってどこですか?
y座標を基準にと言っても昇順ですか?降順ですか?その他ですか?
とりあえずy座標の昇順にソートするための関数です。
コード:
int comp(const void* x,const void* y) {
TEST* xx=(TEST*)x;
TEST* yy=(TEST*)y;
if((xx->y)>(yy->y))return 1;
if((xx->y)<(yy->y))return -1;
return 0;
}
へろりん さんが書きました:だから、y を比較すればいいだけだと思いますが。
とりあえず、比較関数の中身は
int hikaku(const void *a, const void *b)
{
return ((TEST*)a)->y - ((TEST*)b)->y;
}
とでもすればいいかと。
これではいけません。
aのy座標とbのy座標の差が極端な場合、オーバーフローします。
Re: qsortの使い方
Posted: 2011年4月23日(土) 16:28
by ららら
すいません qsort以前に比較の仕方が分かりませんでした
描画したい画像の数だけ構造体をつくるのでしょうか?
コード:
typedef struct{
int x;//x座標の値
int y;//y座標の値
char *name;//画像の名前
}TEST;
TEST base[2];
for( i=0; i<2; i++ ){
LoadGraphScreen( base[i].x , base[i]y ,*base[i].name , TRUE ) ;
}
typedef struct{
int a;//a座標の値
int b;//b座標の値
char *namae;//画像の名前
}TEST2;
TEST2 base[2];
for( i=0; i<2; i++ ){
LoadGraphScreen( base[i].a , base[i]b ,*base[i].namae , TRUE ) ;
}
すいません、、、 上のコードは正直、適当に書きました
二つのLoadGraphScreen関数をソートする為のコードを教えていただけませんか?
他のサイトを見ても分かりませんでした 形だけでもいいのでお願いします
Re: qsortの使い方
Posted: 2011年4月23日(土) 19:44
by box
ららら さんが書きました:二つのLoadGraphScreen関数をソートする為のコードを教えていただけませんか?
関数をソートする、というのがどういう行為を指しているのか、全くわかりません。
質問者さんの頭の中では、きちんとイメージできているんでしょうか?
Re: qsortの使い方
Posted: 2011年4月23日(土) 23:23
by しひ
コード:
typedef struct{
int anko;
}Taiyaki;
これは構造体の「定義」です。たい焼きで例えると、たい焼きの型です。
これは構造体の「宣言」です。たい焼きで例えると、たい焼きそのものです。
コード:
typedef struct{
int anko;
}Taiyaki;
Taiyaki taro;
Taiyaki jiro;
たい焼きを増やすためにわざわざ型を増やす必要はありません。たい焼きだけ増やして下さい。
便宜上、LoadGraphScreen()関数は焼く()関数と名付けます。
コード:
焼く( taro );
焼く( jiro );
たい焼きを2つ焼きたいときは、このように焼く関数を並べます。
焼く順番は上からになります。ソースコードにこのように書いた以上、順番を変えることはできません。
つまり、関数を入れ替えることはできません。実際にはできないこともないのですが、とりあえず今のあなたには無理です。
本題です。
焼く順番を変えたくとも関数は並び替えられません。では、どうするか。
たい焼きの方を並び替えれば焼く順番を変えることができます。
たい焼きを入れる配列を用意しました。これには2尾のたい焼きが入ります。
コード:
int i;
for( i = 0; i < 2; i++ )
{
焼く( hako[i] );
}
繰り返し文と配列を使うことで、焼く関数1つでたい焼きを2尾焼くことができます。
この例の場合、箱0番に入っているたい焼き→箱1番に入っているたい焼き、の順番で焼きます。
箱0番に入っていたたい焼きと箱1番に入っていたたい焼きを入れ替えると、焼く順番も入れ替わります。
このたい焼きの入れ替えを行うのがqsort()関数です。
正直、とある場所にあったコードととある場所に書かれていたコメントが全てだと思います。
それらの意味が分かるようになるまで、ゲーム製作なんて窓から投げ捨ててC言語の勉強をすることをお勧めします。
Re: qsortの使い方
Posted: 2011年4月23日(土) 23:57
by box
しひ さんが書きました:コード:
typedef struct{
int anko;
}Taiyaki;
これは構造体の「定義」です。たい焼きで例えると、たい焼きの型です。
ひじょうにわかりやすい例えをされていると思います。
が、
しひ さんが書きました:
これは構造体の「宣言」です。たい焼きで例えると、たい焼きそのものです。
ここは、構造体の宣言ではなくって、先に定義してあった構造体(たい焼きの型)を使った変数(たい焼き)の定義であります。
Re: qsortの使い方
Posted: 2011年4月24日(日) 00:55
by しひ
少し長い文書いただけですぐぼろが出る!
申し訳ないです。
Re: qsortの使い方
Posted: 2011年4月24日(日) 13:25
by ららら
qsortの勉強からやります
最後にひとつだけ質問させてください
あのようにqsortでやる方法と下のように
コード:
if(y<b)
LoadGraphScreen(x,y,aaa.png,TORE)
LoadGraphScreen(a,b,iii.png,TORE)
if(b>y)
LoadGraphScreen(a,b,iii.png,TPRE)
LoadGraphScreen(x,y,iii.png,TORE)
if文を使うのとどちらが高速なのでしょうか?
数学関数を使うと処理が遅くなると聞いたもんで・・・
Re: qsortの使い方
Posted: 2011年4月24日(日) 20:12
by しひ
そのたった6行のソースコードが既に危ういので、一度qsort関数の存在を忘れて基礎を固めて下さい。
速度の前に気にすべきことは山のようにあります。
それと、qsort関数は数学関数ではありません。
Re: qsortの使い方
Posted: 2011年4月24日(日) 20:38
by ららら
あ、あのですね・・・
じゃあ数学の勉強とif文の勉強からやります
Re: qsortの使い方
Posted: 2011年4月24日(日) 20:46
by ららら
う、今、気付いたのですが描画するものの数だけ構造体をつくるということが間違っていましたね
構造体は一つだけでいいはずです
Re: qsortの使い方
Posted: 2011年4月24日(日) 21:27
by bitter_fox
ららら さんが書きました:qsortの勉強からやります
最後にひとつだけ質問させてください
あのようにqsortでやる方法と下のように
コード:
if(y<b)
LoadGraphScreen(x,y,aaa.png,TORE)
LoadGraphScreen(a,b,iii.png,TORE)
if(b>y)
LoadGraphScreen(a,b,iii.png,TPRE)
LoadGraphScreen(x,y,iii.png,TORE)
if文を使うのとどちらが高速なのでしょうか?
数学関数を使うと処理が遅くなると聞いたもんで・・・
その程度の個数の判定であればわざわざqsortを引っ張り出すまでもないです。
ですが、キャラクターなどが100体(もしくは不定数体)居てそれぞれについてY座標の小さいものから描画しようとした場合はどうでしょう?
この場合は、qsortで構造体変数ごとY座標で並び替えて、それから順番に描画する方がスマートです。
(泥臭くするなら『最低Y座標を求めてその最低Y座標と同じキャラクタを描画、次に最低Y座標より大きいY座標の中で最低の物を見つけて、それを新しい最低Y座標として繰り返す』という方法で出来ますがこれだと二重ループになったりで非常に面倒くさいです。)
[hr]
蛇足ながら、そのコードの問題点を指摘しますと、
1.if構文に恐らく分岐・実行が望まれる文が二つあるのに{}がない
2.文の末尾に;がない
3.TPRE及びTOREはTRUEの誤りではないでしょうか
4.bとyが同じ値の時が考慮されていない
[hr]
ららら さんが書きました:
じゃあ数学の勉強とif文の勉強からやります
数学の勉強は関係ないというか本末転倒ではないでしょうか?
Re: qsortの使い方
Posted: 2011年4月25日(月) 16:42
by ららら
foxさん、わざわざ書き込んでくださってありがとうございました
できるようになるまで繰り返してやってみます
Re: qsortの使い方
Posted: 2011年4月25日(月) 16:54
by lib
あのねぇ、y座標を基準に並び替えたいんだよねぇ?
だったらy座標以外配列をつくらなくてもいいんじゃない?
それと描画したい絵の数だけ構造体をつくらなくてもいいよね?
なんで画像表示のところがポインタなの?
いくつもおかしいところあるんじゃないの?
Re: qsortの使い方
Posted: 2011年4月26日(火) 16:21
by ららら
う、ごめんなさい
自分でも努力します・・・
あと画像表示に使うのは文字列なのでポインタを使うのではないでしょうか?
よく分かりませんが・・・
それと自分も間違っていたかもしれませんが構造体はひとつでいいのですよね?
qsortは同じ構造体じゃないとソートできないような気もしますし・・・
よく分かりませんが・・・
Re: qsortの使い方
Posted: 2011年4月26日(火) 17:00
by softya(ソフト屋)
>>libさん
副管理人をさせていただいているsoftya(ソフト屋)です。
言葉遣いは丁寧にお願できますでしょうか。
ここのスローガンとして「アットホームで温かい」を目指しております。
http://dixq.net/board/board.html
>>らららさん
LoadGraphScreen()はファイルを読み込んで表示する命令ですので凄く遅くゲーム中に使うのは実は向いていません。
普通はLoadGraph()とDrawGraph()でロードと描画のタイミングを分けて使います。
なので、実際に表示にはDrawGraph()を使いますのでファイル名ではなくLoadGraph()の戻り値のグラフィックのハンドルを使います。
LoadGraph()は遅いので毎回表示ループが通らない別の場所で行うわけです。
それとqsort()以前に別のソート方法を学んだほうが良いかも知れません。
qsort()は、相当件数が多くないと高速に動作しないので別のソート方法のほうが有利な場合もあります。
まず、基本的なソートを学んでみましょう。サイトをご紹介します。
「アルゴリズムとデータ構造編 トップページ」
http://www.geocities.jp/ky_webid/algorithm/index.html
「アルゴリズム入門」
http://www5c.biglobe.ne.jp/~ecb/algorit ... thm00.html
>それと自分も間違っていたかもしれませんが構造体はひとつでいいのですよね?
この件は、らららさんが何件のキャラクタをy座標順に並べたいかによりますし、そもそもキャラクタを管理する構造体を利用する方法もあります。
あとポインタを理解いていればポインタリストだけでソートすることも出来ます。
なので、らららさんが理解しているレベルと想定しているプログラムの構造を出来るだけ明かしてもらえば適切なアドバイスが可能になります。
Re: qsortの使い方
Posted: 2011年4月26日(火) 17:58
by ららら
ソフト屋さん、ありがとうございます
(クイックソートのほかにもソート方があったのですね 一度、目を通してみます)
わたしのレベルはざっとCの入門を見ただけで自分の考えたプログラムをつくったことはありません
コード:
#include "DxLib.h"
int comp( const void *c1, const void *c2){
test test3 = *(test *)c1;
test test4 = *(test *)c2;
int tmp1 = test3.y;
int tmp2 = test4.y;
return tmp1 - tmp2;
}
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
typedef struct{
int y;
}test;
test test2[2] = {
{40},
{41}
};
LoadGraphScreen( 20 , test2[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
LoadGraphScreen( -20 , test2[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
qsort(base,2,sozeof(test),comp)
// 絵を打つ
WaitKey() ; // キー入力待ち
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
とあるサイトを参考にわたしなりに考えてみたのですがどこが原因でエラーがでるのか分かりません
よろしければ教えてください
Re: qsortの使い方
Posted: 2011年4月26日(火) 18:15
by ららら
すいません、
baseはtest2に置き換えてください
Re: qsortの使い方
Posted: 2011年4月26日(火) 18:21
by ららら
一部、修正しましたがまだ動きません・・・
コード:
#include "DxLib.h"
typedef struct{
int y;
}test;
int comp( const void *c1, const void *c2){
test test2 = *(test *)c1;
test test3 = *(test *)c2;
int tmp1 = test2.y;
int tmp2 = test3.y;
return tmp1 - tmp2;
}
// プログラムは WinMain から始まります
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow )
{
ChangeWindowMode( TRUE ) ;
if( DxLib_Init() == -1 ) // DXライブラリ初期化処理
{
return -1 ; // エラーが起きたら直ちに終了
}
typedef struct{
int y;
}test;
int x = 20;
test test1[2] = {
{40},
{41}
};
LoadGraphScreen( x , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
LoadGraphScreen( -20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
qsort(test1,2,sozeof(test),comp)
// 絵を打つ
WaitKey() ; // キー入力待ち
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
Re: qsortの使い方
Posted: 2011年4月26日(火) 18:46
by softya(ソフト屋)
少なくとも、そのプログラムはコンパイルが通りません。
エラーメッセージ読み方は慣れたらわかりますので、まずエラーを理解することから始めてください。
何行目にどんなエラーが出ていますか?
[追記]
ソースコードを見る限り、C言語の次の部分が理解出来ていない可能性があります。
・宣言・変数のスコープ
・ポインタ
・配列の添字の範囲
・一部の演算子
あとプログラムの流れそのものを理解出来ていないと思います。
折角ソートしてもその値を使っていませんし、キャラクタの並びをy座標順にソートをしたかったのでは?
Re: qsortの使い方
Posted: 2011年4月26日(火) 19:21
by ららら
ひとつ気付きましたがcomp関数は一番、下にもっていきました
エラーはひとつひとつ潰していきましたが
あと、ひとつというところで行き詰りました
「宣言の構文エラー」とはどういう意味でしょう?
それとqsortを使うとはどのようなことでしょうか?
comp関数の中身から間違っていますか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 19:30
by softya(ソフト屋)
>「宣言の構文エラー」とはどういう意味でしょう?
その書かれている通りの意味なのですが、ソースコードを見ないとなんとも言えません。
>それとqsortを使うとはどのようなことでしょうか?
>comp関数の中身から間違っていますか?
qsort前に表示しているのは意味有りませんし、プログラム的に移動機能がない状況でキャラクタでソートする意味はまったくありません。
comp関数自体の中身はは冗長ですが合っています。
Re: qsortの使い方
Posted: 2011年4月26日(火) 19:59
by ららら
将来は動く画像をソートしたいのですが
今はまだ勉強中ということで静止画をソートしています
エラーは全て潰したのですが
コード:
#include "DxLib.h"
typedef struct{
int y;
}test;
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] = {
{40},
{41}
};
qsort(test1,2,sizeof(test),comp);
LoadGraphScreen( 20 , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
LoadGraphScreen( 20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
// 絵を打つ
WaitKey() ; // キー入力待ち
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
test test2 = *(test *)c1;
test test3 = *(test *)c2;
int tmp1 = test2.y;
int tmp2 = test3.y;
return tmp1 - tmp2;
}
なぜか画像がソートされません
どこかおかしいところはありますか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 20:41
by a5ua
こちらで、LoadGraphScreenとLoadGraphの違いを理解した上で読んでください。
http://dixq.net/g/01_03.html
http://dixq.net/g/01_04.html
ゲームを作るうえで、LoadGraphScreenという関数を使うことはほぼありません。
なので、私もLoadGraphを使って説明します。
まず、以下のプログラムは理解できますか?
このプログラムが理解できないと話を進められないので、理解できないところがあれば言ってください。
戦闘機が、座標(0, 0)に、インベーダーが座標(50, 50)に描画されるはずです。
そして、ららら さんがやりたいことは、“プログラム実行中”に表示される画像を入れ替えることです。
コード:
#include "DxLib.h"
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE) ;
if( DxLib_Init() == -1 ) {
return -1;
}
int handle[2];
handle[0] = LoadGraph("イラスト/戦闘機.bmp");
handle[1] = LoadGraph("イラスト/インベーダー.bmp");
for (int i = 0; i < 2; ++i) {
DrawGraph(50 * i, 50 * i, handle[i], TRUE);
}
WaitKey();
DxLib_End() ;
return 0;
}
Re: qsortの使い方
Posted: 2011年4月26日(火) 21:37
by ららら
アドバイスありがとうございます 大変、嬉しいです
LoadGraphScreen描画関数のことですがテスト用なので簡単な方を選択して使っていました
コードが理解できるかの件ですがそれぐらいであれば理解できます
それと初心者なので分かりませんがi<2ではなくi<1ではないでしょうか? 分かりませんが・・・
Re: qsortの使い方
Posted: 2011年4月26日(火) 21:45
by softya(ソフト屋)
配列の添字の理解があやしいと思います。
LoadGraphScreen( 20 , test1[1].y , "イラスト/戦闘機.bmp" , TRUE ) ;
LoadGraphScreen( 20 , test1[2].y , "イラスト/インベーダー.bmp" , TRUE ) ;
は明らかに間違っています。何処が問題か分かりますか?
ららら さんが書きました:れと初心者なので分かりませんがi<2ではなくi<1ではないでしょうか? 分かりませんが・・・
i<1だと問題があります。
これはforループの基本動作の理解の問題ですので良く考えてみてください。
[追記]
らららさんの書いたコードだと表示座標は小さいものから大きな順にならびますが、画像は描画順番を入れ替えることはありませんが理解されていますか?
それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
出来るだけ正確にお答えください。
Re: qsortの使い方
Posted: 2011年4月26日(火) 22:01
by ららら
すいません 色々おかしいこと言ってました for文のことも狂ったようなこと言っていました
それと配列は0から始まるんでしたっけ じっと見つめていたら思い出しました
ごめんなさい 描画順が入れ替わらないことは理解していませんでした
どこをどう変えればいいのでしょう?
構造体と関連付けをすることが鍵なのかなぁ~と思っていますがよく分かりません
Re: qsortの使い方
Posted: 2011年4月26日(火) 22:03
by softya(ソフト屋)
もうひとつの質問に答えていただいて良いですか?
[追記]
描画順番は先に書いたものから表示上は下になります。後で書いたものが上に重なると言うことですね。
なので、らららさんはy座標が大きいものから先に書きたいのか、小さいものから先に書きたいのか明確に出来ますでしょうか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 22:27
by ららら
私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね
Re: qsortの使い方
Posted: 2011年4月26日(火) 22:34
by softya(ソフト屋)
ららら さんが書きました:私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね
そうすると、yが大きい物を下に描画ですがよろしいですね?
それと、らららさんが書いた下記の配列は、どの様に並び直るか書いてもらって良いですか?
コード:
test test1[2] = {
{40},
{41}
};
test1[0].yはxx
test1[1].yはxx
とお書きください。
それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
出来るだけ正確にお答えください。
もうひとつの質問に答えていただいて良いですか?
こちらの回答もお願いします。
意味もなく聞いているのではなくて全て理由があって質問しています。
Re: qsortの使い方
Posted: 2011年4月26日(火) 22:51
by a5ua
次は、構造体を使った処理を考えましょう。
以下のプログラムでわからないところがあれば言ってください。
コード:
#include "DxLib.h"
// 位置と画像をまとめた構造体を定義
typedef struct
{
int x:
int y;
int image;
} TEST;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow)
{
ChangeWindowMode(TRUE) ;
if( DxLib_Init() == -1 ) {
return -1;
}
// 要素数2個の配列
TEST test[2];
/* 配列のそれぞれの要素に値を設定する */
test[0].x = 60;
test[0].y = 50;
test[0].image = LoadGraph("イラスト/戦闘機.bmp");
test[1].x = 50;
test[1].y = 60;
test[1].image = LoadGraph("イラスト/インベーダー.bmp");
/* 配列の要素を先頭から順に描画する */
for (int i = 0; i < 2; ++i) {
DrawGraph(test[i].x, test[i].y, test[i].image, TRUE);
}
WaitKey();
DxLib_End() ;
return 0;
}
このプログラムの場合、test[0].image→test[1].imageの順番で描画されます。
そういうプログラムを書いたのだから、その順番をプログラム実行中に変更することは出来ません。
ですから、プログラム実行中に描画順を並び替えるには、
test[0] の中身:{60, 50, 戦闘機.bmpへの画像ハンドル}
test[1] の中身:{50, 60, インベーダー.bmpへの画像ハンドル}
となっているところを、
test[0] の中身:{50, 60, インベーダー.bmpへの画像ハンドル}
test[1] の中身:{60, 50, 戦闘機.bmpへの画像ハンドル}
という具合に、testという配列の要素を並び替えなければいけません。
いいですか?プログラム上で描画命令の順番を入れ替えるのではなく、
プログラム実行中に描画する要素を入れ替えるのです。
これを行うために、ソートという処理が必要になります。
ここまでは、理解できましたか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:05
by ららら
>>それと、らららさんが書いた下記の配列は、どの様に並び直るか書いてもらって良いですか?
昇順ですから40→41と直ると思います
>>それとa5uaさんの書いたコードの handle[1] ってなんでしょうか?
イラスト/インベーダーが入っているint型の変数だと思います
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:07
by ららら
a5uaさんの言っていること理解できました
関数を入れ替えるという表現が間違っていました すいません
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:14
by softya(ソフト屋)
ららら さんが書きました:a5uaさんの言っていること理解できました
関数を入れ替えるという表現が間違っていました すいません
今までの私の話やa5uaさんの話が理解できたのでしたら、コードを書いてみてください。
分からないところがあったら聞いてください。
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:27
by ららら
一応、見よう見まねでやってみました
違っていましたら指摘してください
コード:
#include "DxLib.h"
typedef struct{
int x;
int y;
char *image;
}test;
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,40,"イラスト/戦闘機.bmp"},
{20,40,"イラスト/インベーダー.bmp"}
};
for (int i = 0; i < 2; i++) {
LoadGraphScreen( test1[i].x , test1[i].y , test1[i].image , TRUE ) ;
};
qsort(test1,2,sizeof(test),comp);
// 絵を打つ
WaitKey() ; // キー入力待ち
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}
int comp( const void *c1, const void *c2){
test test2 = *(test *)c1;
test test3 = *(test *)c2;
int tmp1 = test2.y;
int tmp2 = test3.y;
return tmp1 - tmp2;
}
ごめんなさい、メモリーに読み込むことは理解できていますが
今回はロードグラフスクリーンでやらせてもらいました
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:33
by ららら
うーん・・・
いまコンパイルしましたがソートしてくれませんね・・・
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:33
by softya(ソフト屋)
まず、問題点1。
y座標が同じなので意味が無いです。
問題点2。
softya(ソフト屋) さんが書きました: ららら さんが書きました:私はy座標が大きいものから描画したいです
並び替えは昇順でいいです・・・よね
そうすると、yが大きい物を下に描画ですがよろしいですね?
この内容とコードで矛盾しているのですが分かりますか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:39
by ららら
数学座標とC座標がごちゃになっていたので言っていることがおかしかったです 反省します
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:46
by softya(ソフト屋)
ららら さんが書きました:数学座標とC座標がごちゃになっていたので言っていることがおかしかったです 反省します
そうですね。
画面座標は上は小さく下は大きな値になります。(Cには座標系という定義はありません。これはDXライブラリが左上を(0,0)と定義しているからくる仕様です)
これは最初はよく間違えますので注意してください。特に画面が擬似3Dだったり本当の3Dだと凄まじく混乱します。
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:48
by ららら
この2つの問題点を解決すれば正常にソートできると思いますでしょうか?
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:51
by ららら
いえ、実はさっきから数をいじっているのですが
画像の表示順が変わらないのでどこか間違いがあるかなと思いまして・・・
Re: qsortの使い方
Posted: 2011年4月26日(火) 23:55
by a5ua
LoadGraphScreenを呼び出して時点で、画像は描画されているので、
そのあとに、qsortを呼び出しても意味がありません。
プログラムは書いた順に実行されますから、
ソートして描画しなければ、値を初期化した後
・ソート
・描画
の順でプログラムを書かなければいけません。
Re: qsortの使い方
Posted: 2011年4月27日(水) 00:00
by softya(ソフト屋)
a5ua さんが書きました:LoadGraphScreenを呼び出して時点で、画像は描画されているので、
そのあとに、qsortを呼び出しても意味がありません。
プログラムは書いた順に実行されますから、
ソートして描画しなければ、値を初期化した後
・ソート
・描画
の順でプログラムを書かなければいけません。
一度説明したので、理解したと思って見逃していました。
らららさん、もう一度良く考えてみてください。
Re: qsortの使い方
Posted: 2011年4月27日(水) 00:02
by ららら
あわわわわ
たった今、自分には無謀だろうなと思っていたソートができました
信じられない・・・ あとはwhile(1)でゲーム用に改造すればいいんですよね
これも一重に先輩方のおかげです 分かるまで何度も教授してくださったことに感謝します
私も先輩方のようになれるようにがんばります ありがとうございました
Re: qsortの使い方
Posted: 2011年4月27日(水) 00:04
by ららら
私の様な人がいるかもしれないのでソースを貼っておきます(綺麗ではないです)
なお降順になるよう修正をするのはまだしてません
コード:
#include "DxLib.h"
typedef struct{
int x;
int y;
char *image;
}test;
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"}
};
qsort(test1,2,sizeof(test),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){
test test2 = *(test *)c1;
test test3 = *(test *)c2;
int tmp1 = test2.y;
int tmp2 = test3.y;
return tmp1 - tmp2;
}
Re: qsortの使い方
Posted: 2011年4月27日(水) 00:22
by softya(ソフト屋)
いえ、これで合ってますよ。
yの小さいほうが画面の奥になるのではありませんか?
あと、一度書きましたが件数次第ではqsortを使わないほうが速いこともあります。