ページ 11

描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 18:35
by sin
はじめましてsinと言います。

field.cppでマップを描写し、その後、cursor.cppでカーソルを作成し、先ほど描写したマップにカーソルを表示したいのですがmain.cppをデバッグすると、真っ暗な画面にカーソルのみが表示されます。

どのあたりを改善すればいいのでしょうか。

Microsoft Visual C++で作成しています。

Re:描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 18:36
by sin
---main.cpp--------------------------------------------------------------------------
#define _GLOBAL_INSTANCE_
#include "DxLib.h"
#include "GV.h"

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
char Key[256];
int Sound ;
if( SetOutApplicationLogValidFlag(FALSE) || ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() || SetWindowSizeExtendRate(1.0)) return -1;//ウィンドウモード
SetDrawScreen( DX_SCREEN_BACK );
Sound = LoadSoundMem( "my turn.mp3" ); //mp3ファイルを読み込み、ハンドルをint型変数格納
PlaySoundMem( Sound , DX_PLAYTYPE_BACK );//バックグラウンド再生
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
map_graph();
cursor();
ScreenFlip();
}

DxLib_End();
return 0;
}
---field.cpp----------------------------------------------------------------------------------
#include "DxLib.h"
#include "GV.h"

void map_graph(){//マップの描画
int i,j;
int sea[16],sougen[16];
int hantei[15][20] = {
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,1,1,1,1,0,1,1,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1 },
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
};

LoadDivGraph( "char.sea.png" , 16 , 4 , 4 , 32 , 32 , sea ) ;//画像を分割してsea配列に保存
LoadDivGraph( "char.sougen.png" , 16 , 4 , 4 , 32 , 32 , sougen ) ;//画像を分割してsougen配列に保存
/*mapを描画*/
for(i=0;i<15;i++){
for(j=0;j<20;j++){
if(hantei[j]==1){
DrawGraph( j*32 , i*32 , sea[0] , TRUE ) ;//sea[0]の画像を描画
}
if(hantei[j]==0){
DrawGraph( j*32 , i*32 , sougen[0] ,TRUE ) ;//sougen[0]
}
}
}
return;
}

Re:描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 18:37
by sin
---cursor.cpp-------------------------------------------------------------------------------
#include "DxLib.h"
#include "GV.h"

typedef struct{
int x,y,muki,moving_flag;
}cursor_t;

int hantei[15][20] = {
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
{ 1,0,0,0,0,1,1,1,1,1,1,1,1,1,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,1,1,1,1,0,1,1,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,1,1,0,0,1,0,0,0,0,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1 },
{ 1,0,0,0,1,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1 },
{ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 },
};

int can_or_cannot(int x,int y,int muki){//進めるかを判定する

    if(muki==0)//上向きなら
if(hantei[y/32-1][x/32]==1)//進めるか判定
return 1;//エラー
if(muki==1)//左向きなら
if(hantei[y/32][x/32-1]==1)
return 1;
if(muki==2)//下向きなら
if(hantei[y/32+1][x/32]==1)
return 1;
if(muki==3)//右向きなら
if(hantei[y/32][x/32+1]==1)
return 1;
return 0;//正常
}
void cursor(){
char Key[256];
cursor_t cursor;

cursor.x =320;
cursor.y =160;
cursor.moving_flag=0;
cursor.muki=3;

SetDrawScreen( DX_SCREEN_BACK ) ;
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
if(cursor.x%32==0 && cursor.y%32==0){ //座標が32で割り切れたら入力可能
cursor.moving_flag=1; //歩くフラグを立てる。
if ( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
cursor.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
cursor.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
cursor.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
cursor.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
cursor.moving_flag=0; //歩かないフラグを立てる
if(cursor.moving_flag==1) //もし歩くなら
if(can_or_cannot(cursor.x,cursor.y,cursor.muki)==1)//行き先が歩けないなら
cursor.moving_flag=0; //歩かないフラグを立てる。
}
if(cursor.moving_flag==1){ //歩くフラグが立っていたら
if (cursor.muki==0) //上向きならch.y座標を減らす
cursor.y--;
else if(cursor.muki==1) //左向きならch.x座標を減らす
cursor.x--;
else if(cursor.muki==2) //下向きならch.y座標を増やす
cursor.y++;
else if(cursor.muki==3) //右向きならch.x座標を増やす
cursor.x++;
}
LoadGraphScreen( cursor.x , cursor.y , "char.cursor.png" , TRUE ) ;
ScreenFlip();
}
return ;
}

Re:描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 18:50
by 迷彩吹雪
void map_graph()関数に描画の処理が含まれていないように見受けられます。
また、WinMain()関数だけでなくvoid cursor()関数にもメインループがあるので、そこで処理が回り続けているのではないでしょうか。

Re:描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 19:50
by sin
cursor.cpp内の
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){

while(!ProcessMessage() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
に変更したところmap_graph()で描写した背景にカーソルを合わせることが出来ましたが、カーソルの残像が残るようになりました。

残像を消すにはcursor.cpp内を

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
に戻して
cursor.cpp内にmap_graph()を入れたほうがいいのでしょうか。

それともmain.cpp内で処理をするようにした方がいいのでしょうか。(cursor.cppではカーソルの位置だけを調べてカーソルの位置を返すようにする。)

Re:描写したものに別の画像を合わせる

Posted: 2010年8月29日(日) 20:49
by 迷彩吹雪
そもそもvoid cursor()関数内のwhile文は不要でしょう。
cursor.cppでカーソルの描画まで行っても問題ありません。問題は、そこで無限ループが回っていることなのです。

そうですね、void cursor()関数の処理を以下のものに置き換えてみてはどうでしょうか。
(動く保証はありませんが……。)
//ループが回る度に初期化されてしまうので、グローバルに置きました
    char Key[256]; 
    cursor_t cursor; 
  
    cursor.x    =320; 
    cursor.y    =160; 
    cursor.moving_flag=0; 
    cursor.muki=3; 

void cursor(){ 

    GetHitKeyStateAll( Key );    //ここで入力状態を更新します
    
    //SetDrawScreen( DX_SCREEN_BACK ) ; //WinMain()で既に呼んでいるので不要です
    //ここにあったwhile文を消しました
            if(cursor.x%32==0 && cursor.y%32==0){         //座標が32で割り切れたら入力可能 
            cursor.moving_flag=1;         //歩くフラグを立てる。 
            if     ( Key[ KEY_INPUT_UP   ]  == 1 )  //上ボタンが押されたら 
                    cursor.muki=0;         //上向きフラグを立てる 
            else if( Key[ KEY_INPUT_LEFT ]  == 1 )  //左ボタンが押されたら 
                    cursor.muki=1;         //左向きフラグを立てる 
            else if( Key[ KEY_INPUT_DOWN ]  == 1 )  //下ボタンが押されたら 
                    cursor.muki=2;         //下向きフラグを立てる 
            else if( Key[ KEY_INPUT_RIGHT]  == 1 )  //右ボタンが押されたら 
                    cursor.muki=3;         //右向きフラグを立てる 
            else                                    //何のボタンも押されてなかったら 
                    cursor.moving_flag=0; //歩かないフラグを立てる 
            if(cursor.moving_flag==1)    //もし歩くなら 
                if(can_or_cannot(cursor.x,cursor.y,cursor.muki)==1)//行き先が歩けないなら 
                    cursor.moving_flag=0;                  //歩かないフラグを立てる。 
        } 
         if(cursor.moving_flag==1){        //歩くフラグが立っていたら 
            if     (cursor.muki==0)        //上向きならch.y座標を減らす 
                    cursor.y--; 
            else if(cursor.muki==1)        //左向きならch.x座標を減らす 
                    cursor.x--; 
            else if(cursor.muki==2)        //下向きならch.y座標を増やす 
                    cursor.y++; 
            else if(cursor.muki==3)        //右向きならch.x座標を増やす 
                    cursor.x++; 
    LoadGraphScreen( cursor.x , cursor.y , "char.cursor.png" , TRUE ) ;     //本来はLoadGraph()などで一度だけ画像を読むべきです
}

Re:描写したものに別の画像を合わせる

Posted: 2010年8月30日(月) 10:39
by sin
迷彩吹雪さんありがとうございます。
グローバル変数に移す理由は分かったのですが、どのように移せばいいのかわかりません。(グローバル変数の書き方)
そのまま書いてもエラーがでてしまいます。
void cursor(){
//----------------------------------------------------------------------------
char Key[256]; // ↑
cursor_t cursor;
                     //この部分をグローバル変数に移す
cursor.x=320;
cursor.y=160;
cursor.moving_flag=0;           // ↓
cursor.muki=3;
//----------------------------------------------------------------------------

GetHitKeyStateAll( Key );

if(cursor.x%32==0 && cursor.y%32==0){ //座標が32で割り切れたら入力可能
cursor.moving_flag=1; //歩くフラグを立てる。
if ( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
cursor.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
cursor.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
cursor.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
cursor.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
cursor.moving_flag=0; //歩かないフラグを立てる
if(cursor.moving_flag==1) //もし歩くなら
if(can_or_cannot(cursor.x,cursor.y,cursor.muki)==1)//行き先が歩けないなら
cursor.moving_flag=0; //歩かないフラグを立てる。
}
if(cursor.moving_flag==1){ //歩くフラグが立っていたら
if (cursor.muki==0) //上向きならch.y座標を減らす
cursor.y--;
else if(cursor.muki==1) //左向きならch.x座標を減らす
cursor.x--;
else if(cursor.muki==2) //下向きならch.y座標を増やす
cursor.y++;
else if(cursor.muki==3) //右向きならch.x座標を増やす
cursor.x++;
}
LoadGraphScreen( cursor.x , cursor.y , "char.cursor.png" , TRUE ) ;
}

Re:描写したものに別の画像を合わせる

Posted: 2010年8月30日(月) 11:59
by 迷彩吹雪
>どのように移せばいいのかわかりません。(グローバル変数の書き方)
関数の外(ファイルの先頭など)で宣言すればグローバル変数になると思いますが……。

>そのまま書いてもエラーがでてしまいます。
私が示した通りに書き変えてもエラーになる、と言うことでしょうか。
「この部分をグローバル変数に移す」と示してある部分をvoid cursor()関数の定義以前に移動して、それでエラーが出たのでしょうか。

エラーの内容を詳しく教えてもらえますか?
(コンパイルエラーなのか、警告文が出たなら何と出たのか)

Re:描写したものに別の画像を合わせる

Posted: 2010年8月30日(月) 12:29
by sin
すいません。わかりにくかったですね。
//------------------------------------------------------------------------------------
char Key[256];
cursor_t cursor;

cursor.x=320;
cursor.y=160;
cursor.moving_flag=0;
cursor.muki=3;

void cursor(){
GetHitKeyStateAll( Key );

if(cursor.x%32==0 && cursor.y%32==0){ //座標が32で割り切れたら入力可能
cursor.moving_flag=1; //歩くフラグを立てる。
if ( Key[ KEY_INPUT_UP ] == 1 ) //上ボタンが押されたら
cursor.muki=0; //上向きフラグを立てる
else if( Key[ KEY_INPUT_LEFT ] == 1 ) //左ボタンが押されたら
cursor.muki=1; //左向きフラグを立てる
else if( Key[ KEY_INPUT_DOWN ] == 1 ) //下ボタンが押されたら
cursor.muki=2; //下向きフラグを立てる
else if( Key[ KEY_INPUT_RIGHT] == 1 ) //右ボタンが押されたら
cursor.muki=3; //右向きフラグを立てる
else //何のボタンも押されてなかったら
cursor.moving_flag=0; //歩かないフラグを立てる
if(cursor.moving_flag==1) //もし歩くなら
if(can_or_cannot(cursor.x,cursor.y,cursor.muki)==1)//行き先が歩けないなら
cursor.moving_flag=0; //歩かないフラグを立てる。
}
後は同じです。
//-------------------------------------------------------
↑のように変更しました。

構文エラー : ';' が '.' の前にありません。
型指定子がありません - int と仮定しました。メモ: C++ は int を既定値としてサポートしていません
'cursor' : 再定義されています。異なる基本型です。
'cursor' の宣言を確認してください。

といったエラーが表示されます。

Re:描写したものに別の画像を合わせる

Posted: 2010年8月30日(月) 12:53
by shuto
関数外で値を入れているのが原因ではないでしょうか?
初期化と代入は別のものです。
そのやり方なら初期化を行う関数を作り 最初に呼ぶといいと思います。

むしろ、キャラの座標をグローバルにするのはどうなんだろうを思いますが・・・

-----------
グローバル変数を関数で初期化するって表現がなんかおかしいですねw
とりあえず
cursor.x=320;
cursor.y=160;
cursor.moving_flag=0;
cursor.muki=3;
の書く場所を考えるといいです。 画像

Re:描写したものに別の画像を合わせる

Posted: 2010年8月30日(月) 18:47
by 迷彩吹雪
あ、確かに代入してますね。
「とりあえず動くようにしよう」と思って深く考えずにグローバルに移動させてました。
cursorを宣言する時に初期化してしまえば良いのかな。
トピックの主題ではないし間違えた責任もあるので……

cursor_t cursor = {320, 160, 3, 0};

これで、どうでしょう。
(構造体はほとんど扱ったことがないので自信はないですww)

Re:描写したものに別の画像を合わせる

Posted: 2010年8月31日(火) 08:15
by sin
main.cppで構造体の初期化をし、cursor.cppで構造体を呼び出すようにしたのですがカーソルが動きません。(一瞬動くがすぐに元の位置に戻る。)
理由としてmain.cppでcursor()を呼び出して値を変更しているが、ループ(main内)で上書きされていることが原因だと思うのですが、どうすればいいですか?
---main.cpp---------------------------------------------------------------
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
char Key[256];
int Sound ;
int i;
i=0;
if( SetOutApplicationLogValidFlag(FALSE) || ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() || SetWindowSizeExtendRate(1.0)) return -1;//ウィンドウモード
SetDrawScreen( DX_SCREEN_BACK );
struct cursor_t curs= {320, 160, 3, 0};
Sound = LoadSoundMem( "my turn.mp3" ); //mp3ファイルを読み込み、ハンドルをint型変数へ格納
PlaySoundMem( Sound , DX_PLAYTYPE_BACK );//バックグラウンド再生
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
map_graph();
char_graph();
cursor(curs);
ScreenFlip();
}

DxLib_End();
return 0;
}
---cursor.cpp------------------------------------------------------------------------------------
void cursor(struct cursor_t curs){
char Key[256];
GetHitKeyStateAll( Key );

後は同じです
--------------------------------------------------------------------------------------------------

Re:描写したものに別の画像を合わせる

Posted: 2010年8月31日(火) 08:50
by shuto
ループ内に上書きをしているところはないように見えますが・・・どこでそう思ったのでしょう?
上書きしているわけではなく、cursの内容を変更できていませんね。


値渡しと参照渡しの違い、実引数、仮引数は理解できていますか?
わからなければ調べてみてから読んでください。

その void corsor の書き方ですと実引数の struct cursor_t 型の cursをコピーして
関数 void cursor(struct cursor_t curs) の仮引数 curs にコピーされます。
コピーされた curs に対して cursor関数で座標が計算されますので移動はできます。
しかし、コピーに対しての計算なのでmainのなかの curs には影響しません。

これを改善するために参照渡しを使います。
実引数を(&curs)としてアドレスを渡し
cursor関数では仮引数を(struct cursor_t* curs)としてアドレスを受け取ります。
構造体へのポインタからののメンバへのアクセスは . ではなく -> を使います。
つまり curs.moving_flag は curs->moving_flag になります。
こうすればcursor関数の中で curs 自体を変更できます。

Re:描写したものに別の画像を合わせる

Posted: 2010年8月31日(火) 10:57
by naohiro19
typedef stuct cursor_tag {
    int x,y;         //位置
    int moving_flag; //移動可能かどうか
    int direction;   //向き
}cursor;
typedef を使うといいですよ。

Re:描写したものに別の画像を合わせる

Posted: 2010年8月31日(火) 15:28
by sin
shutoさんの助言を参考に参照渡しに変更したところカーソルが動くようになりました。
皆さんありがとうございました。