C语言代码:数字雨

开发 前端
本文将通过一个简单的Windows控制台程序,来展示如何实现一个模拟雨水下落的效果。

在我们的日常生活中,雨水是我们经常遇到的一种自然现象。有时候,我们会在雨中漫步,欣赏那美丽的雨景。然而,在计算机世界里,我们如何用代码来模拟这种美丽的雨景呢?本文将通过一个简单的Windows控制台程序,来展示如何实现一个模拟雨水下落的效果。

代码概览

本程序主要使用了Windows API和C语言。通过定义一个RAINDROP结构体来表示雨滴,并使用数组来存储一定数量的雨滴。程序的主要逻辑在main函数中实现,包括初始化控制台信息、随机设置雨滴初始位置和内容、实现雨滴下落过程、以及控制雨滴下落速度等。

关键技术点

  • 结构体使用:通过定义RAINDROP结构体来存储雨滴的x、y坐标和字符内容,便于后续对雨滴的操控。
  • 光标控制:使用SetConsoleCursorPosition函数来控制光标位置,实现雨滴的显示和移动。
  • 颜色设置:使用SetConsoleTextAttribute函数来设置文本颜色,使雨滴呈现绿色。
  • 时间随机性:利用rand()函数生成随机数,控制雨滴的位置和下落速度。
  • 动画效果:通过定时器或Sleep函数实现时间的延迟,使雨滴呈现连续下落的效果。

详细实现

(1) 定义结构体:

typedef struct  
{  
    int x, y;  
    char ch;  
} RAINDROP;

定义了一个名为RAINDROP的结构体,用于存储每个雨滴的x、y坐标和字符内容。

(2) 初始化控制台信息

在main函数中,首先获取控制台的宽度和高度,为后续的雨滴下落提供参考。

RAINDROP raindropLine[BUFFER_SIZE];
HANDLE HOUT = GetStdHandle(STD_OUTPUT_HANDLE);

(3) 随机设置雨滴初始位置和内容

使用rand()函数随机生成雨滴的初始位置和内容。例如:raindropLine[i].x = rand() % WIDTH;。

(4) 雨滴下落过程的实现

在主循环中,不断更新雨滴的位置,并利用光标控制和颜色设置来显示雨滴。例如:gotoxy(raindropLine[i].x, raindropLine[i].y); set_color(FOREGROUND_GREEN); putchar(raindropLine[i].ch);。同时,当雨滴下落过快时,重新设置其位置,使其重新开始下落。例如:if (raindropLine[i].y > HEIGHT + RAIN_LENGTH) raindropLine[i].x = rand() % WIDTH; raindropLine[i].y = rand() % HEIGHT;。

(5) 控制雨滴下落速度

通过Sleep(50)函数实现时间的延迟,使雨滴呈现连续下落的效果。同时,根据不同的显示分辨率调整雨滴的大小和下落速度。

(6) 高亮显示雨滴

为了使雨滴更显眼,使用FOREGROUND_GREEN|FOREGROUND_INTENSITY来设置高亮颜色。例如:set_color(FOREGROUND_GREEN|FOREGROUND_INTENSITY); putchar(raindropLine[i].ch);。

(7) 程序结束

在主循环结束后返回0,表示程序正常退出。例如:return 0;。

(8) 性能与优化

本程序的性能主要受到控制台刷新率和显示分辨率的影响。为了提高程序的性能表现,可以尝试以下优化措施:使用双缓冲技术减少屏幕刷新的次数;根据不同的显示分辨率调整雨滴的大小和下落速度;优化代码逻辑和数据结构等。 

效果展示:

完整代码:

#include <time.h>
#include <Windows.h>
#include <stdio.h>

const int BUFFER_SIZE = 100;
const int RAIN_LENGTH = 18;

typedef struct
{
    int x, y;
    char ch;
} RAINDROP;

RAINDROP raindropLine[BUFFER_SIZE];
HANDLE HOUT = GetStdHandle(STD_OUTPUT_HANDLE);

void gotoxy(int x, int y)
{
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(HOUT, pos);
}

void set_color(WORD wAttributes)
{
    SetConsoleTextAttribute(HOUT, wAttributes);
}

int main()
{
    CONSOLE_SCREEN_BUFFER_INFO info;
    GetConsoleScreenBufferInfo(HOUT, &info);
    int HEIGHT = info.srWindow.Bottom;
    int WIDTH = info.srWindow.Right;
    srand((unsigned int)time(NULL)); // 使用当前时间作为随机数种子  
    for (int i = 0; i < BUFFER_SIZE; i++) // 随机设置雨滴下落的位置和内容  
    {
        raindropLine[i].x = rand() % WIDTH; // 设置x坐标为随机数  
        raindropLine[i].y = rand() % HEIGHT; // 设置y坐标为随机数  
        raindropLine[i].ch = rand() % 2 + 48; // 设置雨滴内容为0或1的随机数,ASCII码48起为数字字符  
    }
    while (true)
    {
        for (int i = 0; i < BUFFER_SIZE; ++i)
        {
            if (raindropLine[i].y <= HEIGHT)
            {
                gotoxy(raindropLine[i].x, raindropLine[i].y);
                set_color(FOREGROUND_GREEN); // 设置雨滴颜色为绿色  
                putchar(raindropLine[i].ch); // 显示雨滴内容  
            }
            gotoxy(raindropLine[i].x, raindropLine[i].y - RAIN_LENGTH); // 擦除过长的雨滴,将光标移动到上一行位置  
            putchar(' '); // 在当前位置填充空白,为雨滴留出空间  
            raindropLine[i].y++; // 雨滴下落一行,增加y坐标值  
            raindropLine[i].ch = rand() % 2 + 48; // 重新生成随机数作为雨滴内容,生成0或1的随机数(ASCII码48起为数字字符)  
            if (raindropLine[i].y > HEIGHT + RAIN_LENGTH) // 如果雨滴下落过快,重新设置其位置,将y坐标设置为窗口顶部附近的位置(HEIGHT+RAIN_LENGTH)附近的值)                   
            {
                raindropLine[i].x = rand() % WIDTH; // 在窗口内随机设置新的x坐标值,让雨滴重新开始下落位置的随机分配过程 
                raindropLine[i].y = rand() % HEIGHT; // 在窗口内随机设置新的y坐标值,让雨滴重新开始下落位置的随机分配过程
                                                     // 如果雨滴位置仍然在窗口内,高亮显示,增加亮度                 
                gotoxy(raindropLine[i].x, raindropLine[i].y);
                set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY); // 高亮显示,增加亮度                
                putchar(raindropLine[i].ch);
            }
            if (raindropLine[i].y <= HEIGHT) // 如果雨滴位置仍然在窗口内,高亮显示,增加亮度            
            {
                gotoxy(raindropLine[i].x, raindropLine[i].y);
                set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY); // 高亮显示,增加亮度               
                putchar(raindropLine[i].ch);
            }
        }
        Sleep(50); // 暂停一段时间,以控制动画的速度,这里设置为50毫秒   
                 
    }
    return 0; // 程序结束,返回0表示正常退出程序  
}
责任编辑:赵宁宁 来源: 鲨鱼编程
相关推荐

2023-12-07 12:59:46

C语言循环队列代码

2022-06-29 09:19:09

静态代码C语言c代码

2022-06-01 10:45:52

C语言代码优化

2022-07-22 14:56:17

Canvas鸿蒙

2020-12-02 10:27:40

C语言

2011-07-05 16:57:53

C语言

2011-07-05 17:07:14

C语言

2010-01-11 11:27:25

C++语言

2022-11-03 18:28:05

C语言Vely

2010-01-15 17:38:37

C++语言

2022-07-20 10:21:11

C语言代码内存

2010-01-14 10:34:02

C++语言

2022-03-10 10:48:30

PolyCoder自动代码生成器语言

2021-06-09 08:50:39

C语言关机代码复杂代码解读

2022-08-26 09:02:57

代码库编程语言

2009-08-03 16:28:53

Java语言与C#语言

2011-10-24 09:42:00

C语言

2022-01-28 14:54:21

staticC语言编译器

2022-04-25 15:55:58

C 语言编程语言Java

2009-09-02 17:10:45

C#语言入门
点赞
收藏

51CTO技术栈公众号