/*! @auther d金魚 @since 2004/2/7 @version 1.02 @note DxLibでサンプルを書いて見ました^^ <h3>見てね^^</h3> このソースコードはBSD Licence的な考えで自由に使ってOKです^^ 簡単に言うと、著作者への配慮を忘れなければ自由って事です。 例:以下のような事は止めてください。BSD Licence的な考えに反します。 これは私が作った!だからみんな使うな!って感じで主張する事のような事。 このソースつかったら被害が出た。賠償金払え!見たいな事。 <h3>謝辞</h3> DxLibの製作者、山田 巧 氏に感謝します。 http://homepage2.nifty.com/natupaji/DxLib/ */ #include "DxLib.h" #include "BMLDLL.h" //********************************************************** ///ベンチマーク用設定でコンパイルする #define BML_BENCHMARK 1 //********************************************************** //ユーティリティ関数 inline bool CheckCollision(const RECT &a,const RECT &g){ return !(a.right<g.left || a.left>g.right || a.top>g.bottom || a.bottom<g.top); } //********************************************************** ///超簡易プレイヤークラス class TestPlayer{ public: TestPlayer(){ mx = 0; my = 0; } ~TestPlayer(){} typedef int Coordinates; Coordinates mx,my; Coordinates getX(){return mx;} Coordinates getY(){return my;} void setX(Coordinates x){mx = x;} void setY(Coordinates y){my = y;} void setXY(Coordinates x,Coordinates y){ setX(x); setY(y); } void addX(Coordinates x){ mx += x;} void addY(Coordinates y){ my += y;} virtual void Move(){ int angle=-1; //とりあえず角度を-1にしておく //[38]↑ [40]↓ [37]← [39]→ bool right = false,left = false,up = false,down = false; //::ProcessMessage(); if(::CheckHitKey(KEY_INPUT_RIGHT)){ right = true; } if(::CheckHitKey(KEY_INPUT_LEFT)){ left = true; } if(::CheckHitKey(KEY_INPUT_UP)){ up = true; } if(::CheckHitKey(KEY_INPUT_DOWN)){ down = true; } if(up && right) //右上 angle=45; else if(left && up) //左上 angle=135; else if(left && down) //左下 angle=225; else if(down && right) //右下 angle=315; else if(up) //↑ angle=90; else if(down) //↓ angle=270; else if(left) //← angle=180; else if(right) //→ angle=0; //angleの値が変わっていたらキャラクタの座標を変更する if(angle!=-1){ int mv = 3;//3の速さ addX(BML_HELPER_AngleToCos(angle)*mv); addY(-BML_HELPER_AngleToSin(angle)*mv); //cx+=fcos[angle]*mv; //cy-=fsin[angle]*mv; } return; } virtual void Draw(int color){ DrawBox(getX(),getY(),getX() + 3,getY() + 3,color,TRUE); return; } }; ///ここでテストプレイヤーを宣言 TestPlayer gPlayer; //********************************************************** //簡易FPSマネージメント class FPSManager{ ///時間を保存しておくもの DWORD mReserveTime; ///次のFPS更新するときの時間の差分を導くための時間保存 DWORD mFPSReserveTime; ///今のフレームカウント DWORD m_CountFrame; ///2回Beginを呼び出さないようにする。カウンタ保存変数 DWORD m_NowFrame; ///1FPSあたりの時間 DWORD mFPSSec; ///FPSのカウント DWORD mFPSCount; ///今のFPS DWORD mNowFPS; bool mFPSManagementEnable; /*DWORD FrameInit(){ m_NowFrame=0; return m_CountFrame = 0; }*/ protected: DWORD IncCountFrame(){ return m_CountFrame++;} public: DWORD NowCountFrame(){ return m_CountFrame;} FPSManager(){ mReserveTime = 0; m_CountFrame = 0; mFPSSec = 0; m_NowFrame = 0; mFPSCount = 0; mFPSReserveTime = 0; SetFPS(60);//defaultは60 //FPS管理は行う。 mFPSManagementEnable = true; } void ClearCountFrame(){ m_NowFrame = 0; m_CountFrame = 0; } virtual ~FPSManager(){} ///1フレームに1回呼び出してほしいもの(ループの最初に呼び出すこと void Begin(){ if( NowCountFrame() == m_NowFrame) return; //フレームカウントを代入 m_NowFrame = NowCountFrame(); //次へのタイムを保存 DWORD getTime = ::timeGetTime(); mReserveTime = getTime; //FPSの更新処理 if (getTime - mFPSReserveTime > 1000) { mNowFPS = mFPSCount;//結果を入れるなり mFPSCount = 0; //カウンタをゼロクリア mFPSReserveTime = getTime;//ここで次への時間の差分をゲット! } } void SetFPS(int seq){ seq *= 2;//なぜかFPSが合わないのでこういう風にするしかない^^; //だれかどこが間違っているか教えて^^;;; mFPSSec = 1000/seq; } ///@param flag[in] FALSEだとFPS管理を行わない。 void Enable(bool flag){ mFPSManagementEnable = flag; } void FPS_Management(){ } void End() { /*do{ :Sleep(CPU_SLEEP_TIME); }while(::timeGetTime() < wait_time + FPSSec); */ if(true==mFPSManagementEnable) { DWORD t = ::timeGetTime(); if(t < mReserveTime + mFPSSec){ DWORD tmp = (mReserveTime + mFPSSec - t); tmp = (tmp > 20) ? tmp - 20 : tmp; Sleep(tmp); } t = ::timeGetTime(); while(t < mReserveTime + mFPSSec){ DWORD tmp = (mReserveTime + mFPSSec - t); tmp = (tmp > 1) ? tmp - 1 : tmp; Sleep(tmp); t = ::timeGetTime(); } } mFPSCount ++;//FPSカウントをUPするなり! //フレームをインクリメント IncCountFrame(); } DWORD GetFPS()const{return mNowFPS;} inline int DrawFPS(int x,int y,int color){ return ::DrawFormatString(x,y,color,"FPS = %d",GetFPS()); } }; //********************************************************** //コールバック関数郡 BOOL CALLBACK GetPlayerCollision(BML_PLAYER_CALLBACK_DATA *data){ int x,y; x = gPlayer.getX(); y = gPlayer.getY(); data->collision.left = x; data->collision.top = y; data->collision.right = x + 1; data->collision.bottom = y + 1; // data->result = TRUE; return TRUE; } ///画面から消えたらTRUE BOOL CALLBACK DisplayCheckCollisionCallback(const RECT *myrect,BML_BULLET_DATA *data){ RECT b={data->x,data->y,data->x + 1,data->y + 1}; return (!CheckCollision(*myrect,b)); } //********************************************************** //メイン関数 int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow ) { char buff[MAX_PATH];//XMLへのパス //フォルダオープンダイアログを表示 if(edk_Not_Selected == BML_HELPER_OpenBMLSelectDialog(buff,sizeof(buff),NULL)) { return 1; } ChangeWindowMode(TRUE);//Window Mode //DxLibを初期化 if(0 != DxLib_Init()){return -1;} SetDrawScreen(DX_SCREEN_BACK);//back buffer write mode //BMLDLLを初期化 10000個の弾領域、スピードは1、200個の空き領域保存キュー if(DKUTIL_FAILED(BML_Init(10000,1,200))) {//error return -1; } int SimpleColor = ::GetColor(255,0,0);//赤色 int ActionColor = ::GetColor(0,255,255);//水色 int PlayerColor = ::GetColor(255,255,255);//白 //BulletMLが定義されたXMLを読み込む。 int bml = BML_LoadXMLFile(buff); if(bml==-1) return -1; char dummywork[1]; //フレームをクリア BML_ClearFrame(); //プレイヤーの座標をセット gPlayer.setX(320); gPlayer.setY(240); FPSManager fps; //FPSのウェイトをTRUEにする。 fps.Enable(TRUE); while(ProcessMessage() != -1){ //FPS計測開始 fps.Begin(); if(CheckHitKey(KEY_INPUT_ESCAPE)==1) {//ESCキーが押されたらこのループを抜ける。 break; } //画面をクリア ClsDrawScreen(); # ifdef BML_BENCHMARK if(BML_GetFrame() % 10 == 0 || BML_GetFrame()==0) # else if(BML_GetFrame() % 60 == 0 || BML_GetFrame()==0) # endif {//60フレームに1回生成。 BML_CreateBullet(bml, 320,//生成する座標 240, dummywork,//タスクワーク sizeof(dummywork), GetPlayerCollision//プレイヤーへの座標を得るコールバック関数 ); } //移動処理 //弾の移動 ここでフレームをひとつインクリメント BML_Move(); //プレイヤーの移動 gPlayer.Move(); //この範囲を出たら弾を削除するようにする。 RECT disp={0 - 5,0 - 5,640 + 5,480 + 5}; //コールバック関数を指定して、コリジョンチェック BML_HELPER_HitDelete( &disp,//この矩形をDisplayCheckCollisionCallbackの第一引数に渡す NULL,//NULLだと内部で用意してくれる DisplayCheckCollisionCallback//チェック関数 ); //libBulletMLの処理 BML_Update(); //描画処理 //弾の描画はヘルパ関数に任せる。 BML_HELPER_DrawBullet(SimpleColor,ActionColor,DrawBox); //プレイヤーの描画 gPlayer.Draw(PlayerColor); //弾数を表示 ::DrawFormatString(0,0,PlayerColor, "弾数 = %d , PlayerX=%d PlayerY=%d", BML_GetBulletNum(),gPlayer.getX(),gPlayer.getY() ); //FPS計測終了 fps.End(); //FPS描画 fps.DrawFPS(0,16,PlayerColor); ScreenCopy(); Sleep(1); } BML_End(); DxLib_End(); return 0; }