Search…

Animation trong Cocos2d-x 3.x.x

02/11/20204 min read
Bài viết nằm trong loạt bài viết chương trình Tự Học Cocos2d-x 3.x.x. Trong bài viết này sẽ giới thiệu nội dung về khái niệm Animation, các loại Animation hiện có và một cách tạo các Animation từ Sprite Sheet.

Animation là gì?

Là một loại Action của Sprite. Một bộ phim thì được tập hợp bởi nhiều tấm ảnh được chụp liên tiếp, khi chiếu bộ phim người ta sẽ cho chạy những tấm ảnh này liên lục trong thời gian ngắn nhằm tạo ảo giác mắt cho người xem. Animation trong Cocos2d-x cũng hoạt động như thế.

Các loại Animation

Có 2 loại Animation trong Cocos2d-x:

  • Sprite Sheets Animation: Tạo Animation bằng một loạt Sprite nối tiếp nhau.
  • Skeleton Animation: Tạo Animation bằng khung xương.

Bài viết này giới thiệu về Sprite Sheets Animation.

Tạo Animation

Khi tạo một Animation, nên sử dụng một file Sprite Sheet chứa tất cả các Sprite cần thiết để tạo Animation thay cho nhiều file Sprite nhằm tăng hiệu suất của game. Tìm hiểu thêm về Sprite Sheet, cách tạo file format trong bài viết Sprite Sheet Trong Cocos2d-x 3.x.x.

Không sử dụng file format

//Khởi tạo một hằng có giá trị là số lượng tối đa Sprite dùng để tạo Animation
const int numberSprite = 4;
//Tạo Sprite sử dụng hình ảnh đầu tiên là mysprite.png với Rect(0, 0, 50, 50), animation dùng Sprite này làm Sprite đầu tiên
auto gameSprite = Sprite::create("mysprite.png", Rect(0,0,50,50));

//Thiết lập vị trí của gameSprite tại vị trí (300, 300). Đây cũng chính là vị trí của Animation trên Screen. gameSprite->setPosition(300, 300);

//Thêm gameSprite vào Scene. this->addChild(gameSprite);
//Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames. Vector<SpriteFrame*> animFrames; animFrames.reserve(numberSprite);
//Push frame từ bộ đệm SpriteFrameCache animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,50,50,50))); animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,150,50,50))); animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,200,50,50)));
//Khởi tạo một khung hình animation từ Vector SpriteFrame Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.1f);

//Tạo animate Animate* animate = Animate::create(animation);
//Chạy Acction animation với số lần lặp vô hạn. Lúc này sẽ có 4 tấm hình như 4 thước phim.  gameSprite->runAction(RepeatForever::create(animate));

Sử dụng file format

File Sprite Sheet có tên là animation.png và một file format của Sprite Sheet này là animation.plist.

//Nạp file format animation.plist và hình ảnh gốc của Sprite Sheet là animation.png vào bộ nhớ đệm SpriteFrameCache
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("animation.plist", "animation.png");
//Khởi tạo một hằng có giá trị là số lượng tối đa Sprite dùng để tạo Animation const int numberSprite = 5;
//Tạo Sprite sử dụng hình ảnh đầu tiên là mysprite.png. Ở đây Animation của mình sẽ dùng Sprite này làm Sprite đầu tiên auto gameSprite = Sprite::createWithSpriteFrameName("mysprite0001.png");

//Thiết lập vị trí của gameSprite tại vị trí (300, 300). Đây cũng chính là vị trí của Animation trên Screen gameSprite->setPosition(300, 300);

//Thêm gameSprite vào Scene this->addChild(gameSprite);
//Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames Vector<SpriteFrame*> animFrames;

//Khởi tạo kích thước của mảng animFrames là 5 animFrames.reserve(numberSprite);
//Push frame từ bộ đệm SpriteFrameCache animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0002.png")); animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0003.png")); animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0004.png"));
//Khởi tạo một khung hình animation từ Vector SpriteFrame Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
//Tạo animate Animate* animate = Animate::create(animation); //Chạy Acction animation với số lần lặp vô hạn gameSprite->runAction(RepeatForever::create(animate));

Chú ý

Với các phương pháp tạo Animation trên, giả sử có một Animation cần một Sprite Sheet chứa 50 Sprite thì sao? Vấn đề đặt ra ở đây, để có thể nạp từng frame từ bộ đệm SpriteFramCache sẽ mất nhiều công sức. Để giải quyết vấn đề này, khi sử dụng file format, nên đặt tên của tất cả các Sprite trong Sprite Sheet nên giống nhau kèm theo số thứ tự của chúng trong Animation.

Ví dụ: sprite0, sprite1, sprite2,..., sprite20, ...

// Nạp file format animation.plist và hình ảnh gốc của Sprite Sheet là animation.png vào bộ nhớ đệm SpriteFrameCache
SpriteFrameCache::getInstance()->addSpriteFramesWithFile("animation.plist", "animation.png");

// Định nghĩa hằng. 
const int numberSprite = 5;
const int maxWord = 50;
 
// Tạo Sprite sử dụng hình ảnh đầu tiên là mysprite0.png. Ở đây Animation của mình sẽ dùng Sprite này làm Sprite đầu tiên.
auto gameSprite = Sprite::createWithSpriteFrameName("mysprite0.png");
// Thiết lập vị trí của gameSprite tại vị trí (300, 300). Đây cũng chính là vị trí của Animation trên Screen.
gameSprite->setPosition(300, 300);
//Thêm gameSprite vào Scene.
this->addChild(gameSprite);
 
// Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames và có kích thước là numberSprite.
Vector<SpriteFrame*> animFrames;
animFrames.reserve(numberSprite);

//*******************************************************
// chuỗi trung gian để đọc tên ảnh trong file format
char spriteFrameByName[maxWord ] = { 0 }; 

// Lặp để đọc numberSprite ảnh trong file format
for (int index = 1; index < numberSprite; index++) 
{
     // Lấy sprite frame name
     sprintf(spriteFrameByName, "mysprite%d.png", index);
		
     // Tạo 1 khung, lấy ra từ bộ đệm SpriteFrameCache có tên là spriteFrameByName;
     auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(spriteFrameByName);
     // Push frame.
     animFrames.pushBack(frame);
}
//*******************************************************

// Khởi tạo một khung hình animation từ Vector SpriteFrame.  
Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
Animate* animate = Animate::create(animation);
 
// Chạy Acction animation với số lần lặp vô hạn.
gameSprite->runAction(RepeatForever::create(animate));

Tổng kết

Animation trong games cũng được coi là một kỹ thuật tiêu chuẩn ở trong ngành công nghiệp games. Animation giúp rất nhiều trong project game, giúp đẹp mắt hơn, tối ưu hơn,...

Tham khảo

http://www.cocos2d-x.org

IO Stream

IO Stream Co., Ltd

30 Trinh Dinh Thao, Hoa Thanh ward, Tan Phu district, Ho Chi Minh city, Vietnam
+84 28 22 00 11 12
developer@iostream.co

383/1 Quang Trung, ward 10, Go Vap district, Ho Chi Minh city
Business license number: 0311563559 issued by the Department of Planning and Investment of Ho Chi Minh City on February 23, 2012

©IO Stream, 2013 - 2024