import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.MemoryImageSource;
import java.util.Random;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Rain extends JDialog implements ActionListener {
private Random random=new Random();
private Dimension screenSize;
private JPanel graphicsPanel;
//行高,列宽
private final static int gap=20;
//存放雨点顶部的位置信息(marginTop)
private int[] posArr;
//行数
private int lines;
//列数
private int columns;
public Rain() {
initComponents();
}
private void initComponents() {
setLayout(new BorderLayout());
graphicsPanel=new GraphicsPanel();
add(graphicsPanel, BorderLayout.CENTER);
//设置光标不可见
Toolkit defaultToolkit=Toolkit.getDefaultToolkit();
Image image=defaultToolkit.createImage(new MemoryImageSource(0, 0, null, 0, 0));
Cursor invisibleCursor=defaultToolkit.createCustomCursor(image, new Point(0, 0), "cursor");
setCursor(invisibleCursor);
//ESC键退出
KeyPressListener keyPressListener=new KeyPressListener();
this.addKeyListener(keyPressListener);
//this.setAlwaysOnTop(true);
//去标题栏
this.setUndecorated(true);
//全屏
this.getGraphicsConfiguration().getDevice().setFullScreenWindow(this);
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
setVisible(true);
screenSize=Toolkit.getDefaultToolkit().getScreenSize();
lines=screenSize.height / gap;
columns=screenSize.width / gap;
posArr=new int[columns + 1];
random=new Random();
for (int i=0; i
posArr[i]=random.nextInt(lines);
}
//每秒10帧
new Timer(100, this).start();
}
private char getChr() {
return (char) (random.nextInt(94) + 33);
}
@Override
public void actionPerformed(ActionEvent e) {
graphicsPanel.repaint();
}
private class GraphicsPanel extends JPanel {
@Override
public void paint(Graphics g) {
Graphics2D g2d=(Graphics2D) g;
g2d.setFont(getFont().deriveFont(Font.BOLD));
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, screenSize.width, screenSize.height);
//当前列
int currentColumn=0;
for (int x=0; x
int endPos=posArr[currentColumn];
g2d.setColor(Color.CYAN);
g2d.drawString(String.valueOf(getChr()), x, endPos * gap);
int cg=0;
for (int j=endPos - 15; j
//颜色渐变
cg +=20;
if (cg > 255) {
cg=255;
}
g2d.setColor(new Color(0, cg, 0));
g2d.drawString(String.valueOf(getChr()), x, j * gap);
}
//每放完一帧,当前列上雨点的位置随机下移1~5行
posArr[currentColumn] +=random.nextInt(5);
//当雨点位置超过屏幕高度时,重新产生一个随机位置
if (posArr[currentColumn] * gap > getHeight()) {
posArr[currentColumn]=random.nextInt(lines);
}
currentColumn++;
}
}
}
private class KeyPressListener extends KeyAdapter {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode()==KeyEvent.VK_ESCAPE) {
System.exit(0);
}
}
}
public static void main(String[] args) {
new Rain();
}
}
编辑
相信大家看过许许多多的关于计算机黑客、骇客、人工智能、AI方面的电影,每当黑客入侵某个五角大楼,某个网站时,都会出现这样一幅画面:
编辑
编辑
O(∩_∩)O和这并没有太大的关系,今天我们要讲的是《数字雨》!
好了,我们来看下什么是数字雨:
编辑
数字雨,顾名思义,就是类似于填上下雨一样,往下掉数字或者是文字。如下动态图:
编辑
这样看起来是不是感觉我们像是进入了一个科幻的虚拟世界呢?当然了程序运行后会有有个小小的惊喜哦?
#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( *** _CXSCREEN), GetSystemMetrics( *** _CYSCREEN), NULL, NULL, hInstance, NULL);
ShowWindow(hwnd, SW_SHOWMAXIMIZED);
UpdateWindow(hwnd);
ShowCursor(FALSE);
srand(time(0));
//消息机制
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
ShowCursor(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( *** _CXSCREEN);
cyScreen=GetSystemMetrics( *** _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(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语言写出来的数字雨代码. 好酷啊.
用VC编辑出来...
大家试下哦. 好漂亮的.
#include
#define
ID_TIMER
1
#define STRMAXLEN 25 //一个显示列的更大长度
#define STRMINLEN 8
//一个显示列的最小长度
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM) ;
//////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////
typedef struct tagCharChain //整个当作屏幕的一个显示列,这是个双向列表
{
struct tagCharChain *prev; //链表的前个元素
TCHAR
ch;
//一个显示列中的一个字符
struct tagCharChain *next; //链表的后个元素
}CharChain, *pCharChain;
typedef struct tagCharColumn
{
CharChain *head, *current, *point;
int x, y, iStrLen; //显示列的开始显示的x,y坐标,iStrLen是这个列的长度
int iStopTimes, iMustStopTimes; //已经停滞的次数和必须停滞的次数,必须停滞的次数是随机的
}CharColumn, *pCharColumn;
int main(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
static TCHAR szAppName[]=TEXT ("matrix") ;
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 =LoadIcon (NULL, IDI_APPLICATION) ;
wndclass.hCursor =LoadCursor (NULL, IDC_ARROW) ;
wndclass.hbrBackground =(HBRUSH) GetStockObject (BLACK_BRUSH) ;
wndclass.lpszMenuName =NULL ;
wndclass.lpszClassName =szAppName ;
if(!RegisterClass (&wndclass))
{
MessageBox (NULL, TEXT ("此程序必须运行在NT下!"), szAppName, MB_ICONERROR)
;
return 0;
}
hwnd=CreateWindow (szAppName, NULL,
WS_DLGFRAME | WS_THICKFRAME | WS_POPUP,
0, 0,
GetSystemMetrics( *** _CXSCREEN), GetSystemMetrics( *** _CYSCREEN),
NULL, NULL, hInstance,
NULL) ;
ShowWindow (hwnd, SW_SHOWMAXIMIZED) ; //更大化显示
UpdateWindow (hwnd) ;
ShowCursor(FALSE); //隐藏鼠标光标
srand ((int) GetCurrentTime ()) ; //初始化随机数发生器
while (GetMessage (&msg, NULL, 0, 0))
{
TranslateMessage (&msg) ;
DispatchMessage (&msg) ;
}
ShowCursor(TRUE); //显示鼠标光标
return msg.wParam ;
}
TCHAR randomChar() //随机字符产生函数
{
return (TCHAR)(rand()%(126-33)+33); //33到126之间
}
int init(CharColumn *cc, int cyScreen, int x) //初始化
{
int j;
cc->iStrLen=rand()%(STRMAXLEN-STRMINLEN) +
STRMINLEN; //显示列的长度
cc->x=x+3
;
//显示列的开始显示的x坐标
cc->y=rand()%3rand()%cyScreen:0;
//显示列的开始显示的y坐标
cc->iMustStopTimes=rand()%6 ;
cc->iStopTimes =0 ;
cc->head=cc->current=
(pCharChain)calloc(cc->iStrLen, sizeof(CharChain));
//生成显示列
for(j=0; jiStrLen-1; j++)
{
cc->current->prev=cc->point;
//cc->point一个显示列的前个元素
cc->current->ch ='\0';
cc->current->next=cc->current+1;
//cc->current+1一个显示列的后个元素
cc->point =cc->current++; //cc->point=cc->current; cc->current++;
}
cc->current->prev=cc->point; //最后一个节点
cc->current->ch ='\0';
cc->current->next=cc->head;
cc->head->prev =cc->current; //头节点的前一个为此链的最后一个元素
cc->current=cc->point=cc->head; //free掉申请的内存要用current当参数
cc->head->ch=randomChar(); //
对链表头的元素填充
return 0;
}
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM
wParam, LPARAM lParam)
{
HDC
hdc ;
//ctn 用来确定一个显示链是否 向下前进,如果等待次数超过必须等待的次数,ctn就代表要向下前进
int i, j, temp, ctn; //j为一个显示链中除链表头外的在屏幕上显示的y坐标,temp绿色过度到黑色之用
static HDC hdcMem;
HFONT
hFont;
static HBITMAP hBitmap;
static int cxScreen, cyScreen; //屏幕的宽度 高度.
static int iFontWidth=10, iFontHeight=15,
iColumnCount; //字体的宽度 高度, 列数
static CharColumn *ccChain;
switch (message)
{
case WM_CREATE:
cxScreen=GetSystemMetrics( *** _CXSCREEN) ; //屏幕宽度
cyScreen=GetSystemMetrics( *** _CYSCREEN) ;
SetTimer (hwnd, ID_TIMER, 10, NULL) ;
hdc=GetDC(hwnd);
hdcMem=CreateCompatibleDC(hdc);
hBitmap=CreateCompatibleBitmap(hdc, cxScreen, cyScreen);
SelectObject(hdcMem, hBitmap);
ReleaseDC(hwnd, hdc);
//创建字体
hFont=CreateFont(iFontHeight, iFontWidth-5, 0, 0, FW_BOLD, 0, 0,
0,
DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS,
DRAFT_QUALITY, FIXED_PITCH | FF_SWISS, TEXT("Fixedsys"));
SelectObject(hdcMem, hFont);
DeleteObject (hFont) ;
SetBkMode(hdcMem, TRANSPARENT); //设置背景模式为 透明
iColumnCount=cxScreen/(iFontWidth*3/2); //屏幕所显示字母雨的列数
ccChain=(pCharColumn)calloc(iColumnCount,
sizeof(CharColumn));
for(i=0; i
(ccChain+i)->iMustStopTimes;
//
(ccChain+i)->point=(ccChain+i)->head; //point用于遍历整个显示列
//之一个字符显示为 白色
SetTextColor(hdcMem, RGB(255, 255, 255));
TextOut(hdcMem, (ccChain+i)->x,
(ccChain+i)->y,
&((ccChain+i)->point->ch),
1);
j=(ccChain+i)->y;
(ccChain+i)->point=(ccChain+i)->point->next;
//遍历整个显示列,将这个显示列里的字符从下往上显示
temp=0 ; //temp绿色过度到黑色之用
while((ccChain+i)->point !=(ccChain+i)->head &&
(ccChain+i)->point->ch)
{
SetTextColor(hdcMem, RGB(0,
255-(255*(temp++)/(ccChain+i)->iStrLen), 0));
TextOut(hdcMem, (ccChain+i)->x, j-=iFontHeight,
&((ccChain+i)->point->ch),
1);
(ccChain+i)->point=(ccChain+i)->point->next;
}
if(ctn)
(ccChain+i)->iStopTimes=0 ;
else continue;
(ccChain+i)->y +=iFontHeight; //下次开始显示的y坐标为当前的y坐标加上
一个字符的高度
//如果开始显示的y坐标减去 整个显示列的长度超过了屏幕的高度
if(
(ccChain+i)->y-(ccChain+i)->iStrLen*iFontHeight
> cyScreen)
{
free( (ccChain+i)->current );
init(ccChain+i, cyScreen, (iFontWidth*3/2)*i);
}
//链表的头 为此链表的前个元素,因为下次开始显示的时候 就相当与在整个显示列的开头添加个元素,然后在开始往上显示
(ccChain+i)->head=(ccChain+i)->head->prev;
(ccChain+i)->head->ch=randomChar();
}
BitBlt(hdc, 0, 0, cxScreen, cyScreen, hdcMem, 0, 0, SRCCOPY);
ReleaseDC(hwnd, hdc);
return 0;
case WM_RBUTTONDOWN:
KillTimer (hwnd, ID_TIMER) ;
return 0;
case WM_RBUTTONUP:
SetTimer (hwnd, ID_TIMER, 10, NULL) ;
return 0;
//处理善后工作
case WM_KEYDOWN:
case WM_LBUTTONDOWN:
case WM_DESTROY:
KillTimer (hwnd, ID_TIMER) ;
DeleteObject(hBitmap);
DeleteDC(hdcMem);
for(i=0; icurrent );
}
free(ccChain);
PostQuitMessage (0) ;
return 0 ;
}
return DefWindowProc (hwnd, message, wParam, lParam) ;
}
跟着经济程度的成长,美食产物也是纷纷映入各人的眼帘。面包产物是公共消费者迩来很是喜爱的美食产物,各人对付面包产物的喜爱是显而易见的,好的面包产物已进入市场就会受到公共消费者的哄抢。因此大消费市场上对付...
写鸟的诗句(有关鸟的古诗100首) 留连戏蝶时刻舞,自在娇莺恰恰啼《江畔独步》 双飞燕子何时回,夹岸桃花运沾水开《春游湖》 独怜幽草涧边生,上面有黄鹂深树鸣《滁州西涧》 花盛开红树乱莺啼,草长...
本文导读目录: 1、vivos6的隐藏功能介绍 2、vivo有哪些隐藏的功能? 3、vivo手机有哪些隐藏功能? 4、vivox21有哪些隐藏功能 5、vivo手机隐藏功能有什么?...
图为此次发现的西藏新记录种。中国科学院昆明植物研究所提供 中新网昆明1月12日电 (记者 胡远航)中国科学院昆明植物研究所12日发布消息称,该所科研人员在西藏发现须弥四带芹、巴洛特栎等4个中国新...
如今的中国,提起网购,你会同时想到三个名字:淘宝、京东、拼多多。 作为电商界的后起之秀,拼多多在创始人黄峥的带领下势如破竹,仅用两年就收获了3亿用户,还敲响了纳斯达克上市的钟声。 拼多多为什么发展...
专四早已考完,专八成绩也出,那专四成绩呢?同学们被“为什么网上查不到?专四不过怎么办?会不会影响报考专八……”等等这些问题困扰着。 今天小编就在这里给大家解答这些问题。 1....