Chào các bạn, hôm nay chúng ta sẽ tiếp tục với một điều khiển mới trong bada, đó là điều khiển Animation. Trong bài viết hôm nay, tôi xin hướng dẫn các bạn cách để đưa một Animation vào trong ứng dụng bada. Rất nhiều ứng dụng mà ở đó bạn sẽ thấy sự xuất hiện của các Animation, ví dụ như trong các màn hình chờ, màn hình loading, và các ứng dụng trò chơi.
Để làm được bài hướng dẫn này thì các bạn nên đọc trước bài viết mà tôi đã hướng dẫn các bạn cách để hiển thị hình ảnh trong bada. Bởi vì sử dụng Animation thì bạn phải làm việc với các đối tượng Bitmap và Image. Do đó bạn cần phải thực hiện một số bước cấu hình cho ứng dụng để có thể sử dụng Animation. Chi tiết các bước tôi đã hướng dẫn chi tiết trong bài viết trước.
Lớp Animation cho phép bạn hiển thị một chuỗi các khung hình (trong bada gọi là các AnimationFrame) một cách tuần tự từng khung hình một. Bạn có thể thiết đặt số lần hiển thị Animation thông qua phương thức SetRepeatCount.
Một hoạt ảnh trong bada tại mỗi thời điểm sẽ thuộc vào một trong 3 trạng thái sau:
- ANIMATION_STOPPED
- ANIMATION_PAUSE
- ANIMATION_PLAYING
Bạn có thể kiểm tra trạng thái hiện thời của hoạt ảnh thông qua phương thức GetStatus()
Nếu ứng dụng muốn biết khi nào thì một hoạt ảnh ngưng trình diễn thì nó phải cài đặt giao diện IAnimationListener và đăng báo thông qua phương thức AddAnimationListener().
Nếu ứng dụng của chúng ta phải cấp phát tài nguyên (các ảnh bitmap) để cấu thành một hoạt ảnh thì bạn phải giải phóng nó sau khi đã khởi tạo thành công hoạt ảnh đó.
Lý thuyết như vậy có lẽ đã đủ rồi, chúng ta bắt tay vào viết mã thôi. Lần này tôi tạo một ứng dụng form đơn giản và đặt tên là AnimationDemo, lớp form thì đặt tên là AnimationForm. Trên form này bạn tạo một nút nhấn và đặt tên là IDC_BUTTON_ANIMATION và nhãn hiển thị là “Start”. Các bạn có thể xem hình vẽ:
Ở tập tin AnimationForm.h, trong phần khai báo lớp AnimationForm bạn phải thêm giao diện IAnimationListener vào. Đồng thời phải khai báo thêm phương thức OnAnimationStopped() của nó. Đồng thời bạn khai báo thêm một số biến mà chúng ta sẽ sử dụng như trong đoạn mã bên dưới.
class AnimationForm :
public Osp::Ui::Controls::Form,
public Osp::Ui::IActionEventListener,
public Osp::Ui::IAnimationEventListener
{
// Construction
public:
AnimationForm(void);
virtual ~AnimationForm(void);
bool Initialize(void);
// Implementation
protected:
static const int ID_BUTTON_ANIMATION = 101;
Osp::Ui::Controls::Button* __pButtonAnimation;
Osp::Ui::Controls::Animation* __pAnimation;
public:
virtual result OnInitializing(void);
virtual result OnTerminating(void);
virtual void OnActionPerformed(const Osp::Ui::Control& source, int actionId);
virtual void OnAnimationStopped(const Osp::Ui::Control& source){};
};
Phần in đậm trong đoạn mã trên là những dòng mã mà các bạn phải thêm vào. Khi lớp của bạn kế thừa giao diện IAnimationListener thì bạn cài đặt cho phương phức OnAnimationStopped(), ở đây chúng ta không xử lí gì nên có thể để rỗng như trên.
Các bước để tạo một hoạt ảnh có thể tóm tắt lại như sau:
- Bước 1: Tạo các đối tượng Bitmap từ các ảnh mà bạn muốn từ đó tạo thành một hoạt ảnh(cấp phát tài nguyên hình ảnh)
- Bước 2: Tạo 1 danh sách các đối tượng AnimationFrame từ các đối tượng Bitmap, 1 AnimationFrame tương ứng với 1 Bitmap (tạo các khung hình từ tài nguyên hình ảnh)
- Bước 3: Đưa danh sách các khung hình vào đối tượng Animation và thiết đặt các thông số cần thiết
Lý thuyết là vậy, bây giờ bạn sẽ bắt tay viết mã để làm theo các bước đó. Trong tập tin AnimationForm.cpp, bạn tiến hành cài đặt lại phương thức AnimationForm::OnInitializing(void) như sau:
result
AnimationForm::OnInitializing(void)
{
result r = E_SUCCESS;
// TODO: Add your initialization code here
// Get a button via resource ID
__pButtonAnimation = static_cast<Button *>(GetControl(L"IDC_BUTTON_ANIMATION"));
__pButtonAnimation->SetActionId(ID_BUTTON_ANIMATION);
__pButtonAnimation->AddActionEventListener(*this);
// Tạo một thể hiện của lớp Image để giải mã dữ liệu ảnh vào các đối tượng Bitmap
Image* __pImage = new Image();
__pImage->Construct();
// Create Bitmap == Bước 1
Bitmap *pBitmap1 = __pImage->DecodeN("/Home/Akuma01.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap2 = __pImage->DecodeN("/Home/Akuma02.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap3 = __pImage->DecodeN("/Home/Akuma03.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap4 = __pImage->DecodeN("/Home/Akuma04.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap5 = __pImage->DecodeN("/Home/Akuma05.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap6 = __pImage->DecodeN("/Home/Akuma06.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap7 = __pImage->DecodeN("/Home/Akuma07.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap8 = __pImage->DecodeN("/Home/Akuma08.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap9 = __pImage->DecodeN("/Home/Akuma09.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap10 = __pImage->DecodeN("/Home/Akuma10.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap11 = __pImage->DecodeN("/Home/Akuma11.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap12 = __pImage->DecodeN("/Home/Akuma12.png", BITMAP_PIXEL_FORMAT_ARGB8888);
Bitmap *pBitmap13 = __pImage->DecodeN("/Home/Akuma13.png", BITMAP_PIXEL_FORMAT_ARGB8888);
// Create AnimationFrames == Bước 2
long duration = 1300 / 13;
AnimationFrame *pAniFrame1 = new AnimationFrame(*pBitmap1, duration);
AnimationFrame *pAniFrame2 = new AnimationFrame(*pBitmap2, duration);
AnimationFrame *pAniFrame3 = new AnimationFrame(*pBitmap3, duration);
AnimationFrame *pAniFrame4 = new AnimationFrame(*pBitmap4, duration);
AnimationFrame *pAniFrame5 = new AnimationFrame(*pBitmap5, duration);
AnimationFrame *pAniFrame6 = new AnimationFrame(*pBitmap6, duration);
AnimationFrame *pAniFrame7 = new AnimationFrame(*pBitmap7, duration);
AnimationFrame *pAniFrame8 = new AnimationFrame(*pBitmap8, duration);
AnimationFrame *pAniFrame9 = new AnimationFrame(*pBitmap9, duration);
AnimationFrame *pAniFrame10 = new AnimationFrame(*pBitmap10, duration);
AnimationFrame *pAniFrame11 = new AnimationFrame(*pBitmap11, duration);
AnimationFrame *pAniFrame12 = new AnimationFrame(*pBitmap12, duration);
AnimationFrame *pAniFrame13 = new AnimationFrame(*pBitmap13, duration);
Osp::Base::Collection::ArrayList animationFrameList;
animationFrameList.Construct();
animationFrameList.Add(*pAniFrame1);
animationFrameList.Add(*pAniFrame2);
animationFrameList.Add(*pAniFrame3);
animationFrameList.Add(*pAniFrame4);
animationFrameList.Add(*pAniFrame5);
animationFrameList.Add(*pAniFrame6);
animationFrameList.Add(*pAniFrame7);
animationFrameList.Add(*pAniFrame8);
animationFrameList.Add(*pAniFrame9);
animationFrameList.Add(*pAniFrame10);
animationFrameList.Add(*pAniFrame11);
animationFrameList.Add(*pAniFrame12);
animationFrameList.Add(*pAniFrame13);
// Deallocate a Bitmap.
delete pBitmap1;
delete pBitmap2;
delete pBitmap3;
delete pBitmap4;
delete pBitmap5;
delete pBitmap6;
delete pBitmap7;
delete pBitmap8;
delete pBitmap9;
delete pBitmap10;
delete pBitmap11;
delete pBitmap12;
delete pBitmap13;
delete __pImage;
// Bước 3: Tạo hoạt ảnh và thiết đặt vị trí, kích thước, số lần lặp của nó trên màn hình.
__pAnimation = new Animation();
__pAnimation->Construct(Rectangle(155,220,165,207), animationFrameList);
__pAnimation->SetRepeatCount(10000);
__pAnimation->AddAnimationEventListener(*this);
AddControl(*__pAnimation);
return r;
}
Ở trên tôi dùng 13 ảnh PNG lần lượt đặt tên là Akuma01.png,..,Akuma13.png, các ảnh này có kích thước bằng nhau (110×138), để tạo ra Animation của mình, và đặt tất cả chúng dưới thư mục Home của dự án. Hoạt ảnh mà tôi muốn thể hiện là đây:
Ở trên lời gọi __pAnimation->Construct(Rectangle(155,220,165,207), animationFrameList); thiết lập tọa độ (155, 220) và kích thước(165×207) khung hình hiển thị cho hoạt ảnh của chúng ta. Các AnimationFrame sẽ tự động co giãn về kích thước của khung hình đó. Như các bạn thấy là ở đây tôi đã phóng to hoạt ảnh của mình lên 165×207 thay vì kích thước ban đầu của nó là 110×138.
Cuối cùng là xử lí các sự kiện khi người dùng kích vào nút nhấn:
- Nếu người dùng kích vào nút “Start” thì bạn cho hoạt ảnh chạy(Play) và đổi nhãn của nút nhấn thành “Stop”
- Nếu người dùng kích vào nút “Stop” thì bạn cho hoạt ảnh dừng(Pause) và đổi nhãn của nút nhấn thành “Start”
Chi tiết cài đặt như sau:
void
AnimationForm::OnActionPerformed(const Osp::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_BUTTON_ANIMATION:
{
if (__pButtonAnimation->GetText()=="Start")
{
__pButtonAnimation->SetText("Stop");
__pAnimation->Play();
}
else
{
__pButtonAnimation->SetText("Start");
__pAnimation->Pause();
}
}
break;
default:
break;
}
RequestRedraw();
}
Như vậy là xong, bạn đã có thể biên dịch và chạy thử ứng dụng của mình. Trên đây tôi đã hướng dẫn các bạn cách làm việc với Animation, từ đó bạn có thể sử dụng các hình ảnh của mình để tạo ra một hoạt ảnh cho riêng mình. Chúc các bạn thành công!




