相信大家看过许许多多的关于计算机黑客、骇客、人工智能、AI方面的电影,每当黑客入侵某个五角大楼,某个网站时,都会出现这样一副画面:

入侵

或者这样的:

数字雨

然后就轻而易举的成功入侵夺取管理员权限了,这时候的我们,心情肯定是激动的无以复加,心里大喊着:666!!!如果我有这么厉害的技术就好了!

所以大家想到今天要说的是什么了吗?没错,

(^U^)ノ~YO

和这并没有太大的关系,今天我们要讲的,是《数字雨》!

好了,我们来看下什么是数字雨。

 

数字雨,顾名思义,就是类似于天上下雨一样,往下掉数字或者是文字。

如下动态图:

 

这样看起来是不是感觉我们像是进入了一个科幻的虚拟世界呢?

当然了程序运行后还会有个小小的惊喜哦?

/**********************************************************************************

项目名称:数字雨《一棵开花的树》

 

***********************************************************************************/

#include

#include

#include

#pragma comment(lib, "WINMM.LIB")

#define NumOfColumn 25 //显示列的列数

typedef struct charList

{

struct charList * prev;

TCHAR ch; //放字符

struct charList * next;

}CharList;

typedef struct tagCharColumn

{

struct charList * head, *cur;

int x, y, iShownLen, iStrNum; //显示字数,字符数

}CharQueue;

struct showChar

{

TCHAR myChar[60];

int iNum; //字符个数

}charArr[7] = {//《一棵开花的树》

{ TEXT("如何让你遇见我,在我最美丽的时刻"),16 },

{ TEXT("为这,我已在佛前求了五百年,求他让我们结一段尘缘"),24 },

{ TEXT("佛于是把我化作一棵树,长在你必经的路旁"),19 },

{ TEXT("阳光下慎重地开满了花,朵朵都是我前世的盼望"),21 },

{ TEXT("当你走近,请你细听,那颤抖的叶是我等待的热情"),21 },

{ TEXT("而当你终于无视地走过,在你身后落了一地的"), 20 },

{ TEXT("朋友啊,那不是花瓣,是我凋零的心"),16 }

};

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)

{

TCHAR szClassName[] = TEXT("数字雨");

HWND hwnd;

MSG msg;

WNDCLASS wndclass;

wndclass.style = CS_HREDRAW | CS_VREDRAW;

wndclass.lpfnWndProc = WndProc;

wndclass.cbClsExtra = 0;

wndclass.cbWndExtra = 0;

wndclass.hInstance = hInstance;

wndclass.hIcon = NULL;

wndclass.hCursor = NULL;

wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);

wndclass.lpszMenuName = NULL;

wndclass.lpszClassName = szClassName;

if (!RegisterClass(&wndclass))

{

return 0;

}

hwnd = CreateWindow(szClassName, NULL, WS_DLGFRAME | WS_THICKFRAME | WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, NULL, hInstance, NULL);

Show Window(hwnd, SW_SHOWMAXIMIZED);

Update Window(hwnd);

Show Cursor(FALSE);

srand(time(0));

//消息机制

while (GetMessage(&msg, NULL, 0, 0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

Show Cursor(TRUE);

return msg.wParam;

}

void CreateQueue(CharQueue * cc, int cyScreen, int x)

{

//bug -- 调用API---写接口---ctrl+c/ctrl+v

CharList * front;

int NumTemp = rand() % 6;

cc->x = x;

cc->y = rand() % 10 ? rand() % cyScreen : 0; //大约9/10的概率从中间开始下落。

cc->iShownLen = 1; //一开始就显示一个字符,然后慢慢增加,增加到等于歌词字符数时保持不变

cc->iStrNum = charArr[NumTemp].iNum; //歌词字符数

cc->head = cc->cur = front = (CharList *)calloc(cc->iStrNum, sizeof(CharList)); //创建显示列

//生成每个节点

int i;

for (i = 0; iiStrNum - 1; i++)

{

cc->cur->prev = front;

cc->cur->ch = charArr[NumTemp].myChar[i];

front = cc->cur++;

front->next = cc->cur;

}

//最后一个是标点符号

cc->cur->prev = front;

cc->cur->ch = charArr[NumTemp].myChar[i];

cc->cur->next = cc->head;

cc->head->prev = cc->cur;

cc->cur = cc->head;

}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)

{

HDC hdc;

static HDC hdcMem;

static HBITMAP hBitmap;

static CharQueue * AllChar;

HFONT hFont;

static int cxScreen, cyScreen;

static int iFontWidth = 20, iFontHeight = 20;

int i, j, y, greenToblack;

CharQueue * ccElem;

CharList * temp;

switch (message)

{

case WM_CREATE:

cxScreen = GetSystemMetrics(SM_CXSCREEN);

cyScreen = GetSystemMetrics(SM_CYSCREEN);

SetTimer(hwnd, 1, 70, NULL);

hdc = GetDC(hwnd);

hdcMem = CreateCompatibleDC(hdc);

hBitmap = CreateCompatibleBitmap(hdc, cxScreen, cyScreen);

SelectObject(hdcMem, hBitmap);

ReleaseDC(hwnd, hdc);

hFont = CreateFont(iFontHeight, iFontWidth, 0/*角度设置*/, 0/*角度设置*/, FW_BOLD/*黑体*/, 0, 0, 0,/*斜体 下划线 啊、删除线*/

DEFAULT_CHARSET/*字符集*/, OUT_DEFAULT_PRECIS/*指定输出精度*/, CLIP_DEFAULT_PRECIS/*指定裁剪精度*/,

DRAFT_QUALITY/*指向输出质量*/, FIXED_PITCH | FF_SWISS/*指定字体间距| 字体族*/, TEXT("宋体"));

SelectObject(hdcMem, hFont);

DeleteObject(hFont);

SetBkMode(hdcMem, TRANSPARENT);

PlaySound(L"素材.wav", NULL, SND_FILENAME | SND_ASYNC | SND_LOOP);//异步循环播放

AllChar = (CharQueue *)calloc(NumOfColumn, sizeof(CharQueue));//自动初始化为o

for (i = 0; i

{

CreateQueue(AllChar + i, cyScreen, 50 * i + 20);

}

return 0;

case WM_TIMER:

//该函数使用当前选入指定设备环境中的刷子绘制给定的矩形区域。通过使用给出的光栅操作来对该刷子的颜色和表面颜色进行组合。

PatBlt(hdcMem, 0, 0, cxScreen, cyScreen, BLACKNESS);

for (i = 0; i

{

ccElem = AllChar + i;

temp = ccElem->head;

SetTextColor(hdcMem, RGB(255, 255, 255));

TextOut(hdcMem, ccElem->x, ccElem->y, &temp->ch, 1/*字符个数*/);

y = ccElem->y;

greenToblack = 0;

ccElem->head = ccElem->head->next;

temp = temp->prev;

for (j = 1; jiShownLen; j++)

{

SetTextColor(hdcMem, RGB(/*greenToblack*5%255*/0, 255 - 255 * (greenToblack++) / (ccElem->iStrNum), 0));

TextOut(hdcMem, ccElem->x, y -= iFontHeight, &temp->ch, 1);

temp = temp->prev;

}

if (ccElem->iShownLeniStrNum)

{

ccElem->iShownLen++;

}

ccElem->y += iFontHeight;

if (ccElem->y - ccElem->iStrNum*iFontHeight>cyScreen)

{

free(ccElem->cur);

CreateQueue(ccElem, cyScreen, 128 * i + 17);

}

}

hdc = GetDC(hwnd);

BitBlt(hdc, 0, 0, cxScreen, cyScreen, hdcMem, 0, 0, SRCCOPY);

ReleaseDC(hwnd, hdc);

return 0;

case WM_RBUTTONDOWN:

KillTimer(hwnd, 1);

return 0;

case WM_RBUTTONUP:

SetTimer(hwnd, 1, 70, NULL);

return 0;

//case WM_LBUTTONDOWN:

case WM_KEYDOWN:

case WM_DESTROY:

KillTimer(hwnd, 1);

for (i = 0; i

{

ccElem = AllChar + i;

free(ccElem->cur);

}

free(AllChar);

DeleteObject(hBitmap);

DeleteDC(hdcMem);

PostQuitMessage(0);

break;

}

return DefWindowProc(hwnd, message, wParam, lParam);

}

看完了今天的效果图和代码,细心的同学是不是发现了什么?

学C/C++不易,此路应携手前行。

欢迎关注我的编程公众號【草莓味狸猫】!

 

如果你想跟着小编一起学编程的话!

可以来我的C语言C++编程学习基地,【点击进入】

还有(源码,零基础教程,项目实战教学视频)!

 

【C语言/C++程序员编程】一小时做出来的数字雨(一颗开花的树)!的更多相关文章

  1. 第一章-第七题( 有人认为,“中文编程”, 是解决中国程序员编程效率一个秘密武器,请问它是一个 “银弹” 么? )--By 侯伟婷

    首先,“银弹”在百度百科中的解释是银色的子弹,我们更熟知的“银弹”一词,应该是在<人月神话>中提到的.银弹原本应该是指某种策略.技术或者技巧可以极大地提高程序员的生产力[1].此题目中关于 ...

  2. 程序员编程艺术:第三章续、Top K算法问题的实现

    程序员编程艺术:第三章续.Top K算法问题的实现 作者:July,zhouzhenren,yansha.     致谢:微软100题实现组,狂想曲创作组.     时间:2011年05月08日    ...

  3. 程序员编程利器:20款最好的免费的IDEs和编辑器

    程序员编程利器:20款最好的免费的IDEs和编辑器 还没转眼明年可就大年三十了,忙的可真是晕头转了个向,看着亲朋好友们那让人欣羡的小肚腩,不禁感慨,岁月是一把猪饲料,绿了芭蕉,肥了那杨柳小蛮腰,可怜我 ...

  4. 程序员编程艺术第三十六~三十七章、搜索智能提示suggestion,附近点搜索

    第三十六~三十七章.搜索智能提示suggestion,附近地点搜索 作者:July.致谢:caopengcs.胡果果.时间:二零一三年九月七日. 题记 写博的近三年,整理了太多太多的笔试面试题,如微软 ...

  5. 如何优化C语言代码(程序员必读)

    1.选择合适的算法和数据结构 应该熟悉算法语言,知道各种算法的优缺点,具体资料请参见相应的参考资料,有很多计算机书籍上都有介绍.将比较慢的顺序查找法用较快的二分查找或乱序查找法代替,插入排序或冒泡排序 ...

  6. 程序员编程艺术:面试和算法心得-(转 July)

    1.1 旋转字符串 题目描述 给定一个字符串,要求把字符串前面的若干个字符移动到字符串的尾部,如把字符串“abcdef”前面的2个字符'a'和'b'移动到字符串的尾部,使得原字符串变成字符串“cdef ...

  7. dart --- 更符合程序员编程习惯的javascript替代者

    dart是google在2011年推出的一门语言,提供较为丰富的lib,并支持将代码转变为javascript,其demo code 和 demo app 也是以web前端代码来展示的. 其语言特性较 ...

  8. 程序员编程时常用的mac快捷方式

    fn + F2/F3 = 调节音量 commend + shift +k = 显示或隐藏键盘 commend+shift +h = iPhone返回主页面 commend+ shift + hh = ...

  9. 【免费电子书】这可能是全网最齐的程序员编程电子书PDF合集了!

    [toc] 最近博主

随机推荐

  1. js拖拽原理及简单实现(渣渣自学)

    第一步 首先简单分析下需求吧,我们就是想实现鼠标拖拽带颜色的方块时,让方块停留在鼠标松开的位置,需要计算的就是拖拽前的坐标和拖拽后的坐标,鼠标移动后相对于原位置的偏移量=目标元素的偏移量,根据这个等式 ...

  2. MvvmLight框架使用入门(5)

    上一次写MvvmLight框架使用入门(4)的时候还在用Visual Studio 2015,我儿子也不会过来盖上我的XPS……重启这个系列一方面是因为最近又开始写UWP的东西了,另一个是因为Mvvm ...

  3. DoS拒绝服务-工具使用hping3、nping等(四)

    Hping3几乎可以定制发送任何tcp/ip数据包,用于测试fw,端口扫描,性能测试 Syn Flood – hping3 -c 1000 -d 120 -S -w 64 -p 80 --flood ...

  4. 乔悟空-CTF-i春秋-Web-SQL

    2020.09.05 是不是有些题已经不能做了--费了半天,到最后发现做不出来,和网上大神的方法一样也不行,最搞笑的有个站好像是别人运营中的,bug好像被修复了-- 做题 题目 题目地址 做题 尝试简 ...

  5. [LeetCode]Mysql系列5

    题目1 1112. 每位学生的最高成绩 编写一个 SQL 查询,查询每位学生获得的最高成绩和它所对应的科目,若科目成绩并列,取 course_id 最小的一门.查询结果需按 student_id 增序 ...

  6. 使用swagger遇到的问题

    1.定义全局的请求参数时, defaultValue不能是中文,不然一直是请求中 ParameterBuilder userName = new ParameterBuilder(); Paramet ...

  7. google protocol buffer——protobuf的问题和改进2

    这一系列文章主要是对protocol buffer这种编码格式的使用方式.特点.使用技巧进行说明,并在原生protobuf的基础上进行扩展和优化,使得它能更好地为我们服务. 在上一篇文章中,我们举例了 ...

  8. python第一节课内容及练习

    一.input输入 sname = input("请输入你的姓名:")yu_yan = input("请输入你学习的语言:")print("{}, 欢 ...

  9. Mybatis快速逆向生成代码

    先下载生成器的文件, 并在eclipse或者IDEA里面打开这个工程 热乎乎的链接 然后配置一下 选择你需要生成的数据的ip和端口 点击运行入口函数 运行成功 接着在浏览器输入localhost: 这 ...

  10. API测试-接口测试基础(1)

    由于自己想学习API方面的测试,但是市面上搜不到相关的图书可以系统学习,网上的内容又零零散散,适合有点API开发基础的人去搜索.为了方面新手学习API测试,现在整理了他人的宝贵经验和自己的学习心得,尽 ...