ちゃんと動いているのか未確認ですが、2~3コマ表示設定にも対応しました。回転中にも切り替えができます。
それと、現在の図柄位置の取り扱いについて、思い切って変更しようと思います。いや、変更しました。
※リールパネル画像が、1~3コマ用に変わっております。
"CReel_panel_2.png"
[album]893[/album]
"CReel_reel.png"
[album]891[/album]
"Class_CReel_100.h"
//*************************************************
// CReel Class Ver. 0.04 2014.11.11 by V30
//*************************************************
#ifndef CLASS_CREEL_100
#define CLASS_CREEL_100
#define CHARACTER_MAX 21 //最大図柄数
#define SHOW_SEGMENT_MAX 3 //最大表示コマ数
#define SHOW_SEGMENT_MIN 1 //最小表示コマ数
//リール表示クラス[縦1列表示型] ver. 0.04
class CReel
{
private:
int i_character_height; //リール図柄1コマ縦サイズ
int i_character_total; //リール図柄総数
BOOL B_enable; //リール稼働フラグ
int i_handle; //リール画像ハンドル
int i_height; //リール画像縦サイズ
int i_last_posision; //前フレームのリール位置(上段リール図柄番号)
int i_left; //リール窓内画像の表示位置(左上x座標)
int i_now_image_type; //表示リール画像タイプ
int i_now_position; //リールの現在位置(上段リール図柄番号)
int i_show_margin; //表示サイズの高さ増分(上下均等配分)
int i_show_segment; //リール窓枠内表示コマ数
int i_speed; //リール回転速度(1フレーム当たりの縦スクロールサイズ)
int i_src_top; //表示画像抽出位置基本y座標
int i_src_h[2]; //抽出画像縦サイズ[array → 0 = 抽出画像1, 1 = 抽出画像2]
int i_src_y[2]; //表示画像抽出位置y座標[array → 0 = 抽出画像1, 1 = 抽出画像2]
int i_state; //リールの回転状態(0 = 停止中, 1 = 回転中, 2 = 停止受付後, 3 = 停止制御中, 4~ = 停止制御後~自由設定)
int i_stop_position; //リール停止予定位置(上段リール図柄番号)
int i_top; //リール窓内画像の表示位置(左上y座標)
int i_total_image_type; //リール画像タイプの保持数
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 = 1,
int marginsize = 0,
int speed = 30,
int nowcharacternumber = 1
);
//描画
void Draw();
//表示リール画像取得
int GetImageType();
//現在位置[図柄番号]取得
int GetNowPosition();
//リール窓枠内表示コマ数取得
int GetShowSegment();
//速度取得
int GetSpeed();
//状態取得
int 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);
//リール描画基本位置設定(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(int statenumber);
//停止位置指定(characternumber = 上段図柄番号)
void SetStopPosition(int characternumber);
//リール表示フラグON
void Show();
//リール回転スタート
void Start();
//リール回転強制停止
void Stop();
//アップデート
void Update();
};
#endif //!CLASS_CREEL_100
//*************************************************
// CReel Class Ver. 0.04 2014.11.11 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 == FALSE) return; //表示フラグOFF時はスルー
//一括描画(分割描画時の上部描画)
DrawRectGraph(i_left, i_top - i_show_margin / 2, i_now_image_type * i_width, i_src_y[0], i_width, i_src_h[0], i_handle, TRUE, FALSE); //抽出画像1描画
//分割描画時の下部描画
if (i_src_top >= i_height - i_character_height * i_show_segment - i_show_margin)
{
DrawRectGraph(i_left, i_top - i_show_margin / 2 + i_src_h[0], i_now_image_type * i_width, i_src_y[1], i_width, i_src_h[1], i_handle, TRUE, FALSE); //抽出画像2描画
}
}
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フレーム当たりの縦スクロールサイズ)返還
}
int CReel::GetState()
{
return i_state; //リールの回転状態(0 = 停止中, 1 = 回転中, 2 = 停止受付後, 3 = 停止制御中, 4~ = 停止制御後~自由設定)返還
}
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 = 0; //リール図柄1コマ縦サイズ
i_character_total = 2; //リール図柄総数
B_enable = TRUE; //リール稼働フラグ
i_height = 0; //リール画像縦サイズ
i_last_posision = 0; //前フレームのリール位置(上段リール図柄番号)
i_left = 0; //リール窓内画像の表示位置(左上x座標)
i_now_image_type = 0; //表示リール画像タイプ
i_now_position = 1; //リールの現在位置(上段リール図柄番号)
i_show_margin = 0; //表示サイズの高さ増分(上下均等配分)
i_show_segment = 1; //リール窓枠内表示コマ数
i_speed = 30; //リール回転速度(1フレーム当たりの縦スクロールサイズ)
i_src_top = 0; //表示画像抽出位置基本y座標
i_src_h[0] = 0; //抽出画像縦サイズ[array → 0 = 抽出画像1, 1 = 抽出画像2]
i_src_h[1] = 0; //抽出画像縦サイズ[array → 0 = 抽出画像1, 1 = 抽出画像2]
i_src_y[0] = 0; //表示画像抽出位置y座標[array → 0 = 抽出画像1, 1 = 抽出画像2]
i_src_y[1] = 0; //表示画像抽出位置y座標[array → 0 = 抽出画像1, 1 = 抽出画像2]
i_state = 0; //リールの回転状態(0 = 停止中, 1 = 回転中, 2 = 停止受付後, 3 = 停止制御中, 4~ = 停止制御後~自由設定)
i_stop_position = 0; //リール停止予定位置(上段リール図柄番号)
i_top = 0; //リール窓内画像の表示位置(左上y座標)
i_total_image_type = 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()-->グラフィックハンドルが不正です!"); //エラーメッセージ
i_height = 0;
return;
}
if (totalcharacter CHARACTER_MAX) totalcharacter = CHARACTER_MAX; //リール図柄総数範囲外補正2
if (totalimagetype width) totalimagetype = width; //リール画像タイプの保持数範囲外補正2
i_character_total = totalcharacter; //リール図柄総数セット
i_total_image_type = totalimagetype; //リール画像タイプの保持数セット
i_handle = reelimagehandle; //リール画像ハンドルセット
i_width = width / i_total_image_type; //リール横サイズ算出
i_character_height = i_height / i_character_total; //リール図柄1コマ縦サイズ算出
SetShowMargin(i_show_margin); //表示サイズの高さ増分上限補正(SetShowMargin関数利用)
}
void CReel::Message(const TCHAR *message)
{
MessageBox(NULL, _T(message), _T("確認"), MB_OK | MB_ICONWARNING); //確認のみ
}
void CReel::SetDrawPosition(int left, int top)
{
i_left = left; //リール基本描画位置x座標セット
i_top = top; //リール基本描画位置y座標セット
}
void CReel::SetEnable(BOOL flag)
{
B_enable = flag; //稼働フラグセット
}
void CReel::SetImageType(int imagetype)
{
imagetype = imagetype % i_total_image_type; //範囲外補正1
if (imagetype i_character_total)
{
Message("class CReel::SetNowPosition()-->図柄番号の指定値が範囲外です!"); //エラーメッセージ
return;
}
i_now_position = characternumber; //リールの現在位置セット
i_src_top = i_character_height * (i_now_position - 1) - i_show_margin / 2; //表示画像抽出位置基本y座標算出
i_src_top = i_src_top % i_height; //表示画像抽出位置基本y座標補正1
if (i_src_top i_character_height) marginsize = i_character_height; //表示サイズの高さ増分範囲外補正2
i_show_margin = marginsize; //表示サイズの高さ増分セット
}
void CReel::SetShowSegment(int showsegment)
{
if (showsegment SHOW_SEGMENT_MAX) showsegment = SHOW_SEGMENT_MAX; //範囲外補正2
i_show_segment = showsegment; //表示コマ数セットセット
}
void CReel::SetSpeed(int speed)
{
if (speed i_character_height) speed = i_character_height; //速度制限(順回転時)
i_speed = speed; //リール回転速度セット
}
void CReel::SetState(int statenumber)
{
i_state = statenumber; //状態番号セット
}
void CReel::SetStopPosition(int characternumber)
{
if (characternumber i_character_total)
{
Message("class CReel::SetNowPosition()-->図柄番号の指定値が範囲外です!"); //エラーメッセージ
return;
}
i_stop_position = characternumber; //停止予定位置セット
i_state = 3; //状態値を指定図柄停止制御中にする
}
void CReel::Show()
{
B_visible = TRUE; //表示フラグON
}
void CReel::Start()
{
i_stop_position = 0; //指定停止位置リセット
i_state = 1; //リール回転開始
}
void CReel::Stop()
{
i_state = 0; //リール回転停止
}
void CReel::Update()
{
if (B_enable == FALSE) return; //非稼動時はスルー
//リール回転時の処理
if (i_state > 0 && i_state i_character_total) i_now_position -= i_character_total; //現在図柄位置補正
#ifdef _DEBUG
//i_now_positionの値チェック
if (i_now_position i_character_total)
{
Message("class CReel::Update() -. i_now_positionの値が不正です!"); //エラーメッセージ
}
#endif
//順回転時の現在位置(上段図柄番号)算出
if (i_speed > 0)
{
i_now_position++; //逆回転用から順回転用に補正
if (i_now_position > i_character_total) i_now_position -= i_character_total; //図柄番号範囲補正
}
//指定図柄停止制御
if (i_state == 3 && i_now_position != i_last_posision && i_now_position == i_stop_position)
{
SetNowPosition(i_stop_position); //正位置に調える
i_state = 4; //状態値を停止制御完了にする
}
}
i_last_posision = 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; //前回入力キー
//変数初期化
i_fhandle = CreateFontToHandle("MS明朝", 24, -1); //フォントハンドル作成
i_lastkey = 0; //前回入力キー初期化
i_ghandle_panel = LoadGraph("Data\\CReel_panel_2.png"); //リールパネル画像読み込み
i_ghandle_reel = LoadGraph("Data\\CReel_reel.png"); //リール画像読み込み
//CReelクラスオブジェクト個別設定(コンストラクタで一括設定も可能)
reel.LoadImageHandle(12, 3, i_ghandle_reel); //画像設定
reel.SetDrawPosition(560, 120); //表示位置設定
reel.SetShowSegment(3); //表示コマ数設定
reel.SetSpeed(10); //速度設定
reel.SetShowMargin(80); //表示高さ増分設定
reel.SetNowPosition(1); //初期停止位置設定
//メインループ
while (ScreenFlip() == 0 && ProcessMessage() == 0 && ClsDrawScreen() == 0)
{
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(30, 120, FONT_COLOR, i_fhandle, "reel.i_now_image_type = %3d", reel.GetImageType()); //リールイメージ番号
DrawFormatStringToHandle(30, 150, FONT_COLOR, i_fhandle, "reel.i_now_position = %3d", reel.GetNowPosition()); //現在図柄位置
DrawFormatStringToHandle(30, 180, FONT_COLOR, i_fhandle, "reel.i_show_segment = %3d", reel.GetShowSegment()); //リール窓枠内表示コマ数
DrawFormatStringToHandle(30, 210, FONT_COLOR, i_fhandle, "reel.i_speed = %3d", reel.GetSpeed()); //回転(スクロール)速度
DrawFormatStringToHandle(30, 240, FONT_COLOR, i_fhandle, "reel.i_state = %3d", reel.GetState()); //状態
DrawFormatStringToHandle(30, 270, FONT_COLOR, i_fhandle, "reel.i_stop_position = %3d", reel.GetStopPosition()); //指定停止図柄番号
}
DxLib_End(); //DxLib終了処理
return 0; //アプリケーション正常終了
}
上段位置番号が分かれば下段の位置番号は簡単に導き出せるので、個人的に慣れ親しんでいる下段基準を撤廃します。
今になって改めて言いますが、リールの図柄番号は、継ぎ目で切り離して最上段が1番で、以降1ずつ増える形式に設定しています。
最下段が1番の形式にしたい場合は、クラス外で計算して変換するか、後でクラス内をイジって下さい。
昨夜かなり大まかにつぶやきました件で、リールのスタート直後(1コマ未満進む間)は、
最高速以外の時に現在の図柄位置(i_now_position)がスタート前の図柄位置と同じ数値を示している期間があるので、
その期間にSetStopPosition関数でスタート前の位置番号を指定すると、
逆回転で一気に戻って指定位置(= スタート前の位置番号が示す正位置)に停止していました。
上記現象は、前フレームのi_now_positionを記憶するi_last_position変数を用意して防ぐ事ができました。
その副作用で、停止中に現在の停止位置番号をSetStopPosition関数に放り込んで呼んでみると、
勝手に1周回って開始位置の正位置に戻りますが、バグではありません。
回転中の正位置の時に同様の事をやると、1周回らずに、ちゃんとビタ停止します。
コード一文で勝手に1周回らないように修正できますが、なんか面白いし、他の仕様との絡みもあるので、まだ放って置きます。
どこか重大なミスがありそうなので、残った自動補正やエラー処理の記述も含めて、もうちょっとプログラム内を巡回しようと思います。