您的位置:首页 > 编程语言

bada 2D游戏编程之二——图像绘制

2012-07-10 17:15 363 查看
bada 2D游戏编程之二——图像绘制

在2D游戏中,图像绘制可以说是无处不在,整个游戏都可以看作是由绘制的图像组成的。拿我们所知道的游戏背景图片、地图、精灵等来说,都是一张张图片通过绘制在手机屏幕上才显示出来的。bada平台上绘制图像都得通过Osp::Graphics::Canvas类提供的绘制函数。它总共提供了5个版本的绘制位图的函数。

(1)result
DrawBitmap
(constPoint& point,constBitmap&
bitmap);

将坐标点(point)作为位图的左顶点来绘制位图(bitmap)。
这也是最常规的绘制整张图片的方式。

(2)resultDrawBitmap(constRectangle& destRect,constBitmap&
srcBitmap,constRectangle& srcRect);
将位图(srcBitmap)中某一区域(srcRect)的内容绘制到目标区域(destRect)。
这常用于从一张图片中抠取部分内容进行绘制。

(3)resultDrawBitmap(constRectangle&
rect,constBitmap& bitmap);
将位图(bitmap)绘制到目标区域(rect),
这个函数常用于对位图进行放缩绘制。

(4)resultDrawBitmap(constPoint& point,constBitmap&
bitmap, FlipDirection dir);
将坐标点(point)作为位图的左顶点来绘制位图(bitmap),但会根据翻转方式(dir)对位图内容进行翻转。
这个函数用于对图片内容进行翻转绘制。

(5)resultDrawBitmap(constPoint&
point,constBitmap& bitmap,constPoint&
pivot,int degree);
将坐标点(point)作为位图的左顶点来绘制位图(bitmap),但会根据相对于位图(bitmap)中的中心点(pivot)来旋转一定角度(degree)进行绘制。
这个函数用于对图片进行旋转绘制。

其中的(3),(4),(5)中的函数在绘制过程中都会对位图进行变换处理,相对于(1)函数绘制效率低了很多。大家可以参这篇文章《2D图形的效率》,它对这(1), (3),(4),(5)这4个函数的绘制效率进行了详细的对比,

http://developer.bada.com/article/2D-Graphics-performance

所以建议大家在绘制图片前先将图片准备好,举例来说如果你需要一张图片的翻转效果,最好事先准备好翻转效果的图片,然后调用(1)函数直接绘制就可以了,而不是准备一张常规的图片,然后调用(4)函数进行翻转绘制,这样就可以提供绘图的效率。

下面给大家介绍在图像绘制过程中常用到的(1),(2)两个函数,如何通过这两个函数进行图像的绘制。

在2D游戏开发中常见的有三种图像绘制方式:

1, 整图绘制

这种绘制方式就是调用(1) result DrawBitmap(const Point& point, const Bitmap& bitmap)来绘制一张完整的图片。
拿游戏中常见的精灵动画图片来说,有的游戏中会将精灵的每个动作做成一张单独的图片,然后将一套动作动画的图片都放在同一个文件夹下方便管理。如下面的这套精灵动作图片:







这3张图片组成了小机器人的一套动作。这样在实现这套动作的动画时,就需要分别加载这3张图片,分别进行绘制。

下面的代码就是如何对这三张图片进行绘制

(1) 图片变量声明

Osp::Graphics::Bitmap*__robot1Bmp;
Osp::Graphics::Bitmap*__robot2Bmp;
Osp::Graphics::Bitmap*__robot3Bmp;

(2) 加载图片

__robot1Bmp =AppResource::GetInstance()->GetBitmapN("robot_1.PNG");
__robot2Bmp =AppResource::GetInstance()->GetBitmapN("robot_2.PNG");
__robot3Bmp =
AppResource::GetInstance()->GetBitmapN("robot_3.PNG");

(3) 在OnDraw函数中进行绘制

Canvas* pCanvas =GetCanvasN();
if(pCanvas){
pCanvas->DrawBitmap(Point(100,100), *__robot1Bmp);
pCanvas->DrawBitmap(Point(100,300), *__robot2Bmp);
pCanvas->DrawBitmap(Point(100,500), *__robot3Bmp);

delete pCanvas;
}

2, 区域绘制

这种绘制方式就是调用(2) resultDrawBitmap(constRectangle&
destRect,constBitmap& srcBitmap,constRectangle&
srcRect)对图片中的部分区域进行绘制。
还是拿游戏中的精灵动画图片来说,有的游戏中会将一个精灵相关的图片组合成一张较大的图片,这样在每次进行精灵的绘制时,只需要在大图片中找到精灵对应的区域进行区域绘制就可以了。
下面的这张图就是由3张精灵图片组合而成的:



这张组合而成的大图片也称为“精灵表”,精灵表就是一个图片中包含一系列以网格形式存在的精灵图片。可以通过每个精灵图片在大图片中的行和列的位置进行访问。简单的精灵表含有多个单一精灵,并且每个精灵的维度都是相同的。这样就很容易通过行列位置访问表格中的某个特定精灵。就拿上面的精灵表来说,它其中包含的精灵的长度和宽度是115*100像素,这样通过使用行列位置进行一些简单的计算就能得出给定精灵的像素位置。例如:
X = 列*100
Y = 行*115
这样的话对第0行第1列的精灵进行计算后得出X的值是100,Y的值为0,也就是第2张图片的坐标位置。通过这个计算可以得出所给精灵图像左上角的精确像素位置。

下面的代码就是如何绘制出这三张精灵图片:

(1) 精灵表图片变量声明

Osp::Graphics::Bitmap*__robotBmp;

(2) 加载精灵表图片

__robotBmp =
AppResource::GetInstance()->GetBitmapN("robot.PNG");

(3) 根据精灵在精灵表中的位置进绘制

Canvas* pCanvas =GetCanvasN();
if(pCanvas){
int spriteWidth = 100;
int spriteHeight = 115; pCanvas->DrawBitmap(Rectangle(100,100,spriteWidth,spriteHeight),*__robotBmp,
Rectangle(0*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));
pCanvas->DrawBitmap(Rectangle(100,300,spriteWidth,spriteHeight),*__robotBmp,
Rectangle(1*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));

pCanvas->DrawBitmap(Rectangle(100,500,spriteWidth,
priteHeight),*__robotBmp,
Rectangle(2*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));

delete pCanvas;
}

3, 创建区域图片

这种方式是先调用Bitmap的result Construct(const Bitmap& bitmap, const Osp::Graphics::Rectangle& rect)将图片中的部分区域创建成一张独立的Bitmap,然后再进行“整图绘制”。

同“区域绘制”类似,它也是采用精灵表,但是与直接绘制精灵表中的精灵不一样,它是先根据精灵列表中的精灵所在区域创建精灵图片,然后再绘制精灵图片。



下面的代码就是如何绘制出上面的三张精灵图片:

(1) 精灵表和精灵图片声明

Osp::Graphics::Bitmap*__robotBmp;
Osp::Graphics::Bitmap*__robot1Bmp;
Osp::Graphics::Bitmap*__robot2Bmp;
Osp::Graphics::Bitmap*__robot3Bmp;

(2) 加载精灵表图片,并根据精灵表中精灵的位置创建精灵图片

__robotBmp =AppResource::GetInstance()->GetBitmapN("robot.PNG");
int spriteWidth = 100;
int spriteHeight = 115;
__robot1Bmp =newBitmap();
__robot1Bmp->Construct(*__robotBmp,Rectangle(0*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));

__robot2Bmp =newBitmap();
__robot2Bmp->Construct(*__robotBmp,Rectangle(1*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));

__robot3Bmp =newBitmap();
__robot3Bmp->Construct(*__robotBmp,Rectangle(2*spriteWidth,0*spriteHeight,spriteWidth,spriteHeight));

(3) 绘制精灵图片

Canvas* pCanvas =GetCanvasN();
if(pCanvas){
pCanvas->DrawBitmap(Point(100,100), *__robot1Bmp);
pCanvas->DrawBitmap(Point(100,300), *__robot2Bmp);
pCanvas->DrawBitmap(Point(100,500), *__robot3Bmp);

delete pCanvas;
}

总结:

上面的3个例子得到的结果都是一样的,可以说是殊途同归。下图是最终的效果图:



这三种方式各有各的优缺点,大家都需要结合游戏的实际情况进行综合应用。

绘制方式

优点

缺点

整图绘制

绘图效率高

每个精灵都用一张单独的图片,会造成图片太多不便于管理

区域绘制

采用精灵表可以减少图片数量,便于管理图片

1. 绘图效率低

2. 需要计算图片在精灵表中的位置

创建区域图片

1. 绘图效率高

2. 采用精灵表可以减少图片数量,便于管理图片

1. 需要计算图片在精灵表中的位置

2. 需要为精灵表中的图片分配内存,增加了程序的内存使用量

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: