というわけで祝日の夜を潰して弾幕を描くプログラム(相当久しぶりなプログラミング)してみました。
なお最低限弾幕が表示できりゃええので、当たり判定とか無く、弾が持つべき最低限の情報(座標、角度、速度)
だけで実装してみました。
なんか皆さんDxLibばっかり使っていらっしゃるので、Siv3D使ってみました、DirectXの世代もかなり新しい(10.0?)ので違いが出るのかなーと
んでなんかstd::listとか言う奴が早いらしいので調べてみて使い方を少し練習してみました。 なんか直感的で使いやすいねlist
でもなんだろう、多分使い方間違ってると思います。 ほっとくとどんどんメモリを確保していくのがその証拠、どうやって直すかも分からんし(おい
それにその場で思いつきの謎設計してるのでスパゲッティ&マイナーだと思います。
CPU:i5-4670 3.4GHz 4core
GPU:GTX760 GDDR5 2G
Mem:16G
VGA(640x480)
で、結果

(拡大してもモアレですよ)
で、大体11万個位描画したあたりから60FPSを維持できなくて低下し始めます。

そしてココでもうRAM占有量90MBぐらいとか恐ろしい
CPU使用率も30%程です。
でも実際ゲームとして使うときはもっとエフェクトバリバリで移動計算ももっと複雑になるでしょうから、遅くなることでしょう。
::追記::
計算と描画、どっちに時間掛かってるか計測してみました。
結果計算は30万描画時でも3ms-4ms程度でGPUが30ms-34msとやっぱりGPUがネックになっているようです、というかコレはピクセルレート的な限界か?
なんか描画はできるだけ一度にドローコールしたほうが良いとかどっかで聞いたことあるけどまぁいいや、もっと高速化の手立ては有るんでしょうけど...
それと、GPUの使用率見ても50%ぐらいしか使用してくれてないんですよねー...ハードの性能を引き出すとか言う作業はもっと難しいんですかねぇ
あれ?これ前もやったこと有る気がするなぁ...
さて、今度の土日は可変長配列とただの配列とstd::vectorでも設計してみよう
ソースコード貼っときます。 かなりマズイ設計だと思うけど(listの要素破棄してなかったり...)
► スポイラーを表示
Shot.h
CODE:
#pragma once
class Bullet
{
private:
float x;
float y;
float vx;
float vy;
float ang;
float speed;
Texture img;
bool flag;
public:
Bullet();
~Bullet();
void Init(float arg_x,float arg_y,float arg_ang,float arg_speed,Texture img);
bool Getflag(){return flag;}
void Update();
void Draw();
void Kill();
};
Shot.cpp
CODE:
#include
#include "Shot.h"
#include
Bullet::Bullet()
{
flag = false;
}
Bullet::~Bullet()
{
}
//初期化
void Bullet::Init(float arg_x, float arg_y, float arg_ang, float arg_speed,Texture arg_img)
{
x = arg_x;
y = arg_y;
ang = arg_ang;
speed = arg_speed;
vx = cos(ang)*speed;
vy = sin(ang)*speed;
img = arg_img;
//フラグを立てる
flag = true;
}
void Bullet::Update()
{
//画面外に出たらフラグを折る
if(x
#include "Shot.h"
#include
class BulletMgr
{
std::list tama0;
Font p;
public:
BulletMgr();
void Init();
void Add(float x,float y,float ang,float speed,Texture img);
void Update();
};
ShotMgr.cpp
CODE:
#include "ShotMgr.h"
BulletMgr::BulletMgr()
{
//何もやること無い
}
void BulletMgr::Init()
{
//何もやること無い
}
void BulletMgr::Add(float x, float y, float ang, float speed,Texture img)
{
//プッシュ用
Bullet n;
//弾の登録(先頭に追加)
tama0.push_front(n);
//先頭のイテレータを指定
auto itr = tama0.begin();
//先頭の初期化
itr->Init(x,y,ang,speed,img);
}
void BulletMgr::Update()
{
//描画個数
int k = 0;
int st = Time::GetMillisec();
//線形でリストの終了まで探す
for (std::list::iterator i = tama0.begin();i != tama0.end();i++)
{
//i番目のフラグが立っていたら 更新、描画
if(i->Getflag() == true)
{
k++;
i->Update();
}
// else {
// tama0.erase(i);
// }
}
int end = Time::GetMillisec() - st;
st = Time::GetMillisec();
for (std::list::iterator i = tama0.begin();i != tama0.end();i++)
{
//i番目のフラグが立っていたら 更新、描画
if (i->Getflag() == true)
{
i->Draw();
}
}
//p(end, L"ms:Tick").draw(0, 50);
//p(Time::GetMillisec() - st, L"ms:Graph").draw(0, 80);
p(k , L" 個").draw(0,20);
}
Main.cpp
CODE:
#include
#include "ShotMgr.h"
void Main()
{
Font p16(16);
BulletMgr Test;
Texture img(L"e:/users/hiragi/desktop/bullet.png");
float i=0;
while (System::Update())
{
i+=0.1;
//弾追加
for(int k = 0;k < 512;k++)
Test.Add(320,240,i+k,1,img);
//弾更新
Test.Update();
//FPS表示
p16(Profiler::FPS() , L"FPS").draw(0,0);
}
}