21xrx.com
2024-12-22 22:04:40 Sunday
登录
文章检索 我的文章 写文章
"C++代码雨的简单实现"
2023-07-05 04:35:10 深夜i     --     --
C++ 代码雨 实现 简单 动画效果

代码雨是指在屏幕上以字符为粒度,不断滑落、旋转、流动的编程艺术,常见于电影和游戏中的场景。它所代表的,可能是信息时代下信息的雨露,亦或是将计算机世界引入了真实世界中,让程序员们更了解自己创造的世界。而本文将介绍C++实现代码雨的简单方法。

首先,我们需要定义两个类,一个是字符粒子类CharParticle,另一个是限制视窗的类WindowLimit。CharParticle类需要定义字符粒子在屏幕上运动的基础属性,如初始位置、速度、旋转角度等。而WindowLimit类则是为了限制字符粒子的运动范围。如下所示:


class CharParticle

{

 private:

  int x, y; //字符粒子的坐标

  char ch; //字符粒子的符号

  int speed; //字符粒子的移动速度

  double angle; //字符粒子的旋转角度

  int width, height; //字符粒子所在窗口的宽高

 public:

  CharParticle(int x, int y, char ch, int speed, double angle, int width, int height);

  void update(); //更新字符粒子的位置

  void draw(HDC hdc); //在屏幕上绘制字符粒子

};

class WindowLimit

{

  int width, height;

 public:

  WindowLimit(int width, int height) : width(width), height(height) {}

  int getWidth() const return width;

  int getHeight() const return height;

};

接下来,我们需要实现CharParticle类和WindowLimit类中的函数的具体内容。

在CharParticle类中,update函数是关键。基于时间流逝、字符粒子的速度和旋转角度,我们可以计算出其在屏幕上的新坐标。观察项目变化情况,我们可以选择将字符粒子运动路线分为两类:以直线为基础的基本运动和以圆线为基础的高级运动。对于前者,我们可以如下实现update函数:


void CharParticle::update()

{

  x += speed * cos(angle);

  y += speed * sin(angle);

  if(x < 0 || x > width || y < 0 || y > height)

  {

    x = rand() % width;

    y = rand() % height;

  }

}

而对于后者,则需要考虑更多的参数。在本文中,我们以半径、圆心位置和方向为例,实现update函数:


void CharParticle::update()

{

  x = cos(angle) * radius + centerX;

  y += speed;

  if (rand() / (double)RAND_MAX < 0.1)

  {

    angle += rand() % 20 - 10;

  }

  if (x < 0 || x > width || y < 0 || y > height)

  {

    x = rand() % width;

    y = 0;

    radius = 5 * (rand() % 10 + 1);

    speed = rand() % 5 + 1;

    angle = rand() % 360;

  }

}

draw函数的内容比较简单,直接在屏幕上绘制出对应的字符即可:


void CharParticle::draw(HDC hdc)

{

  TextOut(hdc, x, y, &ch, 1);

}

对于WindowLimit类,我们需要定义其宽高,并提供对应的getter函数:


WindowLimit::WindowLimit(int width, int height) : width(width), height(height) {}

int WindowLimit::getWidth() const return width;

int WindowLimit::getHeight() const return height;

而最终,在主函数中,我们可以如下实现代码雨的效果:


void RainCode(HWND hwnd, HDC hdc)

{

  WindowLimit windowLimit(GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN));

  vector<CharParticle *> unicodeParticles;

  for(int i = 0; i < 100; i++)

  {

    CharParticle *p = new CharParticle(rand() % windowLimit.getWidth(), rand() % windowLimit.getHeight(), '0' + rand() % 10, rand() % 4 + 1, (rand() % 180) * PI / 180, windowLimit.getWidth(), windowLimit.getHeight());

    unicodeParticles.push_back(p);

  }

  while(true)

  {

    Sleep(200);

    for(auto iter = unicodeParticles.begin(); iter != unicodeParticles.end(); iter++)

    {

      (*iter)->update();

      (*iter)->draw(hdc);

    }

  }

}

在本文中,我们尝试了两种不同的字符粒子的运动方式。在实际项目中,则可以根据实际需求,自由发挥,创造出属于自己的代码雨世界。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复