创建一个粒子圈

时间:2018-04-05 17:04:14

标签: c sfml geometry

我在C中创建了一个粒子引擎(使用CSFML库),其中每个粒子在{X,Y}上都有一个位置,一个生命和{X,Y}中的运动矢量。 我实际上是在屏幕上的相同位置创建X粒子(例如:{100,100},我不想让它们移动以从初始位置创建一个增长的圆圈。 什么是可以帮助我做到这一点的数学函数?

#include <SFML/Graphics/Vertex.h>
#include <math.h>
#include "main.h"

int my_rand(int a, int b){
    return rand()%(b-a) +a;
}

partBuffer *newPartBuffer(int size)
{
    partBuffer *this;
    const size_t size_m = (sizeof(partBuffer) + sizeof(sfVertex) * size * 4
        + sizeof(t_info) * size);
    void *ptn = malloc(size_m);

    if (ptn == NULL)
        return (NULL);
    memset(ptn, 0, size_m);
    this = (partBuffer*)(ptn);
    this->size = size;
    this->vertex = (sfVertex*)(ptn + sizeof(partBuffer));
    this->info = (t_info*)(this->vertex + (size * 4));
    return (this);
}

void setPart(partBuffer *this, uint id, sfVector2f pos)
{
    if (id >= this->size)
        return ;
    this->vertex[(id * 4) + 0].position = (sfVector2f){pos.x + 0, pos.y + 0};
    this->vertex[(id * 4) + 1].position = (sfVector2f){pos.x + 5, pos.y + 0};
    this->vertex[(id * 4) + 2].position = (sfVector2f){pos.x + 5, pos.y + 5};
    this->vertex[(id * 4) + 3].position = (sfVector2f){pos.x + 0, pos.y + 5};
    this->vertex[(id * 4) + 0].color = (sfColor){255, 255, 255};
    this->vertex[(id * 4) + 1].color = (sfColor){255, 255, 255};
    this->vertex[(id * 4) + 2].color = (sfColor){255, 255, 255};
    this->vertex[(id * 4) + 3].color = (sfColor){255, 255, 255};
    //this->info[id].speed = (sfVector2f){my_rand(-3, 3), my_rand(-3, 3)};
    this->info[id].speed = (sfVector2f){0, 0};
    this->info[id].life = 1.0;
}

static uint newPart(partBuffer *this)
{
    for (uint id = this->size - 1; id != 0; id -= 1)
        if (this->info[id].life <= 0)
            return (id);
    return ((uint)(-1));
}

void updatePartBuffer(partBuffer *this)
{
    for (uint id = 0; id < this->size; id += 1) {
        if (this->info[id].life > 0)
            this->info[id].life -= 0.0;
        if (this->info[id].life <= 0)
            this->info[id].life = 0.0;

        this->vertex[(id * 4) + 0].position.x += this->info[id].speed.x;
        this->vertex[(id * 4) + 1].position.x += this->info[id].speed.x;
        this->vertex[(id * 4) + 2].position.x += this->info[id].speed.x;
        this->vertex[(id * 4) + 3].position.x += this->info[id].speed.x;
        this->vertex[(id * 4) + 0].position.y += this->info[id].speed.y;
        this->vertex[(id * 4) + 1].position.y += this->info[id].speed.y;
        this->vertex[(id * 4) + 2].position.y += this->info[id].speed.y;
        this->vertex[(id * 4) + 3].position.y += this->info[id].speed.y;
        this->vertex[(id * 4) + 0].color.a = (sfUint8)(this->info[id].life * 255.);
        this->vertex[(id * 4) + 1].color.a = (sfUint8)(this->info[id].life * 255.);
        this->vertex[(id * 4) + 2].color.a = (sfUint8)(this->info[id].life * 255.);
        this->vertex[(id * 4) + 3].color.a = (sfUint8)(this->info[id].life * 255.);
    }
}

void drawPartBuffer(partBuffer *this, sfRenderWindow *window)
{
    sfRenderWindow_drawPrimitives(window, this->vertex, this->size * 4,
    sfQuads, NULL);
}

void set_circle(partBuffer *this, float points)
{
    sfVector2f start = {0, -1};
    sfVector2f adder = {1 / (points), 1 / (points)};

    for (uint id = 0; id < points; id += 1) {
        this->info[id].speed = (sfVector2f){start.x + adder.x * id, start.y + adder.y * id};
    }
}

int game_loop(sfRenderWindow *window)
{
    partBuffer *buffer = newPartBuffer(10000);
    int points = 11;
    sfClock *clock = sfClock_create();
    sfVector2f position = {250, 250};

    for (uint nb = 0; nb < points; nb += 1)
        setPart(buffer, nb, position);
    set_circle(buffer, points);
    while (sfRenderWindow_isOpen(window)) {
        if (sfTime_asMilliseconds(sfClock_getElapsedTime(clock)) >= 10) {
            updatePartBuffer(buffer);
            sfClock_restart(clock);
        }

        sfRenderWindow_clear(window, sfBlack);
        drawPartBuffer(buffer, window);
        sfRenderWindow_display(window);
    }
}

int main(void)
{
    sfRenderWindow *window = sfRenderWindow_create((sfVideoMode){500, 500, 32},
        "Title", sfDefaultStyle, NULL);
    sfRenderWindow_setFramerateLimit(window, 120);

    game_loop(window);
    return (0);
}

0 个答案:

没有答案