Партиклы
| |
Alkosha | Дата: Пятница, 31 Октября 2014, 23:51 | Сообщение # 1 |
участник
Сейчас нет на сайте
| Делаю самодельную систему партикл https://www.youtube.com/watch?feature=player_detailpage&v=H7410ubOs1Q
И по ходу дела возник вопрос.
есть флаг enable который выключает\включает партиклы. В данный момент в цикле апдейта
Код if(enable){ for(int i=0;i<maxcount;i++) { Апдейт партикл }
То есть, при изменении значения enable будет происходить резкое исчезновение\появление всех частиц. Не красиво.
|
|
| |
MR_Borg | Дата: Воскресенье, 02 Ноября 2014, 01:35 | Сообщение # 2 |
участник
Сейчас нет на сайте
| Так надо выключать не частицы а эмиттер или что у вас испускает частицы. И дайте больше информации по коду.
Изучаю C++ попутно пишу игру.
|
|
| |
Alkosha | Дата: Воскресенье, 02 Ноября 2014, 09:30 | Сообщение # 3 |
участник
Сейчас нет на сайте
| Вот коТ.
Код class myParticles {
struct partic { float psize; int life; float x; float y; float dx,dy; int fade; };
SDL_Rect texRect; vector <partic> partics;
public: float minsize, maxsize; SDL_Rect rectangle; int maxspeedY, minspeedY, maxspeedX, minspeedX; int lifemin; int lifemax; int blend; int maxcount; bool gravity; bool enable; float fadespeed; myParticles() { enable=true; endpartic=false; } private: void inipartic(int idx) {
partics[idx].psize= minsize+(float)(rand()%(int)(maxsize*100 - minsize*100 + 1))/100; partics[idx].x=rand()%(rectangle.w)+rectangle.x;
partics[idx].y=rand()%(rectangle.h)+rectangle.y;
partics[idx].dx=(float)(rand()%(maxspeedX-minspeedX+1))/10+(float)minspeedX/10; partics[idx].dy=(float)(rand()%(maxspeedY-minspeedY+1))/10+(float)minspeedY/10; partics[idx].life=lifemin+(rand()%(int)(lifemax - lifemin + 1));
}
SDL_Texture * particTex;
public:
void init(char* tex, float _minsize,float _maxsize,int _maxcount, SDL_Rect _rectangle ,int _lifemin, int _lifemax , int _minspeedX, int _maxspeedX, int _minspeedY, int _maxspeedY, float _fadespeed, bool _gravity, int _blend) { minsize=_minsize; maxsize=_maxsize; blend=_blend; fadespeed=_fadespeed; maxcount=_maxcount; rectangle=_rectangle; lifemin=_lifemin; lifemax=_lifemax; minspeedX=_minspeedX; maxspeedX=_maxspeedX; minspeedY=_minspeedY; maxspeedY=_maxspeedY; gravity=_gravity; loadTex(tex); for(int i=0;i<maxcount;i++) { partics.push_back(partic()); inipartic(i); } }
void loadTex( char* filename ) { particTex = IMG_LoadTexture(renderer, filename); SDL_QueryTexture(particTex, NULL, NULL, &texRect.w, &texRect.h); }
void update() { if(enable){ for(int i=0;i<maxcount;i++) {
if(gravity)partics[i].dy+=GRAVITATION; partics[i].y+=partics[i].dy; partics[i].x+=partics[i].dx; partics[i].life--;
partics[i].fade+=fadespeed; if(partics[i].fade>=255) { partics[i].life=0; partics[i].fade=0; }
if(partics[i].life<=0)inipartic(i); } } } void display() { if(enable){ for(int i=0;i<maxcount;i++) { SDL_Rect DestRs; DestRs.x=partics[i].x-cum.x; DestRs.y=partics[i].y-cum.y; if(DestRs.x<800&&DestRs.x>0-texRect.w){
if(blend==0) SDL_SetTextureBlendMode(particTex, SDL_BLENDMODE_BLEND); if(blend==1) SDL_SetTextureBlendMode(particTex, SDL_BLENDMODE_ADD); if(blend==2) SDL_SetTextureBlendMode(particTex, SDL_BLENDMODE_MOD); if(blend==3) SDL_SetTextureBlendMode(particTex, SDL_BLENDMODE_NONE);
DestRs.w=texRect.w*partics[i].psize; DestRs.h=texRect.h*partics[i].psize;
SDL_SetTextureAlphaMod(particTex,255-partics[i].fade); SDL_RenderCopy(renderer, particTex , &texRect, &DestRs); } } } } };
Первым делом инициализируются партиклы (кол-во частиц, диапазон размера спрайтов, мин\макс время жизни, начальное ускорение, режим смешивания и тд.). Затем функцией update() обновляется всё в главном цикле. И в цикле рендеринга отрисовывается функцией display()Добавлено (02.11.2014, 09:30) --------------------------------------------- И ещё не решён вопрос с динамическим изменением количества партиклов. Хотя можно изменять maxcount в убывающую сторону. Но если задать maxcount больше, чем было при инициализации - то будет фатал эррор. Нужно динамически расширить вектор.
|
|
| |
MR_Borg | Дата: Воскресенье, 02 Ноября 2014, 12:53 | Сообщение # 4 |
участник
Сейчас нет на сайте
| Цитата Alkosha ( ) Нужно динамически расширить вектор. Замените maxcount в циклах перебора частиц на vector.size.
По поводу 1 вопроса: Я бы так сделал Код Class ParticleRenderer() { boll emitter;//создаем еще частиц? //////////////// void Start() void Update(); void Draw(); }
Далее делай так, инициируеш начальные значения. В методе Update(); Код if(emitter) { создаем еще цастиц(); } particles[i].Update()//считаем какие либо преобразования с частицами( таймер жизни, движение и пр)
Получается при выключенном emitter частицы не создаются, но старые еще пока живут.
Изучаю C++ попутно пишу игру.
Сообщение отредактировал MR_Borg - Воскресенье, 02 Ноября 2014, 12:56 |
|
| |
Alkosha | Дата: Воскресенье, 02 Ноября 2014, 23:42 | Сообщение # 5 |
участник
Сейчас нет на сайте
| Цитата MR_Borg ( ) создаем еще цастиц();
дело в том, что создаются они единожды - при инициализации. В дальнейшем в цикле они циркулируют. То бишь, когда время жизни заканчивается, всё та же частица принимает начальное положение.
|
|
| |
MR_Borg | Дата: Понедельник, 03 Ноября 2014, 00:27 | Сообщение # 6 |
участник
Сейчас нет на сайте
| Цитата Alkosha ( ) В дальнейшем в цикле они циркулируют. То бишь, когда время жизни заканчивается, всё та же частица принимает начальное положение.
Код
if(enable)//если включены, то обновляем и рендерим все { patricles[i].Update(); } else { if(patricles[i].lifetime>0) patricles[i].Update();// тут рендерим только те, которые еше живы. }
Далее в апдейте частиц сбрасываем время жизни, если они включены.
if(lifetime<0 && enable) { lifetime=maxlifetime; }
Изучаю C++ попутно пишу игру.
|
|
| |
Alkosha | Дата: Понедельник, 03 Ноября 2014, 15:13 | Сообщение # 7 |
участник
Сейчас нет на сайте
| спасибо за подсказку. В принципе, я так с самого начала и предполагал, но думал, что есть более оптимальный подход. Так как придётся каждый раз в холостую проходиться по циклу, даже если все партиклы давно потухли (так как присутствуют i-тые элементы в условии). А может можно сделать какой-то флаг, определяющий что абсолютно все частицы вымерли ?
|
|
| |
MR_Borg | Дата: Понедельник, 03 Ноября 2014, 19:08 | Сообщение # 8 |
участник
Сейчас нет на сайте
| Цитата Alkosha ( ) Так как придётся каждый раз в холостую проходиться по циклу, даже если все партиклы давно потухли (так как присутствуют i-тые элементы в условии). Можно конечно придумать множество способов, все зависит от того как вам надо оптимизировать. Если источников будет немного, то встряли производительность сильно падет.
Цитата Alkosha ( ) А может можно сделать какой-то флаг, определяющий что абсолютно все частицы вымерли ? Смотря для каких целей? Если нужно знать конкретно какая частица выключена, это только увеличит число доп. проверок. Если просто число частиц, то сделать переменную и при отключении частицы ее увеличивать и сравнить с максимумом частиц.
Изучаю C++ попутно пишу игру.
|
|
| |
Xakep | Дата: Понедельник, 03 Ноября 2014, 19:21 | Сообщение # 9 |
めちゃくちゃちゃ
Сейчас нет на сайте
| Я бы посоветовал для частиц не использовать vector, а заранее выделять память, к примеру: Particles = new Particle[MAX_PARTICLES]; сделать цикличный связной список (т.е последний элемент ссылается на первый) и просто по кругу выбирать участки памяти и заполнять данные, так будет намного быстрее работать.Добавлено (03.11.2014, 19:21) --------------------------------------------- Хотя может ты так и делаешь примерно, не совсем понятно по коду просто что происходит с частицей когда она умирает )
|
|
| |
|