Visual C++中的图形特技

2016-02-19 14:27 21 1 收藏

下面是个超简单的Visual C++中的图形特技教程,图老师小编精心挑选推荐,大家行行好,多给几个赞吧,小编吐血跪求~

【 tulaoshi.com - 编程语言 】

  随着计算机信息表示及实现的多媒体化,在许多学习软件、游戏软件,以及多媒体课件制作软件中,经常使用各种图形显示技巧,如图形的推拉、交错、雨滴状、百页窗、积木随机堆叠等显示模式。这样使画面变得更为生动活泼,更能吸引用户,也为更好地发挥软件的功能奠定了基础。本文就Visual C++ 6.0中实现图形的各种显示技巧的原理及具体方法做些探讨。

基本原理

  在Visual C++6.0中,显示位图的方法及过程如下:

  1. 显示程序资源中的位图(位图的所有数据均存在于可执行文件中)

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  (1)从资源中装入位图

(本文来源于图老师网站,更多请访问http://www.tulaoshi.com/bianchengyuyan/)

  ● 定义位图对象数据成员CBitmap m_Bitmap;

  ● 调用CBitmap成员函数LoadBitmap(),如m_Bitmap.LoadBitmap(IDB_BITMAP1);

  ● 传入LoadBitmap的参数是位图在图形编辑器中生成或从位图文件中引入时赋予的识别符。

  (2)生成与位图相联系的内存设备情境对象

CDC MemDC;
MemDC.CreateCompatibleDC(NULL);
MemDC.SelectObject(&m_Bitmap);

  (3)显示位图

CClientDC ClientDC(this);
BITMAP BM;
m_Bitmap.GetObject(sizeof(BM),&BM);
ClientDC.BitBlt
( X,Y, //目标设备逻辑横、纵坐标
BM.bmWidth, BM.bmHeight, //显示位图的像素宽、高度
&MemDC,
//待显示位图数据的设备情境对象
0,0, //源数据中的横、纵坐标
SRCCOPY); //位操作方式

  这种方法显示位图速度快,但不是很灵活,而且会使可执行文件增大。

  2. 显示独立文件方式的位图(位图的所有数据独立于可执行文件)

HBITMAP *hBitmap; //定义位图对象句柄
BITMAP BM;
CDC MemDC;
CClientDC ClientDC(this);
MemDC.CreateCompatibleDC(&ClientDC);
hBitmap=(HBITMAP*):: LoadImage
( AfxGetInstanceHandle(),
//取得应用程序句柄
“demo1.bmp”,
//位图文件名
IMAGE_BITMAP,
//类型为Windows位图
0,0,
LR_LOADFROMFILE);
//从文件中取位图数据
MemDC.SelectObject(hBitmap);
:: GetObject(hBitmap,sizeof(BM),&BM);
ClientDC.BitBlt(……)
//使用格式与方法一同

  这种方法显示位图速度较之前一种慢了一点,但其灵活性较大,可以任意变换位图文件,而无需重新编译源程序, 也减小了可执行文件的大小。

实现方法

  下面介绍各种图形显示技巧的具体实现原理及方法。以下所有程序算法的实现均可放在视类(CView,也可视自己的需要放在其他类)中处理,且有必要进行如下的相关操作:

  增加如下类成员变量:

BITMAP m_Bm;
//保存位图的宽、高度等数据
HBITMAP *m_hBitmap;
//保存位图数据句柄
CDC m_MemDC; //内存设备情境对象

  在类构造函数中加入如下代码:

m_MemDC.CreateCompatibleDC(NULL); //产生内存设备情境对象
m_hBitmap=(HBITMAP *)::LoadImage(
//从文件中装入位图数据
AfxGetInstanceHandle(),
“demo1.bmp”,
IMAGE_BITMAP,
0,0,
LR_LOADFROMFILE );
m_MemDC.SelectObject(m_hBitmap); //将位图选入内存设备情境对象
::GetObject(m_hBitmap,sizeof(m_Bm),&m_Bm);

  1. 水平交错效果

  原理:将内存设备情境对象(如MemDC)中的位图数据拆分成奇、偶扫描线两部分,其中奇数条扫描线由上往下移动,偶数条扫描线则由下往上移动,且两者同时进行。屏幕上的效果为分别由上下两端出现的较淡栅栏图形,逐渐相互靠近,直至整个位图完全清楚。垂直交错效果的实现原理与之类似。

程序算法:

int i,j;
for ( i=0; i=m_Bm.bmHeight; i+=2 )
{j = i;
while ( j0 )
{ClientDC.StretchBlt(
//奇数,由上至下
0,j-1,
//目标设备逻辑横、纵坐标
m_Bm.bmWidth,1,
//显示位图的像素宽、高度
&m_MemDC,
//源位图设备情境对象
0,m_Bm.bmHeight-(i-j-1),
//源位图的起始横、纵坐标
m_Bm.bmWidth,1,
//源位图的像素宽、高度
SRCCOPY);
ClientDC.StretchBlt(
//偶数,由下至上
0,m_Bm.bmHeight-j,
//目标设备逻辑横、纵坐标
m_Bm.bmWidth,1,
//显示位图的像素宽、高度
&m_MemDC,
//源位图设备情境对象
0,i-j,
//源位图的起始横、纵坐标
m_Bm.bmWidth,1,
//源位图的像素宽、高度
SRCCOPY);
j-=2; }
// while ( j0 )
Sleep(10);
}
//for ( i=0; i=m_Bm.bmHeight; i+ =2 )

  2. 雨滴效果

  原理:将内存设备情境对象(如MemDC)中位图数据的最后一条扫描线,顺序地从目标设备(如ClientDC)中待显示位图的第一条扫描线所在位置移动至最后一条处,并保留此条扫描线在屏幕上移动时留下的轨迹。接着再把MemDC中位图数据的倒数第二条扫描线,顺序地从目标设备(如ClientDC)中待显示位图的第一条扫描线所在位置移动至倒数第二条处。其余的扫描线依此类推。

  程序算法:

int i,j;
for ( i=0; i=m_Bm.bmHeight; i++ )
{for ( j=0; j=m_Bm.bmHeight-i; j++ )
ClientDC.StretchBlt(
0,j,
//目标设备逻辑横、纵坐标
m_Bm.bmWidth,1,
//显示位图的像素宽、高度
&m_MemDC,
//源位图设备情境对象
0,m_Bm.bmHeight-i,
//源位图的起始横、纵坐标
m_Bm.bmWidth,1,
//源位图的像素宽、高度
SRCCOPY);
Sleep(20);
}
//for ( i=0; i=m_Bm.bmHeight; i++ )

  3. 百叶窗效果

  原理:将内存设备情境对象(如MemDC)中的位图数据分成若干组,然后分别从第一组到最后一组进行搬移,第一次搬移每组中第一条扫描线到目标设备(如ClientDC)中待显示位图的相应位置,第二次搬移每组中第二条扫描线,接着第三条、第四条扫描线。

  程序算法:

int i,stepi,j;
stepi=m_Bm.bmHeight/10;
for ( i=0; i=stepi; i++ )
{for ( j=0; j10; j++ )
ClientDC.StretchBlt(
0,j*stepi+i,
//目标设备逻辑横、纵坐标
m_Bm.bmWidth,1,
//显示位图的像素宽、高度
&m_MemDC,
//源位图设备情境对象
0,j*stepi+i,
//源位图的起始横、纵坐标
m_Bm.bmWidth,1,
//源位图的像素宽、高度
SRCCOPY);
Sleep(20);
} //for ( i=0; i=stepi; i++ )

  4. 随机积木效果

  原理:将内存设备情境对象(如MemDC)中的位图数据分成纵横十等份共一百组数据,然后随机地取出这一百组数据中的某一组显示到目标设备(如ClientDC)中待显示位图的相应位置,如此反复直到所有一百组数据均显示完毕为止。

  程序算法:

int i,j,stepx,stepy,dispnum,x,y;
int pxy[10][10];
//使用本数组记录已显示过的数据组
for ( i=0; i10; i++ )
for ( j=0; j10; j++ )
pxy[i][j]=0;
stepx=m_Bm.bmWidth/10;
stepy=m_Bm.bmHeight/10;
srand( (unsigned)time( NULL ) );
dispnum=0;
//记录已显示过的数据组的个数
while(1)
{ x=rand() % 10;
y=rand() % 10;
if ( pxy[x][y] )
//本组x,y所代表的数据组是否已显示过?
continue;
pxy[x][y]=1;
//表明本组x,y所代表的数据组已显示过
ClientDC.StretchBlt(
x*stepx, y*stepy,
//目标设备逻辑横、纵坐标
stepx,stepy,
//显示位图的像素宽、高度
&m_MemDC,
//源位图设备情境对象
x*stepx, y*stepy,
//源位图的起始横、纵坐标
stepx,stepy,
//源位图的像素宽、高度
SRCCOPY);
dispnum++;
if ( dispnum =100 )
break;
Sleep(30);
} // while(1)

结 语

  以上程序代码均在Visual C++ 6.0中调试通过,所有片断均可编写成独立的函数,灵活使用。如果对以上几种显示效果进行变换,我们还可以实现多种其他特技效果。

来源:http://www.tulaoshi.com/n/20160219/1607001.html

延伸阅读
C/C++语言提供了十分丰富的图形函数,图形函数文件为Graphics.h,使用图形函数前须先将屏幕设置为图形模式,C/C++语言提供了下面的函数: void far initgraph(int far *GD,int far *GM,char *P); 其中,GD和GM分别表示图形驱动程序和图形模式,P指图形驱动程序所在的目录路径。 图形驱动程序由Borland公司(对于Turbo C和Bo...
1. 用Microsoft Visual C++ 6.0编译的程序,或者发布在Windows 2000/NT/ME/98 系统 单纯通过拷贝MSVCRxx.DLL文件到应用程序目录或system32目录即可 2. 用Visual Studio 2005以上编译的程序,且发布在Windows XP及以上系统 为了减少DLL引发的配置问题(DLL hell),C和C++运行时由并行 (Side-by-Side) 程序集实现,单纯通过拷贝MSVCRxx.DLL并不...
在C++中,以类、虚函数等为代表的数据抽象功能一直是C++的核心和难点。这里我想结合自己的使用经验,谈谈对C++中抽象的一点浅薄看法! 我认为C++的抽象应该是指:从我们需要解决的问题出发,在与该问题相关的一组关联对象中提取出主要的或共有的部分――说简单一点,就是用相同的行为来操作不同的对象。 从提出问题到找出与该问题...
在学习c/c+过程中,指针是一个比较让人头痛的问题,稍微不注重将会是程序编译无法通过,甚至造成死机。在程序设计过程中,指针也往往是产生隐含bug的原因。下面就来谈谈指针的应用以及需要注重的一些问题,里面也许就有你平时没有注重到的问题,希望能帮助各位读者理解好指针。 !-- frame contents -- !-- /frame contents -- ...
    DBGrid数据表格控件以其短小精悍而深受大家的喜爱,但其如何在Visual C++中使用却很少有文章提及,本文将VC下使用DBGrid的具体步骤简要地介绍给大家。 一.前期准备 为了实现DBGrid控件的自动捆绑,我们需要建立一个数据库和与之关联的数据源,本例中我们用Access建立数据库mydata.mdb,在数据库中新建一张表users,包...

经验教程

71

收藏

48
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部