簡単なドラムソフトの問題

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

簡単なドラムソフトの問題

#1

投稿記事 by C » 15年前

簡単なキーボードドラムソフトをつくっています。
勉強しながら初製作していて音は出たのですが以下の問題があります。
できればアドバイスをお願いします。

1.時間差が長く 複数のMIDIが同時にならない
 Vista Core2Duo VC++ DXLib ですが環境の限界なのでしょうか
2.オープニング画面をWhileで用意してみたが動かない
3.音と同時に絵が一瞬拡大されるように書いたつもりだが絵が現れない

以下がソースです。動かなかったところは//してあります。

#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;

int snr ; snr = LoadMusicMem( "snr.mid" );
int bsdr ; bsdr = LoadMusicMem( "bsdr.mid" );
int hh ; hh = LoadMusicMem( "hh.mid" );
int ohh ; ohh = LoadMusicMem( "ohh.mid" );
int crsh ; crsh = LoadMusicMem( "crsh.mid" );
int White ; White = GetColor( 255 , 255 , 255 ) ;
int image[5]; LoadDivGraph( "drums.jpg" , 5 , 5 , 1 , 173 , 180 , image );
char Key[ 256 ] ; GetHitKeyStateAll( Key ) ;
SetDrawScreen( DX_SCREEN_BACK ) ;

// while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] && !Key[KEY_INPUT_RETURN])
// {//opening画面
//SetFontSize( 40 ) ;
//SetFontThickness( 1 ) ;
//ChangeFont( "HGS創英角ポップ体" ) ;
//ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );ォントに変更
//DrawString( 100 , 220 , "the Drum soft " , White );
//DrawString( 100 , 240 , "Use GBHYU. Press Enter. Play it!" , White );
//ScreenFlip();//裏画面を表画面に反映
//}

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

DrawGraph( 100 , 100, image[4] , FALSE ) ;
//LoadGraphScreen( 0 , 0 , "yellowback.jpg" , FALSE ) ;
DrawString( 100 , 300 , "the Drum soft " , White );
DrawString( 100 , 320 , "Use GBHYU. Press Enter. Play it!" , White );
ScreenFlip();//裏画面を表画面に反映
if( Key[ KEY_INPUT_G ] == 1 ) {PlayMusicMem( snr , DX_PLAYTYPE_BACK );//DrawRotaGraph( 350 , 350 , 1.1 , 0 , image[0] , FALSE , TRUE);}
if( Key[ KEY_INPUT_H ] == 1 ) {PlayMusicMem( hh , DX_PLAYTYPE_BACK );//DrawRotaGraph( 200 , 300 , 1.1 , 0 , image[1] , FALSE , TRUE);}
if( Key[ KEY_INPUT_Y ] == 1 ) {PlayMusicMem( ohh , DX_PLAYTYPE_BACK );//DrawRotaGraph( 200 , 300 , 1.1 , 0 , image[2] , FALSE , TRUE);}
if( Key[ KEY_INPUT_U ] == 1 ) {PlayMusicMem( crsh , DX_PLAYTYPE_BACK );//DrawRotaGraph( 300 , 100 , 1.1 , 0 , image[3] , FALSE , TRUE);}
if( Key[ KEY_INPUT_B ] == 1 ) {PlayMusicMem( bsdr , DX_PLAYTYPE_BACK );//DrawRotaGraph( 500 , 350 , 1.1 , 0 , image[4] , FALSE , TRUE);}
}

DxLib_End();
return 0;
}

ookami

Re:簡単なドラムソフトの問題

#2

投稿記事 by ookami » 15年前

あまり詳しくはありませんが、
回答します。

> 時間差が長い
MIDシステムの初期化に時間がかかっているためかと思われます。
たぶん、vistaだけでなく、多くの環境でそうなる気がいたします。

> 複数のMIDIが同時にならない
これも、MIDシステム上、複数のmidファイルを同時に鳴らせないものと思います。

> オープニング画面をWhileで用意してみたが動かない
動かないというのは、コンパイルエラーが出るってことでしょうか?
//ChangeFontType( DX_FONTTYPE_ANTIALIASING_EDGE );ォントに変更
ここが怪しい気がしますが、
「動かない」について詳しくお願いします。

>音と同時に絵が一瞬拡大されるように書いたつもりだが絵が現れない
ScreenFlip、
DrawRotaGraph、
ClearDrawScreenの順で実行しているため、描画した直後に消しているものと思われます。

--

ついでに、
int snr ; snr = LoadMusicMem( "snr.mid" );

int snr = LoadMusicMem( "snr.mid" );
の方がすっきりするかも...好みの問題ですかねw

--

midだと、上記のようにいろいろ問題があるし、
環境によって音色も変わってしまうので、
wavなどを用意する方がいいかもと思いました。

C

Re:簡単なドラムソフトの問題

#3

投稿記事 by C » 15年前

回答ありがとうございます。

1、早速mp3を用意してやってみたところ。時間差 同時再生問題は解決しました!
  midiの方が良いと思っていましたが、とても良い教訓になり、前進することができました。

2、オープニングが現れない現象も怪しいと指摘していただいたところをなくしたら現れました
  
3、絵を一瞬ではなくそれぞれ再生中拡大して表示する手段をご存知ですか?

4、mp3でやってみるとキーボードを一瞬たたいたつもりでも2,3回音の頭がダブってしまいます。
  この新しい問題も解決することは可能でしょうか?

以下ソースファイルです。

#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{ if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;

int snr = LoadSoundMem( "snr.mp3" );
int bsdr = LoadSoundMem( "bsdr.mp3" );
int chh = LoadSoundMem( "chh.mp3" );
int ohh = LoadSoundMem( "ohh.mp3" );
int crsh = LoadSoundMem( "crsh.mp3" );
int White = GetColor( 255 , 255 , 255 ) ;
int image[5]; LoadDivGraph( "drums.jpg" , 5 , 5 , 1 , 173 , 180 , image );
char Key[ 256 ] ; GetHitKeyStateAll( Key ) ;
SetDrawScreen( DX_SCREEN_BACK ) ;

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE] && !Key[KEY_INPUT_RETURN])
{//SetFontSize( 40 ) ; opening
SetFontThickness( 1 ) ;
//ChangeFont( "HGS創英角ポップ体" ) ;
DrawGraph( 100 , 100, image[4] , FALSE ) ;
DrawString( 100 , 300 , "the Drum soft " , White );
DrawString( 100 , 320 , "Press Enter." , White );
ScreenFlip();//裏画面を表画面に反映
}

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE])
{//LoadGraphScreen( 0 , 0 , "yellowback.jpg" , FALSE ) ;
DrawGraph( 230, 280, image[0], FALSE ) ;
DrawGraph( 30, 200, image[1] , FALSE ) ;
DrawGraph( 270, 10, image[3] , FALSE ) ;
DrawGraph( 420 , 200, image[4] , FALSE ) ;
DrawString( 20 , 20 , "Use BGNTY. Play it." , White );
ScreenFlip();
if(Key[KEY_INPUT_B] == 1){PlaySoundMem(snr, DX_PLAYTYPE_BACK);DrawRotaGraph( 230, 280, 1.1, 0, image[0], FALSE, TRUE);}
if(Key[KEY_INPUT_G] == 1){PlaySoundMem(chh, DX_PLAYTYPE_BACK);DrawRotaGraph( 30, 200, 1.1, 0, image[1], FALSE, TRUE);}
if(Key[KEY_INPUT_T] == 1){PlaySoundMem(ohh, DX_PLAYTYPE_BACK);DrawRotaGraph( 270, 10, 1.1, 0, image[2], FALSE, TRUE);}
if(Key[KEY_INPUT_Y] == 1){PlaySoundMem(crsh, DX_PLAYTYPE_BACK);DrawRotaGraph( 420, 200, 1.1, 0, image[3], FALSE, TRUE);}
if(Key[KEY_INPUT_N] == 1){PlaySoundMem(bsdr, DX_PLAYTYPE_BACK);DrawRotaGraph( 20, 20, 1.1, 0, image[4], FALSE, TRUE);}
}
DxLib_End();
return 0;
}

C

Re:簡単なドラムソフトの問題

#4

投稿記事 by C » 15年前

4、音がダブル問題は自力で解決できました。
バスドラやスネアなどの短い音は、終わったあとに余白をのこしておくと良いようです。

あとは5の絵が拡大される演出の問題です
拡大している時間を保つ記述がもしいいのがあれば教えてください。よろしくお願いします。

シエル

Re:簡単なドラムソフトの問題

#5

投稿記事 by シエル » 15年前

何カウント目までは大きい画像を描画するというようにすればいいと思います

C

Re:簡単なドラムソフトの問題

#6

投稿記事 by C » 15年前

回答ありがとうございます。
if(Key[KEY_INPUT_G] == 1){}の中にsleep(100)をつけてみると音のダブりはさらによくなりましたが
絵は大きくなるのは見えませんでした。

正直なところカウントを待つ書き方がわからないので最後に教えて欲しい頂けると助かります。

カウントを待つとは時間ではなく変数を数え上げるのを待つということでしょうか?

if(Key[KEY_INPUT_G] == 1){}の中にfor(i=0;i<300;i++){}を書いたりしてみましたが音が連続して再生されるだけで絵は大きくなりませんでした。

GetNowCount()は時間の取得でその差を扱って待たせる場合はSleep()と同じことですか?

ookami

Re:簡単なドラムソフトの問題

#7

投稿記事 by ookami » 15年前

繰り返しますが、

ScreenFlip、
DrawRotaGraph、
ClearDrawScreenの順で実行しているため、描画した直後に消しているものと思われます。

situmon

Re:簡単なドラムソフトの問題

#8

投稿記事 by situmon » 15年前

解決していたらすいませんが、音は
mp3ではなくogg形式にしてみたらどうでしょう。

また、絵を拡大表示するのは、
DrawgraphではなくDrawRotaGraphを使います。(ほかの宣言はDXライブラリリファレンスページで・・・)

その後はシエルさんのいわれたように、
if(現在のカウント<拡大し終わる時間)
を設定したらよいと思います。

それと
DrawRotaGraphは
doubleで拡大率の宣言がされていますので、(DXライブラリリファレンスページを見るとわかります。)
まず最初にint型ではなくdoubleで拡大率の変数を宣言します。

double rate(ここは任意の名前で・・・)などで拡大率の変数を作ります。
以下は仮にrateという拡大率の変数をつくったとして話を進めます。

そして次に
if(現在のカウント<拡大し終わるカウント){
rate+=(毎度拡大する大きさ);
}
で拡大率を大きくしていきます。

最後にDrawRotaGraphで画像を表示します。そのときdouble ExtRateに当たる位置にrateを入れると絵が拡大していき表示されるはずです。

******************************
例:
//宣言
double rate=0;(初期設定は0倍)
//カウントアップ開始からすぐに80カウントで元の画像の2倍まで拡大する。
if(現在のカウント<80){
rate+=2.0/80;
}
//(x,y)=(0,0)の位置にrateの拡大率で画像を表示
DrawRotaGraph( 0 , 0 , rate , 0.0f , (使いたい画像のハンドル) , TRUE ) ;//透過処理あり
(DXライブラリのリファレンスに紹介されているコードを一部コピーしました。)
******************************

しかし拡大し終わる時間と毎度拡大する大きさをしっかり設定しないと、画像が拡大されすぎるので、
そこは計算してください。

もし拡大してまた縮小していくならばsinを使ったほうが綺麗ですが、またそれはわからなければ聞いてみてください。

もし詳しく知りたければDXライブラリのページからリファレンスと書いてあるところにいってみてください。
(下記のURLから)
http://homepage2.nifty.com/natupaji/DxLib/

説明がとても下手なので、わからなければ、ここはなに・・・?ときいていただければできる限りで答えます。
また間違ったこと(その他問題や不適切な点)をいっていたら、訂正していただければ嬉しいです。
長文失礼しました。 画像

C

Re:簡単なドラムソフトの問題

#9

投稿記事 by C » 15年前

いつも回答していただいて本当にありがとうございます。
おかげさまで前進しているつもりですが、一応質問内容をもう一度書いておきます。

常にDrawRotaGraph、rate=1もしくはDrawgraphで表示されてる絵をキー入力と同時に、認識できる一瞬、rate=1.1で拡大表示して戻すにはどうしたらよいですか?

当初rateは四角波のように不連続に大きくなりしばらく一定に保って戻るつもりでrateのところに1 1.1と書いていましたが、situmonさんが教えてくださったノコギリや三角も習得したいと思っています。

シエルさんsitumonさんに教えていただいた方法をためしていますが
カウントの使い方がわからなくて難航しています。

if(現在のカウント<80){rate+=2.0/80;} //現在のカウントについて解説をお願いします。GetNowCount?
これはキーが押されてからカウントアップするようになっているのでしょうか?
カウントと実際の時間の関係がよくわかりません。
GetNowCountの差を使って待たせることは、Sleepと同じことですか?

以下ソースです。何度も質問してすみません。宜しくお願いします。
#include "DxLib.h"
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{ if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;

int snr = LoadSoundMem( "snr.mp3" );
int bsdr = LoadSoundMem( "bsdr.mp3" );
int chh = LoadSoundMem( "chh.mp3" );
int ohh = LoadSoundMem( "ohh.mp3" );
int crsh = LoadSoundMem( "crsh.mp3" );
int White = GetColor( 255 , 255 , 255 ) ;
int image[5]; LoadDivGraph( "drums.jpg" , 5 , 5 , 1 , 173 , 180 , image );
char Key[ 256 ] ; GetHitKeyStateAll( Key ) ;
int i =0; i=GetNowCount();      //???
double rate = 0;           //1ではなく0?
SetDrawScreen( DX_SCREEN_BACK ) ;

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE])
{//LoadGraphScreen( 0 , 0 , "yellowback.jpg" , FALSE ) ;
DrawRotaGraph( 230, 280, rate, 0, image[0], FALSE, TRUE); //DrawGraphでもよいのでは?
DrawRotaGraph( 30, 200, rate, 0, image[1], FALSE, TRUE);
DrawRotaGraph( 270, 10, rate, 0, image[3], FALSE, TRUE);
DrawRotaGraph( 420, 200, rate, 0, image[4], FALSE, TRUE);
DrawString( 20 , 20 , "Use BGYUN. Play it." , White );
ScreenFlip();
for(i=0;i<800;i++){ rate=1.1; }            //以下拡大問題
if(Key[KEY_INPUT_B] == 1){PlaySoundMem(snr, DX_PLAYTYPE_BACK);DrawRotaGraph( 230, 280, rate, 0, image[0], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_G] == 1){PlaySoundMem(chh, DX_PLAYTYPE_BACK);DrawRotaGraph( 30, 200, rate, 0, image[1], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_Y] == 1){PlaySoundMem(ohh, DX_PLAYTYPE_BACK);DrawRotaGraph( 30, 200, rate, 0, image[2], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_[/url] == 1){PlaySoundMem(crsh, DX_PLAYTYPE_BACK);DrawRotaGraph( 270, 10, rate, 0, image[3], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_N] == 1){PlaySoundMem(bsdr, DX_PLAYTYPE_BACK);DrawRotaGraph( 420, 200, rate, 0, image[4], FALSE, TRUE);Sleep(100);}
}
DxLib_End();
return 0;
}

ookami

Re:簡単なドラムソフトの問題

#10

投稿記事 by ookami » 15年前

たいへん失礼ながら
for(i=0;i<800;i++){ rate=1.1; }
とか、あてずっぽうなんじゃ...^^;

とりあえず、whileのところを、以下のように変更すると、どうなりますか?

while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE])
{
rate=1.0;
DrawRotaGraph( 230, 280, rate, 0, image[0], FALSE, TRUE);
DrawRotaGraph( 30, 200, rate, 0, image[1], FALSE, TRUE);
DrawRotaGraph( 270, 10, rate, 0, image[3], FALSE, TRUE);
DrawRotaGraph( 420, 200, rate, 0, image[4], FALSE, TRUE);
DrawString( 20 , 20 , "Use BGYUN. Play it." , White );
rate=1.1;
if(Key[KEY_INPUT_B] == 1){PlaySoundMem(snr, DX_PLAYTYPE_BACK);DrawRotaGraph( 230, 280, rate, 0, image[0], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_G] == 1){PlaySoundMem(chh, DX_PLAYTYPE_BACK);DrawRotaGraph( 30, 200, rate, 0, image[1], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_Y] == 1){PlaySoundMem(ohh, DX_PLAYTYPE_BACK);DrawRotaGraph( 30, 200, rate, 0, image[2], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_[/url] == 1){PlaySoundMem(crsh, DX_PLAYTYPE_BACK);DrawRotaGraph( 270, 10, rate, 0, image[3], FALSE, TRUE);Sleep(100);}
if(Key[KEY_INPUT_N] == 1){PlaySoundMem(bsdr, DX_PLAYTYPE_BACK);DrawRotaGraph( 420, 200, rate, 0, image[4], FALSE, TRUE);Sleep(100);}
ScreenFlip();
}

C

Re:簡単なドラムソフトの問題

#11

投稿記事 by C » 15年前

毎度回答ありがとうございます。ついにやりたい通りに動いてくれました!
大変勉強になりました。これから頑張って勉強していこうと思います。
また何かありましたら宜しくお願いします。ありがとうございました。

閉鎖

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