キー入力状態に応じた分岐

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

キー入力状態に応じた分岐

#1

投稿記事 by land » 14年前

プログラミング初心者でVC++とDXライブラリを使用してプログラミングしているのですが、
キーの入力状態に応じて描画のブレンドモードを変える方法が分からないので質問させていただきます。

例えば、
キーボードのAキーが押されていたらアルファブレンドで描画する。
キーボードのSキーが押されていたら加算ブレンドで描画する。
といった風にしたいのですが、
※プログラムの一部です。全部張ったほうがよろしければ張ります。初心者なのでコードが見にくかったらすいませんm(__)m

コード:

		while(ProcessMessage() == 0){
			if(count >= 14000)break;
		DrawRotaGraph2( 512, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kuro, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(ProcessMessage() == 0){
			if(count >= 28000)break;
		DrawRotaGraph2( 412, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kiiro, TRUE ) ;
		DrawRotaGraph2( 612, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,midori, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(ProcessMessage() == 0){
			if(count >= 42000)break;
		DrawRotaGraph2( 312, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,ao, TRUE ) ;
		DrawRotaGraph2( 712, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,aka, TRUE ) ;
		Sleep(1);
		count++;
		}
	}
※一部「新ゲームプログラミングの館」の書き方を使用させていただいています。問題がありましたらご指摘くだされば幸いです。
という文章に

コード:

     //描画ブレンドモードセット部分
	           while( ProcessMessage() == 0 && gpUpdateKey()==0 ){
                             if( KEY_INPUT_A == 1){
                                 SetDrawBlendMode( DX_BLENDMODE_ALPHA , 100 );
                                       break;
		   }else if( KEY_INPUT_S == 1){
	                    SetDrawBlendMode( DX_BLENDMODE_ADD , 100 );
		            break;
			}
                          }
while(ProcessMessage() == 0){
    //描画部分
		while(ProcessMessage() == 0){
			if(count >= 14000)break;
		DrawRotaGraph2( 512, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kuro, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(ProcessMessage() == 0){
			if(count >= 28000)break;
		DrawRotaGraph2( 412, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kiiro, TRUE ) ;
		DrawRotaGraph2( 612, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,midori, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(ProcessMessage() == 0){
			if(count >= 42000)break;
		DrawRotaGraph2( 312, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,ao, TRUE ) ;
		DrawRotaGraph2( 712, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,aka, TRUE ) ;
		Sleep(1);
		count++;
		}
	}
※「新ゲームプログラミングの館」2.9章のgpUpdateKey関数」を使用しています。
※何故かIFの部分のインデントがおかしなことになっているのですが、直らないのでこのまま投稿させていただきます。すいませんm(__)m
と追加する方法などを試してみたのですがうまくいきません。
いい方法がありましたら教えていただければと思います。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: キー入力状態に応じた分岐

#2

投稿記事 by 史上最悪のデスペナ » 14年前

私も初心者なので間違ってるかもしれませんが、
while(ProcessMessage() == 0)はループ文なので、そんないくつも書かなくてもいいのでは?

質問の意図と多少ずれてる気がしなくもないけど、最低限のプログラムです。

コード:

#include "DxLib.h"

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

        //どんなモードかをセットする変数
        int DrawFlag;

       // キー入力状態を保存する変数
    char KeyBuf[ 256 ];

	if( DxLib_Init() == -1 )	// DXライブラリ初期化処理
	{
		 return -1;	// エラーが起きたら直ちに終了
	}
        //バックバッファに描画
		if(SetDrawScreen(DX_SCREEN_BACK) != 0) return -1;

	// test1.bmpの読み込み
	TestHandle = LoadGraph( "test1.bmp" ) ;

	// back.bmpの読み込み
	BackHandle = LoadGraph( "back.bmp" ) ;

         while(ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0)
	{
                ClearDrawScreen();
                //すべてのキーの状態を得る
		GetHitKeyStateAll( KeyBuf ) ;
       // 背景を描画
	DrawGraph( 0 , 0 , BackHandle , FALSE ) ;

       if(KeyBuf[KEY_INPUT_A] == 1)
               {
                   DrawFlag = 1;
               } else if(KeyBuf[KEY_INPUT_S] == 1)
               {
                   DrawFlag = 2;
               } 
switch(DrawFlag)
{
        case 1:
                // 描画ブレンドモードをアルファブレンド(50%)にする
	        SetDrawBlendMode( DX_BLENDMODE_ALPHA , 128 ) ;
	        // 上に載せるグラフィックを描画
	         DrawGraph( 255 , 0 , TestHandle , TRUE ) ;
                break;
         case 2:
              // 描画ブレンドモードを加算ブレンド(100%)にする
	      SetDrawBlendMode( DX_BLENDMODE_ADD , 255 ) ;
              // 上に載せるグラフィックを描画
	      DrawGraph( 255 , 0 , TestHandle , TRUE ) ;
              break;
}
   //裏画面のを表画面に描画
                ScreenFlip();
             
                
        }
	DxLib_End() ;	// DXライブラリ使用の終了処理

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

naohiro19
記事: 256
登録日時: 15年前
住所: 愛知県

Re: キー入力状態に応じた分岐

#3

投稿記事 by naohiro19 » 14年前

ProcessMessageをwhileの中に何回も入れるとWIndows 自体に重くなったり最悪の場合故障の原因になる可能性がありますので1つにしましょう。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力状態に応じた分岐

#4

投稿記事 by softya(ソフト屋) » 14年前

while(ProcessMessage() == 0)とClearDrawScreen();とScreenFlip();はセットにして、プログラム内に一箇所に置いてください(WinMainが定番)。複数置くとろくな事にはなりません。
機能の切り替えは、史上最悪のデスペナさんが書いたように状態を示す変数を設けて押されたキーに合わせて変数を書き換えます。
あと、みなさんインデントは綺麗に合わせて書きましょう。バグの原因になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: キー入力状態に応じた分岐

#5

投稿記事 by 史上最悪のデスペナ » 14年前

softya(ソフト屋)さん。一応インデントに気をつけているのですが、ここにコードを入力するときに何故か上手くいかないのです。
普段は下のように書いているのですが(直接入力。Tabが使えないので半角スペース4つで代用)

コード:

WinMain()
{
    while()
    {
        if()
        {
            func1();
            func2();
        }
        func3();
    }
    func4();
}
自分のコードを貼り付けると何故か時々おかしなことに・・・・
ここで見た目がおかしいから半角スペースで直すと投稿時に変なインデント状態になっていて・・・・・・
いまだ、ここの機能を把握していないのが問題でしょうか^^;

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力状態に応じた分岐

#6

投稿記事 by softya(ソフト屋) » 14年前

あんまり、この上で編集している人はいないと思います。タブと半角空白がまじるとインデントをうまくこの上で編集できません。
VC++やテキストエディタ上で行ってから貼りつけたほうが速いですからね。

ちなみに、1つ前のものは全角空白が混じっていますのでエラーになりますよ。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

史上最悪のデスペナ
記事: 521
登録日時: 14年前

Re: キー入力状態に応じた分岐

#7

投稿記事 by 史上最悪のデスペナ » 14年前

なるほど。これから今回みたいなアドリブで組み立てるような場合はメモ帳で書いてから貼り付けます。
softya(ソフト屋) さんが書きました:ちなみに、1つ前のものは全角空白が混じっています
・・・・・・・・・・orz

land

Re: キー入力状態に応じた分岐

#8

投稿記事 by land » 14年前

今帰りました。
皆さん回答ありがとうございます。
機能の切り替えは史上最悪のデスペナさんの方法を試してみたいと思います。ありがとうございました。
インデントはなにぶん初心者なものでコードが多くなると分からなくなることが、、、気をつけないといけませんね。
while(ProcessMessage() == 0)の件ですが画像を一つ一つ順番に書きたいと思い、
countが14000以下なら一番の画像(上のコードだとkuroの変数に格納されている画像です)を描画し続けて、
14000以上ならループを抜けて次の28000以下のループ、という風に考えていたのですが、
60分の1秒に一回呼び出さなければいけないと書いてあったので14000以下の間でループしている間は
一番上のProcessMessage()は通らないから・・・と思い全てのwhile毎に呼び出していました。。。
このようにすると自分のパソコンでは止まってしまいます。。。

コード:

	while(ProcessMessage() == 0){
		while(1){
			if(count >= 14000)break;
		DrawRotaGraph2( 512, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kuro, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(1){
			if(count >= 28000)break;
		DrawRotaGraph2( 412, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,kiiro, TRUE ) ;
		DrawRotaGraph2( 612, 384, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,midori, TRUE ) ;
		Sleep(1);
		count++;
		}
		while(1){
			if(count >= 42000)break;
		DrawRotaGraph2( 312, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,ao, TRUE ) ;
		DrawRotaGraph2( 712, 256, 50+sin(PI/120*count)*50, 150, 1.0, (double)count*0.01 ,aka, TRUE ) ;
		Sleep(1);
		count++;
		}
		break;
	}
これに関してはwhile使わない方法を考えてみようかと思います。
後、実は裏画面に描画してからScreenFlip();で表画面に映すと描画スピードが遅くなってしまうので、
ちらつくのを覚悟で表画面に直接描画しています。
たぶんScreenFlip();でスピードをリフレッシュレートに合わせているから?だと思うのですが
どちらの方法を使っても描画スピードが変わらない方法がありましたら教えていただきたいです。
とりあえずもう少し改良してみたいと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力状態に応じた分岐

#9

投稿記事 by softya(ソフト屋) » 14年前

後、実は裏画面に描画してからScreenFlip();で表画面に映すと描画スピードが遅くなってしまうので、
ちらつくのを覚悟で表画面に直接描画しています。
普通はありません。すごいサイズやすごい量を描画すれば別ですが。
1回の描画で何pixelぐらいの面積を描画しているのでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

land

Re: キー入力状態に応じた分岐

#10

投稿記事 by land » 14年前

一回の描画では32*32ピクセルの画像1枚か2枚です。
少し考えてみたのですが、表画面に直接描画すると画面のリフレッシュレートを
無視して描画するからちらつくんですよね?(間違ってたらすいません。)
もしScreenFlip();でそれを合わせているのだとしたら無視して描画するよりも
更新レートに合わせているので遅くなる、ということだと思うのですが。。。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力状態に応じた分岐

#11

投稿記事 by softya(ソフト屋) » 14年前

ちらつく無理をしてまで表画面で描画する意味はないと思いますよ。
それとも秒間60フレームを超えたいのですか? たとえ超えたつもりでも液晶画面は秒間60フレームを超えられないので意味はないのですが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

land

Re: キー入力状態に応じた分岐

#12

投稿記事 by land » 14年前

なるほど。。。
どちらの場合でも描画スピードが変わらないのであれば原因は別のところにありそうですね。
コードを色々改良してみたいと思います。回答ありがとうございました。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: キー入力状態に応じた分岐

#13

投稿記事 by softya(ソフト屋) » 14年前

ちなみに1フレーム毎に640x480pixelx数画面分を書き換えても毎秒60フレーム程度は軽く出るはずです。
※ 何処まで出来るかはパソコンの性能に依存します。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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