Bài 8: Menu - từ cơ bản tới phức tạp ( Part2)

Người đăng: share-nhungdieuhay on Thứ Ba, 29 tháng 4, 2014

Hi 30-4, 1-5!

Tình hình là 2 ngày không được nghỉ, chả biết làm gì, đi làm thì chán chán, đi chơi thì 1 mình nên đành rảnh rỗi ngồi viết bài cho vui vậy. Các anh chị em giờ này chắc đang vi vu tận đẩu tận đâu rồi ấy nhỉ. Còn mình thì đi làm, nhưng mà không sao, double lương cũng tạm.

Bài trước chúng ta đã biết cách tạo Label chứa text và cách chỉnh font, cùng với việc tạo 1 menu chứa item để thực hiện 1 tác vụ nào đó. Để nhớ lâu, các bạn nên dùng VS 2012 gõ lại từng đoạn code nhé. Còn trong bài này chúng ta sẽ đi sâu hơn với một số công việc sau:

+ Tạo hiệu ứng chuyển cảnh cho mỗi Scene
+ Tạo công việc cho các nút của Menu
+ Thêm một chút hiệu ứng cho Label, ví dụ như chuyển động chẳng hạn.

Bắt đầu thôi. Các down file Source ở ĐÂY về, giải nén rồi paste đè vào thư mục Classes của project menu nhé.

Sau đó, bạn chỉnh file Menu.vcxproj (f:/android/project/menu/proj.win32) như thế này để không bị lỗi khi compile



Biên dịch rồi chạy thử cái xem thế nào

>cocos run -s f:/android/project/menu -p win32

Bạn có thấy thay đổi gì không, có hiệu ứng chuyển Scene, hiệu ứng dịch chuyển chữ, và Click vào 2 menu sẽ chuyển sang Scene khác. OK. Tiếp theo chúng ta sẽ đi vào chi tiết phần code xem làm thế nào để được như vậy.

Chi tiết phần Code

Các file SceneManager.h, và MenuLayer.h không thay đổi gì so với phẩn 1. Ở phần 2 này chúng ta thấy có 2 lớp mới xuât hiện đó là CreditLayer, PlayLayer để quản lý 2 thao tác khi nhấn vào 2 menu khác nhau của chúng ta. Bạn mở 2 file CreditLayer.h, và PlayLayer.h ra nhé

Nói chung là ko có gì đặc biệt phải không , ngoài mấy cái hàm tạo, hàm hủy, rồi hàm init, hàm back ( để ấn nút Back xuất hiện ở Scene này). 2 đối tượng này có mỗi một việc là tạo ra 2 cái Layer rồi sau đó sẽ dính vào 1 Scene nào đó. Bỏ qua 2 file này nhé.

A > Tiếp theo mở file CreditLayer.cpp ra, nhìn vào hàm init() // Hàm này tạo ra 1 layer trống để gắn đối tượng. Trong hàm init () này có đoạn code cần chú ý

auto back = MenuItemFont::create("Back", CC_CALLBACK_1(CreditLayer::back,this)); (1)
auto menu = Menu::create(back, NULL); (2)
menu->setPosition(visibleSize.width/2, visibleSize.height/2);
this->addChild(menu);

(1) Đây là câu lệnh quen thuộc đã học từ bài 7, nhiệm vụ tạo ra 1 item menu tên back, khi ấn vào item menu này sẽ gọi hàm CreditLayer::back() ở phía dưới
(2) là câu lệnh cũng quen thuộc có nhiệm vụ tạo ra 1 Menu chứa cái item menu back đã tạo ở trên.
Còn đoạn bên dưới là đặt vị trí Menu trên ở chính giữa màn hình, sau đó dính cái menu này vào Layer tạo ra bởi hàm init()

B > Tiếp theo mở file PlayLayer.cpp, ta thấy rằng các dòng code hoàn toàn tương tự file CreditLayer.cpp, cũng là tạo ra 1 nút back rồi gắn vào Layer này. Các bạn nghiên cứu kỹ lại cho nhớ nhé.

C > Tiếp theo chúng ta nghiên cứu file MenuLayer.cpp, file này có code khá giống Bài 7 đã nghiên cứu, tuy nhiên, nó bổ sung thêm 1 vài code tạo hiệu ứng di chuyển mấy cái Label, xem qua chút nhỉ. Trong hàm init() ta thấy các câu lệnh quen thuộc để tạo ra các Label chứa Text với font chữ, và cỡ chữ xác định, đặt chúng lên Layer tại các vị trí. Nhưng có 1 đoạn code khá lạ, chúng ta cùng xem:

titleLeft->setPosition(titleLeftPosBegin);
Action *titleLeftAction = Sequence::create(
                            DelayTime::create(delayTime),
                            EaseBackOut::create(MoveTo::create(1.0, titleLeftPosEnd)),
                            NULL);

titleLeft->runAction(titleLeftAction); // titleLeft là 1 cái Label nhé
this->addChild(titleLeft);

Đoạn code này hiểu như sau: nhiệm vụ của nó là tạo ra một hành động có tên titleLeftAction = lệnh Sequence::create(). Hành động này cụ thể là gì? hãy xem trong hàm Sequene::create(), hàm này có 3 tham số truyền vào
DelayTime::create(delayTime) // là tạo ra thời gian trễ
 EaseBackOut::create(MoveTo::create(1.0, titleLeftPosEnd)) // MoveTo::create(1.0, titleLeftPosEnd) là hàm tạo 1 hành động di chuyển từ điểm đầu tiên titleLeftPosBegin (đã tính toán ở đoạn code bên trên - trong source) đến điểm cuối titleLeftPosEnd ( cũng đã tính toán trong source), EaseBackOut là 1 lớp tạo ra hiệu ứng ( ko biết phải dịch là gì - đây là 1 trong các hiệu ứng di chuyển thông dụng )
NULL : tham số thứ 3 này chưa hiểu lắm, để hiểu sâu hơn hãy nghiên cứu ở đây http://www.cocos2d-x.org/reference/native-cpp/V3.0rc0/index.html

Lệnh titleLeft->runAction(titleLeftAction); là thực hiện cái hành động di chuyển ở bên trên bằng cách gọi function của đối tượng titleLeft ( đây là 1 cái Label ).

this->addChild(titleLeft); // Gắn cái Label vào Layer tạo bởi init(); 

Đoạn code bên dưới cũng tương tự thế, tạo ra 1 chuyển động cho 1 cái Label khác. OK chưa

Giờ thì tới đoạn này, khá khó hiểu

   for (Node *each : menu->getChildren())
    {
each->setScale(0.0f, 0.0f);
Action *action = Sequence::create(DelayTime::create(delayTime),
                                          ScaleTo::create(0.5f, 1.0f),
                                          NULL);
delayTime += 0.2f;
each->runAction(action);
     }

Đây là vòng lặp for để duyệt các item của Menu đó chính là nút Credits và nút New Game đó ( 2 nút này được tạo ra ở bên trên - trong Source, MenuLayer.cpp)

for (Node *each : menu->getChildren()) cũng khá lại so với for (i=0; i<n; i++) cơ bản của C++ nhỉ, hêhe, nhưng chính xác nó là 1 vòng lặp để duyệt các đơn vị của 1 tập nào đó.

Trong vòng lặp

each->setScale(0.0f, 0.0f); là chỉnh cái nút menu Credits , New Game về tỉ lệ 0, biến mất còn gì, sau đó đến lệnh

Action *action = Sequence::create(DelayTime::create(delayTime),
                                          ScaleTo::create(0.5f, 1.0f),
                                          NULL);
là tạo ra 1 hành động phóng to dần cái nút này lên với tỷ lệ nhất định ScaleTo::create(0.5f, 1.0f),
sau đó là thực hiện hành động each->runAction(action);  Kết quả là tạo 1 hiệu ứng cái nút đó phóng to dần lên thôi, đơn giản và dễ hiểu quá phải không.

D > Tiếp theo chúng ta nghiên cứu file SceneManger.cpp, file này dùng để quản lý các Scene được tạo ra và chạy như thế nào, đồng thời khi chuyển từ Scene này sang scene khác có kèm 1 hiệu ứng chuyển cảnh ( như làm mờ, lộn ngược, quay đảo, v.v...)

Mở file lên nào, Trời ơi, sao code dài thế ~150 dòng code cùng với rất nhiều hàm. Vâng, bạn ạ, thực ra code dài nhưng đơn giản dễ hiểu còn hơn đoạn code ngắn mà phức tạp đọc không hiểu gì. Mình nhớ có lần làm 1 bài tập lớn, search mạng đọc 1 cái code Java thì phải có sấp sỉ 10000 dòng (Notepad ++) đọc mãi mới xong. 

Trong file này tuy nhiều code nhưng thật ra có nhiều đoạn code chức năng na ná nhau đó là tạo ra 1 hiệu ứng chuyển cảnh cho Scene, thế nên mình chỉ giới thiệu với các bạn 1-2 đoạn thôi nhé. Bạn yên tâm rằng các hiệu ứng chuyển cảnh này đều được định nghĩa bằng các lớp tương ứng của Cocos2dx V3 nhé ( ví dụ: TransitionFlipY - lộn theo trục Y,  TransitionFade - làm mờ dần, TransitionZoomFlipX - phóng to theo trục X ) vậy đó

- Bài này đang tạm dừng...

Bài 9: Làm game đầu tiên - Tạo nhân vật (Part -1)

{ 0 nhận xét... read them below or add one }

Đăng nhận xét