ある軌道にそって弾を飛ばす方法

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
FRITIA
記事: 6
登録日時: 3年前

ある軌道にそって弾を飛ばす方法

#1

投稿記事 by FRITIA » 1年前

龍神録プログラミングの館を参考に弾幕サンプルプログラムを作成しました。現在このプログラムを使って東方地霊殿の1面のDNAの形をした弾幕を再現しようとしているのですが、思うようにプログラムが組めなくて困っています。
パスアニメーションのような感じで、弾1つ1つをサイングラフの軌道に動かせば組めると思うのですが、組み方が全く思いつかないため、どなたかアドバイスをお願いします。

例として、直線に発射する弾幕のサンプルを載せます。

header

コード:

#include"AbstractBossShotPattern.h"

class BossShotPattern008 : public AbstractBossShotPattern
{
public:
	BossShotPattern008(const GameScene& gameScene);
	virtual ~BossShotPattern008(void) = default;
	void draw(void) const override {}
	void shotUpdate(GameScene& gameScene, BossBulletManager& shot, Boss& boss, Player& player) override;
private:
	const int _TM000 = 120;
	float _shotAngle;
	float _shotAngleRate;
	float _shotSpeed;
	int _time;
	float _vx, _vy;
};
cpp

コード:

using namespace std;

BossShotPattern008::BossShotPattern008(const GameScene& gameScene) : 
	AbstractBossShotPattern(gameScene),
	_shotAngle(Define::PI / 4.0f),
	_shotAngleRate(0.0f),
	_shotSpeed(2.0f),
	_time(0),
	_vx(0.0f),
	_vy(0.0f)
{
}

void BossShotPattern008::shotUpdate(GameScene& gameScene, BossBulletManager& shot, Boss& boss, Player& player)
{
	_time = boss.getShotCounter() % _TM000;
	int time = boss.getShotCounter();

	if (_time == 0)
	{
		//引数:X座標, Y座標, 角度, スピード, 弾の種類, 弾の色, 弾の状態
		shot.getBullet().emplace_back(make_shared<BossBullet>(
			boss.getX(),
			boss.getY(),
			0.0f,
			0.0f,
			EnemyBulletImage::getIns()->eKodama,
			EnemyBulletImage::getIns()->eBlue,
			0
			)
		);
	}
	
	// 弾の移動処理をコンストラクタではなく、直接ここに計算している。
	_vx = cosf(_shotAngle) * _shotSpeed;
	_vy = sinf(_shotAngle) * _shotSpeed;

	for (int i = 0; i < shot.getBullet().size(); i++)
	{
		shot.getBullet()[i]->setX(shot.getBullet()[i]->getX() + _vx);
		shot.getBullet()[i]->setY(shot.getBullet()[i]->getY() + _vy);
	}
}

アバター
usao
記事: 1887
登録日時: 11年前

Re: ある軌道にそって弾を飛ばす方法

#2

投稿記事 by usao » 1年前

「東方なんたら~」とか言われてもそれを知らない人には通じないので,きちんと自分の言葉で所望の挙動を説明されたい.
これは他者に話が伝わるか否かだけでなく,自分自身の中で 具体的/詳細 に物事を捉えるのにも必要なステップであると思う.
(自分の中で 漠然としたもの は実装できないよ.細かくかみ砕いて細部まで具体化しないと.)


例えば弾がX軸に平行に右向きに撃ちだされたとしたら,時間と共に右の方向に動いていくんだけども,それだけではなくて,上下方向にある振幅でsin関数な動きもしてほしい

…みたいな話なのだろうか?
(文章後半を読んだ雰囲気から想像)

仮にそうだとしたら,コレを弾自身から見た話として書けば
【「前方」には等速直線運動だが,それと鉛直な「左右方向」にsinカーブな運動をする】とか言えるよね.
このくらいに達成すべきことを具体的にしてみれば,実装できるんじゃない?
(あなたの所望の挙動がコレとは異なるとしても話としては同様)

この場合なら,「前方」と「左右方向」の座標を個別に扱ってやればよさそうだよね.

アバター
usao
記事: 1887
登録日時: 11年前

Re: ある軌道にそって弾を飛ばす方法

#3

投稿記事 by usao » 1年前

この例で言えば
  • 初期位置 P(0)
  • 「前方」なるベクトル F
  • 「右方向」なるベクトル R (※別に「左」でやってもいいけど)
  • 「前方」に進む速度 Vf
  • sinカーブの位相の進み具合を決めるための係数 k
くらいを用いた,時刻 t における位置 P(t) に関する式を書けるであろう.
これはプログラミングとは関係なく純粋に数学の話.
まずは落ち着いて,こういう所からやるのがよいかと.

コレみたく解析解が得られる話だとわかれば,差分法でやる必要性も(おそらくそうする利点も)ないだろう,ということも見えるので実装方針も立つかと.

FRITIA
記事: 6
登録日時: 3年前

Re: ある軌道にそって弾を飛ばす方法

#4

投稿記事 by FRITIA » 1年前

すみません。後半の文章で理解してくれるだろうと勝手に解釈してしまいました。
一応、自分なりに納得のいくような動作を実装できたため、解決とします。
回答ありがとうございました。

返信

“C言語何でも質問掲示板” へ戻る