FC2ブログ

【第4回】マジカルハロウィンのデスクトップマスコットを作ってみよう!

どうも、カズズ軍曹です。
デスクトップマスコット制作の続きをやっていきたいと思います。
今回は第4回ということで、前画面表示固定して位置を移動できるようにし、シーン別に複数の画像を表示できるようにしていきます!

今回の目標

前画面表示に対応する。
位置を移動できるようにする。
通常時、クリック時にそれぞれ別の画像を表示できるようにする。

前画面表示に対応させる

まずは前画面表示に対応させていきたいと思います。
デスクトップマスコットは基本的に常に画面に表示させておくものだと思いますので、必須機能ですね。

前画面表示を設定するには、SetWindowPos()という関数を使用することで実現できます。
DXライブラリ初期化処理である、DxLib_Init();の後に、以下の処理を追加してください。

//ウィンドウを最前面に固定
SetWindowPos(GetMainWindowHandle(), HWND_TOPMOST, 0, 0, 0, 0, 0);

SetWindowPosは、名前の通りウィンドウのポジションを設定する関数です。表示位置やサイズの他に、最前面表示するかしないかの設定を行うことができます。
最初の引数には、設定対象のウィンドウのハンドルを渡してやらないといけないので、GetMainWindowHandle()関数を使って、メインウィンドウの値を渡しています。
次の引数は最前面表示するかどうかのハンドルを渡します。HWND_TOPMOSTという値を渡してやると、そのウィンドウは非アクティブ状態でも最前面表示するようになります。
そこから後の引数は、ウィンドウの位置(x,y)・サイズ(cx,cy)・位置調整フラグを設定するものになっています。特に設定する項目はないので、全て0で大丈夫です。
これで起動してみましょう。

desktop20200607-1.png

無事、常に最前面に表示できるようになったと思います。
これで最前面表示の問題は解決しました!
次は、デスクトップマスコットを移動できるようにしてみましょう!

位置を移動できるようにする

普通ウィンドウの位置は、タイトルバーをドラッグして動かしますが、タイトルバーをオフにしている影響で普通に移動することができません。
画像をドラッグすることによって移動したいですよね。
この節では画像の位置を移動できるようにしていきたいと思います。

画像をドラッグしてウィンドウの位置を移動する関数は用意されていないので自分で用意する必要があります。
今回は以下のようにして実現していきます。

1. マウスが左クリックされているかを調べる
2. されていれば、マウスの位置と現在のウインドウの位置を取得
3. 左クリックが離されているかを調べる
4. 離されていれば、現在のマウスの位置を取得
5. クリックする前のマウスの位置と比較し、その差を得る
6. 差の分だけウィンドウを移動

新たに以下の関数を使用します。
GetMouseInput(); マウスの入力状態を取得する関数
GetMousePoint(x, y); マウスの位置を取得する関数
GetWindowPosition(x, y); ウィンドウの位置を取得する関数
SetWindowPosition(x, y); ウィンドウの位置を設定する関数

変更箇所が多いので、以下のコードをコピーして使用してください。
まず、メインループ前に以下の変数宣言を追加します。

int start_windowX = 0; //ドラッグ前のウィンドウのX、Y座標
int start_windowY = 0;
int start_mouseX = 0; //ドラッグ前のマウスのX、Y座標
int start_mouseY = 0;
int Mouse = 0; //マウスの入力状態を格納
int mouseX = 0; //現在のマウスのX、Y座標
int mouseY = 0;
int drag_flag = 0; //現在ドラッグしているかを格納

メインループを以下のように変更してください。

   //メインループ
while (ProcessMessage() == 0 && ClearDrawScreen() == 0) {

//ブレンドモードを乗算済みアルファに設定
SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255);

/* ウィンドウの位置を動かす処理 */

//マウスの入力状態を取得する
Mouse = GetMouseInput();

//現在のマウスの位置を取得する
GetMousePoint(&mouseX, &mouseY);

//左クリックしているかを取得する
if (Mouse & MOUSE_INPUT_LEFT) {
//ドラッグ開始時の処理
if (drag_flag == 0) {
drag_flag = 1;
//ウィンドウの位置を格納
GetWindowPosition(&start_windowX, &start_windowY);
//マウスの位置を格納
GetMousePoint(&start_mouseX, &start_mouseY);
}
}
//左クリックしていない場合
//ドラッグしていた場合
else {
if (drag_flag == 1) {
drag_flag = 0;
//マウス位置の差を算出し、ウィンドウを動かす
SetWindowPosition(start_windowX + mouseX - start_mouseX, start_windowY + mouseY - start_mouseY);
}
}

/* 画像を表示させる処理 */
DrawGraph(0, 0, test_g, TRUE);

//描画先の画像をソフトイメージに取得する
GetDrawScreenSoftImage(0, 0, 640, 480, SoftImage);

//取り込んだソフトイメージを使用して透過ウインドウの状態を更新する
UpdateLayerdWindowForPremultipliedAlphaSoftImage(SoftImage);
}

これで起動してみましょう!
画像をドラッグ・アンド・ドロップすることで、他の場所に移動させることができていれば成功です!
位置調整もできるようになり、本格的にデスクトップマスコットに近づきましたね!
さて次は、状況に応じて画像を切替えられるようにしていきます!

別の画像を表示させる

デスクトップマスコットは、複数の動画データを用いて構成されていると思います。動画データはまだ用意できないので、複数の画像をシーン別に切り替えて表示させてみましょう!

通常時、マウスクリック時の2シーンに分けて画像を切替えて表示させていきます。
まずは画像を追加で用意しましょう。
私は「いらすとや」さんから、「驚いている人のイラスト(棒人間)」を使わせていただきました!
「test_click.png」というファイル名で「image」フォルダに保存します。



このように配置できたら、プログラムを書いていきましょう!
クリックしているかの判定を行えば、画像の切り替えを実現できます!

画像上でクリックされている → test_click.pngを表示
マウスポインタが画像上にない or クリックされていない → test.pngを表示

まず、画像を読み込ませましょう。
メインループ前に以下の2行を追加します。
int test_click_g;
test_click_g = LoadGraph("image/test_click.png");

そして、メインループを以下のように変更してください。

    //メインループ
while (ProcessMessage() == 0 && ClearDrawScreen() == 0) {

//ブレンドモードを乗算済みアルファに設定
SetDrawBlendMode(DX_BLENDMODE_PMA_ALPHA, 255);

/* ウィンドウの位置を動かす処理 */

//マウスの入力状態を取得する
Mouse = GetMouseInput();

//現在のマウスの位置を取得する
GetMousePoint(&mouseX, &mouseY);

//左クリックしているかを取得する
if (Mouse & MOUSE_INPUT_LEFT) {
//ドラッグ開始時の処理
if (drag_flag == 0) {
drag_flag = 1;
//ウィンドウの位置を格納
GetWindowPosition(&start_windowX, &start_windowY);
//マウスの位置を格納
GetMousePoint(&start_mouseX, &start_mouseY);
}
}
//左クリックしていない場合
//ドラッグしていた場合
else {
if (drag_flag == 1) {
drag_flag = 0;
//マウス位置の差を算出し、ウィンドウを動かす
SetWindowPosition(start_windowX + mouseX - start_mouseX, start_windowY + mouseY - start_mouseY);
}
}

/* 画像を表示させる処理 */
//クリックされていたら、
if (Mouse & MOUSE_INPUT_LEFT) {
//test_click.pngを表示
DrawGraph(0, 0, test_click_g, TRUE);
}
//されていなかったら
else 
//test.pngを表示
DrawGraph(0, 0, test_g, TRUE);

//描画先の画像をソフトイメージに取得する
GetDrawScreenSoftImage(0, 0, 640, 480, SoftImage);

//取り込んだソフトイメージを使用して透過ウインドウの状態を更新する
UpdateLayerdWindowForPremultipliedAlphaSoftImage(SoftImage);
}

if文でクリックの有無により、表示させる画像を分けています。




画像をクリックすると、画像が切り替わることが確認できたでしょうか。
これでシーン別の画像の切り替えができました!

いかがでしょうか。前回よりも大分デスクトップマスコットに近づいたと思います。
さて、ここにきてプログラムがかなり複雑になってきました。
似たような処理が至る所にあると思います。
こちらでプログラムを整理したmain.cppを配布しますので、置き換えて使って下さい。
コメントを参考にプログラムを読んでみるのも面白いですよ。

次回は、画像を実際のマジハロキャラクタに置き換えていきたいと思います。
ここからは撮影データが必要なので、揃い次第更新ということにしたいと思います。
では、また!

main.cpp (3kb)

---シリーズ一覧---
第1回
第2回
第3回
第4回(今回)



関連記事

コメントの投稿

管理者にだけ表示を許可する

プロフィール

カズズぐんそー

Author:カズズぐんそー
岡山県在住の情報工学系の大学生です。
情報処理安全確保支援士試験合格。
麻雀とゲーム制作、低貸スロが趣味の自由人です。

最新記事
最新コメント
月別アーカイブ
カテゴリ
アクセスカウンター
オンラインカウンター
スポンサーリンク
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QR
メールフォーム

名前:
メール:
件名:
本文: