废话不多说上视频
粒子系统
谁说程序员不懂浪漫的?诺这就是!
环境:decC++
如果大家用Vs的话,因为vc有一些在dev里的函数已经弃用了,关闭安全警告就可以了。
如果不会配置dev的easyx库可以到官网借鉴帮助文档。
该系统基于easyx图库的粒子系统,基本思想来自于视频帧,每一次将所有需要展示的内容一次性绘画,最后再一次性删除,该系统并不使用清屏函数
基于物理系统:
实现是为每一个烟花颗粒赋予两个方向上的速度和一个加速度。
加速度模拟重力系统,初速度模拟爆炸时的动能,最后执行到指定高度爆炸,爆炸之后到指定步数停止。
#include<stdio.h>
#include <graphics.h>
#include <math.h>
#include <time.h>
#include <pthread.h>
typedef struct fireworks{
int x;
int y;
int Vx;
int Vy;
int a;
int tops;
int r;
int number;
};
typedef struct fireworksmain{
int x;
int y;
int Vx;
int Vy;
int a;
int r;
int heightmax;//最大爆炸高度
int stop;
int i;//对应爆炸效果
int n;
};
void delete_ex();
void delete_exs(int n);
int height=600;//屏幕高
fireworks ax[30][1000];//最多同时绘制10*100个烟花颗粒
fireworksmain as[30];//主烟花
//30是烟花升空的数量,100是烟花爆炸的最多数量
int N=0;//烟花的最初数量
int Nmax=100;
void delay(DWORD ms)
{
static DWORD oldtime = GetTickCount();
while(GetTickCount() - oldtime < ms)
Sleep(1);
oldtime = GetTickCount();
}
void initialization() {//初始化所有烟花
for(int i=0;i<30;i++) {
as[i].a=-1;
as[i].Vx=0;
as[i].Vy=-5;
as[i].y=height-1;
as[i].r=6;
as[i].heightmax=100+rand()%100;
as[i].stop=0;
as[i].i=i;
as[i].n=100;//
for(int i1=0;i1<1000;i1++){
ax[i][i1].r=2;
ax[i][i1].number=0;
//每25个赋予不同方向的初速度
if(i1<=250) {//正方向+x +y
if(i1<100){
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=rand()%20;
ax[i][i1].Vy=rand()%14;
}if(i1>100&&i1<200){
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=rand()%15;
ax[i][i1].Vy=rand()%19;
}if(i1>=200&&i1<=250){
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=rand()%17;
ax[i][i1].Vy=rand()%19;
}else{
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=rand()%17;
ax[i][i1].Vy=rand()%19;
}
}if(i1>250&&i1<=500){//第一
if(i1>250&&i1<=300){
ax[i][i1].a=-1;//加速度
ax[1][i1].Vx=-rand()%10;
ax[i][i1].Vy=rand()%15;
}if(i1>300&&i1<=400){
ax[i][i1].a=-1;//加速度
ax[1][i1].Vx=-rand()%16;
ax[i][i1].Vy=rand()%15;
}if(i1>400&&i1<500){
ax[i][i1].a=-1;//加速度
ax[1][i1].Vx=-rand()%20;
ax[i][i1].Vy=rand()%15;
}
}
if(i1>500&&i1<=750){//第一
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=-rand()%13;
ax[i][i1].Vy=-rand()%15;
}if(i1>750&&i1<1000){//第一
ax[i][i1].a=-1;//加速度
ax[i][i1].Vx=rand()%10;
ax[i][i1].Vy=-rand()%15;
}
}
}
}
void explosion(int i) {//爆炸效果
for(int i1=0;i1<=1000;i1++){
if(ax[i][i1].number>100){
as[i].stop=0;
return ;
}
}
for(int i1=0;i1<1000;i1++){
ax[i][i1].x+=ax[i][i1].Vx;
ax[i][i1].y+=ax[i][i1].Vy;
ax[i][i1].number++;
if(ax[i][i1].number>200){
delete_exs(i);
as[i].stop=0;
}
}
}
void thisa(int i){//爆炸 前
for(int i1=0;i1<1000;i1++){
ax[i][i1].x=as[i].x+rand()%50;
ax[i][i1].y=as[i].heightmax+rand()%50;
}
}
void setXY(){//根据物理量改变位置
for(int i=0;i<Nmax;i++) {
if(as[i].stop==1){//烟花为激活态需要绘制
if(as[i].y<=as[i].heightmax){//到达规定高度绘制爆炸效果
//开始爆炸需要改变 爆炸效果
explosion(i);
} else{//否则继续升空
as[i].y+=as[i].Vy;
as[i].x+=as[i].Vx;
ax[i]->Vy+=ax[i]->a;
}
}
}
}
void explosion_draws(int i1){//批量绘制爆炸效果
for(int i=0;i<=1000;i++){
if(ax[i1][i].number>200){
as[i1].stop=2;
return ;
}
}
for(int i=0;i<1000;i++){
setfillcolor(BLUE);
fillcircle(ax[i1][i].x,ax[i1][i].y,ax[i1][i].r) ;
}
}
void draws(){//开始一次性绘制
for(int i=0;i<Nmax;i++) {
if(as[i].stop==1){//寻找需要绘制的 主烟花
if(as[i].y<=as[i].heightmax&& as[i].stop==1 ){//爆炸效果
explosion_draws(i);
}else{
fillcircle(as[i].x,as[i].y,as[i].r) ;
}
}
}
}
void delete_exs(int i){
for(int i1=0;i1<1000;i1++){
clearcircle(ax[i][i1].x,ax[i][i1].y,ax[i][i1].r+1) ;
}
}
void delete_ex(){//批量删除
for(int i=0;i<Nmax;i++) {
if(as[i].stop==1||as[i].stop==2){//寻
if(as[i].y<=as[i].heightmax){//
delete_exs(i);
}else{
clearcircle(as[i].x,as[i].y,as[i].r+1) ;
}
if(as[i].stop==2) as[i].stop=0;
}
}
}
int H(int x,int y){//寻找一个空的
for(int i=0;i<30;i++) {
if(as[i].stop==0){
for(int i1=0;i1<=1000;i1++){
ax[i][i1].number=0;
}as[i].y=height-1;
as[i].stop=1;
as[i].x=x;
thisa(i);
return i;
}
}return 0;
}
void* pthraed_1_Code(void* arg){
MOUSEMSG msg;
MOUSEMSG m;
while(1){
m = GetMouseMsg(); // 获取鼠标消息
if (m.uMsg == WM_LBUTTONDOWN) { // 判断是否有鼠标消息
printf("sss\n");
H(m.x,m.y);
}
delay(10) ;
}
}
void run(){
delay(1000);
initialization();
as[1].stop=1;
as[1].x=300;
thisa(1);
BeginBatchDraw();
while(1){
setXY();
draws();//绘制
FlushBatchDraw();
delay(14);
delete_ex();
}EndBatchDraw();
draws();
}
int draw() {//绘制烟花 同时绘制帧
}
int main(void){
initialization();
as[1].stop=1;
as[1].x=300;
thisa(1);
initgraph(1500,1000);
initialization();
pthread_t p1,p2;
//初始化线程1(无参)
pthread_create(&p1,NULL,pthraed_1_Code,NULL);
run();
getchar();
pthread_join(p1,NULL);
return 0;
}
缺陷:因为写的急,所以在判断是否到最后一步的地方有待改进,循环判断也有待烟花
最后,祝大家新年快乐!