はかせのラボ

私の頭の中を書いていく雑記ブログです

DirectX 長押しと連打の判別

あいさつ

どうも、はかせです。
今回はキーの長押しと連打の判別です。

実装理由

色々脱線してて忘れてるかもしれませんが私は今弾幕シューティングを作っています。
みなさんは弾幕シューティングと聞いて何が思いつきますか?

東方とか色々あるかもですが、私は怒首領蜂というゲームが思いつきます。
なので作ろうとしてる弾幕シューティングも怒首領蜂に寄せようと思っています。
(完コピに近いものが出来たらベストです)

怒首領蜂ではボタン連打で連射、長押しでレーザーを打ちます。
これを実装するために今回の判別を実装しました。

実装方法

最初の入力で長押し判定フラグを立てて
フラグが立った状態のまま、再び入力されていたら長押しと判定しています。
長押し判定フラグは入力されていなければ倒しています。

コードです。

//長押し判定フラグ
bool mIsLongPush;

void Player::Update()
{
	//毎フレームカウントを行う
	mWaitCount++;

	//ボム
	if (mDXInput->GetKeyDown(DIK_X))
	{
		Bomb();
	}

	//ショットボタンが押されているか
	if(mDXInput->GetInputState(DIK_Z))
	{
		//長押ししているか
		if(mIsLongPush)
		{
			//打てるか
			if (CanShot()) 
			{
				for (int i = 0; i < mPower; i++)
				{
					BULLET_SETTING_DATA data;
					data.transform = mGameObject->GetTransform();
					data.tag = PlayerBullet;
					data.xVectol = 0.0f;
					data.yVectol = 0.05f;
					data.texturePath = _T("Texture/BulletL2.png");
					data.scaleRatio = 0.3f;
					//弾を出す
					auto game = mBulletPool->GetBullet(data);
					auto gameTransform = game->GetTransform();
					//各弾同士の間隔
					auto offset = gameTransform->Scale.x;
					//弾同士のオフセット計算
					gameTransform->Position.x += offset * (i - (float)mPower / 3.0f);
				}
				mGameObject->GetDXResourceManager()->GetSEDXSound()->ResetSound();
				mGameObject->GetDXResourceManager()->GetSEDXSound()->Play();
			}
		}
		//長押ししていない
		else
		{
			//長押しフラグを立てておく
			mIsLongPush = true;

			for (int i = 0; i < mPower; i++)
			{
				BULLET_SETTING_DATA data;
				data.transform = mGameObject->GetTransform();
				data.tag = PlayerBullet;
				data.xVectol = 0.0f;
				data.yVectol = 0.05f;
				data.texturePath = _T("Texture/Bullet3.png");
				data.scaleRatio = 0.3f;
				//弾を出す
				auto game = mBulletPool->GetBullet(data);
				auto gameTransform = game->GetTransform();
				//各弾同士の間隔
				auto offset = gameTransform->Scale.x;
				//弾同士のオフセット計算
				gameTransform->Position.x += offset * (i - (float)mPower / 3.0f);
			}
			mGameObject->GetDXResourceManager()->GetSEDXSound()->ResetSound();
			mGameObject->GetDXResourceManager()->GetSEDXSound()->Play();
		}
	}
	else
	{
		mIsLongPush = false;
		//発射しなかった場合は発射可能状態にしておく
		//-1しているのは次の判定では+1して判定するから
		mWaitCount = mCoolCount - 1;
		//SEをリセットしておく
		mGameObject->GetDXResourceManager()->GetSEDXSound()->Stop();
	}
}

我ながらものすごいごり押し実装だと思います・・・
ネストが深くコードが追いづらいですよね。すみませんorz

ここだけでなく他にもこんな感じのごり押し実装があって
その実装を修正したりするだけでもかなりの時間を持ってかれそうです。

実際タスクシステム開発と並行してやっていたのですが、
このままでいつまでたっても進められないということで
修正を一旦置いて置き実装を進める決断をしました。
(コードはまたタイミングをみて直します)

あとがき

今回は長押しと連打の判別でした。

今回のようなごり押し実装が積もり積もって
俗にいうスパゲティコードになってしまうんでしょうねorz

そんなことにならないよう気を付けたいんですが、
実力が全然足りませんorz

精進します。

それでは今回はこの辺でノシ

今回作ったものはgithubに上げました。
github.com