アニメーション描画

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

アニメーション描画

#1

投稿記事 by kms » 16年前

質問失礼致します。

現在、アニメーションを描画する関数を作成しているのですが、
PCの性質を理解していない為、試行錯誤を繰り返しています。
動かせたいキャラクターの画像は、配列として[11]、用意してはいるのですが、
for文を用いても、キャラクターが動かず(一瞬で止まってしまう)、
[0]>[1]>[2]>[3]>.....と徐々にiの値を増やしたいのですが、どういった計算式が必要でしょうか?

-----------------------
int g_image[ 11 ] ;//画像を分割して配列要素に保存

int Opening( void ){
           for ( i = 0 ; i < 11 ; i++ ){
		DrawGraph( x , y , g_image , TRUE ) ;//画像を描画
		Sleep(60);
		}
	  if ( i == 11 ) i = 0 ;//iが11(配列の要素数)になった時点で0に戻す
                 }
	return 0;
}

----------------------

ヒントを頂けたら幸いです。
文法に関してもご教授頂けたら嬉しいです。

度々申し訳ないです。。

バグ

Re:アニメーション描画

#2

投稿記事 by バグ » 16年前

forループを継続する条件が「iが11未満ならば」ですから、iは0~10に変化するだけで11になる事はありません。よって、0~10の変化を繰り返しさせたいのでしょうが実際にはiの値がリセットされる事なく終了しています。
それから、ループ内でメッセージ処理がされてないので、ProcessMessage関数をどこかに入れてやらないといけないかと…

kms

Re:アニメーション描画

#3

投稿記事 by kms » 16年前

バグ様、お返事ありがとうございます。

「iが11未満ならば」。そうですね。「以下」と「未満」を履き違えていました。。
助かりました^_^

>>ループ内でメッセージ処理がされてないので、
>>ProcessMessage関数をどこかに入れてやらないといけないかと…

ProcessMessage関数は、複数存在しても大丈夫なのでしょうか?
入れる箇所がいまいち理解できていないので。。

(追記:自分で作った関数で、それが繰り返し処理を必要とする関数の場合、
 ProcessMessage関数ループ内にその関数を書かなければいけないのでしょうか?)。

説明下手ですみません。。

バグ

Re:アニメーション描画

#4

投稿記事 by バグ » 16年前

多分、描画用のメッセージ処理を行なわないと画面が描き変わらなくなるんじゃないかな?
ProcessMessage関数自体はメッセージ処理をしているだけのはずなんで、何処で呼び出しても問題ないと思いますが、出来るなら一ヵ所にまとめておいた方がよいかと…
DXライブラリにはそんなに詳しくないので、嘘を言っているかもしれませんが…(^_^;)

TRUTH

Re:アニメーション描画

#5

投稿記事 by TRUTH » 16年前

こんにちはー。

http://dixq.net/rp/2.html
からWinMainだけ抜き出しました。
このような状態でアニメーションを行いたいとします。


ココ!と書かれている場所にOpeningなどの処理したい関数を入れてください。
例え描画の絡む繰り返しの処理(アニメーションやゲーム画面など)はforを使いません。
なぜならScreenFlip();が呼ばれないと画面の更新が行われないはずですので
アニメーションにしたい場合は、アニメ静止画①→ScreenFlip()→アニメ静止画②→ScreenFlip()…
と繰り返されるように組みます。

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

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


        //ココ!!



        ScreenFlip();
    }

    DxLib_End();
    return 0;
}
ココの部分にOpening();を挿入したとしますと
Opening→ScreenFlip()→Opening→ScreenFlip()…と繰り返し処理されます。
上記の説明と比べますとOpening内の描画が、アニメ静止画①→アニメ静止画②…と処理すればいいことが
わかると思います。

龍神録をつくろう7章でアニメーションが実装されていますので参考にしてみるといいかもしれません。
http://dixq.net/rp/7.html

バグ

Re:アニメーション描画

#6

投稿記事 by バグ » 16年前

裏画面処理をしなければ、forループ内で処理しても問題ないと思いますよ。

kms

Re:アニメーション描画

#7

投稿記事 by kms » 16年前

バグ様、TRUTH様、お返事ありがとうございます。
アドバイスを参考にし、どうにかアニメーション描画を完成させる事ができました(感謝!)。

その後、WinMain関数内で、選択画面を作り、エンターキーが押された時点でアニメーション描画関数(Opening();)を呼び出そうとしたのですが、
以下のコードで問題は無いでしょうか?
メッセージ処理と画面クリアを二度、用いているのですが。。。
#include "DxLib.h"
//グローバル
int Opening( void );//プロトタイプ宣言

	int x = 0 , y = 240 , i = 0 ;
	int g_image[ 11 ] ;//画像を分割して配列要素に保存
	char KeyBuf[ 256 ] ;//入力を取得する

int Opening( void )//オープニング関数
		{
			SetDrawScreen( DX_SCREEN_BACK );//裏画面処理
			while( ProcessMessage()==0 && ClearDrawScreen()==0 ){ //*ココ
			
			//アニメーション描画
			DrawGraph( x , y , g_image , TRUE ) ;//画像を描画
			i++;
			if ( i == 11 ) i = 0 ;//iが11(配列の要素数)になった時点で0に戻す
				
			ScreenFlip();//表画面に反映
			}

			WaitKey();
			DxLib_End();
			return 0;
}


int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP , LPSTR lpC , int nC ){
	ChangeWindowMode(TRUE);//ウィンドウサイズの変更
	if( DxLib_Init() == -1 ) return -1;

	LoadDivGraph( "player01.bmp" , 11 , 11 , 1 , 64 , 64 , g_image );//画像を分割して読み込み
	
	SetDrawScreen( DX_SCREEN_BACK );//裏画面処理

	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( KeyBuf ) && !KeyBuf[KEY_INPUT_ESCAPE]){

		int cr_1 = GetColor( 255 , 255 , 255 );//色を取得
		SetFontSize( 40 ) ;                             //サイズを40に変更
        SetFontThickness( 1 ) ;                         //太さを1に変更
        ChangeFont( "HGS創英角ポップ体" ) ;              //HGS創英角ポップ体に変更
        ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );//アンチエイリアス&エッジ付きフォントに変更
		DrawString(220,50,"GAME", cr_1 );

		SetFontSize( 12 ) ;                             //サイズを12に変更
        SetFontThickness( 2 ) ;                         //太さを2に変更
		DrawString( 220 , y , "■" , cr_1 );
		DrawString( 250 , 240 , "NewGame" , cr_1 );//文字列を描画
		DrawString( 250 , 260 , "LoadGame" , cr_1 );//文字列を描画
		if( KeyBuf[ KEY_INPUT_DOWN ] == 1 ){//下キーが押されていたら、
			y += 20 ;//矢印を下に動かす
		    if( y == 280 ) y = 240 ;//yが280に達しようとしたとき、yを初期値に戻す
		}
		if( KeyBuf[ KEY_INPUT_RETURN ] == 1 ){
			ClearDrawScreen();//画面を初期化
			Opening();//ココで呼び出す
		}
	
	ScreenFlip();//表画面に反映
}
	WaitKey();
	DxLib_End();
	return 0;
}


動作はするのですが、文法上、どうなのかな? と気になってしまい。。

閉鎖

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