フェードイン、フェードアウトの作り方
-
situmon
フェードイン、フェードアウトの作り方
ゲームプログラミングの館を見て実装しようとしたのですが、うまくいきませんでした。
どのように実装すればいいのでしょうか?ゲームに応用するのができません。
とくに選択画面で選択したときにどうすればいいのでしょう?
どのように実装すればいいのでしょうか?ゲームに応用するのができません。
とくに選択画面で選択したときにどうすればいいのでしょう?
-
kazuoni
Re:フェードイン、フェードアウトの作り方
どのようにうまくいかないか、もう少し具体的に書いたほうが
より詳しい回答が得られるかと思います。
本家にも参考がでていますが、
これでは不備があるでしょうか?
DXライブラリ置き場
ttp://homepage2.nifty.com/natupaji/DxLib/dxprogram.html#N9
より詳しい回答が得られるかと思います。
本家にも参考がでていますが、
これでは不備があるでしょうか?
DXライブラリ置き場
ttp://homepage2.nifty.com/natupaji/DxLib/dxprogram.html#N9
-
situmon
Re:フェードイン、フェードアウトの作り方
えっと選択画面をswitch形式にしているのですが
switch(choose_y){
case 80:
if( CheckSoundMem( bgm[5] ) == 1 )
StopSoundMem( bgm[5] ) ;
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
main_flag=2;
if(stage_flag!=1)
stage_flag=1;
break;
...省略
}
としているのですが、この選んでからゲームが始まるまでに(main_flag=2になるまでに)フェードインなどをしたいのです。-
チルチル
Re:フェードイン、フェードアウトの作り方
私の経験ですがフェードイン、フェードアウトは関数化しておくと後でかなり楽になります
前に送ったサンプルのSceneChange関数が参考になるかもしれません
1.ZとかXが押された時にカウンタをリセットして
2.カウンタでフェードイン
3.カウンタが半分まで進んだら画面を変える
4.カウンタでフェードアウト
この流れでどうでしょうか?
まあこれだけだと入力関係が不十分ですが・・
前に送ったサンプルのSceneChange関数が参考になるかもしれません
1.ZとかXが押された時にカウンタをリセットして
2.カウンタでフェードイン
3.カウンタが半分まで進んだら画面を変える
4.カウンタでフェードアウト
この流れでどうでしょうか?
まあこれだけだと入力関係が不十分ですが・・
-
situmon
Re:フェードイン、フェードアウトの作り方
// フェードイン処理
for(int i = 0 ; i < 256 ; i++ )
{
// 描画輝度をセット
SetDrawBright( 255 - i , 255 - i , 255 - i ) ;
if(i==255){
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
WaitTimer( 200 ) ;//0.2秒待つ
main_flag=2;
player.easy_flag=0;
player.hard_flag=0;
if(stage_flag!=4)
stage_flag=4;
}
}
としたのですが、なぜか失敗してしまいます。追記
失敗というのは真っ暗のままになってしまうのです。
-
kazuoni
Re:フェードイン、フェードアウトの作り方
このfor文のなかにScreenFlip的な、
表描写もDraw系もないので、
このfor文を抜けるときには、輝度は0で、真っ暗かと思います。
コード全部が載っていないので、あくまで予想ですが・・・。
表描写もDraw系もないので、
このfor文を抜けるときには、輝度は0で、真っ暗かと思います。
コード全部が載っていないので、あくまで予想ですが・・・。
-
situmon
Re:フェードイン、フェードアウトの作り方
#include "DxLib.h"
#include "Extern.h"
void Title_Draw(){
if(bgm_select_flag!=0 ||stage_flag!=0){
stage_flag=0;
bgm_select_flag=0;
}
DrawGraph( 0 , 0 , title_img , FALSE );
DrawStringToHandle( 20 , 420 , "タイトル" , white , font[2] );
DrawStringToHandle( 460 , 420 , "Ver 1.00 (test) " , white , font[3] );
DrawGraph( 50 , 100 , title_d_img[0] , TRUE );
DrawGraph( 50 , 156 , title_d_img[2] , TRUE );
DrawGraph( 50 , 212 , title_d_img[1] , TRUE );
DrawGraph( 10 , title_y+16 , title_d_img[3] , TRUE );
//上キー
if( CheckHitKey( KEY_INPUT_UP ) == 1 && t_count%5==0 ){
if( CheckSoundMem( sound_effect[0] ) == 0 )
PlaySoundMem( sound_effect[0] , DX_PLAYTYPE_BACK ) ;
if(title_y>100){
if(title_y==212&&clear_flag==0)
title_y-=112;
else
title_y-=56;
}
}
//下キー
if( CheckHitKey( KEY_INPUT_DOWN ) == 1 && t_count%5==0 ){
if( CheckSoundMem( sound_effect[0] ) == 0 )
PlaySoundMem( sound_effect[0] , DX_PLAYTYPE_BACK ) ;
if(title_y<212){
if(title_y==100&&clear_flag==0)
title_y+=112;
else
title_y+=56;
}
}
//escapeキー
if( CheckHitKey( KEY_INPUT_ESCAPE ) == 1){
if( CheckSoundMem( sound_effect[0] ) == 0 )
PlaySoundMem( sound_effect[0] , DX_PLAYTYPE_BACK ) ;
if(title_y!=212)
title_y=212;
}
if( CheckHitKey( KEY_INPUT_Z ) == 1 || CheckHitKey( KEY_INPUT_RETURN ) == 1 ){
switch(title_y){
case 100:
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
WaitTimer( 200 ) ;//0.2秒待つ
main_flag=1;
break;
case 156:
if( CheckSoundMem( bgm[5] ) == 1 )
StopSoundMem( bgm[5] ) ;
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
WaitTimer( 200 ) ;//0.2秒待つ
main_flag=2;
player.easy_flag=0;
player.hard_flag=0;
if(stage_flag!=4)
stage_flag=4;
break;
case 212:
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
DxLib_End(); //終了
break;
default:
break;
}
}
}
となっていますが、このfor文のなかにScreenFlip的な
>main.cppで書いているのですが・・・
表描写もDraw系もないので、
>ここにまた
DrawGraph( 50 , 100 , title_d_img[0] , TRUE );
DrawGraph( 50 , 156 , title_d_img[2] , TRUE );
DrawGraph( 50 , 212 , title_d_img[1] , TRUE );
DrawGraph( 10 , title_y+16 , title_d_img[3] , TRUE );
とかくのでしょうか??
-
situmon
Re:フェードイン、フェードアウトの作り方
switch(title_y){
case 100:
if( CheckSoundMem( sound_effect[6] ) == 0 )
PlaySoundMem( sound_effect[6] , DX_PLAYTYPE_BACK ) ;
for(int i=0;i<256;i+=4){
// 描画輝度をセット
SetDrawBright( 255 - i , 255 - i , 255 - i ) ;
DrawGraph( 0 , 0 , title_img , FALSE );
ScreenFlip() ;
}
for(int i=0;i<256;i++){
// 描画輝度をセット
SetDrawBright( i , i , i ) ;
DrawGraph( 0 , 0 , title_img , FALSE );
ScreenFlip() ;
if(i==255){
main_flag=1;
}
}
break;
とすることにより実装できましたが考え的には、DrawGraph( 0 , 0 , title_img , FALSE );
DrawGraph( 50 , 100 , title_d_img[0] , TRUE );
DrawGraph( 50 , 156 , title_d_img[2] , TRUE );
DrawGraph( 50 , 212 , title_d_img[1] , TRUE );
DrawGraph( 10 , title_y+16 , title_d_img[3] , TRUE );
で描いた(映した)画像の上にまた新たにまたDrawGraph( 0 , 0 , title_img , FALSE );
で同じ画像を描いているわけだと思うのですが、これでいいのですか?
-
kazuoni
Re:フェードイン、フェードアウトの作り方
確かに、反映されているので、それで成功するかと思います。
ただ、プログラムの各所に表描写反映(ScreenFlip)を書くと、
いつか、管理しにくくなってくるかと思います。
なので、反映する関数はmainループに一度だけ書くことをお勧めします。
>描いた(映した)画像の上にまた新たにまたDrawGraph( 0 , 0 , title_img , FALSE );
>で同じ画像を描いているわけだと思うのですが、これでいいのですか?
プログラムは上から流れてきますので、そうですね。
裏描写のクリアもしていないので、Drawするたびに、上書きしていっています。
ただ、プログラムの各所に表描写反映(ScreenFlip)を書くと、
いつか、管理しにくくなってくるかと思います。
なので、反映する関数はmainループに一度だけ書くことをお勧めします。
>描いた(映した)画像の上にまた新たにまたDrawGraph( 0 , 0 , title_img , FALSE );
>で同じ画像を描いているわけだと思うのですが、これでいいのですか?
プログラムは上から流れてきますので、そうですね。
裏描写のクリアもしていないので、Drawするたびに、上書きしていっています。
-
situmon
Re:フェードイン、フェードアウトの作り方
その場合、どうすればいいのでしょう。
それだけ消すのか、そのままでは問題ないのでしょうか?
自分の考えではDrawするたび少しですが、パソコンに、負担がかかると思うのですが。
それだけ消すのか、そのままでは問題ないのでしょうか?
自分の考えではDrawするたび少しですが、パソコンに、負担がかかると思うのですが。
-
kazuoni
Re:フェードイン、フェードアウトの作り方
>その場合、どうすればいいのでしょう。
>それだけ消すのか、そのままでは問題ないのでしょうか?
「その場合」がどの場合で、それだけの「それ」がどれかはっきり分かりませんが、
確かに、画面内に動きがない場合はこれでも画面のフェードインアウトはいいと思います。
ただ、もし、次に、キャラクターがぐるぐるフィールド上を
回っている最中にフェードアウトし、フェードインでは次の場面にしたい
なんてなった場合、この書き方では使えないですよね?
なので、根本的な見直しをする必要があるかと思います。
>自分の考えではDrawするたび少しですが、パソコンに、負担がかかると思うのですが。
それはそのとおりです。
ちょっと勘違いをしているかもしれないので付け加えを。
「裏描写の内容は動きのないものだから、一回描写して、
あとはSetDrawBrightで輝度を下げればいいんじゃないの?」
ってことを言いたいのでは?と勝手に決め打ちしますが、
SetDrawBrightはあくまで、描写のモードを決めるだけであって、
今裏描写にあるものの輝度とは別物です。
この関数を読んだ以降のDrawはすべてSetDrawBrightで決めた輝度にセットしますよ
ってな感じです。
>それだけ消すのか、そのままでは問題ないのでしょうか?
「その場合」がどの場合で、それだけの「それ」がどれかはっきり分かりませんが、
確かに、画面内に動きがない場合はこれでも画面のフェードインアウトはいいと思います。
ただ、もし、次に、キャラクターがぐるぐるフィールド上を
回っている最中にフェードアウトし、フェードインでは次の場面にしたい
なんてなった場合、この書き方では使えないですよね?
なので、根本的な見直しをする必要があるかと思います。
>自分の考えではDrawするたび少しですが、パソコンに、負担がかかると思うのですが。
それはそのとおりです。
ちょっと勘違いをしているかもしれないので付け加えを。
「裏描写の内容は動きのないものだから、一回描写して、
あとはSetDrawBrightで輝度を下げればいいんじゃないの?」
ってことを言いたいのでは?と勝手に決め打ちしますが、
SetDrawBrightはあくまで、描写のモードを決めるだけであって、
今裏描写にあるものの輝度とは別物です。
この関数を読んだ以降のDrawはすべてSetDrawBrightで決めた輝度にセットしますよ
ってな感じです。
-
おむすび
Re:フェードイン、フェードアウトの作り方
横スレ失礼いたします。
わたしも以前フェードイン、アウトの処理を使ったのですがうまくいきませんでした。
フェードではなく一瞬で色が変わってしまいます。
わたしも以前フェードイン、アウトの処理を使ったのですがうまくいきませんでした。
フェードではなく一瞬で色が変わってしまいます。
// フェードイン処理
int FadeIn( int Color , int Speed ){
for(int i = 0 ; i < 255 ; i += Speed ){
// 描画輝度をセット
SetDrawBright( i , i , i ) ;
// グラフィックを描画
DrawBox( 0 , 0 , 640 , 480 , Color , true ) ;
if(i < 255) return true;
}
return false;
}
// フェードアウト処理
int FadeOut( int Color , int Speed ){
for(int i = 0 ; i < 255 ; += Speed ){
// 描画輝度をセット
SetDrawBright( 255 - i , 255 - i , 255 - i ) ;
// グラフィックを描画
DrawBox( 0 , 0 , 640 , 480 , Color , true ) ;
if(i < 255) return true;
}
return false;
}
if(CheckHitKey(KEY_INPUT_B)){
FadeIn(RGB(0,0,0),1);
}
if(CheckHitKey(KEY_INPUT_A)){
FadeOut(RGB(0,0,0),1);
}-
kazuoni
Re:フェードイン、フェードアウトの作り方
Drawを表描写にしているのか、裏描写にしているのか定かではないのであれですが・・・
もし、裏描写なら
>フェードではなく一瞬で色が変わってしまいます。
になります。
フェードイン、アウト共に、表描写(ScreenFlip)していないからです。
この関数だと、裏描写には淡々と描写していますが、
それを表描写しなければ、画面には反映されません。
もし、裏描写なら
>フェードではなく一瞬で色が変わってしまいます。
になります。
フェードイン、アウト共に、表描写(ScreenFlip)していないからです。
この関数だと、裏描写には淡々と描写していますが、
それを表描写しなければ、画面には反映されません。
-
おむすび
Re:フェードイン、フェードアウトの作り方
たぶんScreenFlipしておりますので書き方が悪いのかと思います。
サンプル置き場にあるものを実行したら問題なかったので・・・。
現在のソースを書かせていただきます。
サンプル置き場にあるものを実行したら問題なかったので・・・。
現在のソースを書かせていただきます。
// フェードイン処理
bool FadeIn( int Color , int Speed ){
for(int i = 0 ; i < 255 ; i += Speed ){
// 描画輝度をセット
SetDrawBright( i , i , i ) ;
// グラフィックを描画
DrawBox( 0 , 0 , 640 , 480 , Color , true ) ;
// ScreenFlip();
if(i < 255) return true;
}
return false;
}
// フェードアウト処理
bool FadeOut( int Color , int Speed ){
for(int i = 0 ; i < 255 ; i += Speed){
// 描画輝度をセット
SetDrawBright( 255 - i , 255 - i , 255 - i ) ;
// グラフィックを描画
DrawBox( 0 , 0 , 640 , 480 , Color , true ) ;
// ScreenFlip();
if(i < 255) return true;
}
return false;
}
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(true); // ウインドウの変更 フルスクリーン・ウインドウ
SetDrawScreen( DX_SCREEN_BACK ) ; // 描画先を裏画面に設定
// DXライブラリ初期化処理
if( DxLib_Init() == -1 ){
return -1; // エラーが起きたら直ちに終了
}
// 処理
while(1){
// BMP画像の表示
ClearDrawScreen();
if(CheckHitKey(KEY_INPUT_B)){
FadeIn(RGB(0,0,0),1);
}
if(CheckHitKey(KEY_INPUT_A)){
FadeOut(RGB(0,0,0),1);
}
ScreenFlip();
// 処理の終了
if(CheckHitKey(KEY_INPUT_ESCAPE)) break;
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0 ; // ソフトの終了
}-
Dixq (管理人)
Re:フェードイン、フェードアウトの作り方
今コンパイラが手元にないので詳しく書けませんが・・。
ScreenFlip();
はあちこちに書かないほうがいいです。
メインループの中に一度だけ書くようにしてください。
必ずメインに戻しても処理が出来るはずですから。
「輝度」なる変数を用意し、それを変更することで明るさを調整するといいと思いますよ。
ScreenFlip();
はあちこちに書かないほうがいいです。
メインループの中に一度だけ書くようにしてください。
必ずメインに戻しても処理が出来るはずですから。
「輝度」なる変数を用意し、それを変更することで明るさを調整するといいと思いますよ。
-
おむすび
Re:フェードイン、フェードアウトの作り方
管理人さま
ご回答ありがとうございます。
ScreenFlipなのですが現在コメントにしてありますので一回しか書いてありません。
とても便利な関数なのですがよくどちらに書いたかわからなくなるので・・・ww
やはりフェードインしませn。
ご回答ありがとうございます。
ScreenFlipなのですが現在コメントにしてありますので一回しか書いてありません。
とても便利な関数なのですがよくどちらに書いたかわからなくなるので・・・ww
やはりフェードインしませn。
-
Justy
Re:フェードイン、フェードアウトの作り方
>やはりフェードインしません
1回分の whileループ(1フレーム)の中の処理を日本語で書き出してみましょうか。
1 [color=#d0d0ff" face="sans-serif]ClearDrawScreen();[/color]
画面を消す。
2 [color=#d0d0ff" face="sans-serif]if(CheckHitKey(KEY_INPUT_B)) { FadeIn(RGB(0,0,0),1); }[/color]
Bのキーが押されてたら輝度を{ 0, 0, 0 }から { 254, 254, 254 }まで
255回 DrawBox関数で全画面塗りつぶす。
3 [color=#d0d0ff" face="sans-serif]if(CheckHitKey(KEY_INPUT_A)) { FadeOut(RGB(0,0,0),1); }[/color]
Aのキーが押されてたら輝度を{ 255, 255, 255 }から { 1, 1, 1 }まで
255回 DrawBox関数で全画面塗りつぶす。
4 [color=#d0d0ff" face="sans-serif]ScreenFlip();[/color]
裏画面と表画面を交換して、1以降で描画した内容を画面に表示する
5 [color=#d0d0ff" face="sans-serif]if(CheckHitKey(KEY_INPUT_ESCAPE)) break;[/color]
ESCキーが押されたら、whileループを抜ける
これが1回分の whileループの処理です。
さて、ここで2や3の処理をみて下さい。
SetDrawBright~DrawBoxを 255回も行って描いていますが、
当然これ全て1フレームで処理されてしまっています。
透明属性の指定はないので、最終的には 255回目に描いたものが一番上になり
見た目には 1回目~ 254回目までの描画はなかったことになります。
これでは一瞬で色が変わってしまいますよね。
なので、何フレーム~何十フレームもかけて輝度を変化させて表示するように
変更してみて下さい。