池塘夜降彩虹雨C语言数据结构实验(免积分下载+超详细注释)

实验题目

设计一个程序,演示美丽的“池塘夜雨”景色:色彩缤纷的雨点飘飘洒洒地从天而降,滴滴入水有声,溅起圈圈微澜。

操作环境和条件

VS2017,easyX图形库

代码




#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
//conio是Console Input/Output(控制台输入输出)的简写,
//其中定义了通过控制台进行数据输入和数据输出的函数,主要是一些用户通过按键盘产生的对应操作,比如getch()函数等等
#include <time.h>
//从系统时钟获取时间方式
//ime_t time(time_t* timer)
//得到从标准计时点(一般是1970年1月1日午夜)到当前时间的秒数。
//clock_t clock(void)
//得到从程序启动到此次函数调用时累计的毫秒数。
#include <windows.h>
//WINDOWS.H是一个最重要的头文件,它包含了其他Windows头文件,这些头文件的某些也包含了其他头文件。这些头文件中最重要的和最基本的是:
//WINDEF.H 基本数据类型定义。
//WINNT.H 支持Unicode的类型定义。
//WINBASE.H Kernel(内核)函数。
//WINUSER.H 用户界面函数。
//WINGDI.H 图形设备接口函数。


#include <graphics.h>//如果您需要在vc及vs环境中使用graphics.h的功能 
//您可以下载EasyX图形库(注意:这是一个C++的图形库 如果您一定要在C语言环境下使用 graphics.h 您可以使用windows gdi
#include <mmsystem.h>//windows中与多媒体有关的大多数接口 
#pragma comment(lib, "winmm.lib")
#include <graphics.h>
struct rainDrop *head;头结点
MOUSEMSG m;///鼠标信息
int n = 100; //雨的数目
long msecond1, msecond2;
struct rainCircle //雨点落下造成的水圈
{
	int x;
	int y;
	int r;//雨圈的最大半径
	int curR;
	int rainCircleStep; //水圈产生的步骤
};
struct rainDrop
{
	int startX; //雨点开始的X值
	int startY; //雨点开始的Y值
	int endY; //雨点结束的Y值
	int curX; //雨点降落中的X值
	int curY; //雨点降落中的Y值
	COLORREF rainColor; //雨点的颜色
	//COLORREF是color和reference的缩写,表示颜色值,实际上是unsigned long类型。
	//可以配合RGB()宏来设置。
	int rainLineStep; //雨线的顺序
	int rainLineLength; //雨线的长度
	int status;
	struct rainCircle water;//水圈结构体类型
	struct rainDrop *next;//指向下一个雨滴下落的指针
};
struct rainDrop *creatDrop(void)//函数返回一个指向rainDrop类型的结构体
{
	struct rainDrop *p;//定义结构体类型
	p = (struct rainDrop *)malloc(sizeof(struct rainDrop));//动态分配内存
	p->startY = 120;//雨点下落起始Y位置赋初值
	p->startX = rand() % 1000; //rand()函数是产生随机数的一个随机函数,包涵在#include<stdlib.h>头文件中
	p->startY = p->startY + rand() % 630;
	p->endY = 590 + rand() % 50;//雨点结束位置赋值
	p->curX = p->startX;//雨点降落过程中为X赋值
	p->curY = p->startY;//雨点降落过程中为Y赋值
	p->rainLineStep = 8;//雨线顺序赋初值
	p->rainLineLength = 10;//雨线长度赋初值
	p->status = 0;
	p->rainColor = RGB(rand() % 256, rand() % 256, rand() % 256);
	//RGB(red, green, blue)
	//red 0 到 255 间的整数,代表颜色中的红色成分。
	//green 0 到 255 间的整数,代表颜色中的绿色成分。
	//blue 0 到 255 间的整数,代表颜色中的蓝色成分。
	p->water.x = p->startX;//水圈开始的X是雨滴的X
	p->water.y = p->endY;//水圈的Y是雨滴结束的Y
	p->water.r = rand() % 30;//水圈的最大半径随机确定
	p->water.curR = rand() % 2;
	p->water.rainCircleStep = rand() % 2 + 1;
	p->next = NULL;
	return(p);
}
void recreatDrop(struct rainDrop *p)
{
	p->startY = 120;
	p->startX = rand() % 1000;
	p->startY = p->startY + rand() % 630;
	p->endY = 590 + rand() % 50;
	p->curX = p->startX;
	p->curY = p->startY;
	p->rainLineStep = 8;
	p->rainLineLength = 10;
	p->status = 0;
	p->rainColor = RGB(rand() % 256, rand() % 256, rand() % 256);
	p->water.x = p->startX;
	p->water.y = p->endY;
	p->water.r = rand() % 30;
	p->water.curR = rand() % 2;
	p->water.rainCircleStep = rand() % 2 + 1;
}
void creatRain(void) //创建链表
{//创建的是循环链表,不断生成雨滴
	struct rainDrop *p1, *p2;//定义两个指向rainDrop类型的结构体指针
	int i;
	p1 = p2 = creatDrop();
	head = p1;
	for (i = 0; i < n; i++)
	{
		p2 = creatDrop();
		p1->next = p2;
		p1 = p2;
	}
	p1->next = head;
}
//生成下一个雨点的位置
void updateRainLineData(struct rainDrop *p)
{
	if (MouseHit())如果有鼠标信息就获取,没有就不获取
		//检测当前是否有鼠标消息
		m = GetMouseMsg();//获取一个鼠标消息。如果当前鼠标消息队列中没有,就一直等待。
	p->curY += p->rainLineStep;//Y的增量为rainLineStep
	if (m.y < 200)
		p->curY -= p->rainLineStep / 2;
	if (m.y > 450)
		p->curY += p->rainLineStep;
	p->startY = p->curY - p->rainLineLength;
	//
	if (m.x < 300)
	{
		p->curX -= p->rainLineStep;
		p->startX = p->curX + p->rainLineLength;
	}
	if (m.x > 600)
	{
		p->curX += p->rainLineStep;
		p->startX = p->curX - p->rainLineLength;
	}
}
void drawRainLine(struct rainDrop *p) //画雨线
{
	setlinestyle(PS_SOLID, 1);//设置当前画线样式(实线,宽度是1)
	setcolor(p->rainColor);//设置雨线的颜色,实现彩色雨
	line(p->startX, p->startY, p->curX, p->curY);//画直线
}
void clearRainLine(struct rainDrop *p) //以黑 or blue表示雨线消失
{
	if (p->startY > 550)
		setcolor(BLUE);//设置雨线的颜色,用蓝色表示雨消失
	else
		setcolor(BLACK);//设置雨线的颜色,黑色也可以表示雨消失
	setlinestyle(PS_SOLID, 1);// 设置当前画线样式(实线,宽度是1)
	line(p->startX, p->startY, p->curX, p->curY);//画直线
}

void thunder(struct rainDrop *p)
{
	int x, y;
	x = (rand() % 800) + 100;
	y = (rand() % 200) + 200;
	setfillcolor(WHITE);
	bar(0, 250, 1000, 550);
	Sleep(1);
	setfillcolor(BLACK);
	bar(0, 250, 1000, 550);
	POINT pts[] = { {x - 30,y},{x,y},{x,y - 70},{x + 30,y},{x,y},{x,y + 70} };
	setfillcolor(WHITE);
	solidpolygon(pts, 6);
	Sleep(1);
	setfillcolor(BLACK);
	solidpolygon(pts, 6);
	PlaySound("C:\\thunder.wav", NULL, SND_FILENAME | SND_ASYNC); //vc++最简单的声音函数
}

void updateRainCircleData(struct rainDrop *p) //控制水圈的大小
{
	p->water.curR += p->water.rainCircleStep;
}
void drawRainCircle(struct rainDrop *p) //画雨降落后的水圈
{
	int x1, x2, y1, y2;
	setcolor(p->rainColor);//画雨的颜色
	x1 = p->water.x - p->water.curR - 5;
	x2 = p->water.x + p->water.curR + 5;
	y1 = p->water.y - p->water.curR + 5;
	y2 = p->water.y + p->water.curR - 5;//确定雨滴下落后水圈椭圆的各个参数
	ellipse(x1, y1, x2, y2); //画椭圆
}
###########void clearRainCircle(struct rainDrop *p) //以blue色表示水圈消失
{//清除水圈
	int x1, x2, y1, y2;
	setcolor(BLUE);//将绘图背景色设置成蓝色
	x1 = p->water.x - p->water.curR - 5;
	x2 = p->water.x + p->water.curR + 5;
	y1 = p->water.y - p->water.curR + 5;
	y2 = p->water.y + p->water.curR - 5;//和生成水圈椭圆的参数保持一致
	ellipse(x1, y1, x2, y2);//将画出的椭圆的颜色与池塘的颜色保持一致,表示水圈消失
}
########void rainDropDown(struct rainDrop *p) //控制雨的路径
{
	if (p->curY >= p->endY)//雨线的末尾到达产生水圈的位置
	{
		clearRainLine(p);//清除雨线
		p->status = 1;//雨线的末尾到达产生水圈的位置
	}
	else
	{
		clearRainLine(p);//清除雨线
		updateRainLineData(p);//更新雨线下落路径
		drawRainLine(p);//画出雨线
		///
		if (m.mkLButton == true && p->curX % 999 == 1)//此处条件在于减少打雷的概率
			thunder(p);
	}
}
########void fallToWater(struct rainDrop *p) //控制雨圈雨点的衔接
{
	if (p->water.curR >= p->water.r)
	{
		clearRainCircle(p);//清除水圈
		recreatDrop(p);
	}
	else
	{
		clearRainCircle(p);
		updateRainCircleData(p);//更新水圈
		drawRainCircle(p);//画出水圈
	}
}
void rain() //控制全程雨的开始到结束
{
	struct rainDrop *p;
	p = head;
	while (!kbhit())
	{
		if (p->status == 0)
			rainDropDown(p);//清除所有
		else
			fallToWater(p);
		//PlaySound("C:\\rain.wav", NULL, SND_FILENAME | SND_ASYNC); //vc++最简单的声音函数
		p = p->next;
	}
}
void clearAll(void) //画图结束,释放空间
{
	struct rainDrop *p, *pf;
	p = head;
	while (p != head)
	{
		pf = p;
		p = p->next;
		free(pf);
	}
	closegraph();
}
void wuyun()
{
	setlinecolor(DARKGRAY); //定义画线颜色
	setfillcolor(DARKGRAY); //设置填充颜色
	fillellipse(20, 20, 200, 100); // (1)
	fillcircle(50, 60, 40);
	fillcircle(90, 70, 40);
	fillcircle(140, 70, 40);
	fillcircle(90, 35, 30);
	fillcircle(140, 40, 30);
	fillcircle(185, 60, 35);
	fillellipse(270, 20, 450, 100);
	fillcircle(300, 60, 40);
	fillcircle(340, 70, 40);
	fillcircle(390, 70, 40);
	fillcircle(340, 35, 30);
	fillcircle(390, 40, 30);
	fillcircle(435, 60, 35);
	fillellipse(520, 20, 700, 100);
	fillcircle(550, 60, 40);
	fillcircle(590, 70, 40);
	fillcircle(640, 70, 40);
	fillcircle(590, 35, 30);
	fillcircle(640, 40, 30);
	fillcircle(685, 60, 35);
	fillellipse(770, 20, 950, 100);
	fillcircle(800, 60, 40);
	fillcircle(840, 70, 40);
	fillcircle(890, 70, 40);
	fillcircle(840, 35, 30);
	fillcircle(890, 40, 30);
	fillcircle(935, 60, 35);
	//getch();
}
void pond()
{
	setlinecolor(BLUE);
	line(0, 680, 1000, 680);
	setfillstyle(0, NULL, NULL);
	setfillcolor(BLUE);
	bar(0, 550, 1000, 680);
	//池塘
}
int main()
{
	initgraph(1000, 680);
	pond();
	creatRain();
	wuyun();
	rain();
	clearAll();
	return 0;
}

效果图

在这里插入图片描述

注意

安装easyX参照官网:https://www.easyx.cn/
出现了(“The POSIX name for this item is deprecated. Instead, use the ISO C++ conformant name:”) 的报错
https://blog.csdn.net/whappymanlynn/article/details/50930461

下载

实验报告
链接:https://pan.baidu.com/s/1SQI48qpXkH6X7hha7mvmUA 提取码:o5bk
点个赞?再走
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值