Beep

Beepは、ビープ音を鳴らす。

Beep function (utilapiset.h) | Microsoft Docs
ビープ音を鳴らす - プログラミングのメモ帳(C/C++/HSP)

ドの音は440Hzらしいので、それを流してみる。

Win32コンソールアプリケーション
Win32コンソールアプリケーション

Win32コンソールアプリケーションで、

空のプロジェクト
空のプロジェクト

空のプロジェクト。

新しい項目
新しい項目

新しい項目を追加。

Beep.cppを追加。
Beep.cppを追加。

Beep.cppを追加。

440Hzを3秒鳴らす。

Beep 440Hz Start!
Beep 440Hz End!
続行するには何かキーを押してください . . .

動画じゃないと伝わらないと思うが、StartとEndの間でドの音階の信号音が3秒間鳴った。

Sample/winapi/Beep/Beep/src/Beep at master · bg1bgst333/Sample · GitHub

クラスライブラリファイルの静的リンク

DLLを参照する方法以外に、クラスライブラリのファイルを静的にリンクするという方法がある。

クラスライブラリの静的リンクによる参照 - c++ 使いの c# メモ

静的リンクというとスタティックライブラリのことが思い浮かぶが、C#のクラスライブラリはDLL。
ライブラリバイナリではなくライブラリファイルを静的リンク。

空のプロジェクト
空のプロジェクト

空のプロジェクト。

MainClass.cs
MainClass.cs

MainClass.csを追加。

こう書く。

ビルドエラー
ビルドエラー

当然このままではビルドエラー

Libフォルダを作成
Libフォルダを作成

Libフォルダを作成。

ClassLibrary.csを置く
ClassLibrary.csを置く

ClassLibrary.csを置く。

この状態のClassLibrary.cs。

既存の項目を追加
既存の項目を追加

既存の項目を追加。

リンクとして追加
リンクとして追加

ClassLibrary.csを[追加]ではなく[リンクとして追加]を選択。

リンクとして追加された
リンクとして追加された

リンクとして追加された。
ショートカットのアイコンになっている。

ビルド成功
ビルド成功

今度はビルド成功。

i = 10, str = ABC
続行するには何かキーを押してください . . .

このようにライブラリを使える。

Sample/cs/FileStaticLink/FileStaticLink/src/FileStaticLink at master · bg1bgst333/Sample · GitHub

DLLの参照

前回はプロジェクトごと参照したので、今回はDLLだけの場合にDLLを参照する。

C#でプラグインDLLを作る方法(入門編) - Qiita
C# Hello DLL

といってもVisualStudioでだけど。

空のプロジェクト
空のプロジェクト

空のプロジェクトで、

MainClass.csを追加
MainClass.csを追加

MainClass.csを追加。

こう書く。
前回と全く同じ。

ビルドエラー
ビルドエラー

このままだとビルドエラーなので、

あらかじめ用意しておいた2つのDLL
あらかじめ用意しておいた2つのDLL

あらかじめ用意しておいた2つのDLLを置く。

ClassLibrary.1.dllをClassLibrary.dllにリネーム
ClassLibrary.1.dllをClassLibrary.dllにリネーム

ClassLibrary.1.dllをClassLibrary.dllにリネーム。

参照の追加
参照の追加

参照の追加で、

参照タブでClassLibrary.dllを追加
参照タブでClassLibrary.dllを追加

参照タブでClassLibrary.dllを追加。

ビルド成功
ビルド成功

今度はビルド成功。

i = 100, str = ABCDE
続行するには何かキーを押してください . . .

こうなる。

いったんClassLibrary.1.dllに戻す
いったんClassLibrary.1.dllに戻す

いったんClassLibrary.1.dllに戻す。

今度はClassLibrary.2.dllに着目
今度はClassLibrary.2.dllに着目

今度はClassLibrary.2.dllに着目。

ClassLibrary.2.dllをClassLibrary.dllにリネーム
ClassLibrary.2.dllをClassLibrary.dllにリネーム

ClassLibrary.2.dllをClassLibrary.dllにリネーム

参照の追加は不要でビルド成功する
参照の追加は不要でビルド成功する

参照の追加は不要でビルド成功する。

i = 200, str = VWXYZ
続行するには何かキーを押してください . . .

しかし、ClassLibrary.2.dllに差し替えているので結果は変わっている。

Sample/cs/DLLReference/DLLReference/src/DLLReference at master · bg1bgst333/Sample · GitHub

クラスライブラリ

C#でライブラリを作る場合、クラスライブラリと呼ばれていて、形式はDLLである。

C#でプラグインDLLを作る方法(入門編) - Qiita
C# Hello DLL

クラスライブラリプロジェクトで作るのが普通だが、今回は空のプロジェクトで、

空のプロジェクト
空のプロジェクト

プロジェクトClassLibraryを作る。

コードファイルを追加
コードファイルを追加

ClassLibrary.csを追加。

ややこしいけど、クラスの名前はClassLibraryClassにしてしまった。
とりあえず動いてるけど、ファイル名と一緒にすべきだよなあ・・・。
フィールドとメソッドを持つクラスにして、固定の値を返すだけ。

プロジェクトのプロパティ
プロジェクトのプロパティ

プロジェクトのプロパティで、

コンソールアプリケーションからクラスライブラリ
コンソールアプリケーションからクラスライブラリ

コンソールアプリケーションになっているので、クラスライブラリに切り替える。

ビルド
ビルド

ビルドすると、

ClassLibrary.dll
ClassLibrary.dll

ClassLibrary.dllが出来ている。

ソリューションに新しいプロジェクトを追加
ソリューションに新しいプロジェクトを追加

ソリューションに新しいプロジェクトを追加。

今度はMainプロジェクト
今度はMainプロジェクト

今度はMainプロジェクト。

コードファイルを追加
コードファイルを追加

MainClass.csを追加。

スタートアッププロジェクトに設定
スタートアッププロジェクトに設定

スタートアッププロジェクトに設定

参照を追加
参照を追加

ClassLibraryClassにインテリセンスが反応しないので、参照を追加。

DLLでもできるが・・・。
DLLでもできるが・・・。

DLLでも指定できるが・・・。

同じソリューションなのでプロジェクトで指定
同じソリューションなのでプロジェクトで指定

同じソリューションなのでプロジェクトで指定。

名前空間の登録をする
名前空間の登録をする

加えて、usingで名前空間の登録をすると、ビルドに成功する。

MainClass.csは、

これで、

i = 10, str = ABC
続行するには何かキーを押してください . . .

クラスライブラリから値を取り出せてる。

Sample/cs/ClassLibrary/ClassLibrary/src/ClassLibrary at master · bg1bgst333/Sample · GitHub

IComponentConnector.InitializeComponent

WPFのInitializeComponentの正体は、IComponentConnector.InitializeComponentの模様。

IComponentConnector.InitializeComponent Method (System.Windows.Markup) | Microsoft Docs

ちゃんとインターフェースとして定義されてる。

WPFアプリケーション
WPFアプリケーション

WPFアプリケーションで、

Labelを配置
Labelを配置

Labelを配置。

コードの表示
コードの表示

コードの表示で、

定義へ移動
定義へ移動

いったんプロジェクトをビルドしてから、InitializeComponentの定義へ移動。

定義されてる
定義されてる

自動生成されたWindow1.g.i.csに定義されていた。
このメソッド自体の中身はXAMLのロードなどをしている模様。

IComponentConnectorを実装している
IComponentConnectorを実装している

確かに、このクラスはIComponentConnectorを実装している

label1に"ABC"
label1に"ABC"

試しに、label1に"ABC"をセットしてみる。

反映されない
反映されない

反映されない。

ビルド時に自動再生成
ビルド時に自動再生成

ビルド時に自動再生成されるから当然か。

InitializeComponentをコメント
InitializeComponentをコメント

コメントしたらどうなるだろうか。

XAMLはロードされてる
XAMLはロードされてる

XAMLはロードされてる。
どういうことだろうか。
まあ、InitializeComponentの正体がわかっただけいいか。

Sample/wpf/IComponentConnector/InitializeComponent/src/IComponentConnector_ at master · bg1bgst333/Sample · GitHub

Xaoria32(0, 0, 1, 0/Yorii #85) -敵に単発のショットを実装.

敵側にもショット(弾)を実装した。

EnemyMapData.hに、

Playerと同じようにm_vecpShotListを追加。
さらにm_nShotIdxを追加。
今回、Enemy用のEnemyShotではなく、Playerのショットを流用することにした。

EnemyMap.hに、

DrawShotを追加。

EnemyMap.cppは、

DeployEnemyでCShotオブジェクトを作成し、m_vecpShotListに追加。
m_nEnemyNooが0、2、4の時に弾を実装。
(間に合わないのでハードコードせざるを得ない。)

メンバ関数DrawShotは、

こんな感じ。

Procのこの辺がハマりどころ。
y座標の設定がおかしくて、弾が止まったままだったり、消えたりした。
また、実際には 3発連射を用意していたが、この現象のために単発にせざるを得なかった。

RemoveAllでm_vecpShotListの破棄。

GameScene.cppは、

DrawShotの追加。

Player.cppは、

当たり判定の追加。

Shot.cppは、

ここがハマった原因だった。
m_yに座標を保存しているが、指定された座標はスクリーン座標に対し、CShotのm_yはワールド座標のため、弾が消えてしまっていた。
この辺りの座標変換とか管理がちゃんと整理されてない(のと、1年ぶりで覚えてない。)ので、書き直したい・・・。

出現した瞬間に、高速で単発でプレイヤーと同じ直線弾撃ってくるので、意外と難易度高い。
というわけで、なんとかギリギリC96を乗り切ったのであった・・・。

-敵に単発のショットを実装. · bg1bgst333/Xaoria32@a3ab5fc · GitHub

Window.ContentRendered

Window.ContentRenderedは、ウィンドウのXAMLコンテンツがレンダリング完了した後に発生するイベント。

Window.ContentRendered Event (System.Windows) | Microsoft Docs
WPF Windowが最初に表示されたときに処理を行いたい - Qiita

ウィンドウの描画後に処理をしたいなら、こちらの方が有効。

WPFアプリケーション
WPFアプリケーション

WPFアプリケーションで、

Buttonを配置
Buttonを配置

Buttonを配置。

WindowにContentRenderedを追加
WindowにContentRenderedを追加

WindowにContentRenderedを追加。

イベントハンドラ追加
イベントハンドラ追加

イベントハンドラ追加。

Window_ContentRenderedハンドラが追加される
Window_ContentRenderedハンドラが追加される

Window_ContentRenderedハンドラが追加される。

MessageBoxを表示。

今度はButtonが描画されている
今度はButtonが描画されている

今度はButtonが描画されている。

Sample/wpf/Window/ContentRendered/src/Window_ at master · bg1bgst333/Sample · GitHub