C++實(shí)現(xiàn)動(dòng)態(tài)煙花代碼
寫在前面
首先,祝大家新年快樂!
即將迎來新的一年——癸卯兔年,祝大家成績、事業(yè)“兔”飛猛進(jìn),必定紅紅火火!
在這篇文章中,將用煙花致以大家最好的祝福!
煙花代碼將會(huì)用到 Easyx 圖形庫,可以去官網(wǎng)下載:easyx.cn
代碼思路
1 煙花結(jié)構(gòu)體
2 初始化煙花
3 煙花上升
4 煙花爆炸
5 繪制煙花
不需要任何圖片、音效(本來想加的,你要加自己加吧)
開始編寫
提前聲明:代碼純?cè)瓌?chuàng)!
需要用到的頭文件以及宏:
#include <graphics.h> #include <math.h> #include <time.h> #include <stdio.h> #define MAXNUM 15 #define WIDTH 640 #define HEIGHT 480 #define PI 3.1415926
graphics.h Easyx圖形庫
math.h 計(jì)算煙花位置
time.h 選取隨機(jī)種子
stdio.h 標(biāo)準(zhǔn)輸入輸出頭文件
MAXNUM 煙花數(shù)量
WIDTH , HEIGHT 窗口的寬、高
PI 圓周率常量,結(jié)合數(shù)學(xué)庫計(jì)算煙花位置
1 煙花結(jié)構(gòu)體
定義的參數(shù)如下:
nowx , nowy 現(xiàn)在坐標(biāo)
endy 爆炸高度
radio 爆炸半徑
explode 爆炸進(jìn)度
rgb[3] 煙花顏色rgb值
color 煙花顏色
struct Fire
{
int nowx;
int nowy;
int endy;
int radio;
int explode;
int rgb[3];
COLORREF color;
}fire[MAXNUM];2 初始化煙花
nowx , nowy 窗口外的隨機(jī)位置
endy 隨即高度
radio 隨即半徑
explode 一開始設(shè)為0
rgb[3] 一些特定的顏色隨機(jī)取
color 按照rgb值
void Init()
{
for (int i = 0; i < MAXNUM; i++)
{
fire[i].nowx = rand() % WIDTH;
fire[i].nowy = HEIGHT + rand() % 250 + 50;
fire[i].endy = rand() % 100 + 10;
fire[i].radio = rand() % 50 + 120;
fire[i].explode = 0;
int c[][3] = { {255, 0, 0}, {210, 190, 255}, {255, 120, 0}, {255, 0, 150}, {255, 240, 100}, {10, 255, 255}, {160, 10, 255}, {255, 200, 60} };
int n = rand() % 8;
fire[i].color = RGB(c[n][0], c[n][1], c[n][2]);
fire[i].rgb[0] = c[n][0];
fire[i].rgb[1] = c[n][1];
fire[i].rgb[2] = c[n][2];
}
}3 煙花上升
y坐標(biāo) 還沒到達(dá)爆炸高度時(shí)一直上升
for (int i = 0; i < MAXNUM; i++)
{
if (fire[i].nowy > fire[i].endy)
{
fire[i].nowy -= 3;
}
}4 煙花爆炸
爆炸進(jìn)度 explode 不斷增加,如果到達(dá)爆炸半徑,就重新初始化。(接上面的if語句)
else
{
if (fire[i].explode >= fire[i].radio)
{
fire[i].nowx = rand() % WIDTH;
fire[i].nowy = HEIGHT + rand() % 250 + 50;
fire[i].endy = rand() % 100 + 10;
fire[i].radio = rand() % 50 + 120;
fire[i].explode = 0;
int c[][3] = { {255, 0, 0}, {210, 190, 255}, {255, 120, 0}, {255, 0, 150}, {255, 240, 100}, {10, 255, 255}, {160, 10, 255}, {255, 200, 60} };
int n = rand() % 8;
fire[i].color = RGB(c[n][0], c[n][1], c[n][2]);
fire[i].rgb[0] = c[n][0];
fire[i].rgb[1] = c[n][1];
fire[i].rgb[2] = c[n][2];
}
else fire[i].explode++;
}5 繪制煙花
上升
繪制5個(gè)圓,大小從大到小,顏色從深到淺(增加rgb值)
for (int i = 0; i < MAXNUM; i++)
{
if (fire[i].nowy > fire[i].endy)
{
for (int size = 5; size > 0; size--)
{
int temp[] = { fire[i].rgb[0], fire[i].rgb[1], fire[i].rgb[2] };
for (int k = 0; k < 3; k++)
{
temp[k] += 50 * (5 - size);
if (temp[k] > 255) temp[k] = 255;
}
setfillcolor(RGB(temp[0], temp[1], temp[2]));
solidcircle(fire[i].nowx, fire[i].nowy + 15*(10 - size), size);
}
}
}爆炸
重頭戲!重頭戲!重頭戲!需要一些簡(fù)單(zá)的數(shù)(gāo)學(xué)(děng)常(shù)識(shí)(xúe)!
顏色漸變的實(shí)現(xiàn)方式跟前面一樣,只不過這里要用三角函數(shù)計(jì)算坐標(biāo),再用萬有引力、拋物線等改變 y坐標(biāo),讓它看得更真實(shí)!(牛頓:算你小子識(shí)相)
具體如何計(jì)算坐標(biāo),看我的文章,里面有說如何計(jì)算
然后是萬有引力,大概需要高度乘以 0.98 ,這里就相當(dāng)于減去 0.1
由于 easyx 坐標(biāo)上方為 y = 0,所以,應(yīng)該是:
y + (HEIGHT - y) * 0.1
再根據(jù)拋物線:y = x^2 ,修改一下就行了
else
{
for (int a = 0; a < 360; a += 30)
{
for (int size = 5; size > 0; size--)
{
int x = cos(a * PI / 180.0) * (fire[i].explode + size * 10) + fire[i].nowx;
int y = sin(a * PI / 180.0) * (fire[i].explode + size * 10) + fire[i].nowy + fire[i].radio / 2;
int temp[] = { fire[i].rgb[0], fire[i].rgb[1], fire[i].rgb[2] };
for (int k = 0; k < 3; k++)
{
temp[k] += 50 * (5 - size);
if (temp[k] > 255) temp[k] = 255;
}
setfillcolor(RGB(temp[0], temp[1], temp[2]));
solidcircle(x, y + (HEIGHT - y) * 0.1 + size * (size - 2), size);
}
}
}效果展示



還挺好看的,不是嗎?
完整代碼
最后,把函數(shù)封裝一下,main 函數(shù)寫出來(有手就行?。?/p>
/*******************************
* 項(xiàng)目名稱:新年煙花
* 開發(fā)環(huán)境:vs2022 + Easyx
* 作者:軒
* 代碼長度:137 行
* 完成時(shí)間:2023.1.20
* 用時(shí):2.2 小時(shí)
*******************************/
#include <graphics.h>
#include <math.h>
#include <time.h>
#include <stdio.h>
#define MAXNUM 15
#define WIDTH 640
#define HEIGHT 480
#define PI 3.1415926
struct Fire
{
int nowx;
int nowy;
int endy;
int radio;
int explode;
int rgb[3];
COLORREF color;
}fire[MAXNUM];
void Init()
{
for (int i = 0; i < MAXNUM; i++)
{
fire[i].nowx = rand() % WIDTH;
fire[i].nowy = HEIGHT + rand() % 250 + 50;
fire[i].endy = rand() % 100 + 10;
fire[i].radio = rand() % 50 + 120;
fire[i].explode = 0;
int c[][3] = { {255, 0, 0}, {210, 190, 255}, {255, 120, 0}, {255, 0, 150}, {255, 240, 100}, {10, 255, 255}, {160, 10, 255}, {255, 200, 60} };
int n = rand() % 8;
fire[i].color = RGB(c[n][0], c[n][1], c[n][2]);
fire[i].rgb[0] = c[n][0];
fire[i].rgb[1] = c[n][1];
fire[i].rgb[2] = c[n][2];
}
}
void Draw()
{
for (int i = 0; i < MAXNUM; i++)
{
if (fire[i].nowy > fire[i].endy)
{
for (int size = 5; size > 0; size--)
{
int temp[] = { fire[i].rgb[0], fire[i].rgb[1], fire[i].rgb[2] };
for (int k = 0; k < 3; k++)
{
temp[k] += 50 * (5 - size);
if (temp[k] > 255) temp[k] = 255;
}
setfillcolor(RGB(temp[0], temp[1], temp[2]));
solidcircle(fire[i].nowx, fire[i].nowy + 15*(10 - size), size);
}
}
else
{
for (int a = 0; a < 360; a += 30)
{
for (int size = 5; size > 0; size--)
{
int x = cos(a * PI / 180.0) * (fire[i].explode + size * 10) + fire[i].nowx;
int y = sin(a * PI / 180.0) * (fire[i].explode + size * 10) + fire[i].nowy + fire[i].radio / 2;
int temp[] = { fire[i].rgb[0], fire[i].rgb[1], fire[i].rgb[2] };
for (int k = 0; k < 3; k++)
{
temp[k] += 50 * (5 - size);
if (temp[k] > 255) temp[k] = 255;
}
setfillcolor(RGB(temp[0], temp[1], temp[2]));
solidcircle(x, y + (HEIGHT - y) * 0.1 + size * (size - 2), size);
}
}
}
}
}
void Move()
{
for (int i = 0; i < MAXNUM; i++)
{
if (fire[i].nowy > fire[i].endy)
{
fire[i].nowy -= 3;
}
else
{
if (fire[i].explode >= fire[i].radio)
{
fire[i].nowx = rand() % WIDTH;
fire[i].nowy = HEIGHT + rand() % 250 + 50;
fire[i].endy = rand() % 100 + 10;
fire[i].radio = rand() % 50 + 120;
fire[i].explode = 0;
int c[][3] = { {255, 0, 0}, {210, 190, 255}, {255, 120, 0}, {255, 0, 150}, {255, 240, 100}, {10, 255, 255}, {160, 10, 255}, {255, 200, 60} };
int n = rand() % 8;
fire[i].color = RGB(c[n][0], c[n][1], c[n][2]);
fire[i].rgb[0] = c[n][0];
fire[i].rgb[1] = c[n][1];
fire[i].rgb[2] = c[n][2];
}
else fire[i].explode++;
}
}
}
int main()
{
srand(time(NULL));
initgraph(640, 480);
Init();
BeginBatchDraw();
while (true)
{
cleardevice();
Draw();
Move();
FlushBatchDraw();
Sleep(2);
}
EndBatchDraw();
closegraph();
return 0;
}到此這篇關(guān)于C++實(shí)現(xiàn)動(dòng)態(tài)煙花代碼的文章就介紹到這了,更多相關(guān)C++煙花內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用MySQL編程實(shí)現(xiàn)C語言功能強(qiáng)大化步驟示例
這篇文章主要為大家介紹了使用MySQL編程實(shí)現(xiàn)C語言功能強(qiáng)大化步驟示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-05-05
C++實(shí)現(xiàn)基于控制臺(tái)界面的吃豆子游戲
這篇文章主要介紹了C++實(shí)現(xiàn)基于控制臺(tái)界面的吃豆子游戲,實(shí)例分析了吃豆子游戲的原理與C++實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04
Qt使用QListWidget實(shí)現(xiàn)自定義Item
這篇文章主要為大家詳細(xì)介紹了Qt如何使用QListWidget實(shí)現(xiàn)自定義Item的效果,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
舉例分析private的作用(c/c++學(xué)習(xí))
我知道我們可以用 public 中的值,把private中的數(shù)據(jù)給提出來,但是還是搞不懂private該怎么用,或者說在一個(gè)具體程序中,private有什么用2020-08-08

