现在的代码只能在樱花树绘制完之后进行流星的移动,有没有办法可以让流星自由移动的同时绘制樱花树
#include <easyx.h>
#include<stdio.h>
#include <graphics.h>
#include<conio.h>
#include<stdlib.h>
#include <time.h>
#include <algorithm>
IMAGE meteor1, meteor2;
float offsetAngle = PI / 4; // 左右枝干和父枝干偏离的角度
float shortenRate = 0.7; // 子枝干比父枝干变短的倍数
/*星星结构体*/
struct Star
{
int x, y;//坐标
int step;//速度
int color;//颜色
}star[1000];
/*流星结构体*/
struct Metor
{
int x, y;//坐标
int step;//速度
int style;//图片
}meteor[520];
int main()
{
srand(time(0)); // 随机初始化
initgraph(WIDTH, HEIGHT); // 新开一个画面
loadimage(&meteor1, _T("C:\\Users\\suenos\\Desktop\\use\\meteor1.jpg"));
loadimage(&meteor2, _T("C:\\Users\\suenos\\Desktop\\use\\meteor2.jpg"));
int i = 0;
//初始化所有行星
for (i = 0; i < 1000; i++)
initStar(i);
//初始化所有流星
for (i = 0; i < 520; i++)
initMeteor(i);
while (1)
{
BeginBatchDraw();//防止闪屏,和EndBatchDraw()搭配使用
cleardevice();//刷新
for (i = 0; i < 1000; i++)//画1000个星星
drawStar(i);
drawMeteor(i);
Sleep(50);
brunch(WIDTH / 3, HEIGHT, 0.4 * HEIGHT * shortenRate, -PI / 2, 15 * shortenRate, 1); // 递归函数调用
EndBatchDraw();
}
}
float mapValue(float input, float inputMin, float inputMax, float outputMin, float outputMax)
{
float output;
if (abs(input - inputMin) < 0.000001) // 防止除以零的bug
output = outputMin;
else
output = (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin) + outputMin;
return output;
}
float randBetween(float min, float max)
{
float t = rand() / double(RAND_MAX); // 生成[0,1]的随机小数
// 调用mapValue函数,把值范围从[0,1]映射到[min,max]
float r = mapValue(t, 0, 1, min, max);
return r;
}
void brunch(float x_start, float y_start, float length, float angle, float thickness, int generation) //参数:枝干起始x y坐标,枝干长度,枝干角度,枝干绘图线条宽度,第几代
{
int i = 520;
// 利用三角函数求出当前枝干的终点x,y坐标
float x_end, y_end;
x_end = x_start + length * cos(angle);
y_end = y_start + length * sin(angle);
moveMeteor(i);
// 画线条枝干
setlinestyle(PS_SOLID, thickness); // 设定当前枝干线宽
moveMeteor(i);
// 设置枝干为灰褐色,主树干最黑,子枝干逐渐变亮
COLORREF color = HSVtoRGB(15, 0.75, 0.4 + generation * 0.05);
setlinecolor(color); // 设定当前枝干颜色
line(x_start, y_start, x_end, y_end); // 画出当前枝干(画线)
moveMeteor(i);
// 求出子枝干的代数
int childGeneration = generation + 1;
// 生成左、右、中间三个子枝干的长度,逐渐变短,并有一定随机性
float childLength = shortenRate * length;
float leftChildLength = childLength * randBetween(0.9, 1.1);
float rightChildLength = childLength * randBetween(0.9, 1.1);
float centerChildLength = childLength * randBetween(0.8, 1.1);
moveMeteor(i);
// 当子枝干长度大于2,并且代数小于等于10,递归调用产生子枝干
if (childLength >= 2 && childGeneration <= 9)
{
// 生成子枝干的粗细,逐渐变细
float childThickness = thickness * 0.8;
if (childThickness < 2) // 枝干绘图最细的线宽为2
childThickness = 2;
moveMeteor(i);
// 一定概率产生左、右、中子枝干
if (randBetween(0, 1) < 0.95)
brunch(x_end, y_end, leftChildLength, angle + offsetAngle * randBetween(0.5, 1), childThickness, childGeneration);
if (randBetween(0, 1) < 0.95)
brunch(x_end, y_end, rightChildLength, angle - offsetAngle * randBetween(0.5, 1), childThickness, childGeneration);
if (randBetween(0, 1) < 0.85)
brunch(x_end, y_end, centerChildLength, angle + offsetAngle / 5 * randBetween(-1, 1), childThickness, childGeneration);
}
else // 最末端绘制樱花,画一个粉色填充圆
{
setlinestyle(PS_SOLID, 1); // 线宽
// 樱花粉色HSVtoRGB(325,0.3,1),有一定随机性
COLORREF color = HSVtoRGB(randBetween(300, 350), randBetween(0.2, 0.3), 1);
setlinecolor(color); // 设定线条颜色
setfillcolor(color); // 设定填充颜色
if (childLength <= 4) // 如果子枝干长度小于等于4
fillcircle(x_end, y_end, 2); // 圆的半径为2(再小就看不清了)
else
fillcircle(x_end, y_end, childLength / 2); // 画一个圆,半径为子枝干长度的一半
}
moveMeteor(i);
FlushBatchDraw(); // 批量绘制
Sleep(1); // 暂停
}
void initStar(int i)
{
star[i].x = rand() % 1000;
star[i].y = rand() % 600;
star[i].color = RGB(rand() % 256, rand() % 256, rand() % 256);//星星的颜色采用五颜六色
star[i].step = rand() % 5 + 2;
}
void initMeteor(int i)
{
meteor[i].x = rand() % 2000 - 1000;//这样的话,取的值就是在[0,1999]之间
meteor[i].y = rand() % 200;//[0,199]-400;
meteor[i].step = rand() % 20 + 5;//[0,40]+5
meteor[i].style = rand() % 2;//流星有两种风格随便取
}
void drawMeteor(int i)
{
for (i = 0; i < 520; i++)
{
if (meteor[i].style == 0)
putimage(meteor[i].x, meteor[i].y, &meteor1, SRCPAINT);//为了防止这流星图片重叠,而加的SRCPAINT
if (meteor[i].style == 1)
putimage(meteor[i].x, meteor[i].y, &meteor2, SRCPAINT);
}
}
void drawStar(int i)
{
putpixel(star[i].x, star[i].y, star[i].color);
star[i].x += star[i].step;
if (star[i].x > 945)
{
putpixel(star[i].x, star[i].y, star[i].color);
initStar(i);
}
}
void moveMeteor(int i)
{
for (i = 0; i < 520; i++)
{
meteor[i].x += meteor[i].step;
meteor[i].y += meteor[i].step;
if (meteor[i].x > 1000 || meteor[i].y > 600)
initMeteor(i);
}
}