【转】如何编写自己的图形开发包 - 第五章 真正的架构设计! - 5.1 改进位图显示函数(5.1.2 剪切矩形函数)
5.1.2剪切矩形函数
还记得我们前面一节我们假设屏幕为一个可显区,并用变量DrawLeft, DrawTop, DrawWidth, DrawHeight将其标记出来,为的是在后面做判断的时候有一个可比较的界线。但实质上他的功效却远远不只是用于比较的界线。
在(Chap05\main2\GrTry.c)中,图片显示的范围是由DrawLeft, DrawTop, DrawWidth, DrawHeight来限定的。那么如果我将此区域尺寸改变,比如改的比屏幕小,那么我们显示图片的时候,也就只有这个区域能显示出来。
有了这个认识我们就来实验一下,我们将(Chap05\main2\GrTry.c)中的ShowBmp做如下更改:
……
/* 设定可见屏幕范围 */
DrawLeft = 50;
DrawTop = 50;
DrawWidth = 220;
DrawHeight = 100;
……
然后显示一个图片:
#include "GrTry.c"
int main()
{
InitSVGA();
/* 图形初始化开始
*/
SetSVGAMode(TRY320X200X256);
/* 实现图形模式
*/
ShowBmp("mnls1.bmp", 0, 0);
getch();
ExitSVGA();
}
效果如下:
图片点击可在新窗口打开查看此主题相关图片如下:5.6.jpg
图片点击可在新窗口打开查看
图 5.6 更改了可显区域的图片显示
经过实践,我们的可显区的确是起作用的,大家还可以手动将上述代码的更改一番试一试看是否运作正常。正是由于我们可以在屏幕上任意设定一个特定的可显区域,所以我们叫这个区域为“剪切矩形”。
你问这样做有什么好处?那好处可就大了去了。后面我们就弄个小例子试试。不过这之前,我们还是动手改造一下代码。使这个“剪切矩形”是可以很方便设置的。
请查看文件夹(Chap05\main3)的代码:
首先我们增加几个设置“剪切矩形”的全局变量:
static UINT16
ScreenSeeLeft;
/* 设置可见区的顶点和尺寸
*/
static UINT16
ScreenSeeTop;
static UINT16
ScreenSeeWidth;
static UINT16
ScreenSeeHeight;
然后增加一个设置“剪切矩形”的函数:
void ScreenSee(UINT16 Left, UINT16 Top, UINT16 Width, UINT16 Height)
{
if (Left > COLS)
Left = COLS;
if (Left+Width > COLS)
Width = COLS-Left;
if (Top > ROWS)
Top= ROWS;
if (Top+Height > ROWS)
Height = ROWS-Top;
ScreenSeeLeft = Left;
ScreenSeeTop = Top;
ScreenSeeWidth = Width;
ScreenSeeHeight = Height;
}
接着,我们在ShowBmp函数里将设定范围赋值:
/* 设定可见屏幕范围 */
DrawLeft = ScreenSeeLeft;
DrawTop = ScreenSeeTop;
DrawWidth = ScreenSeeWidth;
DrawHeight = ScreenSeeHeight;
其实我们完全可以将DrawLeft等直接做成全局变量,这样可以减少一点开销,不过为了逻辑上更清晰,理解起来更自然我们姑且先这样做。
最后,我们要考虑一下在初始化图形模式时就应该对此“剪切矩形”进行设定吧,我们更改图形模式初始化函数:
/* 设置好寄存器,并完成初始化
*/
void SetSVGAMode(INT16 vmode)
{
ScreenSeeLeft = ScreenSeeTop = 0;
switch (vmode)
/* 记录当前的分辨率
*/
{
case TRY320X200X256:
ScreenSeeWidth = COLS = 320;
ScreenSeeHeight = ROWS = 200;
break;
case TRY640X480X256:
ScreenSeeWidth = COLS = 640;
ScreenSeeHeight = ROWS = 480;
break;
case TRY800X600X256:
ScreenSeeWidth = COLS = 800;
ScreenSeeHeight = ROWS = 600;
break;
case TRY1024X768X256:
ScreenSeeWidth = COLS = 1024;
ScreenSeeHeight = ROWS = 768;
break;
}
_AX = 0x4f02;
_BX = vmode;
__int__(0x10);
}
OK,大功告成。现在我们可以用ScreenSee函数来随意更改我们的可显区域啦。我们的剪切矩形函数就此完成。
下面我们来看个实例,感受一下这个剪切矩形函数带来的奇妙效果。查看代码(Chap05\main3\main.c)
#include "GrTry.c"
int main()
{
int i, j;
InitSVGA();
/* 图形初始化开始
*/
SetSVGAMode(TRY320X200X256);
/* 实现图形模式
*/
ScreenSee(0, 0, 192, 192);
/* 设置可显区域 */
while (!bioskey(1))
/* 连续显示123.bmp的不同位置部分 */
{
for (j = 0; j < 5; j++)
for (i = 0; i < 17; i++)
ShowBmp("123.bmp", -j*192, -i*192);
}
ExitSVGA();
/* 恢复原始的模式
*/
}
效果:
图片点击可在新窗口打开查看此主题相关图片如下:5.7.jpg
图片点击可在新窗口打开查看
图 5.7 连续动画的一个瞬间
游 戏 我们的123.bmp是一个人物的连续动作,我们利用剪切矩形函数来 显示同一图片的不同部分这样就使得我们的人物动作了起来。这样的效果是非常有 用 的。一是由于设定了特定区域,所以我们不用整张的去处理图片减少了程序开 销;二是资源图片将可以集中在一张图片之上而不用将图片散落开。三是毕竟有 的时 候我们只需要显示某一部分到屏幕某区域去这样才能避免其他部分被覆盖。
总之,我们的剪切矩形函数是非常有用的,您可以自己拿着此函数去实现一些你能想到的好创意。
我们ShwBmp到此算是基本完善了。而这个剪切矩形函数就是他最大的特色。而且我们实现剪切矩形函数也不是那么费劲,我们只是顺其自然的就将这样一个功能函数给完成了。下面,我们要给开发包再添加若干函数,并就一些经验总结和讨论一下。