Você está na página 1de 33

Animation Trong Cocos2d-x 3.x.

Giới thiệu
Trong các bài viết Giới Thiệu Về Sprite Trong Cocos2d-x 3.x.x :: www.stdio.vn/articles/read/205-gioi-thieu-
ve-sprite-trong-cocos2d-x-3xx hay Acction Của Sprite Trong Cocos2d-x 3.x.x
:: www.stdio.vn/articles/read/208-action-cho-sprite-trong-cocos2d-x-3xx, 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ằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x
3.x.x :: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

Đố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 :: www.stdio.vn/articles/read/214-sprite-sheet-
trong-cocos2dx-3xx

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.
8. // 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.
9. auto gameSprite = Sprite::createWithSpriteFrameName("mysprite0.png");
10. // 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.
11. gameSprite->setPosition(300, 300);
12. //Thêm gameSprite vào Scene.
13. this->addChild(gameSprite);
14.
15. // Khai báo một mảng Vector kiểu SpriteFrame có tên là animFrames và có kích
thước là numberSprite.
16. Vector<SpriteFrame*> animFrames;
17. animFrames.reserve(numberSprite);
18.
19. //*******************************************************
20. // chuỗi trung gian để đọc tên ảnh trong file format
21. char spriteFrameByName[maxWord ] = { 0 };
22.
23. // Lặp để đọc numberSprite ảnh trong file format
24. for (int index = 1; index < numberSprite; index++)
25. {
26. // Lấy sprite frame name
27. sprintf(spriteFrameByName, "mysprite%d.png", index);
28.
29. // Tạo 1 khung, lấy ra từ bộ đệm SpriteFrameCache có tên là
spriteFrameByName;
30. auto frame = SpriteFrameCache::getInstance()-
>getSpriteFrameByName(spriteFrameByName);
31. // Push frame.
32. animFrames.pushBack(frame);
33. }
34. //*******************************************************
35.
36. // Khởi tạo một khung hình animation từ Vector SpriteFrame.
37. Animation* animation = Animation::createWithSpriteFrames(animFrames, 0.5f);
38. Animate* animate = Animate::create(animation);
39.
40. // Chạy Acction animation với số lần lặp vô hạn.
41. 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 trò chơi của bạn, giúp đẹp mắt hơn, tối ưu hơn,..
Giới Thiệu Về Scene Trong Cocos2d-x 3.x.x
Giới thiệu
Hãy tưởng tượng rằng game của bạn đang làm là một bộ phim, bạn đã có đầy đủ cốt truyện, cách bố trí,...
Công việc của bạn lúc này là cần phải quay cảnh phim và những cảnh phim này được tập hợp thành bộ phim
của bạn. Scene chính là những cảnh quay trong game. Trong bài viết này tôi và các bạn sẽ tìm hiểu về Scene
trong Cocos2d-x 3.4.

Tiền đề bài viết


Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x
3.x.x :: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

Đố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.

Scene là gì?
Scene là một cảnh game, nó chứa đựng những Sprites, Lables, Nodes và tất cả các đối tượng khác mà trò chơi
của bạn cần. Có trác nhiệm điều hành logic của trò chơi, Render lên Screen (Màn hình hiển thị) các nội dụng
cần thiết cho từng Scene mà bạn đã thiết kế. Bạn cần ít nhất một Scene để bắt đầu trò chơi của bạn. Một game
của bạn có thể có rất nhiều Scene, nhưng mà trong một thời điểm nhất định chỉ có một Scene được hoạt động.

Khởi tạo Scene


1. // www.stdio.vn
2. // Khởi tạo Screne có tên là gameScene.
3. Auto gameScene= Scene::create();

Ví dụ về Scene
Cocos2d-x sử dụng hệ tọa độ Oxy với gốc tọa độ O(0,0) nằm tại góc bên trái phía dưới Screen. Vì vậy, khi
thiết kế các thành phần của Scene bạn nên chú ý tới điều này để sao cho thiết lập vị trí của các các thành phần
trong game phù hợp.
Để thêm một Sprite, Lable, hay một đối tượng vào Screne bạn sử dụng phương thức addChild() API.

1. // www.stdio.vn
2. // www.stdio.vn/users/index/11/truong-dat
3. // Khởi tạo một Scene có tên là gameScene.
4. auto gameScene = Scene::create();
5.
6. // Lấy kích thước của màn hình.
7. // Với mỗi Platform thì sẽ có kích thước màn hình khác nhau, khi bạn trò chơi của
bạn được build
8. // qua nhiều nền tảng, bạn không thể áp dụng kích thước "cứng" của một số thiết bị
nào đó.
9. // Việc bạn lấy kích thước màn hình sẽ giúp bạn có thể thiết lập vị trí với các
flotform khác.
10. Size visibleSize = Director::getInstance()->getVisibleSize();
11.
12. // Khởi tạo Sprite.
13. // Sprite boar.
14. auto board = Sprite::create("spr_board.png");
15. board->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));
16. board->setScale(0.5);
17. gameScene->addChild(board, 1);
18.
19. // Sprite title zero
20. auto titleZero = Sprite::create("spr_title_zero.png");
21. titleZero->setPosition(Point(board->getPositionX(),
22. board->getPositionY() + board-
>getContentSize().height/8));
23. titleZero->setScale(0.5);
24. gameScene->addChild(titleZero , 1);
25.
26. // Menu.
27. // Menu item play button.
28. auto playButton = MenuItem::create("spr_btn_play.png", "spr_btn_play_press.png",
29. CC_CALLBACK_1(MenuGame::playGameCallback,
this)));
30. playButton->setPosition(Point(board->getPositionX(),
31. board->getPositionY() - board->getContentSize().height /
8));
32. playButton->setScale(0.5);
33.
34. // Menu item training.
35. auto trainingButton = MenuItem::create("spr_btn_training.png",
"spr_btn_training_press.png ",
36.
CC_CALLBACK_1(MenuGame::trainingGameCallback, this)));
37. trainingButton->setPosition(Point(board->getPositionX() + board-
>getContentSize().width / 8,
38. board->getPositionY() + board-
>getContentSize().height / 4));
39. trainingButton->setScale(0.5);
40.
41. // Menu item about.
42. auto aboutButton = MenuItem::create("spr_btn_about.png",
"spr_btn_about_press.png ",
43. CC_CALLBACK_1(MenuGame::aboutGameCallback,
this)));
44. aboutButton->setPosition(Point(board->getPositionX() + board-
>getContentSize().width / 8 + trainingButton->getContentSize().width/2,
45. board->getPositionY() + board->getContentSize().height
/ 4));
46. aboutButton->setScale(0.5);
47.
48. // Khởi tạo Menu.
49. auto menu = Menu::create(playButton, trainingButton, aboutButton, NULL);
50. // Thêm menu vào Scene hiện tại.
51. gameMenu->addChild(menu, 1);

Ở đoạn code trên tôi cố gắng hiện thực lại Scene Menu Game của game Zero.

Scene Graph
Là một cấu trúc dữ liệu để sắp xếp những đối tượng mà bạn cần trên Scene của bạn. Đây là một điều quan
trọng vì bạn cần phải chắc chắn rằng kết quả nhận được thỏa mãn với mục đích của bạn khi thiết kế game.

Đưới đây là Scene Graph của mục Ví dụ về Scene.

Một số cách chuyển đổi giữa các Scene


runWithScene
Được sử dụng cho Scene đầu tiên trong game của bạn.

1. // runWithScene.
2. Director::getInstance()->runWithScene(gameScene);

replaceScene
Đối với Scene còn lại (Ngoại trừ Scene đầu tiên ra) thì ta dùng phương thức replace để thay thế Scene mới
cho Scene hiện tại.
Khi bạn thay thế một scene bằng một Scene khác, các Scene mới được load vào bộ nhớ Ram trước khi Scene
cũ được giải phóng. Vì vậy, việc chuyển đổi giữa các Scene dễ bị crash liên quan tới việc không đủ bộ nhớ.
Bạn nên kiểm tra thường xuyên việc thay đổi giữa các Scene khi game cần nhiều bộ nhớ.

1. // replaceScene.
2. Director::getInstance()->replaceScene(gameScene);

pushScene và popScene
Scene cũ được thay bằng Scene mới mà không phải giải phóng Scene cũ ra khởi bộ nhớ.

Ưu điểm
Việc chuyển sang Scene mới sẽ nhanh hơn do không phải khởi tạo lại vùng nhớ cho Scene mới và giải phóng
vùng nhớ Scene cũ.

Nhược điểm
Chiếm một lượng lớn bộ nhớ Ram và có thể làm cho game của bạn bị crash. Bạn phải nhớ chính xác có bao
nhiêu Scene để việc pushSence và popScene sao cho phù hợp với mục đích của bạn.

Ta nên dùng PushScene và PopScene lúc nào?

Giả sử game của bạn hiện tại Scene đang chạy là Scene Play, bạn muốn game của bạn chuyển sangScene
Pause và không thay đổi đến trạng thái hiện tại của trò chơi. Lúc này bạn sẽ sử dụng pushScene để chuyển
sang Scene Pause và bạn dùng popScene để chuyển sang Scene Play. Một điều bạn phải luôn nhớ là phải đủ
bộ nhớ để cùng lúc chứa 2 Scene và tránh làm dụng sử dụng pushScene và popScene.

1. // pushScene.
2. Director::getInstance()->pushScene(gameScene);
3.
4. // popScene.
5. Director::getInstance()->popScene(gameScene);

Hiệu ứng chuyển Scene


Cocos2d-x còn cung cấp những hiệu ứng chuyển Scene. Điều này có thể giúp game của bạn đẹp hơn và bắt
mắt hơn. Nhưng bạn cũng cần chú ý, không nên làm dụng các hiệu ứng nhất là các hiệu ứng cần nhiều thời
gian vì rất dễ gây cho người chơi có cảm giác khó chịu.
1. // Khởi tạo một Scene có tên là gameScene.
2. auto gameScene = Scene::create();
3.
4. // Hiệu ứng chuyển Scene Transition Fade.
5. Director::getInstance()->replaceScene(TransitionFade::create(0.5, gameScene,
Color3B(0,255,255)));
6.
7. // Hiệu ứng chuyển Scene FlipX
8. Director::getInstance()->replaceScene(TransitionFlipX::create(2, gameScene));
9.
10. // Hiệu ứng chuyển Scene Transition Slide In
11. Director::getInstance()->replaceScene(TransitionSlideInT::create(1, gameScene)
);

Tổng kết
Trong bài viết này tôi đã giới thiệu các khái niệm, các thành phần và một số thao tác cơ bản với Scene trong
Cocos2d-x 3.x.x.
UI - Phần 1: Khái Niệm Và Một Số Đối Tượng
Để Thiết Kế UI Trong Cocos2d-x 3.x.x
Giới thiệu
UI không chỉ có phục vụ trong ngành công nghiệp game mà còn phục vụ cho rất nhiều ngành công nghiệp
khác. Một game có một UI và một ý tưởng tốt sẽ rất hấp dẫn người chơi. Trong bài này tôi và bạn sẽ tìm hiểu
về UI và một số đối tượng sử dụng để thiết kế UI trong Cocos2d-x 3.4

Tiền đề bài viết


Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x
3.x.x :: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

Đố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.

UI là gì?
Là viết tắt của User Interface (Giao diện người dùng). UI bao gồmm các mục
như Labels, Buttons,Menus, Sliders và Views, đây là những thứ có trên Screen(Màn hình hiển thị). Điều quan
trọng trong thiết kế UI là phải hiểu được yêu cầu của người dùng và nó đóng góp một phần quan trọng trong
việc thành công của game.

Thành phần UI
Bố cục
Quy định những đối tượng nào được hiển thị, được đặt ở vị trí nào?

Màu sắc
Phải thể hiện được thương hiệu game của bạn và tạo một sự thúc đẩy, khuyến khích cho người dùng.

Kiểu chữ và cỡ chữ


Một dòng chữ có kiểu chữ và cỡ chữ tốt khả năng hấp dẫn thị giác con người. Và đặc biệt chú ý, một dòng
chữ là một dòng mà người dùng có thể đọc được, tránh lạm dụng việc cách điệu và mục đích của dòng chữ đó
để sử dụng kiểu chữ và cỡ chữ cho phù hợp.

Đồ họa
Muốn hấp dẫn người chơi thì trước tiên bạn phải tạo cho họ một cảm giác tốt. Ý tưởng game tốt thêm đẹp mắt
chính là sức hấp dẫn không thể bỏ qua với những người chơi.

Thiết kế UI
Để mang lại cho người chơi một cảm giác tốt nhất, bạn cần phải hiểu sở thích của người chơi(đại đa số), thói
quen của họ. Các yếu tố để thiết kế một UI đẹp là: Tính đơn giản hóa, tính nhất quán.

Tính đơn giản hóa


Một UI tuyệt với là một UI có tính dễ sử dụng, đặc biệt là đối với những người mới.

Tính nhất quán


Nếu game của bạn có trên nhiều nền tảng di động khác nhau hay là câp nhật phiên bản mới, bạn nên chú ý về
tính nhất quán này. Ví dụ như button play, pause, exit game. Nó giúp người dùng tiếp cận nhanh hơn.

Một số đối tượng trong Cocos2d-x dùng để thiết kế UI


Label
Là đối tượng được sử đụng để tạo ra những dòng thông tin, văn bản.

Label BMF font


Là loại Label Bitmap Font, các kí tự trong một Bitmap Font được tạo từ một ma trận các dấu chấm và là
một Sprite.

Ưu điểm
Nhanh và dẽ sử dụng. Vì mỗi kí tự trong Label là một Sprite, có nghĩa rằng những kí từ này có thể
được Rotated, Scaled, Tinted.

Nhược điểm
Không thể mở rộng vì nó đòi hỏi một cỡ chữ riêng biệt cho từng kích thước kí tự.
Khởi tạo
Để tạo một Label BMFont bạn cần hai phần. file có định dạng .fnt và một đại diện hình ảnh của mỗi kí tự
trong định dạng .png

1. // www.stdio.vn
2. // Label BMFont
3. auto gameLabel = Label::createWithBMFont("bitmap.fnt", "LabelBMFont");

Label TTF
Là loại Label True Type Font.

Ưu điểm
Không cần phải một file font riêng biệt cho mỗi kích thước và màu sắc, vì vậy việc tạo ra một Label với một
cỡ chữ đúng múc đích của bạn rất dễ dàng.

Nhược điểm
Tuy nó linh hoạt hơn một Font Bitmap nhưng việc Render lên Screen sẽ chậm hơn và việc thay đổi các thuộc
tính của kí tự như kích thước là một việc tốn thời gian xử lý.

Khởi tạo
Để tạo một Label TTF bạn cần tên file Font TrueType, chuỗi văn bản và kích thước của văn bản đó.

1. // www.stdio.vn
2. // Label TTF
3. auto gameLabel = Label::create("LabelTTF", "arial.ttf", 24);

TTF Config
Nếu trong game của bạn sử dụng nhiều Label có cùng một kích cỡ, kiểu chữ thì bạn có thể tạo ra
mộtTTFConfig để quản lý chúng dễ dàng hơn. Một đối tượng TTFConfig cho phép bạn thiết lập các thuộc
tính của Label.

1. // www.stdio.vn
2. // www.stdio.vn/users/index/11/truong-dat
3. // Khởi tọa một Label TTFConfig có tên là labelConfig.
4. TTFConfig labelConfig;
5.
6. // Thiết lập các thuộc tính cho labelConfig.
7. // Kiểu chữ.
8. labelConfig.fontFilePath = "arial.ttf";
9.
10. // Kích cỡ chữ.
11. labelConfig.fontSize = 30;
12.
13. // Một số thuộc tính khác của Label.
14. labelConfig.glyphs = GlyphCollection::DYNAMIC;
15. labelConfig.outlineSize = 0;
16. labelConfig.customGlyphs = nullptr;
17. labelConfig.distanceFieldEnabled = false;
18.
19. // Khởi tạo một Label có tên là gameLabel và sử dụng TTFConfig.
20. auto gameLabel = Label::createWithTTF(labelConfig, "LabelTTF from TTFConfig");

Label SystemFont
Là loại Label giống Label TTF nhưng bạn không thể thay đổi thuộc tính của nó. Nếu bạn cần một Label
nhưng một hệ thống hay quy tắc, hãy sử dụng nó.

1. // Label SystemFont
2. auto gameLabel = Label::createWithSystemFont("Label using SystemFont",
"arial.ttf", 24);

Label Effect
Bạn có thể tạo một số hiệu ứng cho Label của bạn nhằm cho nó thêm đẹp mắt. Không phải tất cả các font chữ
đều hỗ trơ hiệu ứng. Một số loại hiệu ứng như shadow, outline, glow. Bạn có thể sử dụng nhiều hiệu ứng cho
một Label.

Hiệu ứng shadow

1. // Khởi tạo một Label TTF có tên là gameLabel.


2. auto gameLabel = Label::create("LabelTTF with Shadow", "arial.ttf", 24);
3.
4. // Hiệu ứng shadow.
5. gameLabel->enableShadow();

Hiệu ứng outline


1. // Khởi tạo một Label TFF có tên là gameLabel.
2. auto gameLabel = Label::create("LabelTTF with Outline", "arial.ttf", 24);
3.
4. // Hiệu ứng outline
5. gameLabel->enableOutline(Color4B::WHITE, 1));

Hiệu ứng glow

1. // Khởi tạo một Label TFF có tên là gameLabel.


2. auto gameLabel = Label::create("LabelTTF with Glow", "arial.ttf", 24);
3.
4. // Hiệu ứng glow.
5. gameLabel->enableGlow(Color4B::YELLOW);

Kết quả

Tổng kết
UI là một thành phần quan trọng, không chỉ đặc biệt trong ngành công nghiệp games mà còn nhiều trong các
ngành khác. Trong phần tiếp theo, tôi sẽ giới thiệu các khái niệm, thành phần còn lại trong thiết kế UI UI -
Phần 2: Thiết Kế UI Trong Cocos2d-x 3.x.x
UI - Phần 2: Thiết Kế UI Trong Cocos2d-x 3.x.x
Giới thiệu
Ở bài viết UI Phần I: Khái Niệm Và Một Số Đối Tượng Để Thiết Kế UI Trong Cocos2d-x
3.x.x :: www.stdio.vn/articles/read/211-ui-phan-1-khai-niem-va-mot-so-doi-tuong-de-thiet-ke-ui-trong-
cocos2d-x-3xx, tôi đã giới thiệu cho các bạn UI là gì? Các thành phần của UI,… và đối tượng Label dùng
trong thiết kế UI trong Cocos2d-x. Trong bài viết này, tôi sẽ giới thiệu thêm về một số đối tượng khác dùng
thể thiết kế UI trong Cocos2d-x.

Tiền đề bài viết


Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x
3.x.x:: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

Đố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.

Menu Items và Menu


Trong một game thông thường, bạn sẽ thấy các mục như play, pause, about, ... Các mục này sẽ được gọi
là Menu Item. Một Menu được tạo từ một hay nhiều Menu Items. Có tác dụng điều hướng game của bạn
thông qua các tùy chọn của người chơi.

Khởi tạo Menu Item


Tạo một Menu Item sử dụng hình ảnh.

1. // Menu Item sử dụng hình ảnh.


2. // Khởi tạo Menu Item có tên là closeItem.
3. auto closeItem = MenuItemImage::create("CloseNormal.png", "CloseSelected.png",
4. CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
5.
6. // Thiết lập vị trí của closeItem tại vị trí (100, 100).
7. closeItem->setPosition(Vec2(100, 100));

Menu Item có hai trạng thái normal và selected.

1. normal trạng thái của Menu Item khi chưa có thao tác của người chơi lên Menu Item này. Ở đoạn code
trên closeItem ở trạng thái normal sử dụng hình ảnh CloseNormail.png.
2. selectedtrạng thái khi có các thao tác từ người chơi như tourch, mouse click. Khi người chơi hoàn
thành thao tác thì Menu Item sẽ thực hiện một đoạn code. Ở đoạn code trên closeItem ở trạng thái
selected sử dụng hình ảnh CloseSelcted.png.

1. // Nhiệm vụ của đoạn code này là kết thúc trò chơi của bạn. Bạn có thể sử dụng nó
với Menu Item exit.
2. void HelloWorld::menuCloseCallback(Ref* pSender)
3. {
4. #if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8) || (CC_TARGET_PLATFORM ==
CC_PLATFORM_WINRT)
5. return;
6. #endif
7.
8. Director::getInstance()->end();
9.
10. #if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
11. exit(0);
12. #endif
13. }

Bạn có thể tạo một Menu Item sử dụng văn bản. Khi ở trạng thái normal, Menu Item sẽ có cỡ chữ bằng với
lúc thiết lập, trạng thái selected cỡ chữ sẽ to hơn so với trạng thái normal.

1. // Menu Item sử dụng văn bản.


2. // Khởi tạo một Label có tên là myLabel.
3. auto myLabel = Label::create("Close Item", "Arial", 24);
4.
5. // Khởi tạo Menu Item có tên là closeItem.
6. auto closeItemLabel = MenuItemLabel::create(myLael,
CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
7.
8. // Thiết lập vị trí của closeItem tại vị trí (100, 150).
9. closeItemLabel->setPosition(Vec2(100, 150));

Khởi tạo Menu


Bạn có thể khởi tạo một Menu dễ dàng như sau:

1. // Khởi tạo Menu có tên là menu.


2. auto menu = Menu::create(closeItem, closeItemLabel, NULL);
3. // Thêm menu vào Scene hiện tại.
4. this->addChild(menu, 1);

hoặc

1. // Khởi tạo một mảng Vector kiểu MenuItemLabel.


2. Vector<MenuItem*> menuItems;
3.
4. // Thêm Menu Item closeItem vào menuItems.
5. menuItems.pushBack(closeItem);
6. menuItems.pushBack(clostItemLabel);
7.
8. // Tạo một Menu có tên là menu với mảng Vector menuItems.
9. auto menu = Menu::createWithArray(menuItems);
10. // Thêm vào Scence hiện tại của bạn.
11. this->addChild(menu, 1);

Chú ý: Menu Item không thể được thêm vào Scene hiện tại của bạn, bạn phải thêm Menu Item mà bạn muốn
sử dụng vào Menu, sau đó bạn thêm Menu vào Scene hiện tại của bạn.
Button
Là một đối tượng rất hay được sử dụng trong game. Khi người chơi chọn vào nó thì một điều gì đó xảy ra
trong trò chơi của bạn như chuyển Scene hay thêm một Sprite,... Button có hai trạng thái là normal và
selected.

1. #include "ui/CocosGUI.h"
2.
3. auto button = Button::create("normal.png", "selected.png", "disabled.png");
4.
5. button->setTitleText("Button Text");
6.
7. button->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type)
8. {
9. switch (type)
10. {
11. case ui::Widget::TouchEventType::BEGAN:
12. break;
13. case ui::Widget::TouchEventType::ENDED:
14. std::cout << "Button 1 clicked" << std::endl;
15. break;
16. default:
17. break;
18. }
19. });
20.
21. this->addChild(button);

Phân tích
 Dòng 1: Trong Cocos2d-x 3.4, khi bạn muốn sử dụng các đối tượng để thiết kế UI(ngoại trừ Label)
bạn phải including ui/CocosGUI.h.
 Dòng 3: Khởi tạo Button có tên là button.
 Dòng 5: Đặt giá trị Title cho button.
 Dòng 7 - 17: Xử lý sự kiện của người chơi(Ở đây là EventTouch) lên button. Chúng ta sẽ tìm hiểu rõ
hơn trong bài viết Giới Thiệu Event Trong Cocos2d-x 3.x.x.
 Dòng 19: Thêm button vào Scene hiện tại của bạn.

Ở một phần nào đó, Button có nhiều điểm giống với Menu Item, nhưng khác biệt ở chỗ là bạn có thể thêm
trực tiếp Button vào Scene hiện tại không như Menu Item được thêm gián tiếp qua Menu chứa nó.

Như bạn đã thấy ở ví dụ trên. Button được tạo thành từ ba tấm hình đồ họa trông như ở dưới và có tên lần lượt
là: normal.png, selected.png, disable.png.
Trên Screen Button button sẽ được thấy như sau.

Checkbox
Nếu bạn muốn người lựa chọn một tùy chọn gì đó chỉ có hai phương án là có hoặc không? CheckBox sẽ giúp
bạn giải quyết vấn đề này. CheckBox có thể có các trạng thái normal, selected và disabled.

1. // Thêm thư viện CocosGUI.h.


2. #include "ui/CocosGUI.h"
3.
4. // Khởi tạo một CheckBox có tên là checkbox.
5. auto checkbox = CheckBox::create("checkbox_normal.png",
6. "checkbox_normal_press.png",
7. "checkbox_active.png",
8. "checkbox_normal_disable.png",
9. "checkbox_active_disable.png");
10.
11. // Thiết lập sự kiện từ người chơi với checkbok.
12. checkbox->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type)
13. {
14. switch (type)
15. {
16. case ui::Widget::TouchEventType::BEGAN:
17. break;
18. case ui::Widget::TouchEventType::ENDED:
19. std::cout << "checkbox 1 clicked" << std::endl;
20. break;
21. default:
22. break;
23. }
24. });
25.
26. // Thêm checkbox vào Scene hiện tại của bạn.
27. this->addChild(checkbox);
Ở ví dụ trên. CheckBox checkbox được tạo thành từ ba tấm hình đồ họa trông như ở dưới và có tên lần lượt
là: checkbox_normal.png, checkbox_normal_press.png, checkbox_active.png, checkbox_normal_display,
checkbox_active_display.

Trên Screen Checkbox checkbox sẽ được thấy như sau.

LoadingBar
Trong trò chơi của bạn, nếu bạn muốn tải lên một số file audio lên trước, trong quá trình chờ đợi đó bạn có thể
thiết lập một LoadingBar để nhằm thể hiện mức độ hoàn thành việc tải lên đó.

1. // Thêm thư viện CocosGUI.h


2. #include "ui/CocosGUI.h"
3.
4. // Khởi tạo một LoadingBar có tên là loadingBar. loadingBar sử dụng hình ảnh
loadingBar.png
5. auto loadingBar = LoadingBar::create("loadingBar.png");
6. // Thiết lập hướng của tiến trình. Ở đay là từ phải qua trái.
7. loadingBar->setDirection(LoadingBar::Direction::RIGHT);
8.
9. // Đặt mức độ hoàn thành loadingBar ở mức 25/100
10. loadingBar->setPercent(25);
11.
12. // Đặt mức độ hoàn thành loadingBar ở mức 35/100
13. loadingBar->setPercent(35);
14.
15. // Thêm LoadingBar vào Sence hiện tại của bạn.
16. this->addChild(loadingBar);

Loading bar đạt mức hoàn thành 100/100, 60/100 và 80/100.


Slider
Thiết lập giá giá trị bằng cách di chuyển một chỉ số như volume của background music hay độ khó của
game,...

1. // Thêm thư viện CocosGUI.h


2. #include "ui/CocosGUI.h"
3.
4. // Khởi tạo một Slider có tên là slider.
5. auto slider = Slider::create();
6.
7. //
8. slider->loadBarTexture("Slider_Back.png");
9. slider->loadSlidBallTextures("SliderNode_Normal.png", "SliderNode_Press.png",
"SliderNode_Disable.png");
10. slider->loadProgressBarTexture("Slider_PressBar.png");
11.
12. // Thiết lập sự kiện từ người chơi với slider.
13. slider->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type)
14. {
15. switch (type)
16. {
17. case ui::Widget::TouchEventType::BEGAN:
18.
19. std::cout << "slider moved" << std::endl;
20. break;
21. default:
22. break;
23. }
24. });
25.
26. // Thêm slider vào Scene hiện tại của bạn.
27. this->addChild(slider);

TextField
Trong trò chơi của bạn, bạn muốn một nơi dùng để lưu trữ các điểm số cao nhất, bạn sẽ cần phải thiết lập một
nơi dùng để người chơi gõ vào để thể hiện số điểm đó là của ai. TextField sẽ giúp bạn làm điều này.

1. // Thêm thư viện CocosGUI.h


2. #include "ui/CocosGUI.h"
3.
4. // Khởi tạo một TextField có tên là textField với font chữ Arial và kích cỡ chữ là
30.
5. auto textField = TextField::create("","Arial",30);
6.
7. textField->setPasswordEnabled(true);
8.
9. // Thiết lập số người ký tự tối đo cho người chơi có thể nhạp vào cho TextField
10. //textField->setMaxLength(10);
11.
12. // Thiết lập sự kiện của người chơi với textField.
13. textField->addTouchEventListener([&](Ref* sender, Widget::TouchEventType type)
14. {
15. std::cout << "editing a TextField" << std::endl;
16. });
17.
18. // Thêm testField vào Scene hiện tại của bạn.
19. this->addChild(textField);

Chú ý
Button, check box, loading bar, slider, text field. Tất cả các đối tượng dùng để thiết kế UI đều nằm
trong namespace cocos2d::ui. Vậy nên khi bạn muốn sử dụng chúng bạn cần khai báo.

1. //
2. using namespace cocos2d::ui;

Tổng kết
Với phần 2, tôi đã hoàn thành giới thiệu các thành phần cơ bản để thiết kế UI trong Cocos2d-x 3.x.x.
Xử Lý Sự Kiện Trong Cocos2d-x 3.x.x
Giới thiệu
Một game hoàn chỉnh không thể thiếu sự tương tác của người chơi. Trong cocos2d-x có những cơ chế gì,
những hỗ trợ gì đễ giúp cho người chơi có thể tương tác, thao tác. Bài viết này tôi và các bạn sẽ cùng tìm hiểu
về xử lý sự kiện trong Cocos2d-x.

Tiền đề bài viết


Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x 3.x.x
:: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn
:: www.stdio.vn nhằm tìm hiểu những vẫn để cơ bản về xử lý sự kiện trong game với Cocos2d-x
3.x.x.

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


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

Cơ chế Event Dispactch là gì?


Là một cơ chế được Cocos2d-x xây dựng dùng để trả lời các sự kiện của người dùng.

Nhiệm vụ cơ bản của cơ chế Event Dispacth.

 Event listen: Nhận hay lắng nghe sự kiện của người chơi và đóng gói sự kiện đó thành một mã.
 Event dispacth: Thông báo về loại sự kiện của người dùng là loại sự kiện nào.
 Event object: Những đối tượng nào trong game có chứa thông tin về sự kiện này.

Để trả lời lại các sự kiện của người chơi, trước tiên bạn phải tạo ra một Event Listener. Có năm loại Event
Listener trong Cocos2d-x.

 EventListenTouch: Phản ứng với các sự kiện chạm cảm ứng.


 EventListenKeyboard: Phản ứng với các sự kiện bàn phím
 EventListenAcceleration: Phản ứng với các gia tốc sự kiện.
 EventListenMouse: Phản ứng với các sự kiện từ con chuột.
 EventListenCustom: Phản ứng với các sự kiện tùy chỉnh.

Touch Event
Touch Event là sự kiện quan trọng nhất trong game di động, nó dễ tạo ra và cung cấp nhiều chức năng. Khi
bạn chạm vào một màn hình(Cảm ứng) của một điện thoại di động, lúc này điện thoại sẽ nhận sự kiện này và
xử lý nó. Có thể thao tác của bạn sẽ được trả lời hay không được đáp ứng nhưng ở bên dưới vẫn có một cái gì
đó xảy ra.

Dưới đây là cách mà bạn tạo ra một Touch Event đơn giản.
1. // Khởi tạo một Touch event
2. // Xử lý Touch event của người chơi tại một điểm
3. auto listener = EventListenerTouchOneByOne::create();
4.
5. // Khi bạn nhấn xuống.
6. listener->onTouchBegan = [](Touch* touch, Event* event){
7. // Nơi chưa đoạn code của bạn.
8. return true;
9. };
10.
11. // Khi bạn vừa nhấn xuống và di chuyển.
12. listener->onTouchMoved = [](Touch* touch, Event* event){
13. // Nơi chứa đoạn code của bạn.
14. };
15.
16. // Khi bạn thả ra.
17. listener->onTouchEnded = [=](Touch* touch, Event* event){
18. // Nơi chứa đoạn code của bạn.
19. };
20.
21. // Thêm Touch Event vào cơ chế Event Dispatch.
22. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);

Như bạn thấy ở trên có tới 3 sự kiện. Mỗi sự kiện trên có một khoảng thời gian riêng biệt.

 onTouchBegin sự kiện được kích hoạt khi bạn nhấn xuống.


 onTouchMoved sự kiện được kích hoạt nếu bạn di chuyển các đối tượng và vẫn nhấn xuống.
 onTouchEnded sự kiện được kích hoạt khi bạn thả tay ra khỏi màn hình cảm ứng.

Keyboar Event
Với các game trên desktop, bạn có thể muốn sử dụng bàn phím cơ học để thao tác với trò chơi của bạn.

1. // Khởi tạo một keyboar event.


2. auto listener = EventListenerKeyboard::create();
3. listener->onKeyPressed = CC_CALLBACK_2(KeyboardTest::onKeyPressed, this);
4. listener->onKeyReleased = CC_CALLBACK_2(KeyboardTest::onKeyReleased, this);
5.
6. // Thêm keyboar event vào cơ chế event dispatcher.
7. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
8.
9. // Thực hiện các chức năng của keyboar event thông qua gọi hàm nguyên mẫu.
10. void KeyboardTest::onKeyPressed(EventKeyboard::KeyCode keyCode, Event* event)
11. {
12. // Nơi chứa đoạn code của bạn.
13. }
14.
15. void KeyboardTest::onKeyReleased(EventKeyboard::KeyCode keyCode, Event* event)
16. {
17. // Nơi chứa đoạn code của bạn.
18. }

Hàm CC_CALLBACK_2 có chức năng gọi một hàm có hai tham số. Tương
tự CC_CALLBACK_0 vàCC_CALLBACK_1 là gọi một hàm không có tham số và gọi một hàm có một tham
số.

Acceleromenter Event
Một vài thiết bị được trang bị với một gia tốc. Một gia tốc là một cảm biến do g-force để xác định sự thay
đổi hướng hay cân bằng của thiết bị. Acceleromenter event xảy ra khi người chơi di chuyển điện thoại của
bạn, hay làm cho điện thoại mất cân bằng. Một số game đua xe trên điện thoại di động hiện nay hay sử dụng
loại sự kiện này để tạo một cảm giác giống như thật.

1. // Kích hoạt accelerometer trên thiết bị.


2. Device::setAccelerometerEnabled(true);

Trước khi sử dụng Acceleromenter Event, bạn cần phải kích hoạt nó trên các thiết bị.

1. // Khởi tạo một accelerometer event.


2. auto listener = EventListenerAcceleration::create(CC_CALLBACK_2(
3. AccelerometerTest::onAcceleratio
n, this));
4.
5. // Thêm acceleromenter event vào cơ chế event dispatcher.
6. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, this);
7.
8. // Thực hiện các chức năng của accelermonter thông qua gọi các hàm nguyên mẫu.
9. void AccelerometerTest::onAcceleration(Acceleration* acc, Event* event)
10. {
11. // Đoạn code của bạn được chứa ở đây.
12. }

Mouse Event
Là thao tác của người chơi khi sử dụng mouse(chuột).

1. // Khởi tạo một mouse event.


2. auto mouseListener = EventListenerMouse::create();
3.
4. // Một số loại mouse event.
5. mouseListener->onMouseMove = CC_CALLBACK_1(MouseTest::onMouseMove, this);
6. mouseListener->onMouseUp = CC_CALLBACK_1(MouseTest::onMouseUp, this);
7. mouseListener->onMouseDown = CC_CALLBACK_1(MouseTest::onMouseDown, this);
8. mouseListener->onMouseScroll = CC_CALLBACK_1(MouseTest::onMouseScroll, this);
9.
10. // Thêm mouse event vào cơ chế event dispatcher.
11. _eventDispatcher->addEventListenerWithSceneGraphPriority(_mouseListener, this);
12.
13. // Thực hiện các chức năng của mouse envent bằng cách gọi hàm nguyên mẫu.
14. void MouseTest::onMouseDown(Event *event)
15. {}
16.
17. void MouseTest::onMouseUp(Event *event)
18. {}
19.
20. void MouseTest::onMouseMove(Event *event)
21. {}
22.
23. void MouseTest::onMouseScroll(Event *event)
24. {}

Thiết lập Event cho đối tượng vào Event Dispatcher


Việc bạn thiết lập một sự kiện cho một đối tượng vào Event Dispatcher trong Cocos2d-x rất dễ dàng.
1. // Thêm một sự kiện cho một đối tượng sprite vào event dispatcher.
2. eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite);

Một sự kiện chỉ có thể đăng ký một lần cho một đối tượng. Vậy nếu bạn cần thiết lập một sự kiện cho nhiều
đối tượng thì sao? Bạn hãy sử dụng clone() .

1. // Một sự kiện cho một đối tượng sprite vào event dispatcher.
2. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener, sprite1);
3.
4. // Thêm vào cũng sự kiện đó nhưng cho đối tượng sprite2 vào event dispatcher.
5. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(),
sprite2);
6.
7. // Thêm tiếp cũng sự kiện đó nhưng là cho đối tượng sprite3 vào event dispatcher.
8. _eventDispatcher->addEventListenerWithSceneGraphPriority(listener->clone(),
sprite3);

Xóa bỏ Event trong cơ chế Event Dispatcher


Bạn có thể xóa bỏ một Listener Event bằng cách sau:

1. // Xóa một listener event.


2. _eventDispatcher->removeEventListener(listener);

Bạn cũng có thể xỏa bỏ hết toàn bộ Listener Event trong cơ chế Event Dispatcher.

1. // Xóa bỏ toàn bộ các listener event trong cơ chế Event Dispatcher.


2. _eventDispatcher->removeAllEventListeners();

Chú ý: Với một đối tượng Menu, khi bạn xóa bỏ toàn bộ cácListener Event thì Menu cũng không thể hoạt
động. Ví dụ như trên thiết bị di động cảm ứng Menu cần Touch Event để người chơi thao tác với Menu đó.

Tổng kết
Trong bài viết này, tôi đã giới thiệu về xử lý sự kiện trong Cocos2d-x 3.x.x.
Lập Trình Hiệu Ứng Trong Cocos2d-x 3.x.x
Giới thiệu
Nếu trong trò chơi của bạn cần hiệu ứng đốt lửa, hay các vụ nổ,...Làm thế nào để có những hiệu ứng phức tạp
như vậy. Việc bạn thiết kế Animation có thể làm được điều này nhưng để mô phỏng nó chi tiết thì rất cần
nhiều Sprite. Đừng lo lắng về vấn đề này, trong Cocosd-x bạn có thể thậm chí là hiện thực được những hiệu
ứng đó rất đẹp. Trong bài viết này tôi và các bạn sẽ cùng tìm hiểu về lập trình hiệu ứng trong Cocos2d-x.

Tiền đề bài viết


Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x 3.x.x
:: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

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


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

Particle System
Để tạo ra một hiệu ứng như đốt lửa hay đốt lửa,...bạn cần sử dụng một Particle System(Hệ thống hạt). Các hệ
thông hạt này là một kỹ thuật trong đồ họa máy tính và vật lý trò chơi sử dụng một số lượng lớn các Sprites
rất nhỏ hoặc các đối tượng đồ họa khác để mô phỏng một số loại hiện tượng fuzzy. Vì các hiệu ứng như đốt
lửa hay nổ là một hệ thống rất hỗn loạn nên bạn phải cần những hạt nhỏ sẽ dễ dàng mô phỏng được nó.

Thuộc tính của Particle System


Dưới đây là một số thuộc tính của các particle, với một số thuộc tính sau bạn có thể tự hiện thực cho bạn một
hiệu ứng đơn giản nào đó.

 Energy: Khoảng thời gian các hạt tồn tại trong game cho đến khi nó biến mất.
 Looping: Số lượng các hạt sẽ được khởi tạo lại khi hạt cuối cùng biến mất.
 Speed, direction, rotation: Mỗi hạt đều có hướng di chuyển khác nhau, tùy theo điều chỉnh tốc độ,
hướng di chuyển hay góc độ quay của từng hạt.
 Constant: Các hạt đều mang các thông số tùy chỉnh giống nhau.
 Curve: Các thông số của các hạt sẽ thay đổi dựa theo độ lồi lõm của đồ thị. Ví dụ các hạt ban đầu từ từ
to hơn theo thời gian hoặc ngược lại).

Chú ý: Mỗi hiệu ứng đều có một đồ thị tổng quát của nó, các hạt sẽ di chuyển tương đối theo đồ thị này. Ví dụ
như hiệu ứng "vòi nước" được tạo bởi nhiều đồ thị Parabol.

Một số công cụ để tạo hiệu ứng hạt


Việc bạn có thể tạo ra một hiệu ứng sử dụng Particle System bằng định nghĩa của chính bạn, thiết kế theo ý
thích của bạn nhưng đây là việc làm rất tốn thời gian, có thể kết quả lại không được như ý. Những có một số
tools giúp bạn có thể tạo ra hiệu ứng.
 Particle Disigner: Một ứng dụng tạo Particle Effect rất mạnh trên Mac.
 V-play particle editor: Một cross-flatform thiết kệ Particle Effect cho Cocos2d-x.
 Particle2dx: Một công cụ thiết kế Particle Effect online.

Những công cụ này tạo ra một file có định dạng .plist và cocos2d-x có thể đọc được chúng để có thể tạo ra
hiệu ứng trong game của bạn.

Khởi tạo Particle System


Trong cocos2d-x, việc bạn sử dụng một hiệu ứng từ file format .plist là chuyện dễ dàng.

1. // Khởi tạo một Particle System có tên là particleSystem.


2. auto particleSystem = ParticleSystem::create("SpinningPeas.plist");

Một số Particle System trong Cocos2d-x


Có thể bạn chưa sẵn sàng với việc tự tạo ra một hiệu ứng cho game của bạn. Vì vậy bạn có thể sử dụng những
hiệu ứng được thiết kế sẵn trong cocos2d-x để sử dụng. Dưới đây là một số hiệu ứng có sẵn.

 ParticleFire
 ParticleFireworks
 ParticleSun
 ParticleGalaxy
 ParticleFlower
 ParticleMeteor
 ParticleSpiral
 ParticleExplosion
 ParticleSmoke
 ParticleSnow
 ParticleRain

Ví dụ sử dụng PraticleFireWorks trong cocos2d-x


Khởi tạo hiệu ứng ParticleFireWorks.

1. // www.stdio.vn
2. // Khởi tạo.
3. auto emitter = ParticleFireworks::create();
4. // Thêm vào Scene hiện tại.
5. addChild(emitter, 10);

Bạn có thể thao tác các hiệu ứng có sẵn trong cocos2d-x. Dưới đây là một số thao tác với nó.

1. // www.stdio.vn
2. auto emitter = ParticleFireworks::create();
3.
4. // Thiết lập thời gian
5. emitter->setDuration(ParticleSystem::DURATION_INFINITY);
6.
7. // Chế độ bán kính.
8. emitter->setEmitterMode(ParticleSystem::Mode::RADIUS);
9.
10. // Chế độ bán kính: 100 pixels từ trung thâm.
11. emitter->setStartRadius(100);
12. emitter->setStartRadiusVar(0);
13. emitter->setEndRadius(ParticleSystem::START_RADIUS_EQUAL_TO_END_RADIUS);
14. emitter->setEndRadiusVar(0);
15.
16. // Thêm vào Scene hiện tại.
17. addChild(emitter, 10);

Tổng kết
Trong bài viết này, tôi đã giới thiệu về khái niệm lâp trình hiệu ứng trong Cocos2d-x 3.x.x.
Tạo Hiệu Ứng Parallax Scrolling Trong
Cocos2d-x 3.x
Giới thiệu
Parallax Scrolling là một trong số những hiệu ứng được sử dụng rộng rãi trong những năm gần đây, làm tăng
thêm sự sinh động và chiều sâu trong game. Trong bài viết này tôi sẽ hướng dẫn các bạn cách tạo ra hiệu ứng
này.

Tiền đề bài viết


Trong quá trình học tập và làm việc, tôi luôn muốn chia sẻ đến các bạn những kiến thức mà tôi tích lũy được
dù là nhỏ nhất. Bài viết này là một trong số đó.

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


Dành cho các đối tượng đang trong quá trình học tập và bắt đầu tìm hiểu về Cocos2d-x.

Parallax Scrolling
Parallax Scrolling là hiện tượng được tạo ra bởi mắt của người nhìn so với các vất thể xa, gần khác nhau. Vật
nào ở càng xa (so với mắt) thì góc nhìn càng nhỏ, vật nào ở gần thì góc nhìn càng rộng. Khi hai vật di chuyển
cùng vật tốc thì vật ở xa (có vẻ) di chuyển chậm hơn vật ở gần.

Trong cuộc sống hằng ngày, Parallax Ccrolling rất hay được bắt gặp. Ví dụ khi bạn đang đi xe trên đường,
nếu quan sát bạn sẽ dễ dàng thấy rằng các cột điện trên đường di chuyển rất nhanh so với ngọn núi ở xa hơn,
và ngọn núi sẽ di chuyển nhanh hơn mặt trời. Hay khi bạn đứng nhìn 2 tòa nhà (kích thước ngang nhau) trước
mắt, thì tòa nhà ở xa nhìn sẽ nhỏ hơn tòa nhà ở gần.

Hiệu ứng Parallax Scrolling được dùng trong game 2D nhằm tạo chiều sâu cho game.

Hiện thực
Ảnh minh họa:
Tạo class InfiniteParallaxNode
Hiện thực file file InfiniteParallaxNode.h

1. class InfiniteParallaxNode :public ParallaxNode


2. {
3. public:
4. static InfiniteParallaxNode* create();
5. void updatePosition();
6. };

Hiện thực file file InfiniteParallaxNode.cpp


Method create

1. InfiniteParallaxNode* InfiniteParallaxNode::create()
2. {
3. InfiniteParallaxNode* node = new InfiniteParallaxNode();
4. if (node)
5. {
6. node->autorelease();
7. }
8. else
9. {
10. delete node;
11. node = 0;
12. }
13. return node;
14. }

Method updatePossition

1. void InfiniteParallaxNode::updatePosition()
2. {
3. int safeOffset = -10;
4.
5. Size visibleSize = Director::getInstance()->getVisibleSize();
6.
7. for (int i = 0; i < _children.size(); i++)
8. {
9. auto node = _children.at(i);
10. if (convertToWorldSpace(node->getPosition()).x +
11. node->getContentSize().width < safeOffset)
12. {
13. for (int j = 0; j < _parallaxArray->num; j++)
14. {
15. auto po = (PointObject*)_parallaxArray->arr[j];
16. if (po->getChild() == node)
17. po->setOffset(po->getOffset() +
18. Point(visibleSize.width + node->getContentSize().width, 0));
19. }
20. }
21. }

Ở đầu file khởi tạo thêm một class PointObject như sau:

1. class PointObject : public Ref


2. {
3. public:
4. inline void setRation(Point ratio) { _ratio = ratio; }
5. inline void setOffset(Point offset) { _offset = offset; }
6. inline void setChild(Node *var) { _child = var; }
7. inline Point getOffset() const { return _offset; }
8. inline Node* getChild() const { return _child; }
9. private:
10. Point _ratio;
11. Point _offset;
12. Node* _child;
13. };

Cách dùng
Khai báo và khởi tạo biến

1. InfiniteParallaxNode* backgroundElements;
2. backgroundElements = InfiniteParallaxNode::create();

Thêm các đối tượng vào

1. // add rock
2. unsigned int rocksQuantity = 7;
3. for (unsigned int i = 0; i < rocksQuantity; i++)
4. {
5. auto rock = Sprite::create("rock.png");
6. rock->setAnchorPoint(Point::ZERO);
7. rock->setScale(randomValueBetween(0.6, 0.75));
8. backgroundElements->addChild(rock,
9. randomValueBetween(-10, -6),
10. Point(0.05, 1),
11. Point((visibleSize.width / 5) * (i + 1) + randomValueBetween(0, 100),
12. ground->getContentSize().height - 5));
13. }
14.
15. // add tree
16. unsigned int treesQuantity = 35;
17. for (unsigned int i = 0; i < treesQuantity; i++)
18. {
19. auto tree = Sprite::create("tree.png");
20. tree->setAnchorPoint(Point::ZERO);
21. tree->setScale(randomValueBetween(0.5, 0.75));
22. backgroundElements->addChild(
23. tree,
24. randomValueBetween(-5, -1),
25. Point(0.5, 1),
26. Point(visibleSize.width / (treesQuantity - 5) * (i + 1) +
randomValueBetween(25, 50),
27. ground->getContentSize().height - 8));
28. }

Thêm parallax vào và update scene

1. addChild(backgroundElements, 2);
2. schedule(schedule_selector(HelloWorld::update), 0.01);

Você também pode gostar