第2版を参照のことInputクラスの実装。
現状対応しているのは、大きさのあるボタンだけ。=つまりタッチスクリーン。
ゲーム側からの使い方=================
○ボタンの追加・削除
bool addButton(id_t, rect_t);
bool moveButton(id_t, rect_t);
bool removeButton(id_t);
bool hasButton(id_t);
追加・削除は状況に応じてどんどん行う。
画面が変わったときに一斉にadd,removeを行い、タッチスクリーン上のボタンが動いているときにmoveを行うイメージ。
ボタンを一意に表すidは、ゲーム側が自由に設定できる。そのほうがゲーム側が便利なので。
その代わり、idがかぶらないようにする責任もゲーム側が負う。(ゲーム側はたぶんenumでボタンを管理するだろうが、enumのスタート値にオフセットを付けておくとか)
idがかぶると、ボタン追加に失敗する。
なお、id=0は予約済。エラー扱い。id=1も予約するかもしれない。
とりあえず、idは0x1000_0000以上の値を使うようにしたい。
○ボタンの有効・無効
bool enableButton(id_t);
bool disableButton(id_t);
bool isEnableButton(id_t);
追加したらデフォルトで有効になる。
無効にすると、ボタンの中の時間は止まる。つまり、prevOnとかが維持される。
○ボタン状態取得
bool isOn(id_t);
bool isOff(id_t);
bool hasPressed(id_t);
bool hasReleased(id_t);
bool hasMoved(id_t);
point_t getPoint(id_t);
point_t getMovedSize(id_t);
point_t getPrevPoint(id_t);
SButtonSized& getButton(id_t);
一般的な情報がそのまま取れる。
大きさのあるボタンなので、ボタンのどこを押しているかも取得可能。
getButton()で取得してからisOn()などを使うこともできる。
存在しないidを指定したときの動作は未定義。
リピート押しはまだ実装していない。
○サンプリング
void sampling();
ボタン状態をサンプリング(更新)する。
ゲームのexecが走る前に呼び出すのがよい。
○デバッグ表示
void description();
登録されているボタンすべての情報が表示される。
Inputクラス内部の実装=======================
○ボタンの持ち方
マップ。ボタンの追加・削除などの操作は、ほぼmapの操作だけ。
SInputButton構造体は、Inputクラスの中でのボタンの状態を表す。
std::map<id_t, SInputButton>
struct Input::SInputButton{
id_t id; //id. mapのキーと同じ値
bool isEnable; //有効かどうか
SButtonSized button; //ボタン
char name[16]; //識別名
};
SButtonSized構造体は、大きさのあるボタンを表す。
SButton構造体は、大きさの無いボタンを表す。(Aボタンや、キーボードのキーなど想定)
struct SButton{
bool isOn();
bool isOff();
bool hasPressed();
bool hasReleased();
private:
bool on;
bool prevOn;
};
struct SButtonSized: public SButton{
bool hasMoved();
point_t getPoint();
point_t getPrevPoint();
point_t getMovedSize();
rect_t getRect();
void setRect(rect_t);
private:
rect_t rect;
point_t point;
point_t prevPoint;
};
○サンプリングの方法
iPhoneのタッチイベントを保持しておき、サンプリング周期ごとに翻訳。
InputSamplerクラスが行う。
○流れ
(iPhoneコード)
→-(void) touchesBegan: withEvent;
→InputSampler::addTouchBegan();
(ゲーム内)
→Input::sampling();
→InputSampler::samplingData(Input&);
○コード
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
for (id touch in touches) {
inputSampler.addTouchBegan(touch);
}
}
void InputSampler::addTouchBegan(UITouch *touch){
//リストに追加
}
void InputSampler::samplingData(Input&){
//Inputの内部を直接触る
//on->prevOn, point->prevPointに代入
//リストを走査、ボタンの範囲内のタッチがあったら、on,pointを書き込み
}
PR