Game Studio
Liên kế mạng xã hội

Game Studio


Animation Trong Cocos2d-x 3.x.x

Giới thiệu

Trong các bài viết Giới Thiệu Về Sprite Trong Cocos2d-x 3.x.x hay Action Của Sprite Trong Cocos2d-x 3.x.x, tôi đã giới thiệu cho các bạn làm quen với Sprite và các Action cơ bản. Nhưng bạn cũng thấy rằng những Action rất đơn điệu. Vậy khi bạn cần một hành động để thực hiện một di chuyển của một con vật,con người,... hay một hiệu ứng nào đó thì sao? Trong bài viết này tôi và các bạn sẽ tìm hiểu về Animation trong Cocos2d-x 3.4.

Tiền đề bài viết

Bài viết này là bài viết đầu tiên trong những loạt bài viết của tôi về tổng quan làm game 2D sử dụng Cocos2d-x 3.4.

Đối tượng hướng đến

Bài viết này tôi hướng đến những lập trình viên mới bắt đầu tìm hiểu và học tập làm game 2D bằng Cocos2d-x.

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 mắt 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.

Trong bài viết này tôi sẽ giới thiệu cho bạn về Sprite Sheets Animation.

Tạo Animation

Khi bạn tạo một Animation bạn 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. Bạn có thể tìm 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

  1. const int numberSprite = 4;
  2.  
  3. auto gameSprite = Sprite::create("mysprite.png", Rect(0,0,50,50));
  4. gameSprite->setPosition(300, 300);
  5. this->addChild(gameSprite);
  6.  
  7. Vector<SpriteFrame*> animFrames;
  8.  
  9. animFrames.reserve(numberSprite);
  10.  
  11. animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,50,50,50)));
  12. animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,150,50,50)));
  13. animFrames.pushBack(SpriteFrame::create("mysprite.png", Rect(0,200,50,50)));
  14.  
  15. Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.1f);
  16. Animate* animate = Animate::create(animation);
  17.  
  18. gameSprite->runAction(RepeatForever::create(animate));

Phân tích

  • Dòng 1: Khởi tạo một hằng có giá trị là số lượng tối đa Sprite dùng để tạo Animation.
  • Dòng 3: Tạo Sprite sử dụng hình ảnh đầu tiên là mysprite.png với Rect(0,0, 50, 50). Ở đây Animation của mình sẽ dùng Sprite này làm Sprite đầu tiên.
  • Dòng 4: 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.
  • Dòng 5: Thêm gameSprite vào Scene.
  • Dòng 7: Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames.
  • Dòng 8: Khởi tạo kích thước của mảng animFrames là 4.
  • Dòng 10 - Dòng 13: Push frame từ bộ đệm SpriteFrameCache
  • Dòng 15: Khởi tạo một khung hình animation từ Vector SpriteFrame.
  • Dòng 16: Tạo animate.
  • Dòng 18: 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. 

Sử dụng file format

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

  1. SpriteFrameCache::getInstance()->addSpriteFramesWithFile("animation.plist", "animation.png");
  2.  
  3. const int numberSprite = 5;
  4.  
  5. auto gameSprite = Sprite::createWithSpriteFrameName("mysprite0001.png");
  6. gameSprite->setPosition(300, 300);
  7. this->addChild(gameSprite);
  8.  
  9. Vector<SpriteFrame*> animFrames;
  10. animFrames.reserve(numberSprite);
  11.  
  12. animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0002.png"));
  13. animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0003.png"));
  14. animFrames.pushBack(SpriteFrameCache::getInstance()->getSpriteFrameByName("mysprite0004.png"));
  15.  
  16. Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
  17. Animate* animate = Animate::create(animation);
  18.  
  19. gameSprite->runAction(RepeatForever::create(animate));

Phân tích

  • Dòng 1: 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
  • Dòng 3: Khởi tạo một hằng có giá trị là số lượng tối đa Sprite dùng để tạo Animation.
  • Dòng 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.
  • Dòng 6: 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.
  • Dòng 7: Thêm gameSprite vào Scene.
  • Dòng 9: Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames.
  • Dòng 10:  Khởi tạo kích thước của mảng animFrames là 5.
  • Dòng 12 - Dòng 15: Push frame từ bộ đệm SpriteFrameCache
  • Dòng 16: Khởi tạo một khung hình animation từ Vector SpriteFrame.
  • Dòng 17: Tạo animate.
  • Dòng 19: Chạy Acction animation với số lần lặp vô hạn.

Chú ý

Với các phương pháp tạo Animation trên, giả sử bạn có một Animation cần một Sprite Sheet chứa 50 Sprite thì sao? Vấn đề đặt ra ở đây, là bạn không thể ngồi code, nạp từng frame từ bộ đệm SpriteFramCache được. Để giải quyết vấn đề này, khi bạn sử dụng file format, bạn 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, ...

  1. // 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
  2. SpriteFrameCache::getInstance()->addSpriteFramesWithFile("animation.plist", "animation.png");
  3.  
  4. // Định nghĩa hằng.
  5. const int numberSprite = 5;
  6. const int maxWord = 50;
  7. // 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.
  8. auto gameSprite = Sprite::createWithSpriteFrameName("mysprite0.png");
  9. // 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.
  10. gameSprite->setPosition(300, 300);
  11. //Thêm gameSprite vào Scene.
  12. this->addChild(gameSprite);
  13. // Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames và có kích thước là numberSprite.
  14. Vector<SpriteFrame*> animFrames;
  15. animFrames.reserve(numberSprite);
  16.  
  17. //*******************************************************
  18. // chuỗi trung gian để đọc tên ảnh trong file format
  19. char spriteFrameByName[maxWord ] = { 0 };
  20.  
  21. // Lặp để đọc numberSprite ảnh trong file format
  22. for (int index = 1; index < numberSprite; index++)
  23. {
  24. // Lấy sprite frame name
  25. sprintf(spriteFrameByName, "mysprite%d.png", index);
  26. // Tạo 1 khung, lấy ra từ bộ đệm SpriteFrameCache có tên là spriteFrameByName;
  27. auto frame = SpriteFrameCache::getInstance()->getSpriteFrameByName(str);
  28. // Push frame.
  29.   animFrames.pushBack(frame);
  30. }
  31. //*******************************************************
  32.  
  33. // Khởi tạo một khung hình animation từ Vector SpriteFrame.
  34. Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
  35. Animate* animate = Animate::create(animation);
  36. // Chạy Acction animation với số lần lặp vô hạn.
  37. gameSprite->runAction(RepeatForever::create(animate));

Tham khảo

http://www.cocos2d-x.org

Theo: Stdio