前言
该动态图来自另一位程序员之手,他使用的另外编程语言完成,我看不懂,而且代码巨长。
我使用自己熟悉的C语言,用了一个多小时才完成了这个动态的彩虹屁猪猪。
思路
主要的思路有两个,动态的效果,是使用sin函数,实现上下摆动的效果,小猪的图案,采用了二维数组,不同的颜色用不同的数字表示,最后将整个小猪绘制出来。代码有些粗糙,后面可以进一步优化简化,能使用更短的代码完成整个动画。
所有的动态图,其实思路都一样,先初始化,然后更新坐标,绘制图案,循环这个过程即可。
源码
///////////////////////////////////////////////////
// 程序名称:绘制彩虹屁猪猪
// 编译环境:Mictosoft Visual Studio 2022, EasyX_20200315(beta)
// 作 者:luoyh <2864292458@qq.com>
// 最后修改:2024-9-3
// 公 众 号:C语言研究
//
// 一个色块5个像素
struct CH
{
int X;
int Y;
};
int x = 0;
CH chw[3];
CH cht[3];
CH pig;
void initCH(); // 初始化彩虹
void upCH(); // 更新彩虹
void DrawCHW(); // 彩虹尾巴
void DrawCHT(); // 彩虹头
void DrawPIG(); // 绘制小猪
void DrawBK();
void DrawTXT();
// 无填充的为 0
// 填充边界的为1
// 填充皮肤的为2
// 填充眼睛的为3
// 填充鼻子的为5
// 阴影为6
// 鼻孔为7
// 鼻子中间4
static int PIG[11][13] =
{
{0,0,0,0,0,1,0,0,0,0,1,0,0}, // 修改了逗号,并去掉了多余的元素
{0,0,1,1,1,1,1,1,1,1,1,0,0}, // 这将自动扩展为 {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
{0,1,6,6,6,1,2,2,2,6,1,0,0},
{1,6,6,6,2,2,2,2,2,2,2,1,0},
{1,6,6,2,2,2,2,3,2,2,3,1,0},
{1,2,2,2,2,2,2,2,5,5,5,5,5},
{1,2,2,2,2,2,2,2,5,7,4,7,5},
{1,2,2,6,6,2,2,2,5,5,5,5,5},
{1,2,6,6,6,6,2,2,2,2,2,1,0},
{0,1,1,1,1,1,1,1,1,1,1,0,0},
{0,0,1,0,1,0,0,0,1,0,1,0,0}// 最后一行也可以省略,因为所有剩余元素都会自动初始化为0
};
int main()
{
initgraph(600, 300);
BeginBatchDraw();
while (true)
{
DrawBK();
initCH();
DrawCHW();
DrawCHT();
DrawPIG();
DrawTXT();
upCH();
FlushBatchDraw();
Sleep(50);
cleardevice();
}
EndBatchDraw();
_getch();
return 0;
}
void DrawBK()
{
setbkcolor(RGB(16, 14, 38));
cleardevice();
setfillcolor(RGB(16, 19, 35));
solidcircle(300, 100, 160);
setfillcolor(RGB(21, 18, 49));
solidcircle(300, 100, 70);
}
void initCH() // 初始化彩虹
{
for (int i = 0; i < 3; i++)
{
chw[i].X = 120 + i * 20;
chw[i].Y = 130 + sin(x) * 7;
x++;
}
for (int i = 0; i < 3; i++)
{
cht[i].X = 190 + i * 40; // 假设为200
cht[i].Y = 130 + sin(x) * 7;
x++;
}
pig.X = 280;
pig.Y = 100 + sin(x) * 7;
x++;
}
void DrawCHW() // 彩虹尾巴
{
for (int a = 0; a < 3; a++)
{
for (int i = 0; i < 6; i++)
{
switch (i)
{
case 0: setfillcolor(RGB(85, 27, 42)); break;
case 1: setfillcolor(RGB(89, 58, 53)); break;
case 2: setfillcolor(RGB(85, 88, 61)); break;
case 3: setfillcolor(RGB(32, 92, 94)); break;
case 4: setfillcolor(RGB(23, 57, 105)); break;
case 5: setfillcolor(RGB(47, 23, 111)); break;
}
for (int j = 0; j < 4; j++)
{
solidrectangle(chw[a].X - 10 + j * 5, chw[a].Y - 15 + i * 5, chw[a].X - 5 + j * 5, chw[a].Y - 10 + i * 5);
}
}
}
}
void DrawCHT() // 彩虹头
{
for (int a = 0; a < 3; a++)
{
for (int i = 0; i < 6; i++)
{
switch (i)
{
case 0: setfillcolor(RGB(224, 35, 36)); break;
case 1: setfillcolor(RGB(219, 138, 47)); break;
case 2: setfillcolor(RGB(220, 233, 66)); break;
case 3: setfillcolor(RGB(1, 235, 62)); break;
case 4: setfillcolor(RGB(21, 142, 233)); break;
case 5: setfillcolor(RGB(110, 39, 237)); break;
}
for (int j = 0; j < 8; j++)
{
solidrectangle(cht[a].X - 20 + j * 5, cht[a].Y - 15 + i * 5, cht[a].X - 15 + j * 5, cht[a].Y - 10 + i * 5);
}
}
}
}
void DrawPIG()
{
for (int i = 0; i < 13; i++)
{
for (int j = 0; j < 11; j++)
{
switch (PIG[j][i])
{
// 无填充的为 0
// 填充边界的为1
// 填充皮肤的为2
// 填充眼睛的为3
// 填充鼻子的为5
// 阴影为6
// 鼻孔为7
// 鼻子中间4
case 0: break;
case 1:setfillcolor(RGB(241, 145, 131)); break;
case 2:setfillcolor(RGB(252, 217, 215)); break;
case 3:setfillcolor(RGB(13, 14, 9)); break;
case 4:setfillcolor(RGB(245, 108, 104)); break;
case 5:setfillcolor(RGB(244, 145, 148)); break;
case 6:setfillcolor(RGB(250, 196, 184)); break;
case 7:setfillcolor(RGB(231, 60, 53)); break;
}
if (PIG[j][i] != 0)
{
solidrectangle(pig.X+i * 5, pig.Y+j * 5, pig.X+5 + i * 5, pig.Y+5 + j * 5);
}
}
}
setfillcolor(RGB(241, 145, 131)); // 补充一个尾巴
solidrectangle(pig.X + -1 * 5, pig.Y + 25, pig.X , pig.Y + 30);
}
void upCH() // 让它动起来
{
x++;
}
void DrawTXT()
{
settextcolor(WHITE);
settextstyle(20,0,_T("黑体"));
RECT r = { 0, 150, 600, 300 };
drawtext(_T("LOADING..."), &r, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
}
最终效果
敲代码过程