ページ 11

螺旋状の弾幕の作り方

Posted: 2020年6月25日(木) 11:24
by yui01199
現在Visual Sturdyで東方弾幕シューティングに出てくるような弾幕を制作しているのですが
螺旋状に広がっていく弾の作り方が分からないので教えてください。

下のソースは広がりながら一定の場所まで行くと弾を出したところに戻ってくるみたいなやつを作りました。
これを少しいじって螺旋状にしたいと考えています。


static const float FLOOR_Y = WINDOW_HEIGHT - 100.0f; // 床座標
// 出現パラメーター
// パーティクルパラメーター
static const int PIECE_MAX = 100; // パーティクルの総数
bool active[PIECE_MAX]; // 今使っているならtrue, 使ってなければfalse
int lifeTime[PIECE_MAX]; // ピースが出現している時間
float positionX[PIECE_MAX]; // 座標
float positionY[PIECE_MAX];
float velocityX[PIECE_MAX]; // 速度
float velocityY[PIECE_MAX];


static const int SPAWN_COUNT = 5;//1フレームに出現する数
//static const int LIFE_MAX = 120; //生きている時間
int timeCount;//出現時間数える


int PieceMove;
int pieceImage = -1;

float r;//円の半径(展開範囲)
float ang = 0.0f;

void EffectInit()
{
// 画像の準備
pieceImage = LoadGraph("data\\texture\\bullet2.png");

r = 20.0f;
PieceMove = 0;

// データを
for (int i = 0; i < PIECE_MAX; i++) {
active = true;
positionX = 400.0f;
positionY = 300.0f;
velocityX = 0.0f;
velocityY = 0.0f;
lifeTime = 0;
}
}

void EffectUpdate()
{
if (PieceMove <= 300) {
PieceMove += 1;
r += 0.5f;
ang += 0.05f;
}else if(PieceMove <= 350){
r -= 0.5f;
ang -= 0.05f;
}

for (int i = 0; i < PIECE_MAX; i++) {
positionX = r * cos(DX_PI / 18 * i + ang) + 400.0f;
positionY = r * sin(DX_PI / 18 * i + ang) + 300.0f;
}
/*for (int i = 0; 250 > PIECE_MAX; i++) {
positionX = r * cos(DX_PI / 18 * i - ang) - 400.0f;
positionY = r * sin(DX_PI / 18 * i - ang) - 300.0f;
}*/
}

void EffectDraw()
{
for (int i = 0; i < PIECE_MAX; i++) {
if(active[i])
DrawRectGraph(positionX[i], positionY[i], 0, 32, 32, 32, pieceImage, true, false);
}
}

void EffectRelease()
{
DeleteGraph(pieceImage);
pieceImage = -1;
}

Re: 螺旋状の弾幕の作り方

Posted: 2020年6月30日(火) 21:10
by あたっしゅ

コード:

//
//
// https://dixq.net/forum/viewtopic.php?f=3&t=20904&sid=c82e5a12a3183aa784db7af700a48350
// 螺旋状の弾幕の作り方 - [C 言語等何でも質問掲示板 プログラマ専用 SNS]ミクプラ(ja)
//
// for Microsoft Visual Studio 2019
// C++ with DxLib
//
//  現実逃避がしたくなって、久しぶりに DxLib をイジってみました。
//
//  up されたソースそのままでは、動かなかったので、
// [i] をつけたり、WinMain として DxLib ループを追加しました。
// 画像ファイルは、自分の他のプログラムから持ってきたので、大きさがあってません。
//
//  肝心の螺旋(らせん)状にするところは、
//
// 121: positionX[i] = r * ((float)i / PIECE_MAX) * cos(DX_PI / 18 * i + ang) + 400.0f;
// 122: positionY[i] = r * ((float)i / PIECE_MAX) * sin(DX_PI / 18 * i + ang) + 300.0f;
//                       ~~~~~~~~~~~~~~~~~~~~~~~~  
// です。
//
//  めざせ!ウェブ投稿業(^;)
//  都知事選候補の経歴に「ウェブ投稿業」とありました。どうやら YouTuber 等のことのようです。
//
#include "windows.h"

#include <cstdlib>
#include <cmath>

#include "DxLib.h"


const int WINDOW_HEIGHT = 960;

static const float FLOOR_Y = WINDOW_HEIGHT - 100.0f; // 床座標
// 出現パラメーター
// パーティクルパラメーター
static const int PIECE_MAX = 100; // パーティクルの総数
bool active[PIECE_MAX]; // 今使っているならtrue, 使ってなければfalse
int lifeTime[PIECE_MAX]; // ピースが出現している時間
float positionX[PIECE_MAX]; // 座標
float positionY[PIECE_MAX];
float velocityX[PIECE_MAX]; // 速度
float velocityY[PIECE_MAX];


static const int SPAWN_COUNT = 5;//1フレームに出現する数
//static const int LIFE_MAX = 120; //生きている時間
int timeCount;//出現時間数える


int PieceMove;
int pieceImage = 0;

float r;//円の半径(展開範囲)
float ang = 0.0f;

void EffectInit()
{
#define IMAGEFILE "data/texture/bullet2.png"

#define DEBUG
#ifdef DEBUG
	//
	// https://s-kita.hatenablog.com/entry/20100606/1275799360
	// Win32API フルパスを取得する GetFullPathName - s-kita's blog(ja)
	//
	char szFullPath[MAX_PATH] = { '\0' };
	char* szFilePart;

	DWORD dwRet = GetFullPathName(
		IMAGEFILE, /* ファイル名を相対パスで指定 */
		sizeof(szFullPath) / sizeof(szFullPath[0]),
		szFullPath,
		&szFilePart
	);

	if (dwRet != 0) {
		printf("FullPath : %s\n", szFullPath);
		printf("FullPath Length : %u\n", dwRet);
		printf("FilePart : %s\n", szFilePart);
	}
	else {
		printf("GetFullPathName failed.");
	}
#endif

	// 画像の準備
	pieceImage = LoadGraph(IMAGEFILE);
#ifdef DEBUG
	printf( __FILE__ "[%d]:%d\n", __LINE__, pieceImage );
#endif

	r = 20.0f;
	PieceMove = 0;

	// データを初期化
	for (int i = 0; i < PIECE_MAX; i++) {
		active[i] = true;
		positionX[i] = 400.0f;
		positionY[i] = 300.0f;
		velocityX[i] = 0.0f;
		velocityY[i] = 0.0f;
		lifeTime[i] = 0;
	}
}

void EffectUpdate()
{
	if (PieceMove <= 300) {
		PieceMove += 1;
		r += 0.5f;
		ang += 0.05f;
	}
	else if (PieceMove <= 350) {
		r -= 0.5f;
		ang -= 0.05f;
	}

	for (int i = 0; i < PIECE_MAX; i++) {
		positionX[i] = r*( (float)i/PIECE_MAX ) * cos(DX_PI / 18 * i + ang) + 400.0f;
		positionY[i] = r*( (float)i/PIECE_MAX ) * sin(DX_PI / 18 * i + ang) + 300.0f;
	}
	/*for (int i = 0; 250 > PIECE_MAX; i++) {
	positionX = r * cos(DX_PI / 18 * i - ang) - 400.0f;
	positionY = r * sin(DX_PI / 18 * i - ang) - 300.0f;
	}*/
}

void EffectDraw()
{
	for (int i = 0; i < PIECE_MAX; i++) {
		if (active[i])
			DrawRectGraph(positionX[i], positionY[i], 0, 32, 32, 32, pieceImage, true, false);
	}
}

void EffectRelease()
{
	DeleteGraph(pieceImage);
	pieceImage = -1;
}
//
// 参考:
//   http://gameprogrammingunit.web.fc2.com/dxlib/0_setup.htm
//   DXライブラリのスケルトン
//
int WINAPI 
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
#ifdef DEBUG
    // Console for Debug 
	FILE* stream;
	{
		AllocConsole();
		freopen_s(&stream, "CONIN$", "r", stdin);
		freopen_s(&stream, "CONOUT$", "w", stdout);
	}
#endif
	ChangeWindowMode(TRUE); // int Flag

	// 画面モードを設定する
	SetGraphMode( 1280, WINDOW_HEIGHT, 32 );

	// ライブラリ初期化を行う
	if (DxLib_Init() == -1) {
		return -1;
	}

	// 描画先画面を設定する
	SetDrawScreen(DX_SCREEN_BACK);	// int DrawScreen

	EffectInit();

	while( ProcessMessage() == 0 && CheckHitKey(KEY_INPUT_ESCAPE) == 0 )
	{
		// 画面をクリアする
		ClearDrawScreen();  // const RECT *ClearRect = NULL

#ifdef DEBUG
		 // 画面左上に描画します(『DrawGraph』を使用)
		{
			int res = DrawGraph(0, 0, pieceImage, FALSE);
			printf( "%d", res );
		}
#endif

		EffectUpdate();
		EffectDraw();

		// 裏画面と表画面の内容を交換する
		ScreenFlip();
	}
	EffectRelease();
	// ライブラリ使用の後始末を行う
	DxLib_End();

	return EXIT_SUCCESS;
}



Re: 螺旋状の弾幕の作り方

Posted: 2020年6月30日(火) 21:40
by あたっしゅ
動画
https://www.nicovideo.jp/watch/sm37117126
DxLibProject2Rasen.zip - 螺旋状の弾幕


プログラムとソースファイルのダウンロード先
http://atassyu.rosx.net/dixq/index.html
DxLibProject2Rasen.zip - 螺旋状の弾幕の作り方 - [C 言語等何でも質問掲示板 プログラマ専用 SNS]ミクプラ