VC++(2008 Express Edition)

2010年7月15日 (木)

OpenCVで画像処理−2:外部パラメータの表示、や推定

メモメモメモメモ・・・行列の計算はコンピに任せます。
今回はCPUの処理速度というより人間が使いやすいかどうかになるかもしれません。

3次元の任意の軸の周りの回転行列は、回転軸vとして、
Vect1 

となります(導出は省略)が、水平回転と仰角回転があれば十分なので、
こちら向きの右手座標系で
Vect2

でいろいろ回転できます。平行移動も行列計算でやってしまいたいので、
Cocolog_oekaki_2010_07_15_17_58

にして4x4行列を用意すると、平行移動と定数倍は
Vect3_2

回転どもも拡張して
Vect4

としておけば、例えば

①適当な位置に設置されたカメラで見る,ある点(x,y,z)はカメラの座標系から見てどうなるか?(画面上のどこに来るか)
@基準の座標系でのカメラのx,y,zを cx,cy,czとしておきます。
<手順>
ある点(x,y,z)に対して以下の操作をするる
1)カメラ座標が原点になるように平行移動
2)カメラの水平角、仰角の分回しもどして、カメラ座標系に合わせる。
3)スクリーンに投影する。(拡大・縮小)

まず(1)と(2)(↓)
Cocolog_oekaki_2010_07_15_19_03

でAがわかるので、(1)〜(3)をして
Cocolog_oekaki_2010_07_15_19_05
が画面上の点。
 
 

②外部パラメータが知りたい(基準の座標系のx, y, z をカメラから推定)
(ただし既知のパラメータが1つは必要)
さっきの逆を辿ればOKです。
画面上の座標(x,y)に対して以下の操作をするる
1)スクリーンに投影する。(L = zoom距離 を zとして3次元化)
1')実際の長さに延長
2)カメラの水平角、仰角の分回して、基準の座標系に合わせる。
4)カメラ座標を足して原点も合わせる。(平行移動)
Aは平行移動をまたがない限りはいつ掛けても一緒なので、まず
(1)と(2)(↓)

Cocolog_oekaki_2010_07_15_18_38
(対象物の...が既知のパラメータ)
でAを出してから、(1)→(2)→(1')→(3)の順にして、

Cocolog_oekaki_2010_07_15_18_44

を求める感じでしょうか。

2010年7月14日 (水)

OpenCVで画像処理-1:WEBカメラ

 微妙に時間ができたので久々に。前回の不運は忘れます。

OpenCVの触れ始めとして、
新しくプロジェクトを作ってやっていきます。今回もWin32アプリでいきましょう。
とりあえず動作確認したい場合は、
「cv_WebCam.txt」をダウンロード
を参考にしてみて下さい。

たぶんそれより困るであろうパス通しは前回の
パスを通す
で何とか設定できると思います。

実行時にdillが見つからないと言われてしまうときは、数も知れているので
c++ファイルと同じ場所にコピーしてやると手っ取り早いかもしれません。
ちなみにdll達は、
・・・OpenCV2.1 >> binの中にいます。

実行結果(下)

Cvb_1

OpenCVで扱うイメージはIplImageで、
例えばQVGA(320x240)のカラー配列の要素の割り当てが下のようになってます。
(1ピクセルごとにBlue,Green,Redで3要素)

Cocolog_oekaki_2010_07_14_21_33

この絵から何の情報も得られそうにないのはさておき、
対するBITMAPは1ピクセルごとに要素を4つ割いておられるので、その変換をして
仮想画面 hMenDC に読み込んでから BitBlt で hdc にコピーして表示しているのが
最後に書いている関数の内容です。

OpenCVで気を遣う解放ですが、グローバル変数にしておけば大抵は乗り切れます。
(毎回新しくメモリを確保しようとする関数などは注意)不安なときはタスクマネージャで
メモリ使用量がガンガン増えていないか確かめるとよろしゅうございます^^

2010年6月 9日 (水)

・・・パスを通す

 ぐほっ!メンテナンスで記事が消し飛んだ・・・w!?
急がねばならん。
とりあえずスクリーンショットを貼って寝ることにします。

WEBかめら(内蔵isight)のうんたらの予定(だった)。

ダウンロードしてインストールするだけではコンパイルに反映されないので、
パスの設定をします。一度やればあとは使い放題^^
OpenCV Wiki

此のページに書いてあるとおりにするだけです。がVC++2010の場合は
設定する場所が多少異なります。(たしか)やることは同じ。


Cv1_2

こうやって並べてみると編集側はどの絵だかわからない^^
開いたころか。以下説明はずれていても、気にすることはない。
Cv2_2

訳ありでプロジェクトと同じフォルダにライブラリを突っ込んだりするときは、
相対パスでOK。
Cv3_2

VC++2010の場合は、似たような操作を
プロジェクトのプロパティでやります。
Cv4

パスを通す操作は他のライブラリなども大体同じでOK。
wikiさんの指示通りに設定していきます。
インクルードファイル
Cv5
 

ライブラリ
Cv6


ソースファイル
Cva_1


インクルードファイル&ソースファイルはパスを通すだけでOKですが、
ライブラリはもう一カ所(プロパティのリンカの)設定をします。
最後。たぶんこの絵がプロパティの画面でしょうか。
Cv7

余談ですが、直に cvQueryFrame( 〜 )で取得したポインタは、プログラムで勝手に解放すると怒られます。
でもそのコピー等を入れるような手作りのものは解放しないとメモリがパンクしちゃいますw
グローバルなら大丈夫かもしれませんが^^;

2010年5月 7日 (金)

C++第12回:クラスの作成

なかなかに便利なクラスについて、概要をメモっときます^^

クラスの作成は、

 
***************************

class Oyaji
{
private:
・・・・・ローカル部分(クラスに属する関数などのみ使う変数などを宣言)
public:
・・・・・公開部分(どこでも使える)

};←セミコロンを忘れないように注意

***************************
 


と書いておけば、
Oyazi oyazi_1; だとか
Oyazi king_of_oyazi;

という具合に宣言して使ったり、型っぽい感じでも使えます(後述)。
 

 中身を書いていくとき、どうしても外部から書き換えられたくないような(?)部分がない限りは、
public: 以下に書き込んでいけば良いのかと思います。
 

 試しにVECTというクラスを作ります。
タブが効かず、全角スペースを打ってしまいますのでご了承ください。
コンストラクタとかデストラクタといった方たちが出てきます。

*ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー*
@コンストラクタ・・・クラスと同じ名前の関数。初期化時に呼ばれる。
           複数作れて、引数を指定しなくても良い。
@デストラクタ・・・クラスが破棄されるときに呼ばれる。
*ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー*
 
 
 

***************************
class VECT
{
private:
  char vectbuf[64];
public:
  double x,y,z;

  //デフォルト(コンストラクタ)
  VECT(){
   x=0;y=0;z=0;
  }
  //初期代入(これもコンストラクタ)
  VECT(const double a, const double b, const double c){
   x=a;y=b;z=c;
  }

  //デストラクタ
   ~VECT(){
  }

};
**************************
 
 
 
 

これで例えば、

VECT test_v1; と宣言すれば x,y,z に0が入ってtest_v1が作られ、

VECT test_v2(10, 20, 30) と宣言すればそれぞれの値が入って作られます。

それぞれの値を見るときは、
test_v1.x だとか、 test_v1.y 等々。

ただし、private: の中に入っている vectbuf は外から見れないようになってます。
(test_v1.vectbuf を外で書いても「宣言されていません」とお叱りをうける。)

 便利なのが、クラスで演算子(operator)を定義できることでしょうか。
関数も作れます。とりあえず宣言しておいて外に書くか、中に書き込むかは
好きなように。
 
 
 
 

全角スペースなのでコピると大変なことに。
***********************************
class VECT
{
private:
  char vectbuf[64];
public:
  double x,y,z;
  //コンストラクターーーーーーーーーーー
   //デフォルト
   VECT(){
    x=0;y=0;z=0;
   }
   //初期代入
   VECT(const double a, const double b, const double c){
    x=a;y=b;z=c;
   }
  //ーーーーーーーーーーーーーーーーーー

  //関数(プロトタイプ宣言)
  void show(HDC, int, int);

  //演算子
  const VECT operator +( const VECT& b ) const{
   return VECT( x + b.x, y + b.y, z + b.z );
  }

  //デストラクタ
  ~VECT(){
  }

};

//テキスト表示関数
void VECT::show(HDC hdc, int a, int b)
{
  sprintf_s(vectbuf, "(%.1f, %.1f, %.1f)",x,y,z);
  TextOut(hdc, a, b, vectbuf, (int)strlen(vectbuf));//
}

***********************************
 
 
 
 
 


これで、例えば
 VECT test_v0;
 VECT test_v1(1,2,3);
 VECT test_v2(4,5,6);

と宣言しておいて、
 test_v0 = test_v1 + test_v2;   だとか、
 test_v0 = test_v1 + VECT(2,3,4); など計算が楽にできます。

それからウィンドウプロシージャのWM_PAINTのところで
 test_v0.show(hdc, 100,100);

とでもすれば確認も割と簡単です。
 
 
 
 

演算子については中でまたコンストラクタが呼び出されたり、演算途中にうっかり引数が書き換わったり等々を避けるために、
const ○○& といった形をとるんだとか。y軸回転をしたいときなんかは、

 const VECT operator %( const double& rad ) const{

    double tr_x = cos(rad)*x + sin(rad)*z;
    double tr_y = y;
    double tr_z = -sin(rad)*x + cos(rad)*z;
    return VECT( tr_x, tr_y, tr_z );

 }
を定義して、
test_v1 = VECT(1,2,3) % 1.57; (反時計回りに90°回転)

test_v1.show(hdc, 100,150);

等々です。
ちょっと見づらいですが、これの結果を(下)

Mn_d1


2010年4月 5日 (月)

C++第11回:リソースファイル−3

 前回ResEditで適当に作ったところからの続きです。
ふぅ・・・ゆっくりいきましょう。
 

 いろいろ作ってみたくなるところですが、早く確かめたいところ。
それなりにできたら画面左の 
Dialog を右クリック →リソースの追加 →Manifest を選択。(下)

Reso_1
 
 

そうすると、xmlファイルを作るか訊かれるので、言われるがままに「はい」を押します。(下)

Reso_2
 
 

名前は特に変えずにそのまま保存すればよしです。(下)

Reso_3

 
 
相対パスにチェックが入っていたら、そのままOKです。

Reso_4


最後に保存しておくのを忘れないように・・・。(下)
これでResEdit作業は一段落。VC++に移行しましょう。

Reso_6

VC++で先ほど作ったファイルを取り込んでいきます。
画面左の リソースファイルを右クリック →追加 →既存の項目 を選択。

Reso_7


①ResEditで新規プロジェクトを選んだときの*.rcファイル(下の例ではbox_test)
 を追加。同じようにして
②resourse.h(ヘッダファイル)
 も追加しておきます。
 
Reso_8

さてさて、ここからcppファイルの方でボックスを出す関数を入れておきましょう。
といってもコピペしてきたんですけどねぇ

注意すべきは、人によって作ったボックスが違うこと。
とりあえず下の「ダイアログボックスの例」のところに注目。

#include "resource.h"を入れるのをお忘れ無く。

<追加部分を>〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
//はじめの宣言のところ(グローバル宣言)

BOOL CALLBACK DlgTestProc(HWND, UINT, WPARAM, LPARAM);//ダイアログボックス
char EDIT1_pt[1024];//テキストボックスの入力値を取得する。

//ウィンドウプロシージャのswich文のところ
・・・・
case WM_PAINT: //描画処理メッセージが来た
hdc = BeginPaint(hWnd, &ps);//hdc取得(描画)
TextOut(hdc, 0, 50, moji, (int)strlen(moji));//mojiを描画
TextOut(hdc, 0, 100, EDIT1_pt, (int)strlen(EDIT1_pt));//mojiを描画
EndPaint(hWnd, &ps); //描画終了
break;
case WM_LBUTTONDOWN:
DialogBox(NULL, MAKEINTRESOURCE(IDD_DIALOG1), hWnd, (DLGPROC)DlgTestProc);
InvalidateRect(hWnd, NULL, TRUE); //無効領域を発生させる→WM_PAINTを呼び出す
break;

・・・・

/*************************************
*ダイアログボックス動作の例
**************************************/
BOOL CALLBACK DlgTestProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{

switch(msg) {
case WM_INITDIALOG://作られてすぐ
SetDlgItemText(hWnd, IDC_EDIT1,"0");//初期値0をテキストボックス(IDC_EDIT1)に代入
return TRUE;
case WM_COMMAND://コマンド
if(LOWORD(wParam) == IDOK) {//OKを押したとき
GetDlgItemText(hWnd, IDC_EDIT1, EDIT1_pt, sizeof(EDIT1_pt) );//EDIT1_ptにテキストボックス内の文字列を格納
EndDialog(hWnd, IDOK);
return TRUE;
} else
if(LOWORD(wParam) == IDCANCEL) {//キャンセル
EndDialog(hWnd, IDCANCEL);
return TRUE;
}
break;
default:
break;
}
return FALSE;
}


〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

う・・・眠たい。次にresouse.hの中身をのぞいてみましょう。(下)
#difine ○○ ××
は○○は××のことだと定義しているところですね。こちらは至って単純です(−v−
つまりは上の太字ところ「IDC_EDIT1」 には数値の1002が対応してますので、極端な話
SetDlgItemText(hWnd, 1002,"0");と書いてもOKです。
 ちなみに ResEditで作っているときに気がついたかもしれませんが、
IDC_EDIT1はテキストボックスの名前です。(もっとも、この関連づけがなければ
エディタの意味がありませんがw^^;)

Reso_9
 
頭が半分寝ているので、抜けてるところがあるかもしれません。
ソースも載せておきます。(下)
「reso_m1.txt」をダウンロードして開く
 

ついでなので、リソースファイルも覗いてみます。
うむ。自分で書く人がいるのも何となくわかります^^

Reso_10

とりあえずはこんなところでしょうか。コンパイルできてうまくいったら万々歳^^

<追記>
マニフェストファイルへのリンクを設定するところを書いてなかったみたいです。


Mn_1

構成プロパティ→マニフェストツール→入力と出力 で、
作ったマニフェストファイル(上ではmanifest.xml)を打ち込みます。(下)

Mn_2

C++第10回:リソースファイル−2

 とりあえず先にVC++で新規プロジェクトを作っておきます。
C++第3回
にある骨組みをコピペして作っていくことにします。

今まで通りのWin32プロジェクトです。(下)

Dia_1


くどいですが、マルチバイトにするのもお忘れ無く^^
これもC++第3回参照です。

Dia_2

 
 
一応動くか試しておかないと・・・(下)
Dia_3
 
 

ここで改めてResEditを起動して、新規プロジェクトを選択。(下)
ここらあたりから油断は禁物。

Dia_4
 
 


保存場所を尋ねられるので、c++があるところに入れておきます。(下)

Dia_6


作り始める前に、まず
@オプション→設定 を選びます。(下)

Dia_7

 
 
Code generation のところで、言語を日本語にしておきます。(下)

Dia_8


 
それでは早速ダイアログボックスを作ってみます。
使い慣れてるわけでもないので、簡単にだけ説明を。
@ファイル →リソースの追加 →ダイアログ を選択。(下)

Dia_9


いろいろありますが、例えばEdit Control はテキストボックスです。
選択した後、ボックス上でドラッグして作ります。(下)
Dia_10

 
 


文字を変更、正確な値を設定したいときなどは、左下のプロパティを
変更すればOK。(下)
Dia_11
 
適当に作ってしまいましょう。長くなりそうなので次回に回します^^
先に結果だけを・・・。(下)

 

Aa_1

マウスイベントでダイアログボックスが出てきて、
数値(330)を入れてOKをおすと・・・という感じです^^

Aa_2

C++第9回:リソースファイルを取り込む

ちょいとVCの方で3D cadもどきを作ってみたくなったので、うろうろします^^
 テキストボックスなどを出して入力した値を取ってほしくなったので、
別ウィンドウで出てくる入力フォームみたいなのをリソースファイルとして
作って取り込むことにしました。

Visual C++ 2008 Express Editionでは、リソースファイルをさくさくっとは作れないようで、
フリーのエディタをダウンロードして使っていきます。
 

必要なものはおそらく以下の2点。
①Microsoft Platform SDK
 ここで取ってきました。MS Platform SDK
 ダウンロード&インストールにやや時間がかかります。

②リソースエディタ
 ResEdit
 使いやすいようです^^

多少ややこしい部分もあるので、すくしょを交えながら・・・。

まずは①のインストールから。(下)ゆっくり待ちましょう。

Plat_0
 
 
 
その次に②。こちらはインストールはされません。
とりあえずどこでも良いので解凍していきます。

Plat_1

 

解凍できたら開きましょう。最初は英語ですが、日本語に変えられるので大丈夫。

Plat_2

 
 
とりあえず何か設定しろと言っているのかな?「はい(yes)」を押します。(下)

Plat_3

 


これを指定して欲しいそうです。

Plat_4

 
指定するのは①でインストールした
Platform SDKの 「include」です。Cドライブから探せばどこかに・・・(下)

Plat_5


Plat_6
 
 

ちゃんと選択されていたら、OKを押します。(下)
ここまで行ければ順調^^

Plat_7

 
 
お次は日本語にしましょう。
Options → Preferences を選択。(下)

Plat_8
 
 
先ほど見たばかりの画面が出てくるので、
左側はGeneralを選択→languageをJapaneseに設定してOK。
一回ResEditを終了すると、次から日本語で起動します。

Plat_9

これで前半戦は終了(==;ちょっと休憩しましょう。
これからが勝負です。細かいところを見落とさないように・・・。

2010年2月26日 (金)

C++ゲーム制作編:アクション−5

 なかなからしくなってきました。今日は雑魚兵をばっさり。
油断しない限りそんなには斬られまい。(下)


Winl1
 

うじゃうじゃいますが、結構重なりやすいのでまとまってきます。

Winl2
 
兵卒はかわいそうなことに、何も出ないモーションがあったり・・・。

Winl3

さすがに何もしないとボコボコにされます。

雑魚兵(兵卒?)の動きはとりあえず3種類。
・様子見&少し距離を置く
・様子見&追いかけてくる
・突撃野郎

*様子見といってもこちらが攻撃しているときに攻撃を控えたり、
 遠くにいるときに待機して観察する程度ですw^^


 
 
 
ソースのほうは、とりあえず敵を増やしたので、所々にfor文を取り入れていきます。基本的にはそれだけです。
初期設定は実質雑魚兵(兵卒?)を足しただけでしょうか。
HPや攻撃等も形だけ用意しておいた感じです。代入関数を作ったので敵を増やすのが楽に^^

これを書いてるときは頭が回らないので、
変更部分はファイルに書いておくことに。

<test_Init.h>
「wnote_b1.txt」をダウンロードして表示
 

敵の人数も増えたので、残り連続ヒット数も敵の数だけ記憶します。
キー入力はそこのところだけ変更。

<Key_Control.h>
「wnote_b2.txt」をダウンロードして表示

 

あと、何でしょうか。敵の動作決定部分が大きく(?)追加されてます。
一部間違っているところがw・・・match_angleが45度になってます^^;(↓)
<Timer_Action.h>
「wnote_b3.txt」をダウンロードして表示

 
本体も敵の数増大でウィンドウプロシージャに変更部分が。
関数を使って初期設定は割と楽に(下)
 
<test.cpp>
「wnote_b4.txt」をダウンロードして表示
 

 
結局角度のヘッダファイル以外まるごと載せる羽目になりました。
うん、tabが効いてるのは良い。

ざっと眺められる感じになってますでしょうか?
説明よりソースのコメントアウト見た方が手っ取り早いんですよね。


むぅふ、単調なソースなので単調ですなw

2010年2月25日 (木)

C++ゲーム制作編:アクションー4

 今回あたり判定を入れて、とりあえず一騎打ちをしました。(下)

<図>曹操さんに斬られている様子。超接近戦ではコンピュータの方が有利かも?

Wink1
 
 

<図>慣れればボコれます^^ちなみに横の数字は、0以下ならひるんでいるという判定。

Wink2
 
 
 
あたり判定は読み込まれる回数が多いので、重くならないように注意しながら。
今回武器の直線の周りに当たり判定を出してみました。
<図>
Cocolog_oekaki_2010_02_25_00_05

○計算過程
*青い部分は武器の柄と先の x, y 座標による範囲。
*緑の部分は点と直線(武器)の距離に該当する範囲です。
この組み合わせ(ピンク)で判定しています。

Cocolog_oekaki_2010_02_25_00_13
このくらいの角度になるとちょっと形が変わりますが、許容範囲ですw

関数については、敵と味方共通でいこうかと思ったものの、代入動作のロスが微妙に気になるので、
今回は分離です。(下)

<「Timer_Action.h」の一部>
「wnote_a1.txt」をダウンロードして開く

とりあえず範囲に入ったら吹っ飛ばして、相手にストップ時間を発生させるようにしています。
吹っ飛ばす値は、攻撃中に自分が動く距離(+αぐらい?)がようございますね。

相手も攻撃中だと、連続攻撃の条件でストップ時間が消されてしまうので、
斬り合い殴り合い状態にw ひるみはその関係で追加しています。
 
 

とりあえず初期設定の変更点を。(下)

<「test_Init.h」の一部>
「wnote_a3.txt」をダウンロードして開く

 

ひるみっぱなしはいけないので、攻撃していないときに回復するようにします。

<また「Timer_Action.h」の一部>
「wnote_a0.txt」をダウンロードして開く

 

ルート(√)計算は避けて、距離は2乗のまま残してあります。
点と直線の距離を関数にしたので、kaku_setting.h に追加。(下)

<「kaku_setting.h」まるごと>
「wnote_a4.txt」をダウンロードして開く
 
 
 
最後にあたり判定の呼び出しをどこかに入れないと。
何となくウィンドウプロシージャのタイマー部に入れておきました。ついでに耐ひるみの初期値も設定。(下)

<「test.cpp」のウィンドウプロシージャ内部 の一部>
「wnote_a2.txt」をダウンロードして開く

 
 
後は敵を増やしたり、種類を増やしたり・・・
雑魚兵が6連攻撃してきたり、ひるみにくかったり、槍と剣の長さが同じだったりしても困るので、
そういった設定をしないといけなさそうです。

2010年2月23日 (火)

C++ゲーム制作編:アクション−3

 今回は敵さんにも動いてもらって、武器を振ってもらいました。
基本的にはプレイヤーのキーボード操作が自動になったようなもので、
動かす関数などは共通にする方針です。

ソースを載せる必要があるかはわかりませんが、今回も載せてしまいましょう。
先に結果を。(下)

<図>
Winj1
 


まだ当たり判定がないのでお互いすり抜けてしまいます。

とりあえず宣言部として分割した test_Init.h の方に、
敵さん用の宣言を追加。(下)

 「wnote_1.txt」をダウンロードして表示
 
敵さんは20人分ぐらい配列で用意しておきました。後で、
tewho[1] = 0;//(曹操)
tewho[2] = 2;//(孫堅)
・・・
のようにできます。

お次にタイマー系の関数を入れた、 Timer_Action.h の方には
○プレイヤーの動き BOOL PlayerAct() を敵さんにも対応させたもの
○攻撃関数     BOOL Atk_Act() を敵さんにも対応させたもの
○敵の動作決定   BOOL TekiAct() を新しく追加。
 
敵はキーボード入力しないので動作決定がタイマーの部類に入ってしまう羽目に。
動きは単純にまっすぐ近づいてきて、斬りかかってくるだけです(ー ー;
なんだか量がたっぷりにってしまって困りますwやってることはわりと単調です。(下)


「wnote_2.txt」をダウンロードして表示
 

ターゲットとの角度と距離(水平)を計算する
KakuGet();という関数を作って、ヘッダファイル kaku_settinig.h に入れてみました。
これはなかなか便利です。直接載せちゃいましょう。(下)

<kaku_setting.h の中身>〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜
BOOL KakuGet(double x, double y, double tx, double ty, double*lengh, double*kaku)
{
double plengh, pkaku, ptanp;

plengh = sqrt((y-ty)*(y-ty) + (x-tx)*(x-tx));//距離

ptanp = (y-ty)/(tx -x);//タンジェント値
pkaku = atan(ptanp);//ptanp から角度に

if(y-ty >=0){if((tx -x) >=0){}};//相手が右上
if(y-ty >=0){if((tx -x) < 0){pkaku =3.141 +pkaku;}};//相手が左上
if(y-ty < 0){if((tx -x) < 0){pkaku =3.141 +pkaku;}};//相手が左下
if(y-ty < 0){if((tx -x) >=0){pkaku =6.283 +pkaku;}};//相手が右下
//補正
if ( pkaku > 6.283 ){pkaku = pkaku - 6.283;}
if ( pkaku < 0 ){pkaku = pkaku + 6.283;}
//代入
*lengh = plengh;
*kaku = pkaku;//自分に対する軸固定の角度を取得

return TRUE;
}
〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜〜

回りくどい計算になっているかもしれませんが、気にせずに。

 
後は本体のtest.cpp の変更点です。冒頭部分は、

#include < windows.h >
#include < math.h >
#include < stdio.h >
#include "test_Init.h"
#include "kaku_setting.h"
#include "Timer_Action.h"
#include "Key_Control.h"

の順に。ウィンドウプロシージャの中で、敵のもろもろを設定して完了です。
敵の初期設定なんかも最終的に関数になりそうですね。(下)

「wnote_3.txt」をダウンロードして表示

一応作業画面も。(下)

<図>
Winj2