FC2ブログ

もうすこし学習してから

画像とWM_TIMERの発行ごと更新だけで実現するのは少々てこずる。
とりあえず、画像の移動や云々はできた。
もうちょっと学習してから、クラスやマルチスレッドにしよう^^;

簡易なシューティングをつくるために
以下を用意した。
ちなみに、ゲームプログラムに関する参考図書は
一冊も持っていないし調べていない\(^o^)/

まだ、未完成だけど

☟流れはこんな感じ
1.初期位置と最終位置からX’軸を求める
2.その軸とX軸との角度から座標変換
3.座標変換のX方向と弾の動きY方向で行列掛ける
4.弾を表示する座標を求める
5.弾を表示する

パラメータ式を使った行列変換ですね。
パラメータ値のステップを大きくするほど
弾の動きも速くなる。


//弾幕設定構造体
typedef struct __BULET__ {
HBITMAP hBmp;//弾の画像
INT Now;//現在の弾座標パラメータ
DOUBLE Func;//弾の動きを記述
POINT Start;//初期位置
POINT End;//最後位置
BOOL DispYESNO;//弾幕表示可否
} BULLET;

//回転系2次元座標変換
POINT GeometricTrans2D(POINT In,DOUBLE Radian){
POINT Out;

Out.x=(LONG)((DOUBLE)In.x*cos(Radian)-(DOUBLE)In.y*sin(Radian));
Out.y=(LONG)((DOUBLE)In.x*sin(Radian)+(DOUBLE)In.y*cos(Radian));

return Out;
}


//弾幕作成。戻り値は判定に使う
INT Shooting(HDC hdc,//コンテキストハンドル
BULLET *Bullet,//弾構造体
INT step //パラメータ値インクリメント数。弾のスピードも握る
){
HDC hdc_mem;
BITMAP bmp_info;
static DOUBLE Grad;
static DOUBLE Angle;
static POINT Zahyou;
static RECT Judg;
static short int sgn_x,sgn_y;

if((Bullet->End.x-Bullet->Start.x)==0){ //角度が90度になる場合(直角)
Angle=M_PI_2;
sgn_x=1;
sgn_y=((Bullet->End.y-Bullet->Start.y)<0)? -1:1;
Zahyou.x=(LONG)Bullet->Now;//現在のパラメータ値
Zahyou.y=(LONG)Bullet->Func*sgn_y;//弾幕の動きを与える
Zahyou=GeometricTrans2D(Zahyou,Angle);//現在の相対座標を取得
}else{ //その他の角度
Grad=(DOUBLE)(Bullet->End.y-Bullet->Start.y)/(Bullet->End.x-Bullet->Start.x);//初期から最後までの傾き
sgn_x=((Bullet->End.x-Bullet->Start.x)<0)? -1:1;
sgn_y=((Bullet->End.y-Bullet->Start.y)<0)? -1:1;
Angle=atan(Grad);//傾きからラジアンを求める
Zahyou.x=(LONG)Bullet->Now*sgn_x;
Zahyou.y=(LONG)Bullet->Func*sgn_y;
Zahyou=GeometricTrans2D(Zahyou,Angle);//現在の相対座標を取得
}

int x,y,w,h;

hdc_mem=CreateCompatibleDC(hdc);
GetObject(Bullet->hBmp,(int)sizeof(BITMAP),&bmp_info);
SelectObject(hdc_mem,Bullet->hBmp);
x=Zahyou.x-(int)bmp_info.bmWidth/2+Bullet->Start.x;//弾画の左隅X座標
y=Zahyou.y-(int)bmp_info.bmHeight/2+Bullet->Start.y;//弾画の左隅Y座標
w=(int)bmp_info.bmWidth;//弾画の横幅
h=(int)bmp_info.bmHeight;//弾画の縦幅

//判定ブロック。当たり判定にも使える
{
Judg.left=x;
Judg.top=y;
Judg.right=x+bmp_info.bmWidth;
Judg.bottom=y+bmp_info.bmHeight;
}

if(Bullet->DispYESNO==TRUE){
StretchBlt(hdc,x,y,w,h,hdc_mem,0,0,w,h,SRCCOPY);
Bullet->Now+=step;
}else{
//Bullet->Now=0;
}


DeleteDC(hdc_mem);
return 0;//試作
}

この関数使えばもっと拡張できるんだが・・、

クラス使ったほうがすっきりしそうだ。

あと、rand()なんやで座標をちょくちょくかえて
ScratchBlt関数を沢山作れば
一つのこの関数で、たくさん弾を作れる

弾の動きは、初期位置と最終位置、弾の動きを記述する関数によってきまる
スポンサーサイト



テーマ : プログラミング
ジャンル : コンピュータ

コメントの投稿

非公開コメント

ぶろぐかんりしゃ

SmartWoods
最近MoEは・・・
一休み

***** ひとこと *****

MoEの後継ともいわれる
Resonance gamez
完全スキルMMOが
気になるところ



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


↓2016/3/26更新
My MoE









**********

NEWとらっくばっく
あーかいぶ
かてごりー
リンク
ぶろぐないけんさく
RSSふぃーど
おともだちになろ

この人とブロともになる