| 
	
		
		
			| Партиклы |  |  |  | 
| 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)---------------------------------------------
 Хотя может ты так и делаешь примерно, не совсем понятно по коду просто что происходит с частицей когда она умирает )
 |  |  |  |  |  
 |