Пятница, 19 Апреля 2024, 02:38

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Форум игроделов » Программирование » C/C++ » Партиклы
Партиклы
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)
---------------------------------------------
Хотя может ты так и делаешь примерно, не совсем понятно по коду просто что происходит с частицей когда она умирает )

Форум игроделов » Программирование » C/C++ » Партиклы
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг