汎用フィールドクラス
最近、何時間もかけて更新しているので、
今日は軽めのネタで。
例えば、
テトリスやリバーシなどのパズルゲームや、
SLGやRPGでのマップなどを作る際には、
必ず2次元のフィールドが必要となります。
そういった場合に使える、汎用のフィールドクラスを公開します。
(…まあ、なんてことはないですが…)
まずは、ヘッダファイル(Field.h)
#pragma once /** * 汎用フィールドクラス */ class CField { private: int *m_field; int m_width; int m_height; public: CField(void) {Init();} ~CField(void) {Destroy();} void Resize(int width, int height); void Clear(); int GetAt(int x, int y); void SetAt(int x, int y, int value); int *GetAddress(int x, int y); int GetWidth() { return m_width; } int GetHeight() { return m_height; } private: void Init(); void Destroy(); bool IsRange(int x, int y); };
#pragma onceっていうのは、VCだけにある特殊な指令で、
2重インクルードを避けるための指令です。
VC以外の環境の場合は、#ifdefに置き換えてくらはい。
で、CPPファイル(Field.cpp)
#include ".\field.h" // ============================================================================ // 初期化処理 // ============================================================================ void CField::Init() { m_width = 0; m_height = 0; m_field = 0; } // ============================================================================ // フィールドのリサイズ // @param x, y サイズ // ============================================================================ void CField::Resize(int x, int y) { if(x < 1 || y < 1) return; Destroy(); m_width = x; m_height = y; m_field = new int[x * y]; Clear(); } // ============================================================================ // フィールドのクリア // ============================================================================ void CField::Clear() { int *ptr = GetAddress(0, 0); for(int j = 0; j < m_height; j++) { for(int i = 0; i < m_width; i++) { *ptr = 0; ptr++; } } } // ============================================================================ // フィールドの破棄 // ============================================================================ void CField::Destroy() { if(m_field != 0) delete[] m_field; Init(); } // ============================================================================ // フィールドを取得 // @param x, y 座標 // ============================================================================ int CField::GetAt(int x, int y) { if(!IsRange(x, y)) return 0; return m_field[m_width * y + x]; } // ============================================================================ // フィールドに値を設定 // @param x, y 座標 // @param value 値 // ============================================================================ void CField::SetAt(int x, int y, int value) { if(!IsRange(x, y)) return; m_field[m_width * y + x] = value; } // ============================================================================ // フィールドのアドレスを取得 // @param x, y 座標 // ============================================================================ int *CField::GetAddress(int x, int y) { if(!IsRange(x, y)) return 0; return &m_field[m_width * y + x]; } // ============================================================================ // 指定された座標が正常な範囲であるかをチェック // @param x, y 座標 // ============================================================================ bool CField::IsRange(int x, int y) { if(m_field == 0) return false; if(x > m_width - 1 || y > m_height - 1) return false; if(x < 0 || y < 0) return false; return true; }
使い方は、こんな感じです。
CField field; field.Resize(width, height); int *ptr = field.GetAddress(0, 0); for(int j = 0; j < field.GetHeight(); j++) { for(int i = 0; i < field.GetWidth(); i++) { cout << *ptr << endl; ptr++; } }