SimpleCG的使用方法在前面已经介绍了许多,有兴趣的同学如果有去动手,制作一些简单动画应该没多大问题的。所以这次我们来演示一下简单动画。我们刚学习C语言的递归函数时,有一个经典例子相信很多同学都写过,那就是汉诺塔。那么我们今天就来写一个汉诺塔的直观动画演示。
运行程序下载bin/AnimateHannuo.zip · master · b2b160 / SimpleCG_Demo · GitCode
-
- #include "../import/include/CGBoard.h"
- #include "math.h"
- #ifdef _DEBUG
- #pragma comment(lib,"../import/lib/SimpleCG_MDd.lib")
- #else
- #pragma comment(lib,"../import/lib/SimpleCG_MT.lib")
- #endif
-
- #define C_FLOOR_CNT 7
- #define C_FLOOR_BOTTOM 380
- #define C_HAN_HEIGHT 10
- #define C_HAN_SPEED 30
-
- int g_nWidth = 640; //画面宽度
- int g_nHeight= 400; //画面高度
- enum ENUM_DIRECTION
- {
- enumDIR_NULL,
- enumDIR_UP,
- enumDIR_DOWN
- };
- struct tagHannuo
- {
- int nNumber;
- COLORREF nColor;
- int nWidth;
- int nPosHan;
- int nDir;
- POINT ptPos;
- };
-
- tagHannuo g_pHannuo[C_FLOOR_CNT];
- int g_nMoving = -1;
- void DrawHan()
- {
- int i;
- int j=0;
-
- setlinewidth(2);
-
- for(i=0;i<3; i++ )
- {
- _line( 100 + 200 * i, 50, 100 + 200 * i,C_FLOOR_BOTTOM );
- _line( 20 + 200 * i, C_FLOOR_BOTTOM, 180 + 200 * i,C_FLOOR_BOTTOM );
- }
- int nIndex = 0;
- for(j=0;j<3;++j)
- {
- nIndex = 0;
- for(i=C_FLOOR_CNT-1;i>=0; i-- )
- {
- if(g_pHannuo[i].nPosHan == j && i != g_nMoving)
- {
- setfillcolor(g_pHannuo[i].nColor);
- _solidrectangle( 100 +200 * g_pHannuo[i].nPosHan - g_pHannuo[i].nWidth/2, C_FLOOR_BOTTOM - nIndex * C_HAN_HEIGHT - C_HAN_HEIGHT, 100 +200 * g_pHannuo[i].nPosHan + g_pHannuo[i].nWidth/2, C_FLOOR_BOTTOM - nIndex * C_HAN_HEIGHT);
- ++nIndex;
- }
- }
- }
- }
- void DrawMoving()
- {
- if(g_nMoving>=0)
- {
- setfillcolor(g_pHannuo[g_nMoving].nColor);
- _solidrectangle( g_pHannuo[g_nMoving].ptPos.x, g_pHannuo[g_nMoving].ptPos.y, g_pHannuo[g_nMoving].ptPos.x + g_pHannuo[g_nMoving].nWidth, g_pHannuo[g_nMoving].ptPos.y+ C_HAN_HEIGHT);
- }
- }
- void DrawAll()
- {
- ClearDevice();
-
- DrawHan();
- DrawMoving();
- ReflushWindow();
- }
- void Moving( int nItem, int nFrom, int nTo )
- {
- g_nMoving = nItem;
- g_pHannuo[nItem].ptPos.x = 100 +200 * nFrom - g_pHannuo[nItem].nWidth/2;
- for( g_pHannuo[nItem].ptPos.y = C_FLOOR_BOTTOM - C_FLOOR_CNT * C_HAN_HEIGHT; IsShowingWindow()&&g_pHannuo[nItem].ptPos.y>40; g_pHannuo[nItem].ptPos.y-=10 )
- {
- DrawAll();
- Sleep(C_HAN_SPEED);
- }
- int nXStep = (nTo - nFrom) * 5;
- int nDest = 100 +200 * nTo - g_pHannuo[nItem].nWidth/2;
- for( g_pHannuo[nItem].ptPos.x = 100 +200 * nFrom - g_pHannuo[nItem].nWidth/2; IsShowingWindow()&&abs(g_pHannuo[nItem].ptPos.x-nDest)>5; g_pHannuo[nItem].ptPos.x+=nXStep )
- {
- DrawAll();
- Sleep(C_HAN_SPEED);
- }
- g_pHannuo[nItem].ptPos.x = 100 +200 * nTo - g_pHannuo[nItem].nWidth/2;
- for( g_pHannuo[nItem].ptPos.y = 40; IsShowingWindow()&&g_pHannuo[nItem].ptPos.y
10 ) - {
- DrawAll();
- Sleep(C_HAN_SPEED);
- }
- g_nMoving = -1;
- g_pHannuo[nItem].nPosHan = nTo;
- }
- void MoveHan( int nFloor, int nFrom, int nTo, int nMiddle )
- {
- if( nFloor == 1 )
- {
- Moving( nFloor-1, nFrom-1, nTo-1);
- return;
- }
- MoveHan( nFloor-1, nFrom, nMiddle, nTo );
- Moving( nFloor-1, nFrom-1, nTo-1);
- MoveHan( nFloor-1, nMiddle, nTo, nFrom );
- }
- void DrawProcess()
- {
- bool bIsRunning = true;
- int i;
- srand(GetTickCount());
- for(i=0;i
- {
- g_pHannuo[i].nNumber=i+1;
- g_pHannuo[i].nColor = RGB(rand()%200,rand()%200,rand()%200);
- g_pHannuo[i].nDir = enumDIR_NULL;
- g_pHannuo[i].nPosHan = 0;
- g_pHannuo[i].nWidth = 20*(i+1);
- }
- MoveHan(C_FLOOR_CNT,1,2,3);
-
- DrawAll();
- }
- int _tmain(int argc, _TCHAR* argv[])
- {
- //初始化
- if( !ShowingBoard(g_nWidth,g_nHeight, DrawProcess))
- return 1;
- //关闭图库
- CloseBoard();
- return 0;
- }
对于写过汉诺塔的同学来说,程序逻辑应该没什么难度,就是在递归程序上增加了动画过程。
二、演示效果
对于5层来说是不难的,但递归对于层数增加所带来的时间消耗是呈指数增加的,所以通过动画来观察层数增加带来的时间消耗非常直观。在原始的汉诺塔里是64层,要移完所有的层数将会世界末日,因为即便到世界的尽头也无法完成。有兴趣的同学可以把代码输入并把层数加大看看。
三、代码下载
汉诺塔演示源代码
AnimateHannuo · master · b2b160 / SimpleCG_Demo · GitCode
库安装方法如下