はかせのラボ

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

DirectX 後回しにしていたものをつけました

あいさつ

どうも、はかせです。
今回は色々後回しにしていた機能を付けたのでその報告です。

自機の移動制限

弾幕シューティングだけじゃなくゲーム全般の話だと思うんですけど
基本自機とかプレイヤーって無制限には動けませんよね。
行けるとこと行けないとこがあるのが普通だと思います。

今までつけなきゃなと思いつつやれメモリがー
FPSがー透過がーとずるずる後回しになっていた機能をつけました。

実装としては単純でスクリーン座標を取得して
その値が移動可能範囲外なら移動する前の座標に戻しています。
(スクリーン座標取得はこちらの記事をどうぞ)

void Mover::Update()
{
	auto transform = mGameObject->GetTransform();
	//移動前の座標保持
	auto prePos = transform->Position;
	//入力を受けて移動
	if (mDXInput->GetKey(DIK_LEFTARROW)) transform->Position.x -= mMoveSpeed;
	if (mDXInput->GetKey(DIK_RIGHTARROW)) transform->Position.x += mMoveSpeed;
	if (mDXInput->GetKey(DIK_UPARROW)) transform->Position.y += mMoveSpeed;
	if (mDXInput->GetKey(DIK_DOWNARROW)) transform->Position.y -= mMoveSpeed;
	//スクリーン座標取得
	auto screenPos = mGameObject->GetDXManager()->GetDXCamera()->WorldToScreenPoint(transform);
	auto screenPosX = screenPos.m128_f32[0];
	auto screenPosY = screenPos.m128_f32[1];
#if _DEBUG
	std::wstringstream ws;
	ws << "X:" << screenPosX << "Y:" << screenPosY << std::endl;
	OutputDebugString(ws.str().c_str());
#endif

	if(!IsInGameScreen(screenPosX,screenPosY))
	{
		transform->Position = prePos;
	}
}
//移動可能範囲かどうか
bool Mover::IsInGameScreen(float screenX, float screenY)
{
	if (cMinScreenXPos <= screenX && cMaxScreenXPos >= screenX) 
	{
		if (cMinScreenYPos <= screenY && cMaxScreenYPos >= screenY) return true;
	} 
	return false;
}

ちなみに移動可能なスクリーン座標なんですが
手動計測した値を定数として設定しています。

ボム所持数表示

これも必要だなと思いつつ後回しになっていた機能です。
元々ボムの所持数は変数としてあったので
その値をそのまま表示します。

//BOMB表示テキスト
auto bomb = Instantiate();
mBombText = bomb->AddComponent<DXText>();
auto bombTransform = bomb->GetTransform();
//位置と大きさ
bombTransform->Scale = DirectX::XMFLOAT3(0.07f, 0.07f, 1.0f);
bombTransform->Position = DirectX::XMFLOAT3(1.2f, 0.5f, -1.1f);
mAwakeObject.push_back(bomb);

mBombRP =
		std::unique_ptr<ReactiveProperty<int>, Deleter>
		(new ReactiveProperty<int>(),Deleter());

mBombRP->Subscribe
(
[&](int value)->void
{
	std::wstringstream bomb;
	bomb << value;
	mBombText->UpdateText(bomb.str().c_str());
	bomb.clear();
}
);

ボス用の弾幕

今まで何個か弾幕を作って順繰り撃っていました。
ただボスの弾幕といえば画面いっぱいに弾があって
ミリ単位での移動でギリギリかわせるようなものだと思います。

今回は私の知人の協力をうけてボス用の弾幕を作ってみました。
今まで作った弾幕を複数同時に撃っています。
また弾幕の発射間隔や弾速も調整しました。

今まで説明した追加機能と一緒に動画にしました。
動画内で弾にたくさん当たっていますが
デバッグ用の無敵モードにしているので死にません。
(そうしないと私がまともにできないため)
youtu.be

あとがき

今回は後回しにしていた機能の実装報告でした。
どれも今まで作った機能の組み合わせで実現でき、
実装に詰まることもそこまで時間がかかることもありませんでした。

簡単に実装できると思ったことって後回しにしがちですよね。
ただそういう所がゲームのクオリティだったり
手触り感に影響するんですよね。
(「神は細部に宿る」「微に入り細を穿つ」というような言葉もありますしね)

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

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