设为首页收藏本站喵玉殿官方微博

 找回密码
 少女注册中
搜索
楼主: Delta67

[提问其他] 有自己做stg的前辈吗 想请教下弹幕的算法

  [复制链接]
 楼主| 发表于 2015-6-9 10:44:55 | 显示全部楼层
现在的情况是这样
我的弹幕系统是一个预设的指针数组(暂定300个 通过这个方式限制最大弹幕数量)
然后新生成的弹幕就把其地址放到这个数组里面并且记录新的总弹幕数量
每一帧里从0到总数-1 每个弹幕分别跑自己的移动函数

基于这个原因 所以一开始函数指针设计考虑的就是让每个子弹自理自己的移动 弹幕的生成函数只负责创建新的弹幕以及给新生成的弹幕配备相应的移动函数

当然以上内容因为效率太难看已经给否了


说起来这个总体设计是否可取?还是干脆移动不交给全局的函数来管理 而交给不同的stage或者chapter一类的函数来负责?

点评

我的那个核心是参数方程,弹幕数组是二维的,即不同轨迹上的不同子弹。[200][400]帧率掉到40左右?  发表于 2015-6-10 10:11
回复

使用道具 举报

发表于 2015-6-9 12:06:38 | 显示全部楼层
Delta67 发表于 2015-6-9 10:44
现在的情况是这样
我的弹幕系统是一个预设的指针数组(暂定300个 通过这个方式限制最大弹幕数量)
然后新 ...

std::list试过没。。。
我用vector都没那么慢
而且每个弹幕自己一个函数也并不影响效率。。

点评

咦 还有个可能降低效率的地方大概是dx的sprite旋转了 我用的是D3DXMatrixTransformation2D和SetTransform做的 不知道会不会是这个问题 list还没试过 我觉得应该不会比数组更快吧  发表于 2015-6-9 12:25
回复

使用道具 举报

发表于 2015-6-9 13:33:05 | 显示全部楼层
借串问下要如何有效率的决定Sprite的绘制顺序?
我把Sprite指针存在vector内然后每帧绘制前依Z值->Y值->X值来排序,但是上千Sprite就有掉帧的感觉了。

点评

我也是子弹类里挂一个sprite指针成员 然后整个数组跑下来依次绘制 现在也开始怀疑效率问题出在这里了  发表于 2015-6-9 13:36
回复

使用道具 举报

发表于 2015-6-9 19:10:25 | 显示全部楼层
效率问题你是用VS的话可以用vs的性能分析工具跑一下,不是的话就用VTune吧。

点评

官网看了一眼899刀  发表于 2015-6-10 09:26
Vtune看起来好厉害 有免费版么  发表于 2015-6-10 09:20
回复

使用道具 举报

发表于 2015-6-9 22:05:57 | 显示全部楼层
刚花了点时间写了个弹幕的基础类,等会发上来。。。

点评

刚洗了个澡。。。。。集显2000弹幕能有100帧,,,我想想恋恋的弹幕怎么写。。。  发表于 2015-6-9 22:33
回复

使用道具 举报

发表于 2015-6-9 22:56:04 | 显示全部楼层
GIF.gif
这附件大小真鬼畜。。。

点评

我说怎么这么卡。。原来我开了两倍smaa。。。  发表于 2015-6-11 18:09
dx11的程序。。没发  发表于 2015-6-10 09:26
图种?  发表于 2015-6-10 09:17
回复

使用道具 举报

发表于 2015-6-10 09:38:40 | 显示全部楼层
  1. #include "mdl.h"
  2. #include "mdl_Sprite.h"
  3. #include "windows.h"
  4. #include "cmath"
  5. #include "ctime"
  6. #include <VECTOR>
  7. #include <iostream>
  8. #include <functional>

  9. mdl_sprite* gs;

  10. struct spritedes
  11. {
  12.         spritedes::spritedes(DWORD SH)
  13.         {
  14.                 sprite_handle = SH;
  15.         }


  16.         BOOL rS = 1;
  17.         XMFLOAT2 position;
  18.         float rotation=0;
  19.        
  20.         DWORD sprite_handle;
  21.        

  22. };

  23. class globalttime
  24. {
  25. public:
  26.         globalttime::globalttime()
  27.         {
  28.                 startTime = clock();
  29.                 lastTime = startTime;
  30.                 currentTime = lastTime;
  31.         }
  32.         void update()
  33.         {
  34.                 lastTime = currentTime;
  35.                 currentTime = clock();
  36.                 interval = currentTime - lastTime;
  37.         }
  38.         long getInter()
  39.         {
  40.                 return interval;
  41.         }
  42.         long getCurrent()
  43.         {
  44.                 return currentTime;
  45.         }
  46.         long getPassed()
  47.         {
  48.                 return currentTime - startTime;
  49.         }
  50. private:
  51.         clock_t startTime;
  52.         clock_t lastTime;
  53.         clock_t currentTime;
  54.         long interval;
  55. }*gt;

  56. class msprite
  57. {
  58. public:
  59.         msprite::msprite(){};
  60.         msprite::msprite(char* filename)
  61.         {
  62.                 teH = gs->load_texture(filename);
  63.                 spH = gs->init_sprite(teH);
  64.                 big = gs->spritemap[spH].big;
  65.                
  66.         }
  67.         virtual void update()
  68.         {
  69.                
  70.         }
  71.         virtual void draw()
  72.         {
  73.                 std::list < spritedes >::iterator iter = list.begin();
  74.                 for (unsigned int i = 0; i < list.size(); i++, iter++)
  75.                 {
  76.                         int j = gs->RenList.size();
  77.                         gs->add2RenList(spH);
  78.                         gs->RenList[j].position = iter->position;
  79.                         gs->RenList[j].rotation = iter->rotation;
  80.                 }
  81.         }

  82. protected:
  83.         XMFLOAT2 big;
  84.         DWORD teH;
  85.         DWORD spH;
  86.         std::list < spritedes >  list;
  87. };

  88. struct __polar
  89. {
  90.         float r = 0;
  91.         float ra = 0;
  92.         float rv = 0;

  93.         float o = 0;
  94.         float oa = 0;
  95.         float ov = 0;
  96. };

  97. struct __rect
  98. {
  99.         XMFLOAT2 pos = { 0, 0 };
  100.         XMFLOAT2 v = { 0, 0 };
  101. };

  102. class __coord
  103. {
  104. public:
  105.         __coord::__coord(XMFLOAT2 __centre, std::function<void(__coord* lp)> __proc)
  106.         {
  107.                 isRect = 0;
  108.                 centre = __centre;
  109.                 position = { 0, 0 };
  110.                 proc = __proc;
  111.         }

  112.         XMFLOAT2* getCentre()
  113.         {
  114.                 return &centre;
  115.         }
  116.         __polar* getLppolar()
  117.         {
  118.                 return &polar;
  119.         }
  120.         __rect* getLprect()
  121.         {
  122.                 return &rectC;
  123.         }
  124.         XMFLOAT2 getPos()
  125.         {
  126.                 return position;
  127.         }
  128.         float getO()
  129.         {
  130.                 return polar.o;
  131.         }


  132.         void changeCoordMode()
  133.         {
  134.        
  135.         }

  136.         void update()
  137.         {
  138.                 proc(this);
  139.                 polar.ov += polar.oa * gt->getInter()/1000.0f;
  140.                 polar.o += polar.ov* gt->getInter() / 1000.0f;

  141.                 polar.rv += polar.ra* gt->getInter() / 1000.0f;
  142.                 polar.r += polar.rv* gt->getInter() / 1000.0f;

  143.                 while (polar.o >= XM_2PI)
  144.                 {
  145.                         polar.o -= XM_2PI;
  146.                 }
  147.                 while (polar.o <= -XM_2PI)
  148.                 {
  149.                         polar.o += XM_2PI;
  150.                 }

  151.                 position = { centre.x + polar.r * cosf(polar.o), centre.y + polar.r * sinf(polar.o) };
  152.         }
  153. private:
  154.         bool isRect;
  155.         XMFLOAT2 centre;
  156.         XMFLOAT2 position;
  157.         __polar polar;
  158.         __rect rectC;
  159.         std::function<void(__coord* lp)> proc;
  160. };

  161. class danmu:public msprite
  162. {
  163. public:
  164.         danmu::danmu(char* filename)
  165.         {
  166.                 teH = gs->load_texture(filename);
  167.                 spH = gs->init_sprite(teH);
  168.                 big = gs->spritemap[spH].big;
  169.         }
  170.         danmu::~danmu()
  171.         {
  172.                 std::list<__coord*>::iterator iter = danmuLst.begin();
  173.                 for (unsigned int i = 0; i < danmuLst.size(); i++, iter++)
  174.                 {
  175.                         delete *iter;
  176.                 }
  177.                 danmuLst.~list();
  178.         }
  179.         void initADanmu(__polar _polar,  std::function<void(__coord* lp)> __proc, XMFLOAT2 __centre = XMFLOAT2(w_width / 2.0f, w_height / 2.0f))
  180.         {
  181.                 __coord* lpCoord = new __coord(__centre, __proc);
  182.                 __polar* lpPolar = lpCoord->getLppolar();
  183.                 memcpy(lpPolar, &_polar, sizeof(__polar));
  184.                 danmuLst.push_back(lpCoord);
  185.         }
  186.         void update()
  187.         {
  188.                 std::list<__coord*>::iterator iter = danmuLst.begin();
  189.                 for (unsigned int i = 0; i < danmuLst.size(); i++, iter++)
  190.                 {
  191.                         (*iter)->update();
  192.                 }
  193.         }
  194.         void draw()
  195.         {
  196.                 std::list<__coord*>::iterator iter = danmuLst.begin();
  197.                 for (unsigned int i = 0; i < danmuLst.size(); i++, iter++)
  198.                 {
  199.                         int j = gs->RenList.size();
  200.                         gs->add2RenList(spH);
  201.                         gs->RenList[j].position = (*iter)->getPos();
  202.                         gs->RenList[j].rotation = (*iter)->getO() - XM_2PI / 4.0f;
  203.                 }
  204.        
  205.         }
  206.         DWORD size()
  207.         {
  208.                 return danmuLst.size();
  209.         }

  210. private:
  211.         std::list<__coord*> danmuLst;
  212. };

  213. std::vector<msprite*> spriteLst;

  214. #define installdProc __polar* polar = lp->getLppolar();\
  215. __rect* rectC = lp->getLprect();\
  216. XMFLOAT2* centre = lp->getCentre();\
  217. float time = gt->getInter();

  218. void dProc(__coord* lp)
  219. {
  220.         installdProc;


  221.         if (polar->rv < 0)
  222.         {
  223.                 polar->ra = 0;
  224.                 polar->rv = 0;
  225.         }
  226. }

  227. int Render(int state, WORD reflect)
  228. {
  229.         static BOOL inited = FALSE;
  230.         static danmu*id;
  231.         if (!inited)
  232.         {
  233.                 gs = new mdl_sprite;
  234.                 gt = new globalttime;

  235.                 id = new danmu("DT\\bullet.png");
  236.                 spriteLst.push_back(id);
  237.                 inited = true;


  238.         }
  239.         gt->update();

  240.         static long timeProc = 0;
  241.         if (gt->getPassed() -  timeProc >=300)
  242.         {
  243.         timeProc = gt->getPassed();
  244.         const float d = 6.0;
  245.         for (float i = 0; i < d; i++)
  246.         {
  247.                 float o = XM_2PI / d*i;
  248.                 __polar p;

  249.                 p.o = o - XM_2PI / d /2.0f;
  250.                 p.ov = XM_2PI / 360.0 * 30;

  251.                 p.rv = 250.0;
  252.                 p.ra = -100;
  253.                 id->initADanmu(p, dProc);
  254.                 p.o = o ;
  255.                 p.ov = XM_2PI / 360.0 * 45;
  256.                 id->initADanmu(p, dProc);
  257.         }

  258.         }

  259.         for (int i = 0; i < spriteLst.size(); i++)
  260.         {
  261.                 spriteLst[i]->update();
  262.                 spriteLst[i]->draw();
  263.         }
  264.         char danmuNum[16] = { 0 };
  265.         sprintf_s(danmuNum,"%u", id->size());
  266.         SetWindowTextA(g_hWnd, danmuNum);


  267.         gs->spriteRender();
  268.         MDL_RenderPresent();
  269.         gs->RenList.clear();
  270.         MDL_clear();
  271.        


  272.         return state;
  273. }
复制代码
所有代码都在这了,,,这大概是我的算法吧,,,比较low。
本意是实现一个发射器函数,一个弹幕处理函数,,但是还只封装了一个,坐标现在也只能处理极坐标。

点评

唔 现在觉得可能问题就是出在sprite的处理上了(大概)  发表于 2015-6-16 10:26
这最好看看别人的代码对比一下。。  发表于 2015-6-16 08:28
我还写了个细胞自动机(写着玩的) 那个sprite是每次格子被激活就draw 不激活就不draw 然后sprite是初始化时候就生成好的数量固定 texture也是只有一个 结果就是这样还在不断泄漏 所以估计是sprite的问题  发表于 2015-6-16 01:53
说起来一个很严重的问题就是内存泄露 我不确定是泄漏在什么地方 但是估计应该是在sprite的being draw 或者end三个里面的一个里 开着的过程中内存占用一直飚上去2个G 一关掉立马下来了 而且跑的过程中持续增加  发表于 2015-6-16 01:52
先loadtexture到显存,然后createsprite载入显存中的纹理,生成精灵图  发表于 2015-6-13 12:07
想问下关于图像的部分是怎么实现的 每个新的子弹产生就创建一个sprite从文件加载一次纹理? 多个sprite可不可以公用纹理?我试着只在初始化时候载入一次纹理 后面所有的指针都指向这个载入的 结果跑的反而更慢还崩溃  发表于 2015-6-13 12:04
回复

使用道具 举报

 楼主| 发表于 2015-6-10 10:29:21 | 显示全部楼层
谢谢各位的回复 因为我周五有一场考试所以这两天得复习 过两天再来看 再次感谢
回复

使用道具 举报

发表于 2015-6-13 14:48:43 | 显示全部楼层
应该是哪写的有问题,dx hge1.8.1老台机跑上万子弹都不会卡,台机弹幕通常差不多5w不卡比较正常,dx9可以参考下hge,虽然很多人说效率不好,但我感觉其实还挺好。
例子可以参考上古物marisa-ex,大概需要跳墙
https://marisa-ex.googlecode.com/svn/trunk/

点评

具体情形我发在上上楼的点评里了 前辈发的这个我先码着看看 谢谢啦(我本身就在墙外hhh)  发表于 2015-6-16 01:55
dx9的碰到了很奇怪的泄漏问题 估计像是sprite的begin draw或者end三个里面哪个出了问题 运行过程中内存持续飙高然后崩溃了  发表于 2015-6-16 01:54
回复

使用道具 举报

发表于 2015-6-21 21:31:40 来自手机 | 显示全部楼层
提示: 该帖被管理员或版主屏蔽
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 少女注册中

本版积分规则

合作与事务联系|无图版|手机版|小黑屋|喵玉殿

GMT+8, 2025-10-31 12:46

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表