DXライブラリ 総合スレッド その15at GAMEDEV
DXライブラリ 総合スレッド その15 - 暇つぶし2ch1:名前は開発中のものです。
13/04/02 19:54:26.12 7ScEAe8S
Cを習得した程度のスキルでも、ゲームのグラフィックを比較的容易に描画する事のできる、
「DXライブラリ」に関するスレッドです。
DXライブラリに関するテクニックなどの情報交換などを行う事で、
多くのDXライブラリユーザのスキルの向上に役立てたら幸いです。

【公式】
URLリンク(homepage2.nifty.com)

【前スレ】
DXライブラリ 総合スレッド その14
スレリンク(gamedev板)


【過去スレ】
01 スレリンク(gamedev板)
02 スレリンク(gamedev板)
03 スレリンク(gamedev板)
04 スレリンク(gamedev板)
05 スレリンク(gamedev板)
06 スレリンク(gamedev板)
07 スレリンク(gamedev板)
08 スレリンク(gamedev板)
09 スレリンク(gamedev板)
10 スレリンク(gamedev板)
11 スレリンク(gamedev板)
12 スレリンク(gamedev板)
13 スレリンク(gamedev板)

【関連スレ】
C/C++ゲーム製作総合スレッド Part1
スレリンク(gamedev板)

2:名前は開発中のものです。
13/04/02 22:35:09.44 7eJ1IOua
>>1
スレ立て乙です

3:名前は開発中のものです。
13/04/03 14:00:47.17 B3u71YFV
>>3げっと

4:名前は開発中のものです。
13/04/05 03:56:08.42 FZ26RlS8
詳細を記載した方がいいのだろうけど、まずは簡単な回答を頂きたいだけですので
簡素な内容で質問することをお許しください。
DXのサウンド機能の話なんですが、
ステージ中、あるオブジェクトが登場した時だけBGMを変えたいんです。

で、そのオブジェクトが登場した時に元々のステージBGMをストップさせ、
新たに鳴らしたいBGMをplaybgmしているのですが
実行されると無音になってしまいます。
おかしいのはここからで、ステージの場面(scene)をそこから移動させると
鳴り出す、というか聴こえだすんです。(sceneを変えても、ストップさせない限り
BGM再生は生きてるじゃないですか)
しかも、その鳴らすファイルをSEというか短い音でplay関数に変えると問題無く鳴るんです。

もっと言えば、無音になるそのBGMのファイルを別のsceneのBGMとして利用すると
問題無く鳴ってくれます。
つまり、BGMのファイル(mp3)は悪くない。
プログラムソースに問題も無いと、確認出来たわけです。
なにが問題なのか、意味がわかりません。
同じsceneの中で、playbgmは複数利用出来ない
(playbgmを利用してBGMをバンバン変更したりするのは出来ない)
というDXの仕様なのでしょうか?
それともなんか原因が推測出来る方、いらっしゃいませんか?

5:名前は開発中のものです。
13/04/05 04:25:25.33 bPNmD62Y
>>4
PlayMusicとかPlaySoundFileとか使っているならPlaySoundMemのほうを使った方がいいと思うぞ。

6:4
13/04/05 04:47:39.17 cbWh4JId
>>5
レスありがとうございます。
紛らわしい書き方してすみません、
再生にはちゃんとPlaySoundMem(*** , DX_PLAYTYPE_LOOP)をつかっております。

>>4にて書いているplaybgm関数とはDX_PLAYTYPE_LOOPを引数としたもの、
play関数とはDX_PLAYTYPE_BACKを引数としたものになります。

なにか考えられる原因はありますか?

7:名前は開発中のものです。
13/04/05 05:03:31.29 vf3DftM6
今、一番関心のあるスレを発見
丁度、ボクもDXライブラリの門を叩いて
DXライブラリの門をくぐってゲーム開発に挑戦してみようとしているので
ちょくちょく利用させていただきます

URLリンク(blog.livedoor.jp)
ここでゲーム開発日記を書いていく予定です
以後、お見知りおきを

8:名前は開発中のものです。
13/04/05 05:26:37.75 bPNmD62Y
とりあえず>>4の書いてあることの解釈の確認だが
元々のステージBGMを「A」で新たに鳴らしたいBGMを「B」としよう。
>>4がやりたいことは「A→B→A」という風にしたいが
実際には「A→(無音)→B」という風になってしまうということでいい?

「int Handle」という変数があるとして
Handle = LoadSoundMem( A ) ;
Handle = LoadSoundMem( B ) ;
という風にAとBのBGMを共通の変数に代入をしていないか?

「int Handle1」「int Handle2」というような感じで別々の変数を用意しておいて
Handle1 = LoadSoundMem( A ) ;
Handle2 = LoadSoundMem( B ) ;
にしておかないとダメなのでは。

9:4
13/04/05 05:47:35.24 cbWh4JId
>>8
レスありがとうございます。
自分がやりたいことは「A→B→A」という風にしたいが
実際は「A→無音(B)→A」となってしまう、です。

この無音(B)の時にsceneが変わる(例えばゲームオーバーになり、ゲームオーバー画面に変わる)と、
実は実行されていましたといわんばかりにBの音が聞こえだします(もちろん、Bの実行を停止せずにいた場合)。
また、無音(B)の時ですが、完全な無音の時もあれば、
ブツブツとラジオの電波が悪い時みたいな音がしている場合もあります。


もちろん、ハンドルは別で用意しております。
別々のハンドルで用意したBGMを切り替えたい、だけなのですが。。

10:名前は開発中のものです。
13/04/05 06:08:27.12 bPNmD62Y
>>9
if( CheckSoundMem( Handle ) == 0 ){
PlaySoundMem( Handle , DX_PLAYTYPE_LOOP );
}
BGMが流れていないときだけBGMを流すという処理なんだけど
Bに対してこんな風にはしてある?

11:4
13/04/05 08:01:21.00 6yEsDHhh
>>10
BGMが流れていないときだけ流す?
えっと、BGMを流す関数(playbgm)を作っていて(その関数内にPlaySoundMem(***, DX_PLAYTYPE_LOOP)を入れてます)
vectorのコンテナに入れてある各サウンドファイル(順番がIDとなっています)を、
playbgm関数の引数により、ほしいBGMをハンドルの変数bgmに格納、
それをPlaySoundMem(bgm , DX_PLAYTYPE_LOOP)する。
更新中、今流れているID(BGM)と同じID(BGM)の引数の場合はなにもせず(そのBGM流し続ける)、
別のID(BGM)の引数で実行されたら、新しいIDのBGMを流す、といった関数です。

12:4
13/04/05 08:17:13.65 6yEsDHhh
Bの曲と、BGMを実行するという関数においては
別のsceneではなんの問題もなく流れてくれるので
問題ないと思うのです。

13:名前は開発中のものです。
13/04/05 08:26:35.54 XVR7WDIq
そういう仕様は聞いた事ないな。
DXライブラリじゃなくて単純にプログラムのバグな気がするけど……。

俺がやった事ない部分は「Aの曲を途中で止めて、次に再生するのはその途中から」という部分だが
そこを単純に「最初から再生する」にしてらどうなるのかな?

「途中から再生する」という処理をどうやってるのか気になるところだ。
シーンが変わるとBが再生されるというのは、最初からなのか途中からなのか、
Bが鳴らないと思ってるのは、どこかでボリュームをいじってて、それが0になってるだけじゃないのか、とか。

14:4
13/04/05 08:42:09.57 mB5IBgio
ああ、すみません、Aの曲に戻る時はまた最初からになります。
途中で、といった処理はまったくしておりません。

Aの曲をストップするというのはただ単に終了させることです。
で、Bの曲を頭から流し、Bの曲を終わらせたら
またAの曲を頭から流す、というだけです。

今、簡単なプログラムにして
現画面で、上を押したらAの曲、下を押したらBの曲が流れる
といった感じのプログラムを作りましたが
やはり、Bの曲が流れません。ただ、下を押したらブツブツとおかしな音はしています
(もしかしたらBno曲の出だしが連続再生されているのかもしれないけど、再生処理はAの曲と一緒だからそれもおかしい)。

シーンが変わるとBが再生されるというのは
確認しましたが、頭からでした。

15:名前は開発中のものです。
13/04/05 08:50:45.66 /uW22nC0
Bの曲が流れるはずのところ
ProcessMessageはちゃんと毎フレーム呼んでる?
まぁ、ゲームオーバーになりうる状況とのことなので多分呼んでるんだろうけど
一応確認

16:4
13/04/05 09:30:50.57 mB5IBgio
もちろん、呼んでます。


追加した二曲目のBGMはどのファイルでもブツブツと音だけしてます。
まるで、頑張って鳴らそうとしてるんです、みたいに。
これはどういう現象なんでしょうか?

で、sceneが移動したら、そのブツブツが止まって
頭から流れるんです。

17:名前は開発中のものです。
13/04/05 09:51:06.78 XVR7WDIq
そこまでおかしいというのなら、

Aの曲を数秒流してから止め、Bの曲を数秒流してから止め、Aの曲を流す。
という”だけ”のプログラムを組んでやってみたらどうかな。

シーンとかそんなの全く関係ない、新しいプログラムで。
それでもおかしいというのならそのプログラムを晒すといい。

18:名前は開発中のものです。
13/04/05 09:54:31.52 XVR7WDIq
ブツブツと鳴るとう現象から、Bの曲を「毎フレーム先頭から流しなおそうとしている」んじゃないかという気がした。

ひょっとしてBの再生命令、最初の一回だけってなってないんじゃない? 何度も実行してない?

19:名前は開発中のものです。
13/04/05 11:26:17.36 XVR7WDIq
そういえば、シーンが変わると鳴り出すってのも、これが原因なら納得だな。

20:名前は開発中のものです。
13/04/05 12:21:13.09 A+ukN4KC
そういえば自分もBGM再生でミスしたことがあるなあ。

コンストラクタで再生、デストラクタに停止するように書いてたんだけど、
Stateパターンを使ってたためか、タイミング的に A構築→B構築→A消滅 になっちゃって、
クラスB内で再生した曲が、その直後にA内で停止されるというお馬鹿なミスだったw


>>18
あ、確かにそれっぽい

21:名前は開発中のものです。
13/04/05 13:55:20.80 S+xkJq8V
Bの曲を別のものにしたら、きちんと鳴る? 例えば、AとBを取り替えてみるとか。

22:4
13/04/05 14:58:18.71 akoAyRai
>>18>>19
たぶんそうだとは思うのですが、、、ただ、AもBも同じ関数を使って鳴らしていますし、
両方ともUpdate関数の中に書いてます。

極端な話、
Update関数内にて、

int a =0;

if(上が押されたら){
a = 1;}
if(下が押されたら){
a = 0;
}

if(a==0){
再生関数(AのBGM,ループ)
}else if(a==1){
再生関数(BのBGM,ループ)
}

で、なんの問題も無しにBGMは切り替わり、鳴り続けますよね?
なのに、BのBGMだけ「毎フレーム先頭から流しなおそうとしている」になるのが納得いきません。

>>21
それぞれを別の曲にしても、B(主では無い方のBGM)の方に設定したBGMは
BGMは鳴らず、ぶつぶつ「毎フレーム先頭から流しなおそうとしている」状態になります。

23:名前は開発中のものです。
13/04/05 15:17:04.07 cvGYmrrr
Update関数ってことは
a=1の時、毎フレームif(a=1)って事じゃないのか
その場合、再生中かどうかフラグ用意して管理しておかないと



っていう妄想でした

24:4
13/04/05 15:30:40.36 akoAyRai
>>23
あ、もちろん再生関数というのは>>11に書いてありますが
自分で作ったものであり、
同じ曲を再生中の場合はスルーする、という内容を含めた
定義をしております。

25:名前は開発中のものです。
13/04/05 15:37:15.59 rssi5Jdr
XVR7WDIqだけど。

「二重再生しないようにしてる」という言葉を信じるなら、俺の予測は外れてる事になるけど
22の例を見ると、ほんとにちゃんとプログラムできてるのか不安になる。

そのサンプルじゃ、上を押しっぱなしにしない限りずっとAが鳴りっぱなしじゃん。

26:名前は開発中のものです。
13/04/05 15:37:50.15 A+ukN4KC
再生関数の中に、ブレークポイントでも入れてみたら?

27:名前は開発中のものです。
13/04/05 15:43:49.93 cvGYmrrr
>>24
あれ、バグってる場所自分で特定できてるじゃん

28:名前は開発中のものです。
13/04/05 16:01:22.20 j/RBp3Ih
int a =0; が関数内でローカル変数として定義されていると
毎回初期化されてしまうな。

29:名前は開発中のものです。
13/04/05 16:08:38.77 cvGYmrrr
>>4
>プログラムソースに問題も無いと、確認出来たわけです。

俺もたまにやるけど、ヒューマンエラーが一番怖い。
「自分は正しい、間違っているわけがない、他に原因があるはず」
しかしそれが間違いを生んでいる主な原因だったりする。
これは現実世界でも多々ある事。
例えば最近問題になっている歴史問題。記録はどの国家も例外無く正確ではない、捏造が多々含まれている。
更に化学においても、「人体に影響は無い」というのは全て嘘だ。体に良いものですら、良い影響と悪い影響がある。ここから「体に良いもののほうが体に悪い」という論理的な矛盾が生まれる。
何が言いたいかというと

っていう妄想でした

30:4
13/04/05 16:09:31.12 akoAyRai
>>25 >>28
あくまで例として書いてしまったがために
突っ込み所満載ですみません。
お二人のご指摘は本来自分で書いてるプログラムではバッチリなはずです。
変数aについては突っ込まれるかなと思ったんですが
例のつもりだったので強行して書き込んでしまいました。

しかし、皆さんが親身になってくださるので
ソースをさらしてみたいと思います。
どうか、原因を突き止めて頂きたいです。
しばし、お待ちを。

31:4
13/04/05 16:10:28.50 akoAyRai
>>29
その通りですね、なので晒してみますので
ご確認して頂きたいです。しばしおまちを。

32:4
13/04/05 16:45:50.42 hmFS+1t8
すみません、行数があり、書き込みできませんでしたのでソースを書いたTXTをうpします。
あと、実際に鳴らしているsceneクラスは継承+ポリモフィズムを使っており、
余計なものまで解説せねばならないことになりますのでその辺は割愛させて頂きました。
URLリンク(ux.getuploader.com)

出来たら、このサウンドクラスを使って、二つのBGMを切り替えるプログラムを作ってみてください。
そちらでうまく出来たら、私の実行のさせ方が間違っているということですね。。

33:名前は開発中のものです。
13/04/05 17:58:12.04 CEwZ/NG5
mp3のサイズがでかすぎてメモリに読み切れてないとかじゃないよね
いっぺんSetCreateSoundDataTypeで再生形式切り替えてみたらええんでない

34:名前は開発中のものです。
13/04/05 18:00:16.17 bPNmD62Y
SoundBox* sound;
sound->getInstance()->loadFiles();
while( 1 ){
  if( ProcessMessage() != 0 ){ // メッセージ処理
    break;//ウィンドウの×ボタンが押されたらループを抜ける
  }
  ClearDrawScreen(); // 画面を消す
  if( CheckHitKey( KEY_INPUT_UP ) ){
    sound->getInstance()->playbgm( 0 );
  }
  if( CheckHitKey( KEY_INPUT_DOWN ) ){
    sound->getInstance()->playbgm( 1 );
  }
  ScreenFlip(); //裏画面を表画面に反映
}

これで実行してみたが問題はなかった。

35:名前は開発中のものです。
13/04/05 18:10:03.77 bPNmD62Y
更新関数

SoundBox::getInstance()->playbgm(1);//Abgmスタート

if(*****){
a=1;
}

if(a=1){
SoundBox::getInstance()->playbgm(2);//Bbgmスタート


のところなんだが

更新関数

a=-1;
if(*****){
a=0;
}else if(-----){
a=1;
}

if(a=0){
SoundBox::getInstance()->playbgm(0);//Abgmスタート
}else if(a=1){
SoundBox::getInstance()->playbgm(1);//Bbgmスタート
}

普通こんな感じじゃない。

36:4
13/04/05 18:17:50.69 hmFS+1t8
>>33
それがデカくないんですよ、Aは205KB、Bは180KBです。

>>34>>35
うまく流すことが出来たわけですね??
ちょっと>>34を使わせてもらい、試してみます!

37:4
13/04/05 18:28:45.68 hmFS+1t8
皆さんにも体験してもらうソースがわかりました!!
3つのBGMを読み込ませ、>>34に付け足した感じですが


while( 1 ){
  if( ProcessMessage() != 0 ){ // メッセージ処理
    break;//ウィンドウの×ボタンが押されたらループを抜ける
  }

    SoundBox::getInstance()->playbgm(0);

if( CheckHitKey( KEY_INPUT_UP ) ){
SoundBox::getInstance()->playbgm(1);
}
if( CheckHitKey( KEY_INPUT_DOWN ) ){
SoundBox::getInstance()->playbgm(3);
}
  }
  ScreenFlip(); //裏画面を表画面に反映
}


これで実行してみてください!
要は、最初に別のBGMを流していて、
その上で、「上」か「下」かで二つのBGMを切り替えて鳴らしてください

これで、同じ現象がおきるはずです!

38:4
13/04/05 18:30:36.95 hmFS+1t8
誤字です。
BGMを3つ読み込ませといてください。

while( 1 ){
  if( ProcessMessage() != 0 ){ // メッセージ処理
    break;//ウィンドウの×ボタンが押されたらループを抜ける
  }

    SoundBox::getInstance()->playbgm(0); //1曲目

if( CheckHitKey( KEY_INPUT_UP ) ){
SoundBox::getInstance()->playbgm(1); //2曲目
}
if( CheckHitKey( KEY_INPUT_DOWN ) ){
SoundBox::getInstance()->playbgm(2); //3曲目
}
  }
  ScreenFlip(); //裏画面を表画面に反映
}

39:名前は開発中のものです。
13/04/05 19:41:33.84 rssi5Jdr
あん?
それだと、キーを例えば下にすると
まず一曲目を流そうとして、
次に三曲目を流そうとして
また次のループで一曲目を流そうとして、
さらに三曲目を流そうとしたりするんじゃ。


最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch