在C语言中实现简单的烟花效果,不需要依赖复杂的第三方图形库,借助Windows系统自带的控制台API就可以完成。核心思路是通过控制台光标定位、字符输出和颜色设置,模拟烟花粒子从发射到绽放再到消散的整个过程。

实现烟花效果的核心逻辑
整个烟花效果可以分为三个主要阶段:
- 发射阶段:烟花粒子从底部向上运动,速度逐渐减慢
- 绽放阶段:粒子到达顶点后向四周扩散,速度逐渐降低
- 消散阶段:粒子亮度逐渐降低,最终消失
需要用到的Windows API函数
这里主要用到以下几个控制台相关的函数:
SetConsoleCursorPosition:设置控制台光标的位置,用来定位烟花粒子的输出位置SetConsoleTextAttribute:设置控制台文字的颜色和背景色,用来实现烟花的彩色效果system("cls"):清空控制台内容,实现动画的刷新效果Sleep:让程序暂停指定毫秒数,控制动画的播放速度
完整代码示例
下面是完整的可运行代码,代码中已经添加了详细的中文注释:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <math.h>
#include <time.h>
#define WIDTH 80 // 控制台宽度
#define HEIGHT 25 // 控制台高度
#define PI 3.1415926
// 烟花粒子结构体
typedef struct {
int x; // 粒子x坐标
int y; // 粒子y坐标
int vx; // x方向速度
int vy; // y方向速度
int color; // 粒子颜色
int life; // 粒子剩余生命值
int is_alive; // 粒子是否存活
} Particle;
// 设置控制台光标位置
void setCursor(int x, int y) {
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
// 初始化烟花发射粒子
void initLaunchParticle(Particle *p, int start_x) {
p->x = start_x;
p->y = HEIGHT - 1;
p->vx = 0;
p->vy = -2; // 向上运动
p->color = 10; // 绿色
p->life = 10; // 发射阶段生命值
p->is_alive = 1;
}
// 初始化绽放粒子
void initBoomParticle(Particle *p, int center_x, int center_y, int index, int total) {
// 计算粒子扩散角度
double angle = 2 * PI * index / total;
p->x = center_x;
p->y = center_y;
p->vx = (int)(3 * cos(angle));
p->vy = (int)(3 * sin(angle));
p->color = rand() % 15 + 1; // 随机颜色
p->life = 15; // 绽放阶段生命值
p->is_alive = 1;
}
int main() {
srand((unsigned)time(NULL));
Particle launch_p; // 发射粒子
Particle boom_p[50]; // 绽放粒子数组
int boom_count = 0; // 绽放粒子数量
int is_launching = 1; // 是否处于发射阶段
int launch_x = rand() % (WIDTH - 10) + 5; // 随机发射位置
// 初始化发射粒子
initLaunchParticle(&launch_p, launch_x);
while (1) {
system("cls"); // 清空控制台
if (is_launching) {
// 发射阶段逻辑
setCursor(launch_p.x, launch_p.y);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), launch_p.color);
printf("*");
launch_p.y += launch_p.vy;
launch_p.life--;
// 发射阶段结束,进入绽放阶段
if (launch_p.life <= 0) {
is_launching = 0;
boom_count = 30; // 生成30个绽放粒子
for (int i = 0; i < boom_count; i++) {
initBoomParticle(&boom_p[i], launch_p.x, launch_p.y, i, boom_count);
}
}
} else {
// 绽放阶段逻辑
for (int i = 0; i < boom_count; i++) {
if (boom_p[i].is_alive) {
setCursor(boom_p[i].x, boom_p[i].y);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), boom_p[i].color);
printf("*");
boom_p[i].x += boom_p[i].vx;
boom_p[i].y += boom_p[i].vy;
boom_p[i].life--;
// 生命值耗尽,粒子消失
if (boom_p[i].life <= 0) {
boom_p[i].is_alive = 0;
}
}
}
// 所有绽放粒子都消失后,重新初始化新的烟花
int all_dead = 1;
for (int i = 0; i < boom_count; i++) {
if (boom_p[i].is_alive) {
all_dead = 0;
break;
}
}
if (all_dead) {
is_launching = 1;
launch_x = rand() % (WIDTH - 10) + 5;
initLaunchParticle(&launch_p, launch_x);
}
}
Sleep(100); // 控制动画速度
}
return 0;
}
代码运行说明
这段代码需要在Windows系统的编译环境下运行,比如Dev-C++、Visual Studio等。编译运行后,会看到控制台中不断有烟花从底部发射,到达顶部后绽放出彩色的粒子,之后粒子逐渐消失,然后新的烟花再次发射。
代码优化方向
如果想要让烟花效果更真实,可以尝试以下优化:
- 给粒子添加重力效果,让绽放后的粒子有下落的运动轨迹
- 不同烟花设置不同的绽放半径和粒子数量
- 添加多个烟花同时发射的效果,让画面更丰富
- 调整粒子的生命值和颜色变化,模拟不同材质的烟花效果