本教程与“Simple Finger Drawing(v.1.1.0)”这个bada应用相关,你能在projects section找到这个应用。我将用它作为一个例子来演示用双缓冲这种最有效的方式(我的个人观点)在窗体上绘制。
双缓冲背后的思想就是你在一张不可见的位图上执行了许多绘制操作,这张位图仅仅在你准备将绘制操作在屏幕上生效时作为一个整体被复制到另一张最终可见的位图上。这种方法节省了很多绘图资源,因为 每次一小部分被绘制后,屏幕不必须立即刷新了。这在游戏和绘制操作频繁的bada应用中尤为重要。
在我们的例子中,唯一不同之处在于我们使用Canvas对象而不是位图。首先绘图板得到一个被命名为"Canvas * canvas_"的私有成员变量,我们将其作为绘制的缓存。
首先我们需要如下代码构造它:
canvas_ = new Canvas();
canvas_->Construct(GetBounds());
canvas_->SetBackgroundColor(Color::COLOR_WHITE);
canvas_->Clear();
我们将其尺寸设置为窗体的大小(通过GetBounds()),背景颜色设置为白色,再以该背景色清除画布。然后编写由touch事件调用的绘制函数:
inline void
DrawingBoardForm::DrawBrush(const Osp::Ui::Control & source,
const Osp::Graphics::Point& currentPosition)
{
int radius = brush_->size;
int x = currentPosition.x-radius;
int y = currentPosition.y-radius;
canvas_->FillEllipse(brush_->color.GetRGB32(),
Rectangle(x, y,radius*2,radius*2));
this->RequestRedraw(true);
}
我们只需在画布缓存上绘制,当所有绘制操作完成时,通过"RequestRedraw(true)"请求一次对窗体的异步重绘。请注意这个例子中的绘制操作是十分简单的。在一个复杂的游戏中,重绘之前你将执行上百次绘制操作。传递给"RequestRedraw()"的布尔变量告诉窗体在绘制后是否应自动调用"Show()"。
最后,我们重写这个窗体的"OnDraw()"函数:
result
DrawingBoardForm::OnDraw()
{
Canvas* pCanvas = GetCanvasN();
if (pCanvas)
{
pCanvas->Copy(Point(GetClientAreaBounds().x, GetClientAreaBounds().y),*canvas_, GetClientAreaBounds());
delete pCanvas;
}
// Do not call Show(). It will be called automatically after OnDraw() callback.
return E_SUCCESS;
}
我们只是将缓存画布的内容复制到窗体的画布。窗体会以新内容被重绘和显示。很简单吧?
与刚开始学习bada时创建的早期版本相比,这次事情进行得多么顺利,我感到很惊讶
好吧,我们都是bada初学者!
原文链接:http://www.badadev.com/how-to-use-double-buffering-to-draw-on-a-form/