代码雨由N列“代码”组成,每列“代码”由于M个代码组成,每个“代码”看作一个对象,它有四个属性,分别是:x坐标、y坐标、速度、内容。
各列的速度和初始位置不一样才会有错落有致的感觉,但每列中的每个“代码”的速度却要一样。
#include <bits/stdc++.h>
#include <Windows.h>
typedef struct{
int x, y;
char ch;
}RAINDROP;
const int BUFFER_SIZE = 50;
int WIDTH = 80;
int HEIGHT = 30;
const int RAIN_LENGTH = 18;
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 show_cursor(BOOL hide){
CONSOLE_CURSOR_INFO cciCursor;
if (GetConsoleCursorInfo(HOUT, &cciCursor))
{
cciCursor.bVisible = hide;
SetConsoleCursorInfo(HOUT, &cciCursor);
}
}
void set_color(int color){
SetConsoleTextAttribute(HOUT, color);
}
int main(){
CONSOLE_SCREEN_BUFFER_INFO info;
GetConsoleScreenBufferInfo(HOUT, &info);
HEIGHT = info.srWindow.Bottom;
WIDTH = info.srWindow.Right;
show_cursor(FALSE);
srand((unsigned int)time(NULL));
for (int i=0; i<BUFFER_SIZE; i++){
raindropLine[i].x = rand()%WIDTH;
raindropLine[i].y = rand()%HEIGHT;
raindropLine[i].ch = ' '+i+rand() %2;
}
while(true){
GetConsoleScreenBufferInfo(HOUT, &info);
HEIGHT = info.srWindow.Bottom;
WIDTH = info.srWindow.Right;
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++;
raindropLine[i].ch = ' '+i+rand() %2;
if (raindropLine[i].y > HEIGHT + RAIN_LENGTH)
{
raindropLine[i].x = rand() % WIDTH;
raindropLine[i].y = rand() % HEIGHT;
}
if ( raindropLine[i].y <= HEIGHT)
{
gotoxy(raindropLine[i].x, raindropLine[i].y);
set_color(FOREGROUND_GREEN|FOREGROUND_INTENSITY);
putchar(raindropLine[i].ch);
}
}
Sleep(30);
}
getchar();
return 0;
}