ゲーム画面の遷移

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

ゲーム画面の遷移

#1

投稿記事 by kms » 15年前

質問させて頂きます。

画面の遷移処理を勉強しているのですが、色々とgoogleで検索したところ、
列挙型なるものを見つけ、フィールド画面から戦闘画面への遷移をこころみているのですが、
うまくいきません。。

ランダムエンカウント風に、乱数を取得して、Battle関数を呼び出したいのですが、
以下の処理を実行すると、キャラが止まってしまいます。

画像は、サンプルのものではなく、3×4のpngを使用しています。
なので、ch.mukiやimageは変更してあります。
元のソースコードは、22章の、「キャラを四方に歩かせる」です。

ソースコードが長い為、レスを分割します。ご容赦ください。。 画像

kms

Re:ゲーム画面の遷移

#2

投稿記事 by kms » 15年前

#include "DxLib.h"

enum GameState{
        GAME_Battle = 1,
};
GameState g_gamestate;

int Battle();

int Battle( void )
{
    ClearDrawScreen() ;
    if( DxLib_Init() == -1 )    // DXライブラリ初期化処理
    {
         return -1;                // エラーが起きたら直ちに終了
    }


    // ループ
    while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 )
    {

        printfDx( "戦闘画面\n" ) ;

    }


    DxLib_End() ;                // DXライブラリ使用の終了処理

    return 0 ;                    // ソフトの終了
}
画像

kms

Re:ゲーム画面の遷移

#3

投稿記事 by kms » 15年前

typedef struct{
        int x,y,img,muki,walking_flag;
}ch_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,1,1,1,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,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,1,0,0,0,0,0,1,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1 },
        { 1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1 },
};

int can_or_cannot(int x,int y,int muki){//進めるかを判定する
        if(muki==3)//上向きなら
                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==0)//下向きなら
                if(hantei[y/32+1][x/32]==1)
                        return 1;
        if(muki==2)//右向きなら
                if(hantei[y/32][x/32+1]==1)
                        return 1;
        return 0;//正常
}
 
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
        
    int image[12],i,j;
    char Key[256];
    ch_t ch;
 
    if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
 
    ch.x    =320;
    ch.y    =160;
    ch.walking_flag=0;
    ch.muki=0;
 
    SetDrawScreen( DX_SCREEN_BACK ) ;                                                 //描画先を裏画面に設定
    LoadDivGraph( "image_2.png" , 12 , 3 , 4 , 32 , 32 , image ) ;//画像を分割してimage配列に保存

kms

Re:ゲーム画面の遷移

#4

投稿記事 by kms » 15年前

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了
 
                /*白い壁を描画*/

                for(i=0;i<15;i++)
                        for(j=0;j<20;j++)
                                if(hantei[j]==1)
                                        DrawBox(j*32,i*32,(j+1)*32,(i+1)*32,GetColor(255,255,255),TRUE);
 
                if(ch.x%32==0 && ch.y%32==0){         //座標が32で割り切れたら入力可能
            ch.walking_flag=1;         //歩くフラグを立てる。
            if     ( Key[ KEY_INPUT_UP   ]  == 1 )  //上ボタンが押されたら
                    ch.muki=3;         //上向きフラグを立てる
            else if( Key[ KEY_INPUT_LEFT ]  == 1 )  //左ボタンが押されたら
                    ch.muki=1;         //左向きフラグを立てる
            else if( Key[ KEY_INPUT_DOWN ]  == 1 )  //下ボタンが押されたら
                    ch.muki=0;         //下向きフラグを立てる
            else if( Key[ KEY_INPUT_RIGHT]  == 1 )  //右ボタンが押されたら
                    ch.muki=2;         //右向きフラグを立てる
            else                                    //何のボタンも押されてなかったら
                    ch.walking_flag=0; //歩かないフラグを立てる
            if(ch.walking_flag==1)    //もし歩くなら
                if(can_or_cannot(ch.x,ch.y,ch.muki)==1)//行き先が歩けないなら
                    ch.walking_flag=0;                  //歩かないフラグを立てる。
            if(ch.walking_flag==1) //歩くフラグ
                if(GetRand(4)==0){ //乱数の取得
                    static int g_gamestate = GetRand(4);
                    switch( g_gamestate == GetRand(4)){ //switch文
                        case GAME_Battle: 
                                Battle(); //戦闘用画面関数を呼び出す。
                                break;
                        default :
                                printfDx("テスト\n");
                                break;

                    }
                    
            }

        }
 
        
        if(ch.walking_flag==1){        //歩くフラグが立っていたら
            if     (ch.muki==3)        //上向きならch.y座標を減らす
                    ch.y--;
            else if(ch.muki==1)        //左向きならch.x座標を減らす
                    ch.x--;
            else if(ch.muki==0)        //下向きならch.y座標を増やす
                    ch.y++;
            else if(ch.muki==2)        //右向きならch.x座標を増やす
                    ch.x++;
        }
 
        
        ch.img=image[(ch.x%32+ch.y%32)/11 + ch.muki*3];     //画像をセット

        DrawGraph( ch.x , ch.y , ch.img , TRUE ) ;//画像を描画
 
        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}


上記のコードはすべて、同一のcppファイルに記述してあります。
レスを使いすぎて、申し訳ないです。。
不適切でしたら削除致します。

画面の遷移について、ご意見を聞かせて頂けたら幸いです。

softya

Re:ゲーム画面の遷移

#5

投稿記事 by softya » 15年前

長いですね~。
これなら拡張子をtxtにして添付するか、zip圧縮での添付をお願いしても良いですか。

ざっと見たところ、乱数で状態遷移が毎回変わるのは状態遷移とは言えないとおもうんですよね。

softya

Re:ゲーム画面の遷移

#6

投稿記事 by softya » 15年前

それともう一つ、メインループを2つ作るのはお行儀の良いプログラムとは言えません。

kms

Re:ゲーム画面の遷移

#7

投稿記事 by kms » 15年前

>長いですね~。
これなら拡張子をtxtにして添付するか、zip圧縮での添付をお願いしても良いですか。

申し訳ありません。txtにして添付します。上記のソースコードのレスは、削除したほうが宜しいでしょうか?

>ざっと見たところ、乱数で状態遷移が毎回変わるのは状態遷移とは言えないとおもうんですよね。

すみません。。ちょっとまだ理解できていないみたいです。。

>それともう一つ、メインループを2つ作るのはお行儀の良いプログラムとは言えません。

申し訳ないです。。善処します。 画像

softya

Re:ゲーム画面の遷移

#8

投稿記事 by softya » 15年前

基本的な状態遷移の見本は、ゲームプログラミングの館の34章にありますが、ごらんになりました?
http://dixq.net/g/37.html

ソースを見るとRPGのエンカウントを作っていると考えて良いですか?

>>上記のソースコードのレスは、削除したほうが宜しいでしょうか?
そうですね。ややこしいので、その方が良いでしょう。

kms

Re:ゲーム画面の遷移

#9

投稿記事 by kms » 15年前

>基本的な状態遷移の見本は、ゲームプログラミングの館の34章にありますが、ごらんになりました?

はい。これは、つまりcppファイルを分割する、という意味なのでしょうか?
そうすると、ヘッダファイルもいじらないといけないのでしょうか?
それとも新規作成なのでしょうか?

>ソースを見るとRPGのエンカウントを作っていると考えて良いですか?

はい。ランダムエンカウントで、戦闘画面(実験的なものです)を表示させたいのですが。。

(記事の削除を実行したのですが、削除は管理者のみということなので、ご連絡しておきますね) 画像

softya

Re:ゲーム画面の遷移

#10

投稿記事 by softya » 15年前

>はい。これは、つまりcppファイルを分割する、という意味なのでしょうか?
本質はそこでは無いです。
34章は、1つのメインループで状態に応じて呼び出す関数を変えるところにあります。それが状態遷移に対応したプログラムの書き方なのですよ。34章の場合だとfunction_statusの値を書き換えることで状態を遷移していますね。

RPGなら次のような状態遷移が必要だと思います。

1.フィールドの初期化。初期化が終わったら状態2へ。
2.フィールドの処理。エンカウントしたら状態3へ。
3.バトルの初期化。初期化が終わったら状態4へ。
4.バトルの処理。戦闘が終了したら状態1へ。ゲームオーバーなら状態5へ。
5.ゲームオーバー処理。

バトルの処理自体も、内部でボトル専用の状態遷移が必要なりますね。
ドラクエ的なものとして考えると。
B1.コマンドの入力。コマンド入力が完了したら状態B2へ。
B2.戦闘処理。素早い者から順番に攻撃を行う。攻撃キャラが決まったら状態B3へ。
B3.攻撃処理。ダメージとか計算する。ステータスにも反映。表示するメッセージを決めて状態B4へ。
B4.メッセージを順番に1フレームごとに決まった単位で表示。全部は一度に表示しない。表示が終わったら状態B5へ。
B5.敵が生きているか、自分が生きていたら状態B1へ。敵が死んだら経験値の処理をして状態B6へ。自分が死んだら状態B7へ。
B6.メッセージを順番に1フレームごとに決まった単位で表示。全部は一度に表示しない。表示が終わったら状態1へ。
B7.ゲームオーバーに移行するので、状態5へ。

だいたいこんな感じですかね。
ヌケがあるかもしれませんが。

kms

Re:ゲーム画面の遷移

#11

投稿記事 by kms » 15年前

ありがとうございます。
関数を変えることにより、処理が可能なのですね。

ちなみに、以前ヘッダファイルを作成し、リビルドやビルドを実行していたときの話なのですが、

LINK : fatal error LNK1104: ファイル
'C:\Users\名前\Desktop\VS_4\kaihatsu\DxLib_VC\サンプルプログラム実行用フォルダ
\Debug\DxLib_VC2005用.exe' を開くことができません。

DxLib_VC2005用 : error PRJ0008 : ファイル
'c:\Users\名前Desktop\VS_4\kaihatsu\DxLib_VC\サンプルプログラム実行用フォルダ
\Debug\DxLib_VC2005用.exe' を削除できませんでした。
1>このファイルが他のプロセスによって使用されていないこと、
また書込み禁止になっていないことを確認してください。

上記のようなエラーメッセージが表示されたのですが、
(VC++2008 EE)
これはファイルにアクセス許可が無いのが原因なのでしょうか?
困った記憶があります。
これに関しては、別のスレッドを立てたほうが良いのでしょうか。。。

Dixq (管理人)

Re:ゲーム画面の遷移

#12

投稿記事 by Dixq (管理人) » 15年前

前に実行した実行ファイルが、実行しっぱなしになっているということはないでしょうか?

一見どこにもいないように見えてもプロセスをみると残っている場合があります。
タスクマネージャーのプロセスを開き、自分が作っている名前の実行ファイルが実行中ではないか確認してみてください。
PCを再起動してなお起こるならこれが原因ではないと思いますが。

softya

Re:ゲーム画面の遷移

#13

投稿記事 by softya » 15年前

>ありがとうございます。
>関数を変えることにより、処理が可能なのですね。

これも微妙に意味が違います。関数である必要はありません。
本質は、状態変数で処理の流れを変えてるって事ですね。
動作状態を状態変数で管理しつつ、条件を満たすことで状態変数を書き換えて状態を遷移させる事にあります。
状態遷移の参考サイト。
http://web.hc.keio.ac.jp/~fujimura/2002 ... c-n15.html

>これはファイルにアクセス許可が無いのが原因なのでしょうか?困った記憶があります。
こちらの件に付いては、Dixq (管理人)さんと同意見です。
プログラムが動いたままじゃないでしょうか?

kms

Re:ゲーム画面の遷移

#14

投稿記事 by kms » 15年前

>管理人様、softya様

お返事ありがとうございます。
再起動してもだめでしたね。。
おそらくソースコードに誤りがあるのだと思いますが、
他の可能性も考え、過去ログを検索したり、ヘルプを読み、
色々と試したのですがだめでした。
すみません。タスクマネージャーのプロセスとは何でしょうか?


>softya様

>1つのメインループで状態に応じて呼び出す関数を変えるところにあります

これを考慮し、添付したソースコードを実行してみたのですが、
エラーはないものの、画面に何も出力されず、マウスカーソルも消えてしまいました。。

戦闘画面処理はまだ作ってはおらず、実験的に文字を表示するだけのものですが。。

ゲームプログラミングの館の34章を参考にさせて頂いたのですが、
でもこれでは、ランダムエンカウントどころではないですね。。

34章と25章aを混同しちゃってます。。
焦ってます。

今は、「DxLib.h」、「test.cpp」ファイルのみを活用させて頂いています。
うえのレスのヘッダファイルの件は、以前に作成していたものです。 画像

softya

Re:ゲーム画面の遷移

#15

投稿記事 by softya » 15年前

とりあえず、Field()とBattle()の中にDxLib_Init()とかDxLib_End()があってはいけません。
while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
より内側の内容だけを書いて下さい。
基本的に、元の22章に合わせて下さいね。

kms

Re:ゲーム画面の遷移

#16

投稿記事 by kms » 15年前

お返事ありがとうございます。

とりあえず、ソースを簡略化して、
「フィールド画面」→「戦闘画面」への移行を目的として本来のサンプルプログラムにしました。

softya様の助言でキャラクターが動くようになりました。
本当にありがとうございます。

フィールドの処理を、「Field関数」から「WinMain関数」に戻したら動くようになりました。

そして、乱数の取得は一旦保留にし、
「フィールド画面(WinMain関数)」から、
Zキーを押すことで、「戦闘画面(Battle関数)」に移行するようにしました。

これでBattle関数は無事呼び出されるようになったのですが、
「画面が切り替わる(フィールド画面が消え、戦闘画面が現れる)」
という処理の記述方法はまだ模索中です。

残っている課題は、「ランダムエンカウント」と、「画面の切り替え」なんです。

「画面が切り替わる(フィールド画面が消え、戦闘画面が現れる)」
という処理の記述は、どういった形式を取るのでしょうか? 画像

softya

Re:ゲーム画面の遷移

#17

投稿記事 by softya » 15年前

とりあえず、フィールド・バトル切り替えを付けました。
Bでバトル、Fでフィールドに切り替わります。
なにか歩く処理の当たり判定が私の環境ではバグってるんですが、お任せします。

kms

Re:ゲーム画面の遷移

#18

投稿記事 by kms » 15年前

ソースコードを実行して純粋に驚きました。。

凄いです。切り替わっています。

自分が作っていたソースと見比べてみると、勉強になりますね。
case STATE_BATTLE:
            //    戦闘画面
            Battle();
            if(Key[KEY_INPUT_F]==1) { //Fキーが押されたら、
                function_status = STATE_FIELD;    //フィールドへ移行。
            }
            break;
等、細かい部分の違いで、なるほど!と唸りました。

でも何故、こう画面が(二つあるかのように)切り替わるのでしょうか。

色々といじったところ、clsDx()関数ではないようですし、
ただの僕のソースコードの打ち間違いだったのでしょうか?

>歩く処理の当たり判定が私の環境ではバグってるんですが

あ、これは自作の画像を用いている為なので、大丈夫です。

softya

Re:ゲーム画面の遷移

#19

投稿記事 by softya » 15年前

>ただの僕のソースコードの打ち間違いだったのでしょうか?

それはですね。
STATE_FIELDの時とSTATE_BATTLEでプログラムがどう流れているか違いをデバッガでステップ実行してみて下さい。それとkmsさんのプログラムの流れの違いを調べてみれば分かります。
こればかりは私が色々書くより、プログラムを追いかけてみた方が理解出来ると思います。

kms

Re:ゲーム画面の遷移

#20

投稿記事 by kms » 15年前

お返事遅れてしまい、すみません。。

わかりました。ありがとうございます。

ゲーム画面の遷移については、softya様の助力もあり、
一応の解決をみたので、あとは、プログラムの流れを把握し、
当初の目的のランダムエンカウントですね。

本当にありがとうございます。
模索してみます。

「ゲーム画面の遷移」ということで、
解決マークをチェックさせて頂きたいと思います。

閉鎖

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