一、项目介绍

这是一个用C语言实现的雪花飘落小程序。

背景图片可自行替换用作表白。

编译环境:Visual Studio2019

第三方库:Easyx2022  注意需要提前安装easyX,如没有基础可以先了解easyX图形编程

二、运行截图

雪花

雪花

加菲

三、完整源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
/*Love Snow
 *需要自己提供一张大小为 800×600 的图片(img.jpg)在工程文件夹根目录下
 *大小可以在程序内更改,图片名字也可以。
 */
#include <graphics.h>
#define MAX_STAR 500// 雪花数量上限
#define SCREEN_WIDTH 800// 屏幕宽度
#define SCREEN_HEIGHT 600// 屏幕高度
#define MAX_STEP 5// 雪花每次移动最高步长
#define MAX_RADIUS 5// 雪花最大半径
#define IMGNAME _T("img.jpg")// 图片名字
using namespace std;
// 图片转数组(这个有很大优化空间的,需要识别彩色照片可以看这)
int imgList[SCREEN_HEIGHT][SCREEN_WIDTH] = { 0 };
// 雪花状态
enum STATUS
{
STOP = 0,// 不动
UP,// 向上
DOWN,// 向下
LEFT,// 向左
RIGHT,// 向右
RANDOM,// 随机
ALL_STATUS// 记录状态总数
};
struct STAR
{
int x;// 雪花的 x 坐标
int y;// 雪花的 y 坐标
enum STATUS stat;// 雪花状态
unsigned radius;// 雪花的半径
int step;// 雪花每次移动的步长
int color;// 雪花的颜色
};
struct SqList
{
struct STAR* elems; // 顺序表的基地址
int length;// 顺序表的长度
int size;// 顺序表的空间
};
// 顺序表的接口
bool initList(SqList& L);
bool listAppend(SqList& L, struct STAR e);
bool listDelete(SqList& L, int i);
void destroyList(SqList& L);
bool initList(SqList& L)
{
L.elems = new struct STAR[MAX_STAR];
if (!L.elems) return false;
L.length = 0;
L.size = MAX_STAR;
return true;
}
bool listAppend(SqList& L, struct STAR e)
{
if (L.length == L.size) return false;// 存储空间已满
L.elems[L.length] = e;
L.length++;// 表长加 1
return true;
}
bool listDelete(SqList& L, int i)
{
if (i < 0 || i >= L.length) return false;
if (i == L.length - 1)
{// 删除最后一个元素
L.length--;
return true;
}
for (int j = i; j < L.length - 1; j++)
{
L.elems[j] = L.elems[j + 1];// 删除位置的后续元素一次往前移
}
L.length--;
return true;
}
void destroyList(SqList& L)
{
if (L.elems) delete[]L.elems;// 释放存储空间
L.length = 0;
L.size = 0;
}
/************************************
* 功能:移动雪花,并在指定区域留下雪痕
* 输入参数:
* L - 雪花对象
* i - 雪花在全局数组中的下标
* 返回值:无
************************************/
void MoveStar(SqList& L, int i)
{
// 留下雪痕
if (L.elems[i].stat == DOWN)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1)
{
L.elems[i].y += L.elems[i].step;
L.elems[i].x -= 2;
}
}
if (L.elems[i].stat == UP)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1)
{
L.elems[i].y -= L.elems[i].step;
L.elems[i].x -= 2;
}
}
if (L.elems[i].stat == LEFT)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1) L.elems[i].x -= L.elems[i].step;
}
if (L.elems[i].stat == RIGHT)
{
if (imgList[L.elems[i].y][L.elems[i].x] == 1) L.elems[i].x += L.elems[i].step;
}
if (L.elems[i].stat == STOP) return;
// 擦除原来的雪花
setfillcolor(BLACK);
solidcircle(L.elems[i].x, L.elems[i].y, L.elems[i].radius);
if (L.elems[i].stat == DOWN)
{
L.elems[i].y += L.elems[i].step;
L.elems[i].x -= 2;
if (L.elems[i].x < 0) L.elems[i].x = SCREEN_WIDTH;
if (L.elems[i].y > SCREEN_HEIGHT) L.elems[i].y = 0;
//if(L.elems[i].y>SCREEN_HEIGHT) listDelete(L, i);// 这段代码可以让飘出屏幕外的雪花消亡
}
else if (L.elems[i].stat == UP)
{
L.elems[i].y -= L.elems[i].step;
L.elems[i].x -= 2;
if (L.elems[i].x < 0) L.elems[i].x = SCREEN_WIDTH;
if (L.elems[i].y < 0) L.elems[i].y = SCREEN_HEIGHT;
//if(L.elems[i].y<0) listDelete(L, i);
}
else if (L.elems[i].stat == LEFT)
{
L.elems[i].x -= L.elems[i].step;
if (L.elems[i].x > 0) L.elems[i].x = SCREEN_WIDTH;
//if(L.elems[i].x<0) listDelete(L, i);
}
else if (L.elems[i].stat == RIGHT)
{
L.elems[i].x += L.elems[i].step;
if (L.elems[i].x > SCREEN_HEIGHT) L.elems[i].x = 0;
//if(L.elems[i].x>SCREEN_WIDTH) listDelete(L, i);
}
setfillcolor(L.elems[i].color);
solidcircle(L.elems[i].x, L.elems[i].y, L.elems[i].radius);
}
/************************************
* 功能:初始化雪花
* 输入参数:
* i - 雪花在全局数组中的下标
* 返回值:无
************************************/
void initStar(struct STAR& _star)
{
int rgb = 0;
//rand() 得到随机数范围 0 - 32767 RAND_MAX
_star.x = rand() % SCREEN_WIDTH;// x 范围 0 - SCREEN_WIDTH
_star.y = rand() % SCREEN_HEIGHT;// y 范围 0 - SCREEN_HEIGHT
//_star.stat = STATUS(rand() % 6);// 雪花状态:随机
_star.stat = DOWN;// 雪花状态:向下
_star.radius = 1 + rand() % MAX_RADIUS; // 半径控制 1 - MAX_RADIUS
_star.step = rand() % MAX_STEP + 1;// 步长 1 - MAX_STEP
rgb = 255 * _star.step / MAX_STEP;// RGB:0 - 255
_star.color = RGB(rgb, rgb, rgb);
}
int main()
{
bool quit = false;
struct STAR star;
SqList starList;
// 初始化屏幕
initgraph(SCREEN_WIDTH, SCREEN_HEIGHT);
// 初始化图片
IMAGE img;
loadimage(&img, IMGNAME);
SetWorkingImage(&img);// 设置 img为绘制设备
COLORREF color;// 记录像素颜色
BYTE r, b, g;// 记录像素RGB
for (int y = 0; y < SCREEN_HEIGHT; y++)
{
for (int x = 0; x < SCREEN_WIDTH; x++)
{
color = getpixel(x, y);// 获取像素颜色
r = GetRValue(color);
b = GetBValue(color);
g = GetGValue(color);
if (r < 200 && b < 200 && g < 200)
{// 判断需留下“雪痕”的数组位置
imgList[y][x] = 1;
}
}
}
SetWorkingImage();// 设置回默认绘制设备
cleardevice();
// 初始化保存雪花状态的顺序表
initList(starList);
for (int i = 0; i < MAX_STAR; i++)
{
initStar(star);
listAppend(starList, star);
}
for (int i = 0; i < starList.length; i++)
{
setfillcolor(starList.elems[i].color);
solidcircle(starList.elems[i].x, starList.elems[i].y,
starList.elems[i].radius);
}
while (quit == false)
{
for (int i = 0; i < starList.length; i++)
{
MoveStar(starList, i);
}
if (starList.length == 0)
{// 若设置雪花离开屏幕后消亡,则会触发此退出
quit = true;
}
Sleep(50);
}
system("pause");
closegraph();
return 0;
}
点赞(216)

C语言网提供由在职研发工程师或ACM蓝桥杯竞赛优秀选手录制的视频教程,并配有习题和答疑,点击了解:

一点编程也不会写的:零基础C语言学练课程

解决困扰你多年的C语言疑难杂症特性的C语言进阶课程

从零到写出一个爬虫的Python编程课程

只会语法写不出代码?手把手带你写100个编程真题的编程百练课程

信息学奥赛或C++选手的 必学C++课程

蓝桥杯ACM、信息学奥赛的必学课程:算法竞赛课入门课程

手把手讲解近五年真题的蓝桥杯辅导课程

Dotcpp在线编译      (登录可减少运行等待时间)
#include<stdio.h>
int main()
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX