今日の呟き

リール表示クラスを改めて作ってみる_8

アバター
V30
記事: 21
登録日時: 9年前
住所: 岡山県

リール表示クラスを改めて作ってみる_8

投稿記事 by V30 » 9年前

素人のクラス製作日記・第8弾!です。

超我流のクラス製作も、いよいよ大詰めとなって来ました。

一眠りしてから作業しましたので、微量しか進んでおりません。

"CReel_panel_2.png"
[album]893[/album]

"CReel_reel.png"
[album]891[/album]

"Class_CReel_100.h"

CODE:

//*************************************************
//   CReel Class Ver. 0.07   2014.11.15   by V30   
//*************************************************

#ifndef CLASS_CREEL_100
#define CLASS_CREEL_100

#define CHARACTER_MAX		21	//最大図柄数
#define SHOW_SEGMENT_MAX	3	//最大表示コマ数

//リール表示クラス[縦1列表示型] ver. 0.07
class CReel
{
public:

	//リール状態列挙体
	enum ReelState
	{
		RS_STOP,		//停止中
		RS_ROUND,		//回転中(停止受付中)
		RS_RECIEVE,		//回転中(停止受付後)
		RS_CONTROL,		//回転中(停止制御中)
		RS_AFTER		//停止制御後
	};

private:

	int			i_character_height;	//リール図柄1コマ縦サイズ
	int			i_dest_lower_top;	//下部抽出画像描画y座標
	int			i_dest_upper_top;	//上部抽出画像描画y座標
	BOOL		B_divide_draw;		//分割描画フラグ
	BOOL		B_enable;			//リール稼働フラグ
	int			i_half_margin;		//表示サイズの高さ増分(上下均等配分)[array → 0 = 上下合計値, 1 = 片側分]
	int			i_handle;			//リール画像ハンドル
	int			i_height;			//リール画像縦サイズ
	int			i_last_position;	//前フレームのリール位置(上段リール図柄番号)
	int			i_left;				//リール窓内画像の表示位置(左上x座標)
	int			i_now_image_type;	//表示リール画像タイプ
	int			i_now_position;		//リールの現在位置(上段リール図柄番号)
	int			i_show_segment;		//リール窓枠内表示コマ数
	int			i_speed;			//リール回転速度(1フレーム当たりの縦スクロールサイズ)
	int			i_src_left;			//表示画像抽出位置基本x座標
	int			i_src_lower_height;	//下部抽出画像縦サイズ
	int			i_src_top;			//表示画像抽出位置基本y座標
	int			i_src_upper_height;	//上部抽出画像縦サイズ
	ReelState	RS_state;			//リール状態
	int			i_stop_position;	//リール停止予定位置(上段リール図柄番号)
	int			i_top;				//リール窓内画像の表示位置(左上y座標)
	int			i_total_character;	//リール図柄総数
	int			i_total_image_type;	//リール画像タイプの保持数
	int			i_total_margin;		//表示サイズの高さ増分(上下均等配分)[array → 0 = 上下合計値, 1 = 片側分]
	BOOL		B_visible;			//リール表示フラグ
	int			i_width;			//リール横サイズ

public:

	//コンストラクタ
	CReel();

	//コンストラクタ[初期設定用](left = 描画x座標, top = 描画y座標, totalcharacter = 1リールのコマ数, totalimagetype = リール画像保持数, reelimagehandle = 画像ハンドル, showsegment = 表示コマ数, marginsize = 表示サイズの高さ増分[上下均等配分・最大1コマ分の縦サイズ], speed = 回転速度, nowcharacternumber = 現在の図柄位置番号)
	CReel(int left, int top, int totalcharacter, int totalimagetype, int reelimagehandle, int showsegment, int marginsize, int speed, int nowcharacternumber);

	//描画
	void Draw();

	//表示リール画像取得
	int  GetImageType();

	//現在位置[図柄番号]取得
	int  GetNowPosition();

	//リール窓枠内表示コマ数取得
	int  GetShowSegment();

	//速度取得
	int  GetSpeed();

	//状態取得
	ReelState  GetState();

	//指定停止位置[図柄番号]取得
	int  GetStopPosition();

	//リール横サイズ取得
	int  GetWidth();

	//リール表示フラグOFF
	void Hide();

	//初期化
	void Initialize();

	//リール画像読込(totalcharacter = 図柄コマ数, totalimagetype = 画像タイプの保持数, reelimagehandle = 画像ハンドル)[自由サイズ。但し、縦のサイズは図柄のコマ数で割り切れる事!]
	void LoadImageHandle(int totalcharacter, int totalimagetype, int reelimagehandle);

	//メッセージ表示(*message = "メッセージ")
	void Message(const TCHAR *message);

	//図柄番号範囲外補正[値代入版]
	int  ReviseCharacterNumber(int characternumber);

	//リール描画基本位置設定(left = 左上x座標, top = 左上y座標)
	void SetDrawPosition(int left, int top);

	//稼働フラグ設定
	void SetEnable(BOOL flag);

	//表示リール画像変更(imagetype = リール画像タイプ)
	void SetImageType(int imagetype);

	//リール位置強制移動(characternumber = 上段図柄番号)
	void SetNowPosition(int characternumber);

	//表示サイズの高さ増分設定(marginsize = 延長サイズ[上下均等配分・最大1コマ分の縦サイズ])
	void SetShowMargin(int marginsize);

	//リール窓枠内表示コマ数設定(showsegment = 表示コマ数)
	void SetShowSegment(int showsegment);

	//リール回転速度設定(speed = リール回転速度[1フレーム当たりの縦スクロールサイズ])
	void SetSpeed(int speed);

	//状態設定(statenumber → 0 = 停止中, 1 = 回転中, 2 = 停止受付後, 3 = 停止制御中, 4~ = 停止制御後~自由設定)
	void SetState(ReelState statenumber);

	//停止位置指定(characternumber = 上段図柄番号)
	void SetStopPosition(int characternumber);

	//リール表示フラグON
	void Show();

	//リール回転スタート
	void Start();

	//リール回転強制停止
	void Stop();

	//アップデート
	void Update();
};

#endif //!CLASS_CREEL_100
"Class_CReel_100.cpp"

CODE:

//*************************************************
//   CReel Class Ver. 0.07   2014.11.15   by V30   
//*************************************************

#include 
#include 

CReel::CReel()
{
	Initialize();	//初期化
}
CReel::CReel(int left, int top, int totalcharacter, int totalimagetype, int reelimagehandle, int showsegment, int marginsize, int speed, int nowcharacternumber)
{
	Initialize();														//初期化

	SetDrawPosition(left, top);											//描画位置設定(left = 左上x座標, top = 左上y座標)
	LoadImageHandle(totalcharacter, totalimagetype, reelimagehandle);	//リール画像読込(totalcharacter = 図柄コマ数, totalimagetype = 画像タイプの保持数(横分割数), reelimagehandle = 画像ハンドル)[自由サイズ。但し、縦(高さ)のサイズは図柄のコマ数で割り切れる事!]
	SetShowMargin(marginsize);											//表示サイズの高さ増分設定(marginsize = 延長サイズ[上下均等配分・最大1コマ分の縦サイズ])
	SetSpeed(speed);													//リール回転速度設定(speed = リール回転速度[1フレーム当たりの縦スクロールサイズ])
	SetNowPosition(nowcharacternumber);									//リール位置強制移動(characternumber = 上段図柄番号)
}
void CReel::Draw()
{
	if (!B_visible) return;		//表示フラグOFF時はスルー

	//分割描画
	if (B_divide_draw)
	{
		DrawRectGraph(i_left, i_dest_upper_top, i_src_left, i_src_top, i_width, i_src_upper_height, i_handle, TRUE, FALSE);	//上部抽出画像描画
		DrawRectGraph(i_left, i_dest_lower_top, i_src_left,         0, i_width, i_src_lower_height, i_handle, TRUE, FALSE);	//下部抽出画像描画
	}
	//一括描画
	else
	{
		DrawRectGraph(i_left, i_dest_upper_top, i_src_left, i_src_top, i_width, i_src_upper_height, i_handle, TRUE, FALSE);	//抽出画像描画
	}
}
int  CReel::GetImageType()
{
	return i_now_image_type;	//表示リール画像タイプ返還
}
int  CReel::GetNowPosition()
{
	return i_now_position;		//リールの現在位置(上段リール図柄番号)返還
}
int  CReel::GetShowSegment()
{
	return i_show_segment;		//リール窓枠内表示コマ数返還
}
int  CReel::GetSpeed()
{
	return i_speed;				//リール回転速度(1フレーム当たりの縦スクロールサイズ)返還
}
CReel::ReelState CReel::GetState()
{
	return RS_state;			//リール状態返還
}
int  CReel::GetStopPosition()
{
	return i_stop_position;		//リール停止予定位置(上段リール図柄番号)返還
}
int  CReel::GetWidth()
{
	return i_width;				//リール横サイズ返還
}
void CReel::Hide()
{
	B_visible = FALSE;			//リール表示フラグOFF
}
void CReel::Initialize()
{
	i_character_height	= 1;		//リール図柄1コマ縦サイズ
	i_dest_lower_top	= 0;		//下部抽出画像描画y座標
	i_dest_upper_top	= 0;		//上部抽出画像描画y座標
	B_divide_draw		= FALSE;	//分割描画フラグ
	B_enable			= TRUE;		//リール稼働フラグ
	i_half_margin		= 0;		//表示サイズの高さ増分(ハーフサイズ)
	i_height			= 1;		//リール画像縦サイズ
	i_last_position		= 0;		//前フレームのリール位置(上段リール図柄番号)
	i_left				= 0;		//リール窓内画像の表示位置(左上x座標)
	i_now_image_type	= 0;		//表示リール画像タイプ
	i_now_position		= 1;		//リールの現在位置(上段リール図柄番号)
	i_show_segment		= 1;		//リール窓枠内表示コマ数
	i_speed				= 0;		//リール回転速度(1フレーム当たりの縦スクロールサイズ)
	i_src_left			= 0;		//表示画像抽出位置基本x座標
	i_src_lower_height	= 0;		//下部抽出画像縦サイズ
	i_src_top			= 0;		//表示画像抽出位置基本y座標
	i_src_upper_height	= 0;		//上部抽出画像縦サイズ
	RS_state			= RS_STOP;	//リール状態
	i_stop_position		= 1;		//リール停止予定位置(上段リール図柄番号)
	i_top				= 0;		//リール窓内画像の表示位置(左上y座標)
	i_total_character	= 2;		//リール図柄総数
	i_total_image_type	= 1;		//リール画像タイプの保持数
	i_total_margin		= 0;		//表示サイズの高さ増分(上下均等配分)
	B_visible			= TRUE;		//リール表示フラグ
	i_width				= 0;		//リール横サイズ
}
void CReel::LoadImageHandle(int totalcharacter, int totalimagetype, int reelimagehandle)
{
	int width;																			//リール元画像横サイズ取得用

	//リール画像計測
	if (GetGraphSize(reelimagehandle, &width, &i_height) != 0)
	{
		Message("class CReel::LoadImageHandle()-->グラフィックハンドルが不正です!");	//エラーメッセージ
		return;																			//現設定のまま続行
	}

	//リール図柄総数範囲未満の時の処理
	if (totalcharacter 図柄数の指定値が小さすぎます!");		//エラーメッセージ
		totalcharacter = i_show_segment + 1;											//リール図柄総数範囲外補正
	}
	
	//リール図柄総数範囲超過の時の処理
	if (totalcharacter > CHARACTER_MAX)
	{
		Message("class CReel::LoadImageHandle()-->図柄数の指定値が大きすぎます!");		//エラーメッセージ
		totalcharacter = CHARACTER_MAX;													//リール図柄総数範囲外補正
	}

	//リール画像タイプの保持数範囲未満の時の処理
	if (totalimagetype 画像保持数の指定値が小さすぎます!");	//エラーメッセージ
		totalimagetype = 1;																//リール画像タイプの保持数範囲外補正
	}
	
	//リール画像タイプの保持数範囲超過の時の処理
	if (totalimagetype > width)
	{
		Message("class CReel::LoadImageHandle()-->画像保持数の指定値が大きすぎます!");	//エラーメッセージ
		totalimagetype = width;															//リール画像タイプの保持数範囲外補正
	}

	i_handle			= reelimagehandle;												//リール画像ハンドルセット
	i_total_character	= totalcharacter;												//リール図柄総数セット
	i_total_image_type	= totalimagetype;												//リール画像タイプの保持数セット

	i_width = width / i_total_image_type;												//リール横サイズ算出
	i_character_height = i_height / i_total_character;									//リール図柄1コマ縦サイズ算出
	SetShowMargin(i_total_margin);														//表示サイズの高さ増分上限補正(SetShowMargin関数利用)
	i_src_left = i_now_image_type * i_width;											//表示画像抽出位置基本x座標セット
}
void CReel::Message(const TCHAR *message)
{
	MessageBox(NULL, _T(message), _T("確認"), MB_OK | MB_ICONWARNING);	//確認のみ
}
int  CReel::ReviseCharacterNumber(int characternumber)
{
	if ((characternumber %= i_total_character)  i_total_character)
	{
		Message("class CReel::SetNowPosition()-->図柄番号の指定値が範囲外です!");	//エラーメッセージ
		return;																		//呼び出し元に修正させる為、スルー
	}

	i_now_position = characternumber;												//リールの現在位置セット

	i_src_top = i_character_height * (i_now_position - 1) - i_half_margin;			//表示画像抽出位置基本y座標算出
	if ((i_src_top %= i_height)  i_character_height) marginsize = i_character_height;	//表示サイズの高さ増分範囲外補正2

	i_half_margin = marginsize / 2;											//表示サイズの高さ増分(ハーフサイズ[端数切捨て])セット
	i_total_margin = i_half_margin * 2;										//表示サイズの高さ増分(偶数補正値)セット
	i_dest_upper_top = i_top - i_half_margin;								//上部抽出画像描画y座標セット
}
void CReel::SetShowSegment(int showsegment)
{
	if (showsegment  SHOW_SEGMENT_MAX) showsegment = SHOW_SEGMENT_MAX;						//範囲外補正2

	if (showsegment > i_total_character - 1)
	{
		Message("class CReel::SetShowSegment()-->図柄数以上の設定は受け付けできません!");	//エラーメッセージ
		return;																				//呼び出し元に修正させる為、スルー
	}

	i_show_segment = showsegment;															//表示コマ数セット
}
void CReel::SetSpeed(int speed)
{
	if (speed  i_character_height) speed = i_character_height;		//速度制限(順回転時)

	i_speed = speed;												//リール回転速度セット
}
void CReel::SetState(ReelState reelstate)
{
	RS_state = reelstate;	//リール状態列挙子セット
}
void CReel::SetStopPosition(int characternumber)
{
	if (characternumber  i_total_character)
	{
		Message("class CReel::SetNowPosition()-->図柄番号の指定値が範囲外です!");	//エラーメッセージ
		return;																		//呼び出し元に修正させる為、スルー
	}

	i_stop_position = characternumber;												//停止予定位置セット

	RS_state = RS_CONTROL;															//リール状態を指定図柄停止制御中にする
}
void CReel::Show()
{
	B_visible = TRUE;		//表示フラグON
}
void CReel::Start()
{
	i_stop_position = 0;	//指定停止位置リセット

	RS_state = RS_ROUND;	//リール状態を回転開始にセット
}
void CReel::Stop()
{
	RS_state = RS_STOP;		//リール状態を回転停止にセット
}
void CReel::Update()
{
	if (!B_enable) return;																				//非稼動時はスルー

	//リール回転時の処理
	if (RS_state == RS_ROUND || RS_state == RS_RECIEVE || RS_state == RS_CONTROL)
	{
		i_src_top -= i_speed;																			//回転(スクロール)

		if ((i_src_top %= i_height)  0) nextposition = ReviseCharacterNumber(i_stop_position - 1);					//次番号設定(順回転時)

			if (i_now_position == nextposition)
			{
				SetNowPosition(i_stop_position);														//正位置に調える
				RS_state = RS_AFTER;																	//リール状態を停止制御完了にする
			}
		}
	}

	i_last_position = i_now_position;																	//図柄番号の保存

	//抽出画像設定(一括描画時)
	if (i_src_top 
#include 

#define WINDOW_WIDTH		1280								//ウインドウサイズ
#define WINDOW_HEIGHT		 720								//ウインドウ高さ
#define WINDOW_DEPTH		  32								//ビット深度
#define WINDOW_TITLE	"CReel Class - Tester"					//ウインドウタイトル
#define FONT_COLOR		0xff8800								//フォントカラー

//***アプリケーション本体***
int WINAPI WinMain(HINSTANCE h1, HINSTANCE hP, LPSTR lpC, int nC)
{
	SetOutApplicationLogValidFlag(FALSE);						//ログ出力OFF
	ChangeWindowMode(TRUE);										//ウインドウモード変更[FALSE・全文省略(デフォルト)は、全画面モード]
	SetGraphMode(WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_DEPTH);	//ウインドウサイズ&ビット深度設定
	SetWindowSizeChangeEnableFlag(TRUE);						//ウインドウサイズ変更可能フラグ設定
	SetWindowTextA(WINDOW_TITLE);								//ウインドウタイトル設定
	if (DxLib_Init() == -1) return -1;							//DxLibを初期化→DxLibが異常なら、アプリを異常終了
	SetDrawScreen(DX_SCREEN_BACK);								//描画画面を裏画面に切り替え

	//変数宣言
	CReel		reel;											//CReelクラスオブジェクト
	int			i_fhandle;										//フォントハンドル
	int			i_ghandle_panel;								//リールパネル画像ハンドル
	int			i_ghandle_reel;									//リール画像ハンドル
	int			i_key;											//最新入力キー
	int			i_lastkey;										//前回入力キー
	LONGLONG	LL_frametime;									//フレーム時間計測用
	LONGLONG	LL_starttime;									//処理時間計測用

	//変数初期化
	i_fhandle		= CreateFontToHandle("MS明朝", 16, -1);	//フォントハンドル作成
	i_ghandle_panel = LoadGraph("Data\\CReel_panel_2.png");		//リールパネル画像読み込み
	i_ghandle_reel  = LoadGraph("Data\\CReel_reel.png");		//リール画像読み込み
	i_lastkey		= 0;										//前回入力キー初期化
	LL_frametime	= 0;										//フレーム時間初期化
	LL_starttime	= 0;										//処理開始時刻初期化

	//CReelクラスオブジェクト個別設定(コンストラクタで一括設定も可能)
	reel.LoadImageHandle(12, 3, i_ghandle_reel);				//画像設定
	reel.SetDrawPosition(560, 120);								//表示位置設定
	reel.SetShowSegment(1);										//表示コマ数設定 
	reel.SetSpeed(10);											//速度設定 
	reel.SetShowMargin(81);										//表示高さ増分設定
	reel.SetNowPosition(1);										//初期停止位置設定

	//メインループ
	while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClsDrawScreen() == 0)
	{
		LL_frametime = GetNowHiPerformanceCount() - LL_starttime;	//フレーム時間保存
		LL_starttime = GetNowHiPerformanceCount();					//処理開始時刻保存

		i_key = GetJoypadInputState(DX_INPUT_KEY_PAD1);										//キーボードとジョイパッド1の状態取得

		//キー入力処理(前回の入力と違う場合のみ)
		if (i_key != i_lastkey)
		{
			if (i_key & PAD_INPUT_DOWN)		reel.Start();									//[↓] リール回転開始
			if (i_key & PAD_INPUT_LEFT)		reel.SetImageType(reel.GetImageType() - 1);		//[←] リール画像変更(画像番号--)
			if (i_key & PAD_INPUT_RIGHT)	reel.SetImageType(reel.GetImageType() + 1);		//[→] リール画像変更(画像番号++)
			if (i_key & PAD_INPUT_UP)		reel.SetSpeed(reel.GetSpeed() * -1);			//[↑] リール回転方向転換
			if (i_key & PAD_INPUT_1)		reel.Stop();									//[Z] リール回転強制停止
			if (i_key & PAD_INPUT_2)		reel.SetSpeed(reel.GetSpeed() - 1);				//[X] リール速度上方向加速
			if (i_key & PAD_INPUT_3)		reel.SetSpeed(reel.GetSpeed() + 1);				//[C] リール速度下方向加速
			if (i_key & PAD_INPUT_4)		reel.SetStopPosition(1);						//[A] リール停止位置[1番図柄]指定停止
			if (i_key & PAD_INPUT_5)		reel.SetShowSegment(reel.GetShowSegment() - 1);	//[S] リール窓枠内表示コマ数(--)
			if (i_key & PAD_INPUT_6)		reel.SetShowSegment(reel.GetShowSegment() + 1);	//[D] リール窓枠内表示コマ数(++)
			if (i_key & PAD_INPUT_9)		break;											//[ESC]アプリ終了
		}

		i_lastkey = i_key;																	//入力キー保存

		reel.Update();								//リールアップデート

		reel.Draw();								//リール描画
		DrawGraph(390, 0, i_ghandle_panel, TRUE);	//パネル描画

		DrawFormatStringToHandle(50, 120, FONT_COLOR, i_fhandle, "reel.i_now_image_type   =   %3d"	, reel.GetImageType());							//リールイメージ番号
		DrawFormatStringToHandle(50, 140, FONT_COLOR, i_fhandle, "reel.i_now_position     =   %3d"	, reel.GetNowPosition());						//現在図柄位置
		DrawFormatStringToHandle(50, 160, FONT_COLOR, i_fhandle, "reel.i_show_segment     =   %3d"	, reel.GetShowSegment());						//リール窓枠内表示コマ数
		DrawFormatStringToHandle(50, 180, FONT_COLOR, i_fhandle, "reel.i_speed            =   %3d"	, reel.GetSpeed());								//回転(スクロール)速度
		DrawFormatStringToHandle(50, 200, FONT_COLOR, i_fhandle, "reel.RS_state           =   %3d"	, reel.GetState());								//状態
		DrawFormatStringToHandle(50, 220, FONT_COLOR, i_fhandle, "reel.i_stop_position    =   %3d"	, reel.GetStopPosition());						//指定停止図柄番号
		DrawFormatStringToHandle(50, 280, FONT_COLOR, i_fhandle, "  Frame Time[μs]       = %5lld"	, LL_frametime);								//フレーム時間[μs]
		DrawFormatStringToHandle(50, 260, FONT_COLOR, i_fhandle, "Process Time[μs/f]     = %5lld"	, GetNowHiPerformanceCount() - LL_starttime);	//処理時間[μs/f]
	}

	DxLib_End();	//DxLib終了処理

	return 0;		//アプリケーション正常終了
}
列挙子のネーミングが簡素過ぎますが、状態値を列挙体で表現しました。

メンバ変数の宣言と初期化は綺麗に分けてあるので、enum文では定数の定義のみ行っています。



状態の種類に関しては、骨格を参考にした旧作のクラスがパチスロ専用の仕様だったので、
このままでは依存しまくりの融通が利かない気がします。
他のジャンルでも使える様にと想っても、他のジャンルが思い浮かばない・・・。

回っているかいないか、停止制御中かそうでないか、みたいに『ある・ない』方式に考えて個別のフラグを用意すれば、
シンプル且つ拡張性が高い気もしますが、列挙体が劣るとも思えませんし、難しい問題です。



描画用変数をやたらと増やしましたが、決して間違いではないと考えています。←かと言って、正解でもない気が・・・

DrawRectGraph関数の仕様は全く調べていませんが(描画はBitBltなのかな???)、DXライブラリの描画処理は連続でやるのが鉄則だと認識しているので、
ダブリ表記が気になりますけれど、この様な形式にしました。でも、後で元に戻すかも知れません。

分割描画はメモリ上の同じ画像データを参照しているものの、連続はしていないので、微妙な所です。



表示フラグと稼働フラグは、ハッキリ言って使う事はありません。

クラスを利用する側で作っても良い(実質同じだと思う)ので、後にバッサリ斬るかも知れません。



簡単なミニゲームと言っても全然思いつきませんが、1リール1コマ表示で、リール画像をそのまま使ったゲームを考案中です。
定番の『ジャン!ケン!ポン!ズコー!!!』でも良かったんですが、画像を用意するのが面倒なので却下しました。
SEも付けない予定なので、しようもない駄作になりそうです。



ミニゲームを作れば今回で結末を迎えられましたが、次回以降にお見送りさせて頂きます。

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