我在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);
}