2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Siv3DAdvent Calendar 2019

Day 17

文化祭用にランチャーを作った話

Last updated at Posted at 2019-12-16

こんにちは。今年は OpenSiv3D(v0.4.0) を使用して文化祭のランチャーのプログラム開発を担当したので記事にしたいと思います。

何を作ったか

# 便利だった機能 このランチャー制作で特に苦労したのがアニメーションなのですが、それを作るのに`Transition` や `Periodic::Sine0_1()`などがとても便利で、これとEasingを組み合わせてほとんどの動きを作っています。 この二つの機能は [OpenSiv3Dのサンプル](https://scrapbox.io/Siv3D/%E3%83%9E%E3%82%A6%E3%82%B9%E3%82%AA%E3%83%BC%E3%83%90%E3%83%BC%E3%81%A7%E5%9B%B3%E5%BD%A2%E3%82%92%E3%83%8F%E3%82%A4%E3%83%A9%E3%82%A4%E3%83%88) に載っているのでそちらを参考にしてください。

苦労したこと

アニメーションももちろん苦労しましたが、ランチャー制作にあたってウィンドウへの操作が必須だったので、Windows APIをかじった程度の腕だとそこに苦労しました。いくつか苦労したことを挙げていきたいと思います。
###Process機能の未実装
旧Siv3DにあったSystem::CreateProcessにあたる機能が当時OpenSiv3Dにはありませんでした。
自分で実装するのは手間がかかるなーと思いながらSiv3DのSlackで質問したところ、
image.png

1分で参考になるリンクと共に回答が来ました。

開発者に質問しやすく対応が早いのはSiv3Dの良いところですね。
※ちなみにOpenSiv3D v0.4.1で Process 機能が公式に実装されたので現在は楽にできるようになってます。

###アクティブウィンドウ問題
ランチャーからゲームを起動している間に何らかのキー入力をするとアクティブなウィンドウがランチャーウィンドウのまま起動してしまう致命的なバグがありました。
そこでこれを解決するためにゲームウィンドウのhWndを使いアクティブ化しようと考えたのですが、プロセスIDしか保持していないため

各ウィンドウのプロセスIDを調べ、ゲームのプロセスIDと一致していたらそのhWndを返す

という関数を作り、取得したhWndを使って

SetWindowPos(processHWND, HWND_TOP, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);

という風にすることで解決しました。
###フルスクリーン化問題
例年モニターにゲーム画面のみを映すゲームセンター形式なので、フルスクリーン化は必須でした。
フルスクリーン化するだけなら公式リファレンスを参考にすれば実装できる(僕の場合はSceneのサイズを変更したくなかったので Window::SetFullscreenの第三引数にWindowResizeOption::KeepSceneSizeを指定しました)のですが、ここで問題が発生しました。
ランチャーをフルスクリーン化するとゲームウィンドウがランチャーの後ろに隠れてしまうようになりました。

困ったので Window::SetFullscreen の内部コードを調べたところ、SetWindowPosHWND_TOPMOSTが指定されていました。
普通、アクティブなウィンドウが最前面にくるのですが、SetWindowPosHWND_TOPMOST を指定すると、ウィンドウは常に最前面におかれ、他のウィンドウがアクティブになっても最前面ウィンドウの後ろにおかれます。そのため作成したゲームウィンドウがフルスクリーン化、つまり最前面指定されたランチャーより後ろに置かれていたのです。
これはランチャーのhWndを使って

SetWindowPos(launcher_hWnd, HWND_NOTOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

という風にすることで最前面指定を解除でき、解決しました。
###その他の問題

  • ゲームを起動している最中にタスクバーとスタートボタンが見えてゲームセンター感がなかったので、タスクバーShell_TrayWndとスタートボタン ButtonFindWindow してhWndを取得、これを使い ShowWindowSW_HIDE を指定して隠しました
  • これは別に苦労してないのですが、ゲームのプレイ動画を流したかったけど動画再生機能が実装されてなかったので連番画像を12FPSで5秒ほど流してループさせるといった形式で代用しました

感想

デザイン担当が頑張ってくれたので僕はデザインの再現と機能面の実装をするだけで済み、とても早く作業が進みました。分担は大事ですね。
文化祭当日でも特にバグはでなかったのでなんとかうまくいって良かったです。

おわりに

これからランチャーを制作したい人は OpenSiv3Dサンプルのゲームランチャー をぜひ読んでみてください。僕の場合はキーボードのみで動作させる、フルスクリーン表示させるという前提があったのでやや苦労しましたが、その辺にこだわりがなければほぼサンプルだけでも制作できると思います。がんばってください。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?