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

 

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

(1)result DrawBitmap(const Point& point, const Bitmap& bitmap);

将坐标点(point)作为位图的左顶点来绘制位图(bitmap)

这也是最常规的绘制整张图片的方式。

 

(2)result DrawBitmap(const Rectangle& destRect, const Bitmap& srcBitmap, const Rectangle& srcRect);

将位图(srcBitmap)中某一区域(srcRect)的内容绘制到目标区域(destRect)

这常用于从一张图片中抠取部分内容进行绘制。

 

(3)result DrawBitmap(const Rectangle& rect, const Bitmap& bitmap);

将位图(bitmap)绘制到目标区域(rect)

这个函数常用于对位图进行放缩绘制。

 

(4)result DrawBitmap(const Point& point, const Bitmap& bitmap, FlipDirection dir);

将坐标点(point)作为位图的左顶点来绘制位图(bitmap),但会根据翻转方式(dir)对位图内容进行翻转。

这个函数用于对图片内容进行翻转绘制。

 

(5)result DrawBitmap(const Point& point, const Bitmap& bitmap, const Point& 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) result DrawBitmap(const Rectangle& destRect, const Bitmap& srcBitmap, const Rectangle& srcRect)对图片中的部分区域进行绘制。

还是拿游戏中的精灵动画图片来说,有的游戏中会将一个精灵相关的图片组合成一张较大的图片,这样在每次进行精灵的绘制时,只需要在大图片中找到精灵对应的区域进行区域绘制就可以了。

下面的这张图就是由3张精灵图片组合而成的:

 

 

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

X = *100

Y = *115

这样的话对第0行第1列的精灵进行计算后得出X的值是100Y的值为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;

}