ウィンドウを閉じた際に

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

ウィンドウを閉じた際に

#1

投稿記事 by 深黒 » 15年前

DXライブラリで、
作成してるゲームに効果音をつけたのですが、
ウィンドウを閉じた際に、次に鳴る筈だったらしい効果音が鳴るのですが、
どうしたらこれは防げるでしょうか?

↓簡略化したプログラム
#include "DxLib.h"
int sound();

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE); // ウインドウモードに変更]
SetUseMenuFlag(-1);
enum { MenuID_File = 1000, MenuID_NewFile, MenuID_Open, MenuID_Exit, MenuID_Help, MenuID_About };
AddMenuItem_Name(NULL, "A");
AddMenuItem_Name("A", "B");
SetGraphMode(800,600,32);
if( DxLib_Init()==-1) return -1;// DXライブラリ初期化処理 エラーが起きたら終了

while(ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0){
sound();
その他いろいろ処理
}
return 0;
}

int sound(){
int oto=LoadSoundMem( "効果音.wav" ) ;
PlaySoundMem(oto,DX_PLAYTYPE_BACK) ;
その他いろいろ処理
return 0;
}

ookami

Re:ウィンドウを閉じた際に

#2

投稿記事 by ookami » 15年前

「簡略化したプログラム」は、特に問題なさそうに見えました。
# LoadSoundMemは ループの外でやるのがいいとは思いますが。

> ウィンドウを閉じた際に、次に鳴る筈だったらしい効果音が鳴る
というのをもう少し詳しくお願いします。
「ウィンドウを閉じる」というのは、
 ・×で閉じた場合
 ・Alt+F4で終了した場合
 ・ESCで終了した場合
のどれでしょうか。また、「次に鳴る筈だったらしい効果音が鳴る」というのは、
 ・一瞬(0.2秒くらい?)鳴ってすぐ鳴り止む
 ・wavファイルの終わりまで鳴る
のどちらでしょうか。

深黒

Re:ウィンドウを閉じた際に

#3

投稿記事 by 深黒 » 15年前

説明足らずですみません…。
私の言う「ウィンドウを閉じる」は、右上の×で閉じた場合です。

「次に鳴る筈だったらしい効果音が鳴る」の方は、
・wavファイルの終わりまで鳴る
です。

らしい、と言っているのは、
ウィンドウを閉じた際に、for文等で音が連続して鳴るように仕組んだ部分が影響してか、ウィンドウが消えているのに音が連続して鳴ったからです。

ookami

Re:ウィンドウを閉じた際に

#4

投稿記事 by ookami » 15年前

すると、確かに「その他いろいろ処理」「音が連続して鳴るように仕組んだ部分」が怪しい気がしますねぇ。

DxLib_Endが明示されていませんが、呼ばなくてもちゃんとDXライブラリ側で終了してくれるはずだから、その線は薄いハズ...

「×」ボタンで閉じる前後で、
タスクマネージャの「プロセス」タブで、
[プロジェクト名].exe
は表示されていますか?
ウィンドウが閉じているのにタスクマネージャに残っているようですと、
実は終了していない、ということになります。

あるいは、ソースをそのままアップしてもらったほうが早いかもですね。

深黒

Re:ウィンドウを閉じた際に

#5

投稿記事 by 深黒 » 15年前

プロセスは、音が鳴り終わったら消えてますね。
「音が連続して鳴るように仕組んだ部分」はただのfor文で作っているから、ESCキーで終われないってのは分かるんですが・・・

ソースは出来れば必要以上の部分は見せたくないですね・・・ 画像

fatens

Re:ウィンドウを閉じた際に

#6

投稿記事 by fatens » 15年前

本家のリファレンスによると、DxLib_End 関数は、

>DXライブラリの使用を終了する関数です。
>DXライブラリを使用しているソフトはすべてソフトを終了させる前にこの関数を呼ぶ必要があります。
>同時に、DXライブラリはソフトのウインドウの制御もしているので、
この関数を呼び出した後はなるべくすぐにプログラムを終了させなければなりません。

とのことなので、WinMain 関数のreturn 0の前にDxLib_end 関数を呼び出してみてください。

深黒

Re:ウィンドウを閉じた際に

#7

投稿記事 by 深黒 » 15年前

一応入ってはいるのですが…
もう少し書き加えたのを出します

#include "DxLib.h"
int draw(int);
int p1hand[16];
int p2hand[16];
int i=0;

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
ChangeWindowMode(TRUE); // ウインドウモードに変更]
SetUseMenuFlag(-1);
enum { MenuID_File = 1000, MenuID_NewFile, MenuID_Open, MenuID_Exit, MenuID_Help, MenuID_About };
AddMenuItem_Name(NULL, "A");
AddMenuItem_Name("A", "B");
SetGraphMode(800,600,32);
if( DxLib_Init()==-1) return -1;// DXライブラリ初期化処理 エラーが起きたら終了
for(i=0;i<=4;i++){
p1hand[draw(1)]++;
p2hand[draw(2)]++;
}
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){
p1hand[draw(1)]++;
色々処理
}
DxLib_End() ; // DXライブラリ使用の終了処理
return 0;
}

int draw(int hands){
int card=GetRand(120);
WaitTimer(300) ;
int hiki=LoadSoundMem( "ドロー.wav" ) ;
PlaySoundMem(hiki,DX_PLAYTYPE_BACK) ;

GetRandの値によっては値の取得しなおしの処理

return card;
}

前のプロトタイプ関数soundが、今回のdrawにあたります。
前の効果音.wavが、今回のドロー.wavです

s-rush

Re:ウィンドウを閉じた際に

#8

投稿記事 by s-rush » 15年前

私も似たような現象が起こっています。

私の場合はバックグラウンドでBGMをループ再生しているのですが(音楽形式:wav)、
右上の×で終了するとウインドウが消えてからも音楽が鳴り続けています。
タスクマネージャで確認すると「プロジェクト名.exe」が残ったままなので
プログラムそのものが終了してなさそうです。

どうも×で終了しても現在実行中の関数(DXライブラリにある関数だけ?)は
終了されていないような感じがします。

効果音ということなので、私のようにループ再生はおそらくしていないと思いますが、
PlaySoundMem関数が実行中
 ↓
×で終了
 ↓
効果音が鳴って関数終了
のような現象が起こっているのではないでしょうか?


ちなみに、私は原因が分からないのでEscで終了してもらうようにして、
問題そのものは放置プレーを決め込んでますw

時間があれば解決策を探したいのですが^^;

Justy

Re:ウィンドウを閉じた際に

#9

投稿記事 by Justy » 15年前

 ×を押しても終了できないのは(×を無効にしている場合はともかく)大抵 WinMain関数を抜けていないからで、
今回のケースでは多分 ProcessMessage関数まで到達できていないか、到達していても処理に負荷がかかっていて
内部の終了判定まで到達出来ていないかのどちらかでしょう。


>音が連続して鳴るように仕組んだ部分」はただのfor文で作っているから、
>ESCキーで終われないってのは分かるんですが・
 上の2つのコードで ESCで終了できないのであれば×でも終了できない思うのですが、そもそもどうして ESCで終了できないのでしょうか?
 コードからはそれが読み取れないです。

深黒

Re:ウィンドウを閉じた際に

#10

投稿記事 by 深黒 » 15年前

ESCキーで終われないと言ったのは、for文ではCheckHitKey( KEY_INPUT_ESCAPE ) == 0が無いせいで、繰り返してしまっていると考えたので・・・

軽々しく分かってるなんて言ってはいけなかったかもしれないです・・・

Justy

Re:ウィンドウを閉じた際に

#11

投稿記事 by Justy » 15年前

> for文
 その連続で鳴らしているという for文はどうなっているのでしょうか。
 そのあたりのコードを提示できますか?
 又構造的に No:55810の draw関数のように毎フレーム呼ばれているのでしょうか?



# 再現できる最小限のプロジェクトとか作れないですかね?

深黒

Re:ウィンドウを閉じた際に

#12

投稿記事 by 深黒 » 15年前

こんな感じになると思います

#include "DxLib.h"
int i=0;
int White=GetColor(255,255,255);
int draw();
int victory();

int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){
ChangeWindowMode(TRUE);
if( DxLib_Init() == -1 ) return -1;
SetGraphMode(800,600,32);
int j;
for(j=0;j<=4;j++){
draw();
draw();
}

while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){
i++;
draw();
DrawFormatString(1,i*24,White,"自分ターン:残りデッキ%d枚",10-i);
int mouse_pos_X=-1;
int mouse_pos_Y=-1;
while( ProcessMessage() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ){
if(( GetMouseInput()&MOUSE_INPUT_LEFT)!=0)// 左クリックされたら
GetMousePoint(&mouse_pos_X,&mouse_pos_Y);// マウスの座標を取得
if(mouse_pos_Y>=0&&mouse_pos_Y<600&&mouse_pos_X >= 0 &&mouse_pos_X<= 800){
DrawString(250,i*24,"ターン交代",White);
break;
}
}
WaitTimer(150);
i++;
draw();
DrawFormatString(1,i*24,White,"相手ターン:残りデッキ%d枚",10-i);
DrawString(250,i*24,"ターン交代",White);
}
DxLib_End() ;
return 0 ;
}
int draw(){
if(i>10){
victory();
return 0;
}
WaitTimer(300) ;
int hiki=LoadSoundMem( "test.wav" ) ;
PlaySoundMem(hiki,DX_PLAYTYPE_BACK) ;
return 0;
}
int victory(){
DrawString(300,300,"デッキ切れです",White);
WaitTimer(2000);
DxLib_End() ; // DXライブラリ使用の終了処理
return 0;
}

始めの連続の部分でウィンドウを閉じると、for文が音が鳴り終わるまで終わらないです。
while中で閉じると、消えた後ぐらいに一回効果音が鳴ります

深黒

Re:ウィンドウを閉じた際に

#13

投稿記事 by 深黒 » 15年前

画面をクリックしたらデッキからカードを引く(ドロー)
デッキ切れで終了です

Justy

Re:ウィンドウを閉じた際に

#14

投稿記事 by Justy » 15年前

>始めの連続の部分でウィンドウを閉じると、for文が音が鳴り終わるまで終わらないです
 なるほど。
 この構造では鳴り終わるまで終らないですね。
 ウインドウを閉じたことを検出するのが ProcessMessage関数ですから、これを随時呼んで
終了を検出し、速やかに WinMain関数を抜ければいいかと。
[color=#d0d0ff" face="monospace]
for(j=0;ProcessMessage() == 0 && j<=4;j++)
[/color]

とか。

(ループ中の draw()を2回から1回にし、その分ループの数を減らすとより速やかに終了できるでしょう)

深黒

Re:ウィンドウを閉じた際に

#15

投稿記事 by 深黒 » 15年前

for文にそんな使い方があったんですか!?
for文の問題は返信のおかげで解決できました。

while文の方は、各draw();の後に、各プレイヤーがカードを使用する等の処理が入る為、draw()を減らすということは出来ないです・・・。

閉鎖

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