トップページ > 記事閲覧
画面を停止させない方法、東方のHP描画方法、他
名前:にこよう 日時: 2019/07/21 16:11

こんにちは、お世話になっております いくつか詰まってしまったので質問させていただきますm(__)m 複数の質問すみません Dxライブラリの関数で処理を一時停止しないようにする関数はありますか?(例えばウィンドウを動かしている最中など) また、現在東方シューティングのような円形のゲージを描画する関数を使っているのですが、 敵ごとにそれぞれ適したドーナツ型の画像を用意しなければなりません 下の関数の拡大描画か、ドーナツ型の画像を生成するなどのことをして、すべてのサイズに対応する方法があれば教えていただけると嬉しいです DrawCircleGauge((int)X, (int)Y, 100.0, img_circle[5], percent); // 白のゲージを描画 DrawCircleAA(X, Y, 199, quality, color, FALSE); // 指定色の外枠を描画 DrawCircleAA(X, Y, 191, quality, color, FALSE); // 指定色の中枠を描画 DrawBox(....FALSE);(淵だけの四角) を発光したような(徐々にぼけていくような)描画をしたいのですが、可能でしょうか? もし可能でしたら教えていただけると嬉しいです また、おそらくこちらが原因でDXライブラリは関係ないと思いますが、よくわからないエラーが発生したので一応報告させていただきます 下のコードの※2の部分で箱を点滅描画したかったのですが、点滅されず、(おそらくα160?)の状態で描画されていました 色々やってみたのですが(クリーン、再起動等)結果は変わらず、int(cos(radian_count)*30.0f)も正しい値を計算していました(printfDxにて) そしてなんとなく※1の部分の180の後にint(cos(radian_count)*30.0f)を付け加えてリリースモードに変更してF5を押すと正常に動作しました その後再びデバッグに戻してF5で正常起動、※1を元の状態(下のコード)に戻しても正常に動作しました void SelectBox::draw() const { //DrawBox(def_edge_x, def_edge_y_up, draw_size_x - def_edge_x, draw_size_y - def_edge_y_down, col.black, FALSE); // 全体の囲い SetDrawBlendMode(DX_BLENDMODE_ALPHA, 180); // 描画モードを半透明に(※1ここ DrawBox(draw_size_x - def_edge_x - def_bar_x, def_edge_y_up, draw_size_x - def_edge_x, draw_size_y - def_edge_y_down, col.p_gray, TRUE); // スクロールバーの囲い DrawBox(draw_size_x - def_edge_x - def_bar_x, ber_y, draw_size_x - def_edge_x, ber_y + ber_length, col.darkgray, TRUE); // スクロールバー SetDrawBlendMode(DX_BLENDMODE_ALPHA, 160); // 描画モードを半透明に SetDrawArea(def_edge_x, def_edge_y_up, draw_size_x - def_edge_x, draw_size_y - def_edge_y_down); // 描画範囲を設定する int dy = def_edge_y_up; for (int i = 0; i < select_max; i++) { if (select_num == i) { SetDrawBlendMode(DX_BLENDMODE_ALPHA, 180 + int(cos(radian_count)*30.0f)); // 描画モードを半透明に DrawBox(def_edge_x, dy + add_y, draw_size_x - def_edge_x - def_bar_space - def_bar_x, dy + def_box_size_y + add_y, col.white, TRUE); // 選択状態のハコ(※2ここ SetDrawBlendMode(DX_BLENDMODE_ALPHA, 160); // 描画モードを半透明に } else DrawBox(def_edge_x, dy + add_y, draw_size_x - def_edge_x - def_bar_space - def_bar_x, dy + def_box_size_y + add_y, col.p_gray, TRUE); // ハコ if (select_num == i) DrawBox(def_edge_x, dy + add_y, draw_size_x - def_edge_x - def_bar_space - def_bar_x, dy + def_box_size_y + add_y, col.white, FALSE); // 選択状態のハコ else DrawBox(def_edge_x, dy + add_y, draw_size_x - def_edge_x - def_bar_space - def_bar_x, dy + def_box_size_y + add_y, col.p_gray, FALSE); // ハコ dy += def_box_size_y + def_box_space; } SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0); // 描画モードを通常に SetDrawAreaFull(); // 描画範囲を戻す }
メンテ

Page: 1 |

Re: 画面を停止させない方法、東方のHP描画方法、他 ( No.1 )
名前:管理人 日時:2019/07/20 20:53

> Dxライブラリの関数で処理を一時停止しないようにする関数はありますか?(例えばウィンドウを動かしている最中など) すみません、ありません > また、現在東方シューティングのような円形のゲージを描画する関数を使っているのですが、 > 敵ごとにそれぞれ適したドーナツ型の画像を用意しなければなりません > 下の関数の拡大描画か、ドーナツ型の画像を生成するなどのことをして、すべてのサイズに対応する方法があれば教えていただけると嬉しいです DrawCircleGauge に拡大率の引数を追加しましたので、よろしければ 引数を追加したこちらのバージョンをダウンロードしてください m(_ _)m https://dxlib.xsrv.jp/temp/DxLibVCTest.zip // Windows版 VisualC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCCTest.zip // Windows版 BorlandC++ 用 https://dxlib.xsrv.jp/temp/DxLibBCC2Test.zip // Windows版 C++ Builder 10.2 用 https://dxlib.xsrv.jp/temp/DxLibGCC_MinGWTest.zip // Windows版 MinGW 用 https://dxlib.xsrv.jp/temp/DxLibDotNet.zip // Windows版 .NET用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM.zip // Android版 ARM用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_ARM64.zip // Android版 ARM64用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x86.zip // Android版 x86用 https://dxlib.xsrv.jp/temp/DxLibAndroidTest_x64.zip // Android版 x64用 https://dxlib.xsrv.jp/temp/DxLibiOSTest.zip // iOS版 https://dxlib.xsrv.jp/temp/DxLibMakeTest.zip // ソース (中身を既存のライブラリのファイルに上書きして『リビルド』をして下さい) // 円グラフ的な描画を行う int DrawCircleGauge( int CenterX, int CenterY, double Percent, int GrHandle, double StartPercent, double Scale ) ; 追加した第6引数の Scale が拡大率です、2.0 にすると 2倍拡大で表示されます よろしければお試しください > DrawBox(....FALSE);(淵だけの四角) > を発光したような(徐々にぼけていくような)描画をしたいのですが、可能でしょうか? > もし可能でしたら教えていただけると嬉しいです GraphFilterBlt を使ってガウシアンフィルターでぼかせば実現できそうです ガウシアンフィルターで DrawBox で描画した四角形をぼかしていくプログラムを組んでみましたので、 よろしければご覧になってみてください #include "DxLib.h" int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { int Index ; int WorkScreen[ 2 ] ; // ウインドウモードで起動 ChangeWindowMode( TRUE ) ; // DXライブラリの初期化 if( DxLib_Init() < 0 ) return -1 ; // ぼかし作業用のスクリーンを作成 SetDrawValidFloatTypeGraphCreateFlag( TRUE ) ; WorkScreen[ 0 ] = MakeScreen( 256, 256, FALSE ) ; WorkScreen[ 1 ] = MakeScreen( 256, 256, FALSE ) ; // 作業用スクリーンの中心に四角形を描画 SetDrawScreen( WorkScreen[ 0 ] ) ; ClearDrawScreen() ; DrawBox( 128 - 48, 128 - 48, 128 + 48, 128 + 48, GetColor( 255,255,255 ), TRUE ) ; // 有効な作業用スクリーンの番号を初期化 Index = 0 ; // 描画先を裏画面にする SetDrawScreen( DX_SCREEN_BACK ) ; // メインループ while( ProcessMessage() == 0 ) { // 画面のクリア ClearDrawScreen() ; // ガウシアンフィルタで画像をぼかす( 出力結果は有効ではない作業用スクリーン ) GraphFilterBlt( WorkScreen[ Index ], WorkScreen[ Index == 0 ? 1 : 0 ], DX_GRAPH_FILTER_GAUSS, 8, 200 ) ; // 有効な作業用スクリーンを変更 Index = Index == 0 ? 1 : 0 ; // 画面にぼかした画像を加算描画する SetDrawBlendMode( DX_BLENDMODE_ADD, 255 ) ; DrawGraph( 0, 0, WorkScreen[ Index ], FALSE ) ; // 裏画面の内容を表画面に反映 ScreenFlip() ; } // DXライブラリの後始末 DxLib_End() ; // ソフトの終了 return 0 ; } > また、おそらくこちらが原因でDXライブラリは関係ないと思いますが、よくわからないエラーが発生したので一応報告させていただきます すみません、載せていただいた情報だけでは何とも言えません
メンテ
Re: 画面を停止させない方法、東方のHP描画方法、他 ( No.2 )
名前:95 日時:2019/07/20 23:49

タイトルの 東方のHP描画方法 とはどの質問項目が該当するのでしょうか?円形ゲージの件? また最後に書いてあるコードですが、変数が大量にあり何も定義などが書いていないため このままではビルドすることすらできず、ほとんどの人は試そうとも思わないと思います。 文法だけさっと確認してみて、というのであれば別ですが、普通は動かして確認した方がいいでしょう。 というわけで適当な数値を設定して動かしてみましたが、特に問題は無さそうです。 > この関数で描画することはできませんでした これは、選択行に何も表示されなかったということですか?コードを見るとwhiteかgrayで 必ず描画されますしα=0には絶対にならないので、考えられるのは画面外になってしまっているか DrawArea設定が狭いか他の領域を指しているということくらいしか思いつきませんが、 その行だけ外れるというのはちょっと考えにくいですね。 一時停止させない方法はスレッドを使うしかありませんが、これは今まで管理人さんが何度もコメント されているように完全に無保証です。私は動画撮影時のみスレッド動作させて『見栄えの良い動画』を録画 するためだけの機能として実装していますが、実際、開始後すぐに落ちることもしばしばです。 他の人に配るのであれば、まずやめた方がいいです。
メンテ
Re: 管理人様 ( No.3 )
名前:にこよう 日時:2019/07/21 16:09

ご返信ありがとうございます >すみません、ありません 分かりました 画面停止を検知して何とかするなど別の方法を考えようと思います >DrawCircleGauge に拡大率の引数を追加しましたので、よろしければ >引数を追加したこちらのバージョンをダウンロードしてください m(_ _)m ありがとうございます、助かります >GraphFilterBlt を使ってガウシアンフィルターでぼかせば実現できそうです ガウシアンフィルターで DrawBox で描画した四角形をぼかしていくプログラムを組んでみましたので、 よろしければご覧になってみてください すみません、有難うございます 試してみます >すみません、載せていただいた情報だけでは何とも言えません そうですよね... ただ、量を考えるとどうしても全体を乗せるわけにもいかず、再現することも叶わなかったので もしかしたら役に立つかもしれないという考えでのせました
メンテ
Re: 95様 ( No.4 )
名前:にこよう 日時:2019/07/21 16:14

ご返信ありがとうございます >タイトルの 東方のHP描画方法 とはどの質問項目が該当するのでしょうか?円形ゲージの件? そうです(ドーナツ型の画像の質問です) 完全に言葉足らずでした すみません >また最後に書いてあるコードですが、変数が大量にあり何も定義などが書いていないため 似たようなことを数字を使った小さいプロジェクトで再現できなかったため、原因が一切推測できず 発生した時のコードをそのまま載せたほうが良いかと思い、そのまま載せました >これは、選択行に何も表示されなかったということですか?コードを見るとwhiteかgrayで 必ず描画されますしα=0には絶対にならないので 書き方を間違えていました 正しくは、点滅されず、(おそらくα160?)の状態で描画されていました printfDxでその時のint(int(cos(radian_count)*30.0f))が正常に-30〜30をうろうろしていたので、 おそらくDxライブラリの関数の方には正しい値が渡されていたと思われます >一時停止させない方法はスレッドを使うしかありませんが、これは今まで管理人さんが何度もコメント されているように完全に無保証です。 すみません、そのスレッドを知りませんでした そのコメントを知らなかったので助かります 画面停止を検知して何とかするなど別の方法を考えようと思います
メンテ
Re: 画面を停止させない方法、東方のHP描画方法、他 ( No.5 )
名前:にこよう 日時:2019/07/23 21:44

ドーナツ型のゲージ描画関数と、光る箱の描画関数がほぼ完成したのでここに乗せておきます サンプルコードをありがとうございました // 円状のゲージを描画する void DrawCircleMeter(float X, float Y, float now, float max, float size, int quality, int Color) { int color; if (Color == 1) color = col.red; // 1 の場合は赤にする else color = Color; // それ以外なら指定色 if (quality <= 8) quality = 8; // 品質を下げすぎないようにする if (quality >= 64) quality = 64; // 品質を上げすぎないようにする quality = quality * 4; if (max < now) ERR("最大値を超えています"); if (max < 0.0) ERR("maxが小さすぎます"); float percent = now / max; // %を求める percent = percent * 100.0f; if (percent <= 0) percent = 0; // %が 0 以下にならないようにする if (percent >= 100) percent = 100; // %が 100 以上にならないようにする percent = 100 - percent; // %が 100 の時に最大で描画されるようにする DrawCircleGauge((int)X, (int)Y, 100.0, img_circle[5], percent, size); // 白のゲージを描画 DrawCircleAA(X, Y, 199.f*size, quality, color, FALSE); // 指定色の外枠を描画 DrawCircleAA(X, Y, 191.f*size, quality, color, FALSE); // 指定色の中枠を描画 } // グロー効果のある箱を描画する int DrawGlowBox(int x1, int y1, int x2, int y2, unsigned int color, int FillFlag) { int WorkScreen[2]; int box_size_x = x2 - x1; // 箱の大きさを求める int box_size_y = y2 - y1; // 箱の大きさを求める int img_x1 = x1 - box_size_x / 2; // 完成した画像の描画点を求める int img_y1 = y1 - box_size_y / 2; int img_x2 = x2 + box_size_x / 2; int img_y2 = y2 + box_size_y / 2; // ぼかし作業用のスクリーンを作成 SetDrawValidFloatTypeGraphCreateFlag(TRUE); WorkScreen[0] = MakeScreen(box_size_x * 2, box_size_y * 2, FALSE); WorkScreen[1] = MakeScreen(box_size_x * 2, box_size_y * 2, FALSE); // 作業用スクリーンの中心に四角形を描画 SetDrawScreen(WorkScreen[0]); ClearDrawScreen(); DrawBox(box_size_x / 2, box_size_y / 2, box_size_x + box_size_x / 2, box_size_y + box_size_y / 2, color, FillFlag); // 描画先を裏画面にする SetDrawScreen(game_screen_handle); // 描画先を仮想画面に変更 // ガウシアンフィルタで画像をぼかす( 出力結果は有効ではない作業用スクリーン ) GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); GraphFilterBlt(WorkScreen[1], WorkScreen[0], DX_GRAPH_FILTER_GAUSS, 8, 200); GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); // 画面にぼかした画像を加算描画する int mode, parameter; GetDrawBlendMode(&mode, &parameter); SetDrawBlendMode(DX_BLENDMODE_ADD, 255); DrawGraph(img_x1, img_y1, WorkScreen[0], FALSE); SetDrawBlendMode(mode, parameter); return 0; } ただ一点だけ疑問があり、この変数の引数は何を表しているのでしょうか? GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); 3度読んで調整していますが、もう少し良いやり方があるのではないかと思っていますm(__)m
メンテ
Re: 画面を停止させない方法、東方のHP描画方法、他 ( No.6 )
名前:管理人 日時:2019/07/24 01:04

すみません、No.1のサンプルでは MakeScreen で作成したグラフィックハンドルを DeleteGraph で削除していませんが、グラフィックハンドルは不要になったら DeleteGraph で 削除しないとVRAMがどんどん消費してメモリ不足になってしまいます なので、DrawGlowBox から抜ける前に DeleteGraph で削除するようにしてください // グロー効果のある箱を描画する int DrawGlowBox(int x1, int y1, int x2, int y2, unsigned int color, int FillFlag) { int WorkScreen[2]; int box_size_x = x2 - x1; // 箱の大きさを求める int box_size_y = y2 - y1; // 箱の大きさを求める int img_x1 = x1 - box_size_x / 2; // 完成した画像の描画点を求める int img_y1 = y1 - box_size_y / 2; int img_x2 = x2 + box_size_x / 2; int img_y2 = y2 + box_size_y / 2; // ぼかし作業用のスクリーンを作成 SetDrawValidFloatTypeGraphCreateFlag(TRUE); WorkScreen[0] = MakeScreen(box_size_x * 2, box_size_y * 2, FALSE); WorkScreen[1] = MakeScreen(box_size_x * 2, box_size_y * 2, FALSE); // 作業用スクリーンの中心に四角形を描画 SetDrawScreen(WorkScreen[0]); ClearDrawScreen(); DrawBox(box_size_x / 2, box_size_y / 2, box_size_x + box_size_x / 2, box_size_y + box_size_y / 2, color, FillFlag); // 描画先を裏画面にする SetDrawScreen(game_screen_handle); // 描画先を仮想画面に変更 // ガウシアンフィルタで画像をぼかす( 出力結果は有効ではない作業用スクリーン ) GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); GraphFilterBlt(WorkScreen[1], WorkScreen[0], DX_GRAPH_FILTER_GAUSS, 8, 200); GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); // 画面にぼかした画像を加算描画する int mode, parameter; GetDrawBlendMode(&mode, &parameter); SetDrawBlendMode(DX_BLENDMODE_ADD, 255); DrawGraph(img_x1, img_y1, WorkScreen[0], FALSE); SetDrawBlendMode(mode, parameter); // ぼかし作業用スクリーンの削除 DeleteGraph(WorkScreen[0]); DeleteGraph(WorkScreen[1]); return 0; } > ただ一点だけ疑問があり、この変数の引数は何を表しているのでしょうか? >  GraphFilterBlt(WorkScreen[0], WorkScreen[1], DX_GRAPH_FILTER_GAUSS, 8, 200); > 3度読んで調整していますが、もう少し良いやり方があるのではないかと思っていますm(__)m GraphFilter はリファレンスに載っている関数なので、よろしければリファレンスの解説をご覧ください m(_ _)m https://dxlib.xsrv.jp/function/dxfunc_graph1.html#R3N26S1 とりあえず 8 と 200 の引数の意味は以下の通りです   引数    int PixelWidth : 使用ピクセル幅( 8 , 16 , 32 の何れか )    int Param : ぼかしパラメータ( 100 で約1ピクセル分の幅 )
メンテ
Re: 画面を停止させない方法、東方のHP描画方法、他 ( No.7 )
名前:にこよう (解決) 日時:2019/07/24 15:12

ご回答ありがとうございます >DeleteGraph で削除していませんが、グラフィックハンドルは不要になったら DeleteGraph で 削除しないとVRAMがどんどん消費してメモリ不足になってしまいます 忘れていました ご指摘ありがとうございます >GraphFilter はリファレンスに載っている関数なので、よろしければリファレンスの解説をご覧ください m(_ _)m すみません、確認不足でした ありがとうございますm(__)m
メンテ

Page: 1 |

題名
名前
コメント
パスワード (記事メンテ時に使用)

   クッキー保存