Escolar Documentos
Profissional Documentos
Cultura Documentos
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.
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ế.
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
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.
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.
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.
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.
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.
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.
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);
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
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.
Đồ 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.
Ư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.
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.
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.
hoặc
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.
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 đó.
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.
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.
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.
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.
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.
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.
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ị.
Mouse Event
Là thao tác của người chơi khi sử dụng mouse(chuột).
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);
Bạn cũng có thể xỏa bỏ hết toàn bộ Listener Event trong cơ chế Event Dispatcher.
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.
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ó.
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.
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.
ParticleFire
ParticleFireworks
ParticleSun
ParticleGalaxy
ParticleFlower
ParticleMeteor
ParticleSpiral
ParticleExplosion
ParticleSmoke
ParticleSnow
ParticleRain
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.
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. 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:
Cách dùng
Khai báo và khởi tạo biến
1. InfiniteParallaxNode* backgroundElements;
2. backgroundElements = InfiniteParallaxNode::create();
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. }
1. addChild(backgroundElements, 2);
2. schedule(schedule_selector(HelloWorld::update), 0.01);