基於EasyX和Raylib的字符雨

思路

按如下順序嘗試:

  • 繪製一個字符下落
  • 繪製4個字符(一列)的下落
  • 繪製20個字符(一列)的下落,並封裝其位置更新、繪製的過程爲 Rain 類的成員函數
  • 繪製多個雨滴
  • 每個雨滴在更新位置時, 也修改字符
  • 每個雨滴初始化時,位置、速度都隨即化

基於 EasyX

// 字符雨 (基於 easyx)
// 來源: https://zhuanlan.zhihu.com/p/434484127

#include<stdio.h>
#include<graphics.h> //圖形庫頭文件
#include<Windows.h>
#include <time.h>

#define WIDTH 1615//960
#define HEIGHT 1006//640
#define STR_SIZE 20 //數字雨數組最大存儲
#define STR_NUM 128 //數字雨的串數
#define STR_WIDTH 15 //字符串

struct Rain //雨的結構
{
	int x; //數字雨橫向位置
	int y; //y座標
	int speed; //下降速度
	char str[STR_SIZE]; //數字雨數組
} rain[STR_NUM];

char CreateCh()
{
	char temp = 0;
	int flag = rand() % 3;//0 1 2
	if (flag == 0)
	{
		temp = rand() % 26 + 'a';
	}
	else if (flag == 1)
	{
		temp = rand() % 26 + 'A';
	}
	else
	{
		temp = rand() % 10 + '0';
	}

	return temp;
}

void GameInit()
{
	//初始化基礎數據
	for (int i = 0; i < STR_NUM; i++)
	{
		rain[i].x = i*STR_WIDTH;
		rain[i].y = rand() % HEIGHT;
		rain[i].speed = rand() % 5 + 5;//5 6 7 8 9 10
	}
	//初始化字符串
	for (int i = 0; i < STR_NUM; i++)
	{
		for (int j = 0; j < STR_SIZE; j++)
		{
			rain[i].str[j] = CreateCh();
		}
	}
}

void GameDraw()
{
	cleardevice();
	for (int i = 0; i < STR_NUM; i++)
	{
		for (int j = 0; j < STR_SIZE; j++)
		{
			outtextxy(rain[i].x, rain[i].y-STR_WIDTH*j, rain[i].str[j]);
			settextcolor(RGB(0,255-13*j,0));
		}
	}
}

void GamePlay()
{
	for (int i = 0; i < STR_NUM; i++)
	{
		rain[i].y += rain[i].speed;
		if (rain[i].y-STR_SIZE*STR_WIDTH>HEIGHT)
		{
			rain[i].y = 0;
		}
	}
}

void ChangeCh()
{
	for (int i = 0; i < STR_NUM; i++)
	{
		rain[rand()%STR_NUM].str[rand()%STR_SIZE] = CreateCh();
	}
}

int main()
{
	initgraph(WIDTH,HEIGHT);
	srand((unsigned)time(NULL));
	GameInit();
	DWORD t1, t2;
	t1 = t2 = GetTickCount();
	while (1)
	{
		BeginBatchDraw();
		GameDraw();
		ChangeCh();
		if (t2 - t1 > 20)//使遊戲下落延時
		{
			GamePlay();
			t1 = t2;
		}
		t2 = GetTickCount();
		EndBatchDraw();
		//Sleep(20); //使整個程序延時
	}

	getchar();
	closegraph();
	return 0;
}

基於 Raylib

// 每個雨滴的速度都爲隨機數,每次落雨都修改雨滴的組成字符
#include "raylib.h"
#include "raylib_helper.hpp"
#include <stdlib.h>
#include <vector>

using std::vector;

#define WIDTH 1615
#define HEIGHT 1006
#define RAIN_HEIGHT 20
#define STR_WIDTH 15

class Rain
{
public:
	char str[RAIN_HEIGHT];
	int x;
	int y;
	int speed;

	void update()
	{
		y += speed;
		if (y - 20 * STR_WIDTH > HEIGHT)
		{
			y = 0;
		}
		change_chars();
	}

	void draw()
	{
		int font_size = 13;
		for (int j = 0; j < RAIN_HEIGHT; j++)
		{
			char s[2] = { 0 };
			s[0] = str[j];
			Color color = make_color(0, j * 13, 0, 255);
			DrawText(s, x, y + j * font_size, font_size, color);
		}
	}
	void change_chars()
	{
		for (int j = 0; j < RAIN_HEIGHT; j++)
		{
			str[j] = ( rand() / (double)RAND_MAX ) * 26 + 'A';
		}
	}
};

vector<Rain> rain(128);

void update()
{
	static int cnt = 0;
	cnt++;
	if (cnt == 2)
	{
		cnt = 0;

		for (int i = 0; i < rain.size(); i++)
		{
			rain[i].update();
		}
	}
}

void startup()
{
	InitWindow(WIDTH, HEIGHT, "The Matrix");
	SetTargetFPS(60);

	for (int i = 0; i < rain.size(); i++)
	{
		rain[i].x = i * STR_WIDTH;
		rain[i].y = rand() % HEIGHT;
		rain[i].speed = rand() % 5 + 5;
		rain[i].change_chars();
	}
}

void show()
{
	BeginDrawing();
	{
		ClearBackground(BLACK);
		for (int i = 0; i < rain.size(); i++)
		{
			rain[i].draw();
		}
	}
	EndDrawing();
}

int main()
{
	startup();
	while (!WindowShouldClose())
	{
		update();
		show();
	}
	CloseWindow();

	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章