画像の変更

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

画像の変更

#1

投稿記事 by エメ » 15年前

前にタイトル画面で質問させていただいた者です。
今回は少し漠然とした質問になってしまいますが、
これからのゲーム製作の上での方針(?)を教えていただきたいです。
C言語とDXライブラリは初めて2週間程度でゲーム製作の経験は今回が初めてです.

#include "DxLib.h"

int counter=0;
int color_white;
int y = 0;
int count=0;
char Key[256];

#define DISPLAY_POS_X 500
#define DISPLAY_POS_Y(i) (200 + 50 * (i))
#define N 5 // 項目数
#define M -1

void message_box(){ //スクリーン設定
int flag;
flag=MessageBox(
NULL ,
TEXT("Yでフルスクリーン、Nでウィンドウモードです。") ,
TEXT("スクリーン設定") ,
MB_YESNO | MB_ICONQUESTION );
if(flag==IDNO)
ChangeWindowMode( TRUE );
}

int GetHitKeyStateAll_2(int KeyStateBuf[/url]){
char GetHitKeyStateAll_Key[256];
GetHitKeyStateAll( GetHitKeyStateAll_Key );
for(int i=0;i<256;i++){
if(GetHitKeyStateAll_Key==1) KeyStateBuf++;
else KeyStateBuf=0;
}
return 0;
}

void char_disp(int White,int y){
DrawString( DISPLAY_POS_X - 20 , DISPLAY_POS_Y(y) , "■" , White );
DrawString( DISPLAY_POS_X , DISPLAY_POS_Y(0) , "SHOOTING" , White );
DrawString( DISPLAY_POS_X , DISPLAY_POS_Y(1) , "MUSICROOM" , White );
DrawString( DISPLAY_POS_X , DISPLAY_POS_Y(2) , "OPTION" , White );
DrawString( DISPLAY_POS_X , DISPLAY_POS_Y(3) , "MANUAL" , White );
DrawString( DISPLAY_POS_X , DISPLAY_POS_Y(4) , "QUIT" , White );
}

void SetColor(){
color_white = GetColor(255,255,255); //白色ハンドルを取得
}

void Backmusic(){
int Sound ;
Sound = LoadSoundMem( "music/harutoman.wav" ); //wavファイルを読み込み、ハンドルをint型変数へ格納
PlaySoundMem( Sound , DX_PLAYTYPE_BACK );//バックグラウンド再生
}

int FontHandle;

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

SetDrawScreen( DX_SCREEN_BACK ) ; //裏画面を使用する。

message_box();

int RefreshTime=0;

SetMainWindowText( "時鏡 鉢帳録" ) ;// タイトルを変更

SetColor(); //色を取得

int Key[256];
int White ; //色とy座標の宣言

if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化

Backmusic(); //演奏

White = GetColor( 255 , 255 , 255 ) ; //色の取得

RefreshTime = GetNowCount(); //今の時間を取得

int image; //ハンドルを受け取るためのint型変数を宣言
image = LoadGraph( "gazo/taitoru2.png" ) ; //gazo/taitoru2.pngのハンドルを代入

int image2; //ハンドルを受け取るためのint型変数を宣言
image2 = LoadGraph( "gazo/rogo.png" ) ; //gazo/rogo.pngのハンドルを代入

int image3; //ハンドルを受け取るためのint型変数を宣言
image3 = LoadGraph( "gazo/option.png" ) ; //gazo/rogo.pngのハンドルを代入5

while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){
//↑メッセージ処理   ↑画面をクリア     ↑入力状態を保存       ↑ESCが押されていない

DrawGraph( 0 , 0 , image , FALSE ) ; //gazo/taitoru2.pngを表示
DrawGraph( 10 , 10 , image2 , TRUE ) ; //gazo/rogo.pngを表示
char_disp(White,y); // 文字を描画
;

if( Key[KEY_INPUT_DOWN]==1 ||( Key[KEY_INPUT_DOWN]%5==0 && Key[KEY_INPUT_DOWN]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y++;
if(y==N) // y座標がNなら(選択が一番下なら)
y=0; // 選択座標を一番上に
}

if( Key[KEY_INPUT_UP]==1 ||( Key[KEY_INPUT_UP]%5==0 && Key[KEY_INPUT_UP]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y--;
if(y==M) // y座標がMなら(選択が一番上なら)
y=4; // 選択座標を一番下に
}

if( Key[KEY_INPUT_Z ]==1 ||( Key[KEY_INPUT_Z ]%5==0 && Key[KEY_INPUT_Z ]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
if(y==4){ // y座標が4なら(選択が一番下なら)
DxLib_End(); // DXライブラリ使用の終了処理
return 0;} // ソフトの終了
}

(コメントに続きます) 画像

エメ

Re:画像の変更

#2

投稿記事 by エメ » 15年前

if( Key[KEY_INPUT_Z ]==1 ||( Key[KEY_INPUT_Z ]%5==0 && Key[KEY_INPUT_Z ]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
if(y==2){ // y座標が4なら(選択が一番下なら)
//optionを表示させるつもりです

}
}


if( Key[KEY_INPUT_X ]==1 ||( Key[KEY_INPUT_X ]%5==0 && Key[KEY_INPUT_X ]>30)){
// たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
y=4; // 選択座標を一番下に
}

ScreenFlip();//裏画面を表画面に反映


}
DxLib_End(); // DXライブラリ使用の終了処理
return 0; // ソフトの終了

}

まずOPTIONの中身を完成させたいと思っているんですがOPTIONのところでZキーを押すと別の背景画像が表示され、選択画面を表示させるようにしたいのですが…。
一旦曲を終了させたり画像を変更したりするのはどうすればいいのでしょうか。
//optionを表示させるつもりです のところに
DrawGraph( 0 , 0 , image3 , TRUE ) ; //gazo/option.pngを表示
このように書いてみることしか思いつかなくて…(失敗)
選択画面などの表示の参考(理想)にしているゲームは東方文花帖ダブルスポイラーです。

OS windows7 64bit
Visual Studio 2010

エメ

Re:画像の変更

#3

投稿記事 by エメ » 15年前

ご教授お願いしますorz

迷彩吹雪

Re:画像の変更

#4

投稿記事 by 迷彩吹雪 » 15年前

「もう自己解決しちゃたかなぁ」と思いながら方法を考えていましたw。遅れて申し訳ありません。
つまりはシーケンス遷移の問題ですよね。
全く同じではありませんが、私が普段使っている方法(設計?)を真似てやってみました。
(多分動くと思いますが、これがベストな方法とは限りませんのであしからず)

添付データが手を加えたコードです。
これはシーケンス別に処理を関数化し、その返り値で次の行き先を受け取るようになっています。
返り値は列挙型ですが、その内実はint型なのでswitch文の式に利用できます。
(このような使い方をenumハックと呼ぶそうです。)
MenuExec()関数の中身は最初にエメさんが記述されていたものをほぼそのまま移動しています。
但しその冒頭では「次の行き先」をMenu自身にし、シーケンス移動が発生しなければまた次のループで自分に戻ってくるようになっています。
Option画面へ移動する時には画像データを破棄し、新たにOption用の画像を読み込みます。
(そのために画像ハンドルや音楽ハンドルがグローバル変数になっていますが、ここはもっと工夫できると思います)
あるいは最初にOptionExec()へ処理が移った時に読み込んでも良いでしょう。

以上、参考になれば幸いです。

エメ

Re:画像の変更

#5

投稿記事 by エメ » 15年前

迷彩吹雪さんありがとうございます!
参考にしてやってみます!
ありがとうございました。
(あと添付の内容が文字化け?みたいになってしまっています…。) 画像

迷彩吹雪

Re:画像の変更

#6

投稿記事 by 迷彩吹雪 » 15年前

あれ、文字化けしちゃいました?
それでは以下に示しておきます。念のためもう一度言っておきますが、必ずしもこれがベストではありません。

//-------------------------シーケンス遷移サンプル-----------------------------//

#include "DxLib.h"

//処理を行うシーケンスを示す列挙型
//別に列挙型でなくint型を使っても構わない
enum Sequence{
    Menu,
    Option,
    Game
    //その他必要なものを追加する
};

//それぞれのシーケンスで行う処理を実行する関数の宣言
//戻り値はSequence型
Sequence MenuExec();
Sequence OptionExec();
Sequence GameExec();

//グローバル変数の宣言と初期化
int counter = 0;
int color_white;    //どこかで使っているのか?
int y = 0;
int count = 0;
int FontHandle;
int image  = 0;        //ハンドルを受け取るためのint型変数を宣言
int image2 = 0;        //ハンドルを受け取るためのint型変数を宣言
int image3 = 0;        //ハンドルを受け取るためのint型変数を宣言
int Sound;            //音楽データへのハンドル
int White;            //色とy座標の宣言
char Key[256];

#define DISPLAY_POS_X    500
#define DISPLAY_POS_Y(i) (200 + 50 * (i))
#define N 5 // 項目数
#define M -1
  
void message_box(){    //スクリーン設定 
    int flag; 
    flag=MessageBox(
        NULL,
        TEXT("Yでフルスクリーン、Nでウィンドウモードです。"),
        TEXT("スクリーン設定"),
        MB_YESNO | MB_ICONQUESTION );
    if(flag == IDNO)
    ChangeWindowMode( TRUE );
} 

int GetHitKeyStateAll_2(int KeyStateBuf[/url]){
    char GetHitKeyStateAll_Key[256];
    GetHitKeyStateAll( GetHitKeyStateAll_Key );
    for(int i=0;i<256;i++){
        if(GetHitKeyStateAll_Key==1) KeyStateBuf++; 
        else                            KeyStateBuf=0; 
    } 
    return 0;
} 

void char_disp(int White,int y){    
DrawString( DISPLAY_POS_X - 20 , DISPLAY_POS_Y(y)  , "■"       , White );
DrawString( DISPLAY_POS_X      , DISPLAY_POS_Y(0)  , "SHOOTING" , White );
DrawString( DISPLAY_POS_X      , DISPLAY_POS_Y(1)  , "MUSICROOM" , White );
DrawString( DISPLAY_POS_X      , DISPLAY_POS_Y(2)  , "OPTION" , White );
DrawString( DISPLAY_POS_X      , DISPLAY_POS_Y(3)  , "MANUAL" , White );
DrawString( DISPLAY_POS_X      , DISPLAY_POS_Y(4)  , "QUIT"     , White );
}

void SetColor(){
    color_white = GetColor(255,255,255);       //白色ハンドルを取得 
} 

void Backmusic(){
    Sound = LoadSoundMem( "music/harutoman.wav" );      //wavファイルを読み込み、ハンドルをint型変数へ格納
    PlaySoundMem( Sound , DX_PLAYTYPE_BACK );//バックグラウンド再生
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){

    SetDrawScreen( DX_SCREEN_BACK ) ;                 //裏画面を使用する。 

    message_box();
    int RefreshTime = 0;

    SetMainWindowText( "時鏡 鉢帳録" );    // タイトルを変更

    SetColor();            //色を取得

    int Key[256];

    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化 

    Backmusic();    //演奏

    White = GetColor( 255 , 255 , 255 );    //色の取得

    RefreshTime = GetNowCount();            //今の時間を取得

    image  = LoadGraph( "gazo/taitoru2.png" );    //gazo/taitoru2.pngのハンドルを代入
    image2 = LoadGraph( "gazo/rogo.png" );        //gazo/rogo.pngのハンドルを代入
    image3 = LoadGraph( "gazo/option.png" );    //gazo/rogo.pngのハンドルを代入
    Sequence Seq = Menu;    //最初はメニューから始まる

    while(ProcessMessage()==0 && ClearDrawScreen()==0 && GetHitKeyStateAll_2(Key)==0 && Key[KEY_INPUT_ESCAPE]==0){ 
    //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない 

        //Seqの値によって実行する処理を切り替える
        switch(Seq){
            case Menu:
                Seq = MenuExec();    //メニュー画面の処理を実行し次の行き先を受け取る
                break;
            case Option:
                Seq = OptionExec();
                break;
            case Game:
                Seq = GameExec();
                break;
            default:
                //必要なら何らかのエラー処理
                break;
        }

        ScreenFlip();//裏画面を表画面に反映
    }

DxLib_End();  // DXライブラリ使用の終了処理
return 0;     // ソフトの終了

}


//文字数制限により次のコメントに続きます

迷彩吹雪

Re:画像の変更

#7

投稿記事 by 迷彩吹雪 » 15年前

//上コメントからの続き

//シーケンス別処理を実行する関数の定義
Sequence MenuExec(){

    Sequence S = Menu;        //特に変更がなければまたここへ戻ってくる

    DrawGraph( 0 , 0 , image  , FALSE );    //gazo/taitoru2.pngを表示 
    DrawGraph( 10 , 10 , image2  , TRUE );    //gazo/rogo.pngを表示 
    char_disp(White,y);                        // 文字を描画 

    if( Key[KEY_INPUT_DOWN]==1 ||( Key[KEY_INPUT_DOWN]%5==0 && Key[KEY_INPUT_DOWN]>30)){
    // たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
        y++;
            if(y==N)  // y座標がNなら(選択が一番下なら)
            y=0;      // 選択座標を一番上に
    }

    if( Key[KEY_INPUT_UP]==1 ||( Key[KEY_INPUT_UP]%5==0 && Key[KEY_INPUT_UP]>30)){  
    // たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
        y--;
            if(y==M)  // y座標がMなら(選択が一番上なら)  
            y=4;      // 選択座標を一番下に 
    }

    if( Key[KEY_INPUT_Z ]==1 ||( Key[KEY_INPUT_Z ]%5==0 && Key[KEY_INPUT_Z ]>30)){  
    // たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
        if(y==4){  // y座標が4なら(選択が一番下なら)  
            //DxLib_End();  // DXライブラリ使用の終了処理 
            //return 0;}     // ソフトの終了
            //returnでSequence型以外を返せなくなっているので、別の方法を取る必要がある
        }
    }

    if( Key[KEY_INPUT_Z ]==1 ||( Key[KEY_INPUT_Z ]%5==0 && Key[KEY_INPUT_Z ]>30)){
    // たった今押したか、30カウンター以上押しっぱなしかつ5回に一度
        if(y==2){  // y座標が4なら(選択が一番下なら)
            //-----Optionへ移動-----//
            //行き先変更のための準備として画像ハンドルが差すデータを差し替える
            DeleteGraph( image );    //まず削除
            DeleteGraph( image2 );
            DeleteGraph( image3 );
            image = LoadGraph( "オプション画面用の画像パス" );
            image2 = 0;    //使うかどうかわからないので0を代入
            image3 = 0;    //何もロードせずに使おうとするとプログラムが停止するだろう
            //音楽の再生を停止(ついでに再生中かどうかも確認)
            if( !CheckSoundMem( Sound ) ){
                StopSoundMem( Sound );
            }
            //他に必要な処理があれば追加
            S = Option;        //行き先をOptionに変更
        }
    } 

    if( Key[KEY_INPUT_X ]==1 ||( Key[KEY_INPUT_X ]%5==0 && Key[KEY_INPUT_X ]>30)){  // たった今押したか、30カウンター以上押しっぱなしかつ5回に一度  
        y=4;      // 選択座標を一番下に 
    }

    return S;    //次の行き先を返す

}

Sequence OptionExec(){
    Sequence S = Option;

    //何らかの処理

    if(/*Menuへ移動する*/){
        DeleteGraph( image );
        DeleteGraph( image2 );
        DeleteGraph( image3 );
        image   = LoadGraph( "gazo/taitoru2.png" );
        image2  = LoadGraph( "gazo/rogo.png" );
        image3  = LoadGraph( "gazo/option.png" );
        //BGMを再生
        PlaySoundMem( Sound , DX_PLAYTYPE_BACK );
        S = Menu;
    }

    return S;
}

閉鎖

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