ページ 11

時間制限がつけられない?

Posted: 2010年11月20日(土) 19:26
by マグロ丼
短期間での投稿お許しください。
1ステージ20秒ほどの時間制限をつけようと思いGetNowCount関数を使ってみたのですが
ぜんぜん作動してくれませんでしたorz
とりあえず6秒たったらfunction_statesでcase2のクラスに飛びたいのに
うまくいきません。

あともう一つお伺いします。
先ほど弾丸がうてるようにはなったのですが、弾の速度が速すぎるのです。
多分ch.xを多用しているからとは思いますが、
どこのch.xをとっても今度は弾がキャラからでなくなってしまうのです。

どうかご指導ご鞭撻のほど、よろしくお願いします!

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 20:04
by 迷彩吹雪
>とりあえず6秒たったらfunction_statesでcase2のクラスに飛びたいのにうまくいきません。
どのように上手く行かないのか、詳細を教えてもらえますか?

>弾の速度が速すぎるのです。
if(tama.flag==1){ //発射している玉なら
    tama.x+=ch.x+100; //xをキャラ位置分増やす 
    DrawGraph( tama.x , tama.y , image2 , TRUE );//玉を描画
    if(tama.x < -32){ //もし画面外まで来たら
        tama.x=ch.x; //初期値に戻し、
        tama.flag=0; //発射フラグを戻す
    }
}

この部分の、「100」の実数値を減らすと弾速が遅くなると思います。
そしておそらく、ch.xは加算する必要ないと思います。

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 20:25
by マグロ丼
回答ありがとうございます!

>どのように上手く行かないのか、詳細を教えてもらえますか?
上手くいかないというか、作動してくれないんです。
6秒たってもmain関数内の処理のままなんです。

>そしておそらく、ch.xは加算する必要ないと思います。
確かにch.xを加算しないと弾速度は遅くなりました。
しかしキャラから弾の描画が外れてしまうのですorz

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 20:38
by ひよこ
Main関数を呼ぶとして
if((GetNowCount() - StartTime) > 6000){ //1ステージの制限時間は6秒
function_status=2;
}
はwhile外なので呼ばれません。

他にもプログラムの構造的にも良くないので、
ゲームプログラミングの館を読んだほうがいいと思います。

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 20:44
by 迷彩吹雪
if((GetNowCount() - StartTime) > 6000){    //1ステージの制限時間は6秒
    function_status=2; 
}
この部分をメインループの中に入れてやって下さい。

>しかしキャラから弾の描画が外れてしまうのですorz
私がゲームを普段しない人間なので、どのような動作を期待しているのかちょっとわからないですが、
とりあえず実数値を減らせば弾速は調整できませんか?
そして弾を発射する時のみ、tama.xにch.xを代入してはどうでしょう。
if(tama.flag==0){     //発射していない玉を探し、
    tama.flag=1;  //発射フラグを立てる
    tama.x = ch.x;//発射初期位置は自機の場所
    break;
}


改行を修正しました。
……あれ、修正できない? 画像

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 20:57
by マグロ丼
>>ひよこさん

読んではいますが、なにぶん初心者なので…というより初見なものばかりで中々難しいのです。
のっぴきならない事情があり、どんなコードでもいいのでとりあえずゲーム(のようなもの)を
製作しないといけないので(@A@;){時間制限もあるので厳しいですが、何卒ご指導くださいorz

>>迷彩吹雪さん

おおおおおお!!!!!!
これです! この動作が欲しかった!!
弾の発射初期位置がキチンとキャラクターについてくれる。
ありがとうございます!


あとは時間制限がなんとかなれば。
while文の中にいれてみたものの作動する気配なしですorz

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 21:36
by 迷彩吹雪
動作しませんでしたか……。
念のため、もう一度Main()関数の内容をアップしてもらえますか?
こちらの言葉が上手く伝わらなかったかも知れないので。

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 21:47
by マグロ丼
こちらです。
よろしくおねがいします(@A@;)ノ

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 21:55
by ひよこ
function_status=2;って書いてあっても
whileループ内にif(function_status==2)とかないから何も状況は変わりません。

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 22:02
by 迷彩吹雪
私が見たところでは、間違いないようですね。
function_statusはMain()関数外で使用する変数だと思いますが、他の場所で値を書き変えていないか確認してみて下さい。

例えば
if(function_status = 1){
    Main();
}
else if(function_status == 2){
    //何か別の処理
}
などとしていませんか?

[訂正]
私の勘違いでした。
ひよこさんの仰る通り、function_statusの値を利用(評価)する場所がループ内に存在しないが原因です。 画像

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 22:32
by ひよこ
マグロ丼さんへ 少し時間がたったのでソースを作りました。
解決できない場合見てください。
マグロ丼さんのイメージ通りに実行できると思います。

掲示板の同じ悩みの人のためにも置きます。
自分なりに書き直してます、ソースを少し解説をしました、これであっていると思います。

弾関係のソース内容

最初のwhileループ前はflagの初期化以外、特に意味はありません。
Enterキーで使っていない弾(flag==0)があったら
弾のflagを立てて(flag==1)弾のX座標にch.xを弾のY座標にch.y/2を入れています。
フラグが立っている弾を探してそれがあったら弾のX座標に100足し描画します。
弾が画面外ならフラグを下します。

whileループなどについて
whileループは1ループでメッセージ処理・キー取得などを行って
画像は1回ロードするだけで十分。(void Main()と書いてあるから)
#include "DxLib.h"
 
char Key[256] ;

//場面処理用
int function_status;

//キャラクターシート
int image[12];

//弾画像
int image_tama;

//背景画像
int image_stage;

//発射してからのカウントをする変数。
int counter=0;

//始まった時間
int StartTime;

struct shot{
    int x,y;
    int flag;
};

typedef struct{
        int x,y,img,muki,walking_flag,attack_flag;
}ch_t;

ch_t ch;//キャラクターの位置
struct shot tama[50];

void calc0(){
    int i;
    
    if((GetNowCount() - StartTime) > 6000){    //1ステージの制限時間は6秒
        function_status=2;
    }
    DrawGraph( 0 , 0 ,image_stage, TRUE) ;//背景を描写
    
    if(ch.x%30==0){         //座標が30で割り切れたら入力可能          
        ch.walking_flag=1;//歩くフラグを立てる。
        
        if( Key[ KEY_INPUT_RIGHT   ]  == 1 )  //→ボタンが押されたら                     
            ch.muki=1;         //右向きフラグを立てる
        else                                    
            //何のボタンも押されてなかったら
            ch.walking_flag=0; //歩かないフラグを立てる

        if( Key[ KEY_INPUT_SPACE   ]  == 1 )
            ch.attack_flag=1;//攻撃フラグをタテル。    
    }
    if(ch.walking_flag==1){        //歩くフラグが立っていたら    
        if(ch.muki==1)        //→向きならch.x座標を増やす        
            ch.x++;

        ch.img=image[(ch.x%30)/5+6];
    }
    if(ch.walking_flag==0){
        ch.img=image[(ch.x%30)/5+0];
    }

    if(ch.attack_flag==1){
        ch.img=image[(ch.x%30)/5+2];
        ch.attack_flag=0;
    }
    if(counter<5)                        //前にエンターを押してから5カウント未満なら              
        counter++;                       //カウントアップ 
    else if( Key[ KEY_INPUT_SPACE]  == 1 ){//5カウント以上たっていたら
        counter=0;//カウンターを戻す

        for(i=0;i<50;i++){
            if(tama.flag==0){     //発射していない玉を探し、        
                tama.x=ch.x;
                tama.y=ch.y/2;
                tama.flag=1;  //発射フラグを立てる
                break;
            }
        }                           
    }
    
    for(i=0;i<50;i++){
        if(tama.flag==1){ //発射している玉なら
            tama.x+=100; //xをキャラ位置分増やす 
            DrawGraph( tama.x , tama.y , image_tama , TRUE );//玉を描画

            if(tama.x < -32 || tama.x > 672){ //もし画面外まで来たら
                tama[i].flag=0; //発射フラグを戻す
            }
        }
    }

    DrawGraph( ch.x , ch.y , ch.img  , TRUE ) ;//画像を描画
    
    //Xキーが押されてたら
    if(Key[KEY_INPUT_X]==1)           
        function_status=2;
}

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
    ChangeWindowMode(TRUE);//ウィンドウモード
    if(DxLib_Init() == -1 || SetDrawScreen( DX_SCREEN_BACK )!=0) return -1;//初期化と裏画面化
 
    function_status=0;

    image_tama = LoadGraph("tama.png");
    LoadDivGraph( "chara_sheet.png" , 12 , 3 , 4 , 250 , 250 , image );//画像を分割してimage配列に保存
    image_stage = LoadGraph( "stage.png" ) ;//背景の読み込み

    ch.x   =0;
    ch.y   =240;
    ch.muki=3;
    ch.attack_flag;
    ch.walking_flag=0;
    
    int i;
    
    for(i=0;i<50;i++){                  //初期化処理
        tama[i].x=640/2; tama[i].y=480; //座標代入
        tama[i].flag=0;                 //飛んでいない事を示すフラグ=0
    }
    StartTime = GetNowCount();
    while(ProcessMessage()==0 && ClearDrawScreen()==0 && !GetHitKeyStateAll(Key) && Key[KEY_INPUT_ESCAPE]==0){
          //↑メッセージ処理          ↑画面をクリア           ↑入力状態を保存       ↑ESCが押されていない       
        switch(function_status){                        
            case 0:
                calc0();
                break;
            case 1:
                break;
            case 2:
                break;
            default:       
                DxLib_End() ;                                // DXライブラリ使用の終了処理                
                return 0;                
                break;        
        }

        ScreenFlip();
    }
 
    DxLib_End();
    return 0;
}

Re:時間制限がつけられない?

Posted: 2010年11月20日(土) 22:45
by マグロ丼
>>迷彩吹雪さん

ヒントを与えてくださりありがとうございました!
またよろしくお願いしますヽ(゜∀゜)ノ!

>>ひよこさん

……感動に打ち震えております。
ここまでわかりやすい、というよりまさか解答をパパっと書き上げてしまうとは……
感謝いたします。これでなんとか次の段階に進めそうです。
今日のこのコードを復習して明日以降に活かしていこうと思います!
本当にありがとうございました!