Project:Project_SH 第3回「メインループの作成」

アバター
藍沢 冬月
記事: 0
登録日時: 14年前
住所: 京都
連絡を取る:

Project:Project_SH 第3回「メインループの作成」

投稿記事 by 藍沢 冬月 » 14年前

今回はいよいよ、メインループを作りたいと思います。
だんだんとシューティングの骨格が完成に近付いてきています。

◆ファイル構成
/Project
  Project_SH.sln …VC++の場合のみ
  /codeフォルダ  …ここにプログラムを入れる
   Main.cpp       …これがメインのファイル
   GameFrame.cpp  …今回作成するGameFrameファイル
   GameFrame.h    …GameFrameファイルのヘッダ
  /includeフォルダ…ここにヘッダとかを入れる
   Globalpack.h  …主なヘッダファイル
  /dataフォルダ  …ここにデータを入れる

さて、早速プログラムを見てみましょう。

CODE:

// -------------------------------------
// 全体のフレーム←親玉クラスになる
// GameFrame.h

#include "../include/Globalpack.h"

class GameFrame
{
private:
protected:
	int GetHitKeyStateAll_2() ;
public:
	int Key[ 256 ] ;
	int Frame_ini() ;
	virtual void doMainLoop() {}
	virtual void doDrawObj() {}
	virtual void doObjInit() {}
	virtual void doKeyCheck() {}
};

今回はprotectedというラベルの所にGetHitKeyStateAll_2という関数を追加しました。
これはキーチェックの関数を拡張したもので、dixq様のゲームプログラミング講座で解説されていたものを便利だからと勝手に流用したものです((dixq様本当にすいません!

加えて、publicのところに書いてある関数の宣言の型の前に"virtual"と書かれているのが分かりますか?
この、virtualによる宣言について今回は主に解説をしたいと思います。
その前に、GameFrame.cppをどうぞ。

CODE:

// -------------------------------------
// 全体フレームの中身
// GameFrame.cpp

#include "GameFrame.h"

// フレーム全体の初期化
int GameFrame::Frame_ini()
{
	// ウインドウモードに変更
	if( ChangeWindowMode( TRUE ) != DX_CHANGESCREEN_OK ) return -1 ;

	// 画面モードの変更
	if( SetGraphMode( 640, 480, 32 ) != DX_CHANGESCREEN_OK ) return -1 ;

	// タイトルを変更
	if( SetMainWindowText( "Project_SH" ) != 0 ) return -1 ;

	// ログの出力を行わない
	if( SetOutApplicationLogValidFlag( FALSE ) != 0 ) return -1 ;

	// DXライブラリ初期化処理
	if( DxLib_Init() == -1 ) return -1;

	// フォントの初期化
	SetFontSize( 20 ) ;
	ChangeFont( "メイリオ" ) ;
	ChangeFontType( DX_FONTTYPE_ANTIALIASING ) ;

	// 描画先画面を裏にする
	SetDrawScreen( DX_SCREEN_BACK ) ;

	return 0 ;
}

// GetHitKeyStateAllにカウンタをつける
int GameFrame::GetHitKeyStateAll_2()
{
	char Temp_Key[ 256 ] ;
	if( GetHitKeyStateAll( Temp_Key ) != 0 ) return -1 ;
	for( int i = 0 ; i Frame_ini() != -1 ) mf->doMainLoop() ;

	// いまはキーのウェイトでもかけておく
	WaitKey() ;

	// DXライブラリ使用の終了処理
	DxLib_End() ;

	// ソフトの終了
	return 0 ;
}

メインは今回いくつか手を加えました。
まずはこれ↓

CODE:

// ここでクラスの継承を行う
class MainGameFrame :public GameFrame
{
private:
protected:
public:
	void doMainLoop() ;
};
publicのところにdoMainLoopという関数を追加しました。
…ちょっと待ってください。
そういえば、親のクラスだったGameFrameクラスにも同じ名前の関数がありましたね?
つまり、普通に考えれば同じ名前の関数がMainGameFrameクラスに存在することになるので(継承すると、親のすべての変数&関数などは受け継がれます)、これは結構ヤバそうです。

そこで、
親元のクラスの関数を書き換えたい場合
は、親元のクラスの関数の前に"virtual"をつけることになっています。
こうすれば、子のクラスでもう一度定義されればそれが関数として登録されるのです。
これによって、関数がバッティングしてしまうことを防ぐことができます。

そして、メインループに関してはあんまり問題もないと思います。

最後に、メイン関数。

CODE:

	// ここにメインの処理
	MainGameFrame *mf = new MainGameFrame ;
	if( mf->Frame_ini() != -1 ) mf->doMainLoop() ;
最後の行はこんな風におしゃれに(?)書いています。
これは単に、Frame_iniでは異常が起こるとすべて-1で戻り値が返ってくるように設定されているから、こう書けばエラー時には実行されなくなるからです。

***
最後に余談ですが、GetHitKeyStateAll_2をGameFrame.hのprotectedに書いたのは、これが
同じクラスの中、または派生クラス(子のクラス)のみからのアクセスを認める
という意味だからです。

今回は子クラスのMainGameFrameクラス内の関数(メインループ関数)でこの関数を使う必要があったのでここに書きました。

ちなみに、
privateは、同じクラスの中のみからのアクセスを認める
pulbicは、どこからでもアクセス可能
という意味です。


さて、メインループ関数も無事完成しました。
((今回も実行画面は同じですが、ESCキーでのみ終了操作ができるようになりました

では、次からいよいよシューティングの基礎となるゲーム画面を作っていくことにしましょう!

コメントはまだありません。