CodeBus

分享代码,一起进步~

动态立体方块

一个绘图程序。 执行效果如下: 完整源代码如下: /*********************************************** * 程序名称:动态立体方块 * * 编译环境:Visual C++ 6.0 / EasyX冬至版 * * 作者:Kenny <499508968@qq.com> * * 最后修改:2015.05.21 * ***********************************************/ #include <graphics.h> #include <conio.h> #include <math.h> void Block(int length); // 画方块函数声明 void StrongBlock(); // 动态立体方块函数声明 // 主函数 int main() { StrongBlock(); return 0; } // 画方块函数定义 void Block(int length, COLORREF color) { setorigin(getwidth() / 2, getheight() / 2); // 设置坐标原点为窗口中心 POINT a[4][6]; // 定义二维数组存放点,4条边,每条边分5段,也就是6个点 int i, j; // 顺时针初始化点坐标,第一条边为坐标原点左上方的边 for (j = 0; j < 4; j++) { for (i = 0; i < 6; i++) // 初始化每条边上的6个点坐标 { a[j][i].x = (int)pow(-1, j / 2 + j % 2 + 1) * length * i / 5; a[j][i].y = (int)pow(-1, j / 2 + 1) * length * (5 - i) / 5; } } setlinecolor(color); // 设置线条颜色 for (i = 0, j = 5; i < 6; i++, j--) { line(a[0][i].x, a[0][i].y, a[2][j].x, a[2][j].y); // 连接第一条和第三条边上的6对点坐标 line(a[1][i].x, a[1][i].y, a[3][j].x, a[3][j].y); // 连接第二条和第四条边上的6对点坐标 } } // 动态立体方块函数定义 void StrongBlock() { initgraph(800,800); int length; float H, S, L; while (!kbhit()) { length = 10; H = 0; S = 1; L = 0.5; while (length <= getwidth() / 2) { Block(length, HSLtoRGB(H, S, L)); Sleep(150); length += 4; // 长度递增 H += (float)1.8; // 改变颜色 } length = 400; H = 360; S = 1; L = 0.5; while (length > 10) { Block(length, HSLtoRGB(H, S, L)); Sleep(150); length -= 4; // 长度递减 H -= (float)1.8; // 改变颜色 } } getch(); closegraph(); } 作者:Kenny作者 QQ:499508968

用绘图语句画安卓(android)机器人(初学 C 语言的同学必看)

学编程最需要注意的就是多动手,多练习。不管你学了多少,学一点,就要练习一点。哪怕没有学习循环和判断,都可以写出一些不错的程序来。 所以,我写了这个范例程序给大家参考。希望可以抛砖引玉,给初学 C 语言的同学以启发。 执行效果如下: VC 源代码如下: ///////////////////////////////////////////////////////////// // 程序名称:用绘图语句画安卓(android)机器人(初学 C 语言的同学必看) // 编译环境:Visual C++ 6.0 / 2013,EasyX 20140321(beta) // 作  者:yangw80 <yw80@qq.com> // 最后修改:2014-10-9 // #include <graphics.h> #include <conio.h> #define PI 3.14159265 void main() { // 创建大小为 800 * 600 的绘图窗口 initgraph(800, 600); // 设置原点 (0, 0) 为屏幕中央(Y轴默认向下为正) setorigin(400, 300); // 使用藏青色填充背景 setbkcolor(0x7c5731); cleardevice(); // 设置绘图样式 setlinecolor(WHITE); // 设置线条颜色为白色 setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 10); // 设置线条样式为宽度 10 的实线,端点是平的 setfillcolor(0x24c097); // 设置填充颜色为绿色 // 画身体 fillroundrect(-75, -111, 75, 39, 36, 36); // 画头 fillpie(-75, -166, 75, -30, 0, PI); // 脸 circle(-31, -131, 3); // 右眼 circle( 31, -131, 3); // 左眼 // 画天线 fillellipse(-52, -181, -38, -167); // 右天线 line(-50, -169, -41, -156); line(-38, -177, -28, -162); fillellipse( 52, -181, 38, -167); // 左天线 line( 50, -169, 41, -156); line( 38, -177, 28, -162); // 用绿色擦掉天线部分多余的线 setlinecolor(0x24c097); // 设置线条颜色为绿色 setlinestyle(PS_SOLID | PS_ENDCAP_ROUND, 5); // 设置线条样式为宽度 5 的实线,端点为圆形 line(-44, -174, -23, -142); // 画右天线内部的绿线 line( 44, -174, 23, -142); // 画左天线内部的绿线 setlinecolor(WHITE); // 恢复线条颜色为白色 setlinestyle(PS_SOLID | PS_ENDCAP_FLAT, 10); // 恢复线条样式为宽度 10 的实线,端点是平的 // 画胳膊 fillroundrect(-117, -99, -75, 7, 42, 42); // 右胳膊 fillroundrect( 117, -99, 75, 7, 42, 42); // 左胳膊 // 画腿 fillpie(-50, 49, -8, 91, PI, PI * 2); // 右腿 line(-50, 40, -50, 70); line(-8, 40, -8, 70); solidroundrect(-45, 0, -13, 86, 32, 32); fillpie( 50, 49, 8, 91, PI, PI * 2); // 左腿 line( 50, 40, 50, 70); line( 8, 40, 8, 70); solidroundrect( 45, 0, 13, 86, 32, 32); // 画字母 A arc(-185, 132, -144, 173, PI / 2, PI * 3 / 2); line(-165, 132, -135, 132); line(-165, 173, -154, 173); line(-140, 127, -140, 178); // 画字母 N arc(-118, 131, -78, 171, 0, PI); line(-118, 151, -118, 178); line(-78, 151, -78, 178); // 画字母 D arc(-57, 132, -16, 173, PI * 3 / 2, PI / 2); line(-60, 132, -37, 132); line(-60, 173, -37, 173); // 画字母 R arc(14, 132, 40, 158, PI * 3 / 2, PI / 2); arc(-2, 158, 38, 198, 0, PI / 2); line(1, 132, 27, 132); line(1, 158, 27, 158); // 画字母 O circle(81, 152, 21); // 画字母 I line(124, 127, 124, 178); // 画字母 D arc(144, 132, 185, 173, PI * 3 / 2, PI / 2); line(141, 132, 164, 132); line(141, 173, 164, 173); // 按任意键退出 _getch(); closegraph(); }

用绘图语句画机器猫(初学 C 语言的同学必看)

学编程最需要注意的就是多动手,多练习。不管你学了多少,学一点,就要练习一点。哪怕没有学习循环和判断,都可以写出一些不错的程序来。 所以,我写了这个范例程序给大家参考。希望可以抛砖引玉,给初学 C 语言的同学以启发。 执行效果如下: 具体这个家伙叫机器猫还是小叮当还是多啦A梦就不管啦,看代码吧: ///////////////////////////////////////////////////////////// // 程序名称:用绘图语句画机器猫(初学 C 语言的同学必看) // 编译环境:Visual C++ 6.0 / 2013,EasyX 20140321(beta) // 作  者:yangw80 <yw80@qq.com> // 最后修改:2014-9-17 // #include <graphics.h> #include <conio.h> #define PI 3.14159265 // 主函数 void main() { // 创建大小为 800 * 600 的绘图窗口 initgraph(800, 600); // 设置原点 (0, 0) 为屏幕中央(Y轴默认向下为正) setorigin(400, 300); // 使用白色填充背景 setbkcolor(WHITE); cleardevice(); // 画脸 setfillcolor(RGB(7, 190, 234)); // 头 setlinecolor(BLACK); fillroundrect(-135, -206, 135, 54, 248, 248); setfillcolor(WHITE); // 脸 fillellipse(-115, -144, 115, 46); fillroundrect(-63, -169, 0, -95, 56, 56); // 右眼 fillroundrect(0, -169, 63, -95, 56, 56); // 左眼 setfillcolor(BLACK); solidcircle(-16, -116, 6); // 右眼球 solidcircle( 16, -116, 6); // 左眼球 setfillcolor(RGB(201, 62, 0)); // 鼻子 fillcircle(0, -92, 15); line(0, -77, 0, -4); // 人中 arc(-108, -220, 108, -4, PI * 5 / 4, PI * 7 / 4); // 嘴 line(-42, -73, -90, -91); // 胡子 line( 42, -73, 90, -91); line(-41, -65, -92, -65); line( 41, -65, 92, -65); line(-42, -57, -90, -39); line( 42, -57, 90, -39); // 画身体 line(-81, 32, -138, 72); // 手臂(上) line( 81, 32, 138, 72); line(-96, 96, -116, 110); // 手臂(下) line( 96, 96, 116, 110); line(-96, 85, -96, 178); // 腿外侧 line( 96, 85, 96, 178); arc(-10, 168, 10, 188, 0, PI); // 腿内侧 setfillcolor(WHITE); // 手 fillcircle(-140, 99, 27); fillcircle( 140, 99, 27); fillroundrect(-2, 178, -112, 205, 24, 24); // 脚 fillroundrect( 2, 178, 112, 205, 24, 24); setfillcolor(RGB(7, 190, 234)); // 身体填充蓝色 floodfill(0, 100, BLACK); setfillcolor(WHITE); // 肚皮 fillcircle(0, 81, 75); solidrectangle(-60, 4, 60, 24); // 用白色矩形擦掉多余的肚皮 pie(-58, 23, 58, 139, PI, 0); // 口袋 // 画铃铛 setfillcolor(RGB(169, 38, 0)); // 绳子 fillroundrect(-100, 23, 100, 42, 12, 12); setfillcolor(RGB(245, 237, 38)); // 铃铛外形 fillcircle(0, 49, 19); setfillcolor(BLACK); // 铃铛上的洞 solidellipse(-4, 50, 4, 57); setlinestyle(PS_SOLID, 3); line(0, 57, 0, 68); setlinestyle(PS_SOLID, 1); // 铃铛上的纹路 line(-16, 40, 16, 40); line(-18, 44, 18, 44); // 按任意键退出 _getch(); closegraph(); }

视觉错觉艺术4

这是网上经常见的视觉错觉艺术图片,可以用程序生成的。效果如下: 完整的源代码如下: /////////////////////////////////////////////////// // 程序名称:基于 Bresenham 算法画圆 // 编译环境:Visual C++ 6.0 / 2013,EasyX 20140321(beta) // 作  者:yangw80 <yw80@qq.com> // 最后修改:2014-7-14 // #include <graphics.h> #include <conio.h> // 定义回调 void (*callback)(int x, int y); // 画方块上的小方块 void DrawSmallBox(int x, int y, bool lt, bool rt, bool lb, bool rb) { int nx = x * 26 - 13; int ny = y * 26 - 13; if (lt) solidrectangle(nx + 1, ny + 1, nx + 1 + 6, ny + 1 + 6); if (rt) solidrectangle(nx + 24, ny + 1, nx + 24 - 6, ny + 1 + 6); if (lb) solidrectangle(nx + 1, ny + 24, nx + 1 + 6, ny + 24 - 6); if (rb) solidrectangle(nx + 24, ny + 24, nx + 24 - 6, ny + 24 - 6); } // 圆中的每个点(回调函数) void CirclePoints(int x, int y) { if (x == 0 && y < 0) DrawSmallBox(x, y, false, false, true, true); else if (x == 0 && y > 0) DrawSmallBox(x, y, true, true, false, false); else if (x < 0 && y == 0) DrawSmallBox(x, y, false, true, false, true); else if (x > 0 && y == 0) DrawSmallBox(x, y, true, false, true, false); else if (x == 0 && y == 0) ; else if ((x < 0 && y < 0) || (x > 0 && y > 0)) DrawSmallBox(x, y, false, true, true, false); else DrawSmallBox(x, y, true, false, false, true); } // 基于 Bresenham 算法画填充圆 // 修改自 www.easyx.cn, yw80@qq.com void FillCircle_Bresenham(int x, int y, int r) { int tx = 0, ty = r, d = 3 - 2 * r, i; while( tx < ty) { // 画水平两点连线(<45度) for (i = x - ty; i <= x + ty; i++) { CirclePoints(i, y - tx); if (tx != 0) // 防止水平线重复绘制 CirclePoints(i, y + tx); } if (d < 0) // 取上面的点 d += 4 * tx + 6; else // 取下面的点 { // 画水平两点连线(>45度) for (i = x - tx; i <= x + tx; i++) { CirclePoints(i, y - ty); CirclePoints(i, y + ty); } d += 4 * (tx - ty) + 10, ty--; } tx++; } if (tx == ty) // 画水平两点连线(=45度) for (i = x - ty; i <= x + ty; i++) { CirclePoints(i, y - tx); CirclePoints(i, y + tx); } } // 主函数 void main() { // 创建绘图窗口 initgraph(640, 480); setbkcolor(LIGHTGRAY); cleardevice(); setorigin(320, 240); // 画 15 x 15 的间隔黑白块,每块 26 x 26,共 390 x 390 setlinecolor(BLACK); setfillcolor(WHITE); fillrectangle(-210, -210, 209, 209); COLORREF fc = WHITE; for (int x = -195; x < 195; x += 26) for (int y = -195; y < 195; y += 26) { fc = (~fc) & 0xffffff; setfillcolor(fc); solidrectangle(x, y, x + 25, y + 25); } // 在填充圆内的方块内画小方块 setrop2(R2_XORPEN); setfillcolor(WHITE); FillCircle_Bresenham(0, 0, 6); // 按任意键退出 getch(); closegraph(); }

视觉错觉艺术3

这是网上经常见的视觉错觉艺术图片,可以用程序生成的。效果如下: 完整的源代码如下: /////////////////////////////////////////////////// // 程序名称:视觉错觉艺术3 // 编译环境:Visual C++ 6.0 / 2013,EasyX 20140321(beta) // 作  者:yangw80 <yw80@qq.com> // 最后修改:2014-7-14 // #include <graphics.h> #include <conio.h> // 定义回调 void (*callback)(int x, int y); // 圆中的每个点(回调函数) void CirclePoints(int x, int y) { if (x < y) { COLORREF c1 = getpixel(x, y); COLORREF c2 = getpixel(y, x); putpixel(x, y, c2); putpixel(y, x, c1); } } // 基于 Bresenham 算法画填充圆 // 修改自 www.easyx.cn, yw80@qq.com void FillCircle_Bresenham(int x, int y, int r) { int tx = 0, ty = r, d = 3 - 2 * r, i; while( tx < ty) { // 画水平两点连线(<45度) for (i = x - ty; i <= x + ty; i++) { CirclePoints(i, y - tx); if (tx != 0) // 防止水平线重复绘制 CirclePoints(i, y + tx); } if (d < 0) // 取上面的点 d += 4 * tx + 6; else // 取下面的点 { // 画水平两点连线(>45度) for (i = x - tx; i <= x + tx; i++) { CirclePoints(i, y - ty); CirclePoints(i, y + ty); } d += 4 * (tx - ty) + 10, ty--; } tx++; } if (tx == ty) // 画水平两点连线(=45度) for (i = x - ty; i <= x + ty; i++) { CirclePoints(i, y - tx); CirclePoints(i, y + tx); } } // 主函数 void main() { // 创建绘图窗口 initgraph(640, 480); setbkcolor(LIGHTGRAY); cleardevice(); setorigin(320, 240); // 画间隔的黑白块 setlinecolor(BLACK); rectangle(-201, -201, 200, 200); for (int x = 0; x < 10; x++) for (int y = 0; y < 40; y++) { setfillcolor( (((x + y) % 2) == 1) ? BLACK : WHITE); solidrectangle(x * 40 - 200, y * 10 - 200, x * 40 + 39 - 200, y * 10 + 9 - 200); } // 填充圆内横竖取反 FillCircle_Bresenham(0, 0, 120); // 按任意键退出 getch(); closegraph(); }

多个小球在方框内的碰撞运动

本程序模拟了多个小球在方框内的碰撞运动。 源代码如下: /////////////////////////////////////////////////// // 程序名称:多个小球在方框内的碰撞运动 // 编译环境:Visual C++ 6.0,EasyX 2013冬至版 // 作  者:可可 // 最后修改:2014-03-18 // #include <graphics.h> #include <conio.h> #include <math.h> #define XN 640 #define YN 480 // 设置图形窗口的大小 #define N 40 // 设置球的个数,最多 90 个 #define V 20 // 设置球的速度 // 画出一个球 void Ball(int x, int y) { fillcircle(x, YN - y, 20); // 转换成常用的坐标 } // 判定是否发生二维平面小球完全弹性碰撞(速度较大) // (当速度很小时,不服从。因为计算后的结果因为保留有限位而比真实情况小,很快衰减到 0) int PerfectElasticCollision(float v1[2], float v2[2], float u[2]) { float t, v11[2], v12[2], v21[2], v22[2]; // 保存球心连线上和垂直于连线的速度分量 v11[0] = (v1[0] * u[0] + v1[1] * u[1]) * u[0] / (u[0] * u[0] + u[1] * u[1]); v11[1] = (v1[0] * u[0] + v1[1] * u[1]) * u[1] / (u[0] * u[0] + u[1] * u[1]); v12[0] = v1[0] - v11[0]; v12[1] = v1[1] - v11[1]; v21[0] = (v2[0] * u[0] + v2[1] * u[1]) * u[0] / (u[0] * u[0] + u[1] * u[1]); v21[1] = (v2[0] * u[0] + v2[1] * u[1]) * u[1] / (u[0] * u[0] + u[1] * u[1]); v22[0] = v2[0] - v21[0]; v22[1] = v2[1] - v21[1]; if( ( ((fabs(v11[0]) <= fabs(v21[0])) && (v11[0] * u[0] >= 0) && (v11[0] * v21[0] >= 0)) || ((v11[0] * v21[0] <= 0) && (v21[0] * u[0] >= 0)) || ((fabs(v11[0]) >= fabs(v21[0])) && (v21[0] * u[0] >= 0) && (v11[0] * v21[0] >= 0)) ) && ( ((fabs(v11[1]) <= fabs(v21[1])) && (v11[1] * u[1] >= 0) && (v11[1] * v21[1] >= 0)) || ((v11[1] * v21[1] <= 0) && (v21[1] * u[1] >= 0)) || ((fabs(v11[1]) >= fabs(v21[1])) && (v21[1] * u[1] <= 0) && (v11[1] * v21[1] >= 0)) ) ) return 0; // 不会发生碰撞的情况就直接返回 // 在球心连线上速度交换 t = v11[0]; v11[0] = v21[0]; v21[0] = t; t = v11[1]; v11[1] = v21[1]; v21[1] = t; // 得到新的速度 v1[0] = v11[0] + v12[0]; v1[1] = v11[1] + v12[1]; v2[0] = v21[0] + v22[0]; v2[1] = v21[1] + v22[1]; return 1; } // 最小时间单位内的位移变化 int BallMove(float x[], float y[], float a[], float b[], int n) { for(int i = 0; i < n; i++) { x[i] += a[i] / 100; // 对最小长度(这里指一个像素点的抽象的边长)的分割 y[i] += b[i] / 100; } return 0; } // 碰撞判定 void Judge(float x[], float y[], float a[], float b[], int n) { int i = 0, j = 0; float v1[2], v2[2], u[2]; // 保存相碰两小球的初速度和碰撞方向 while(i < n) // 小球是否相碰 { for(j = i + 1; j < n; j++) { if(((x[i] - x[j]) * (x[i] - x[j]) + (y[i] - y[j]) * (y[i] - y[j]) <= 1600)) { u[0] = x[j] - x[i]; // 保存两小球的初速度和碰撞方向 u[1] = y[j] - y[i]; v1[0] = a[i]; v1[1] = b[i]; v2[0] = a[j]; v2[1] = b[j]; // 判定两相切小球是否相碰 if(PerfectElasticCollision(v1, v2, u)) { a[i] = v1[0]; // 碰撞后两小球的速度的改变 b[i] = v1[1]; a[j] = v2[0]; b[j] = v2[1]; } } } i++; } i = 0; while(i < n) // 小球是否碰壁 { if((x[i] - 21) <= 0 || ((XN - 21) - x[i]) <= 0) if((y[i] - 21) <= 0 || (y[i] - (YN-21)) >= 0) { a[i] = -a[i]; b[i] = -b[i]; } else a[i] = -a[i]; if((y[i] - 21) <= 0 || (y[i] - (YN - 21)) >= 0) b[i] = -b[i]; i++; } return; } // 主函数 void main() { int i = 0, j = 0, n = N; float x[N] = {0}, y[N] = {0}, a[N] = {0}, b[N] = {0}; // 初始化坐标位置(x[], y[])和速度向量(a[], b[]), 速度向量 for(i = 0; i < n; i += 1) { x[i] = (float) 50 * (i % 10) + 50; y[i] = (float) 50 * (i / 10) + 50; a[i] = (float) V; b[i] = (float) -V * (i % 2); } initgraph(XN, YN); BeginBatchDraw(); setrop2(R2_XORPEN); setfillcolor(RED); while(true) { for(i=0; i<n; i++) Ball((int)x[i], (int)y[i]); FlushBatchDraw(); Sleep(1); for(i=0; i<n; i++) Ball((int)x[i], (int)y[i]); Judge(x, y, a, b, n); // 判定是否相碰或碰壁,若有,改变速度向量 BallMove(x, y, a, b, n); // 最小时间单位坐标位置的变动 } EndBatchDraw(); getch(); closegraph(); } 作者:可可博客:<跳转至博客>

视觉错觉艺术2

这是网上经常见的视觉错觉艺术图片,可以用程序生成的。效果如下: 完整的源代码如下: /////////////////////////////////////////////////// // 程序名称:视觉错觉艺术2 // 编译环境:Visual C++ 6.0,EasyX 2013霜降版 // 作  者:yangw80 <yw80@qq.com> // 最后修改:2013-12-16 // #include <graphics.h> #include <conio.h> // 定义常量 #define UNIT 24 #define OFFSET_X 116 #define OFFSET_Y 36 // 画装饰花 void DrawUnit(int x, int y, int shape) { // 设置颜色 int n = ((shape & 1) ? 1 : 0) + ((shape & 2) ? 1 : 0) + ((shape & 4) ? 1 : 0); setlinecolor((n % 2 == 1) ? 0xaa00cc : WHITE); // 画枝干 line(x - 5, y, x + 5, y); line(x, y - 5, x, y + 5); // 画叶子 rectangle(x - 1, y - 4, x + 1, y - 2); rectangle(x - 1, y + 2, x + 1, y + 4); rectangle(x - 4, y - 1, x - 2, y + 1); rectangle(x + 2, y - 1, x + 4, y + 1); } // 主函数 void main() { // 创建绘图窗体 initgraph(640, 480); // 设置白色背景 setbkcolor(WHITE); cleardevice(); // 设置坐标原点 setorigin(OFFSET_X, OFFSET_Y); int x, y; // 画格子背景 for (y = 0; y < 17; y++) for (x = 0; x < 17; x++) { setfillcolor(((x + y) % 2) ? 0x83be3e : 0x01dcaa); solidrectangle(x * UNIT, y * UNIT, (x + 1) * UNIT - 1, (y + 1) * UNIT - 1); } // 画装饰花 for (y = 0; y < 16; y++) { int shape = 8 - y % 8; for (x = 0; x < 16; x++) DrawUnit((x + 1) * UNIT, (y + 1) * UNIT, shape++); } // 按任意键退出 getch(); closegraph(); }

视觉错觉艺术1

这是网上经常见的视觉错觉艺术图片,可以用程序生成的。效果如下: 完整的源代码如下: /////////////////////////////////////////////////// // 程序名称:视觉错觉艺术1 // 编译环境:Visual C++ 6.0,EasyX 2013霜降版 // 作  者:yangw80 <yw80@qq.com> // 最后修改:2013-12-16 // #include <graphics.h> #include <conio.h> // 定义常量 #define UNIT 15 #define OFFSET_X 122 #define OFFSET_Y 23 // 画每个小单元 void DrawUnit(int x, int y, int shape) { // 定义颜色 static COLORREF c[4] = {0x0000ff, 0x0077ff, 0x00ddff, 0x0077ff}; // 画背景白色角块 setfillcolor(WHITE); switch(shape) { case 0: solidrectangle(x, y, x + UNIT - 1, y + UNIT - 1); break; case 1: solidrectangle(x, y + UNIT / 2, x + UNIT / 2, y + UNIT - 1); break; case 3: solidrectangle(x + UNIT / 2, y, x + UNIT - 1, y + UNIT / 2); break; } // 画彩色角块 setfillcolor(c[shape]); if (shape % 2 == 0) { solidrectangle(x, y + UNIT / 2, x + UNIT / 2, y + UNIT - 1); solidrectangle(x + UNIT / 2, y, x + UNIT - 1, y + UNIT / 2); } else { solidrectangle(x, y, x + UNIT / 2, y + UNIT / 2); solidrectangle(x + UNIT / 2, y + UNIT / 2, x + UNIT - 1, y + UNIT - 1); } // 画圆角矩形 solidroundrect(x, y, x + UNIT - 1, y + UNIT - 1, 9, 9); } // 主函数 void main() { // 创建绘图窗体 initgraph(800, 600); // 设置坐标原点 setorigin(OFFSET_X, OFFSET_Y); int x, y; // 画背景及灰色边框 setbkcolor(WHITE); cleardevice(); setfillcolor(0xf3f3f3); solidrectangle(-8, -8, UNIT * 37 + 8 - 1, UNIT * 37 + 8 - 1); setfillcolor(BLACK); solidrectangle(0, 0, UNIT * 37 - 1, UNIT * 37 - 1); // 生成规律的图案 for (y = 0; y < 37; y++) { int shape = (4 - y % 4) & 3; for (x = 0; x < 37; x++) { DrawUnit(x * UNIT, y * UNIT, shape++); shape &= 0x3; } } // 中央部分左右颠倒 COLORREF c1, c2; for (y = 8 * UNIT + UNIT / 2; y < (37 - 8) * UNIT - UNIT / 2; y++) for (x = 8 * UNIT + UNIT / 2; x < 37 * UNIT / 2; x++) { c1 = getpixel(x, y); c2 = getpixel(37 * UNIT - x - 1, y); putpixel(x, y, c2); putpixel(37 * UNIT - x - 1, y, c1); } // 按任意键退出 getch(); closegraph(); }

带一盏油灯去巡视仓库

今天是 2013 年光棍节,写个程序庆祝一下,呵呵。 本程序模拟了这样一个场景:一个空地上乱七八糟地堆了一些货物,一个孤独的仓库管理员,带了一盏油灯,去巡视这些货物。 在鼠标的位置会亮起一盏油灯,随着鼠标的移动,部分光线会被仓库的货物遮挡。 就不抓图了,有兴趣的编译一下代码看看效果吧。 以下是全部源代码: ///////////////////////////////////////////////////////// // 程序名称:带一盏油灯去巡视仓库 // 编译环境:Visual C++ 6.0 / 2010,EasyX 2013霜降版 // 作 者:yangw80 <http://hi.baidu.com/yangw80> // 最后修改:2013-11-11 // #include <graphics.h> #include <conio.h> #include <math.h> #define RANGE 80 // 灯光照射半径 #define WIDTH 320 // 场景宽度 #define HEIGHT 240 // 场景高度 #define ZOOM 2 // 显示时的缩放倍数 #define PI 3.1415926536 // 圆周率 DWORD* g_bufMask; // 指向“建筑物”IMAGE 的指针 DWORD* g_bufRender; // 指向渲染 IMAGE 的指针 // 创建“仓库” void MakeMask() { // 创建“仓库” IMAGE 对象 static IMAGE g_imgMask(WIDTH, HEIGHT); g_bufMask = GetImageBuffer(&g_imgMask); // 设置绘图目标 SetWorkingImage(&g_imgMask); // 绘制“仓库” settextstyle(100, 0, _T("Courier")); outtextxy(8, 60, _T("EasyX")); // 恢复绘图目标为默认窗口 SetWorkingImage(NULL); } // 在指定位置“照明” void Lighting(int _x, int _y) { int i; // 定义循环变量 // 清空 Render 对象 memset(g_bufRender, 0, WIDTH * HEIGHT * 4); // 计算灯光照亮的区域 for(double a = 0; a < 2 * PI; a += PI / 180) // 圆周循环 { for(int r = 0; r < RANGE; r++) // 半径循环 { // 计算照射到的位置 int x = (int)(_x + cos(a) * r); int y = (int)(_y + sin(a) * r); // 光线超出屏幕范围,终止 // (为了简化全凭模糊运算,不处理最上和最下一行) if (x < 0 || x >= WIDTH || y <= 0 || y >= HEIGHT - 1) break; // 光线碰到建筑物,终止 if(g_bufMask[y * WIDTH + x]) break; // 光线叠加 g_bufRender[y * WIDTH + x] += 0x101000; // 0x101000 是很淡的黄色 } } // 修正曝光过度的点 for (i = WIDTH * HEIGHT - 1; i >= 0; i--) if (g_bufRender[i] > 0xffff00) g_bufRender[i] = 0xffff00; // 将光线模糊处理(避开建筑物) for(i = WIDTH; i < WIDTH * (HEIGHT-1); i++) if (!g_bufMask[i]) for (int j = 0; j < 2; j++) { g_bufRender[i] = RGB( (GetRValue(g_bufRender[i - WIDTH]) + GetRValue(g_bufRender[i - 1]) + GetRValue(g_bufRender[i]) + GetRValue(g_bufRender[i + 1]) + GetRValue(g_bufRender[i + WIDTH])) / 5, (GetGValue(g_bufRender[i - WIDTH]) + GetGValue(g_bufRender[i - 1]) + GetGValue(g_bufRender[i]) + GetGValue(g_bufRender[i + 1]) + GetGValue(g_bufRender[i + WIDTH])) / 5, (GetBValue(g_bufRender[i - WIDTH]) + GetBValue(g_bufRender[i - 1]) + GetBValue(g_bufRender[i]) + GetBValue(g_bufRender[i + 1]) + GetBValue(g_bufRender[i + WIDTH])) / 5); } } // 主函数 void main() { // 初始化绘图窗口 initgraph(WIDTH * ZOOM, HEIGHT * ZOOM); BeginBatchDraw(); DWORD* bufScreen = GetImageBuffer(NULL); // 制作建筑 MakeMask(); // 创建渲染对象 IMAGE imgRender(WIDTH, HEIGHT); g_bufRender = GetImageBuffer(&imgRender); // 定义鼠标消息变量 MOUSEMSG msg; while(true) { // 获取一条鼠标移动的消息 do { msg = GetMouseMsg(); } while((msg.uMsg != WM_MOUSEMOVE) || MouseHit()); // 在鼠标位置模拟灯光 Lighting(msg.x / ZOOM, msg.y / ZOOM); // 将渲染的内容拉伸后显示在绘图窗口中 int ps = 0, pr = 0; for (int y = 0; y < HEIGHT; y++) for (int x = 0; x < WIDTH; x++, pr++) { ps = y* ZOOM * WIDTH * ZOOM + x * ZOOM; for (int zy = 0; zy < ZOOM; zy++) { for (int zx = 0; zx < ZOOM; zx++) bufScreen[ps++] = g_bufRender[pr]; ps += ZOOM * (WIDTH - 1); } } // 刷新显示,并延时 FlushBatchDraw(); Sleep(20); // 按任意键退出 if (_kbhit()) { EndBatchDraw(); closegraph(); } } }

物理程序:引力模拟

一个模拟引力的程序。可以在程序中创建不同质量和初始速度的天体,天体按照万有引力定律运行。 左键创建天体。按下左键不松开,天体质量会增加;然后移动,会给天体赋值初始速度,然后松开左键。 右键删除天体。 超出屏幕、碰撞后的天体不会消失。 程序的运行截图如下: 完整源代码、图片及编译后的可执行文件请【点击这里下载】。 作者:有时的迷惘https://www.baidu.com/p/有时的迷惘