Cocos2d-x 3.2 Final

Cập nhật lên phiên bản Cocos2d-x 3.2. Bổ sung 3D sprite, 3D animation, game controller, fast Tilemap,..v...v... Cập nhật thường xuyên nhé

Cocos2d-x 3.0 Final

Cocos2d-x là Engine lập trình game đa nền tảng phổ biến nhất trên thế giới. Tính năng mạnh mẽ, dễ sử dụng, miễn phí, mã nguồn mở.

Cocos2d-x V3.0 Final

Hướng dẫn chi tiết, đầy đủ bằng Video, Blog. Cộng đồng hỗ trợ rộng lớn. Sản phẩm phong phú mọi nền tảng

Game Badland

Một trong những game nổi tiếng nhất được tạo ra bởi Engine Cocos2d-x.

Cocos2d-x V3.1

Cập nhật phiên bản Engine Cocos2d-x V3.1 bổ sung thêm nhiều tính năng. Sửa các lỗi nhỏ của các phiên bản trước

Contra Evolution - KONAMI

1 Game rất hay không thể bỏ qua, 1 vé trở về với tuổi thơ.

Wednesday, April 30, 2014

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

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)

Tuesday, April 29, 2014

Tài liệu tiếng Việt học Cocos2dx

Hi all!

Đúng là học thầy không tày học bạn, học bạn không bằng...tự đọc sách. Đọc sách mà cũng không xong thì khỏi học. hêhê

Nói vậy cho vui thôi, khi học bất cứ ngành nghề gì chúng ta đều phải cần tới sự hướng dẫn chỉ dạy từ những cuốn sách, từ thầy giáo hoặc bạn bè, và ngày nay là bác Google.

Sau một thời gian tìm tòi trên mạng, mình cũng tìm được Vô số sách hướng dẫn Cocos2d-x trên mạng NHƯNG, toàn phiên bản cũ 2.x đổ về trước.VÀ có một khó khăn nữa là, 

1/ Sách đó toàn tiếng ANH, TRUNG, HÀN, NHẬT. ( không đến nỗi ko thể đọc)
2/ Trong sách chỉ có một số đoạn code, hướng dẫn, giải thích. Còn lại Source đầy đủ nằm trong đĩa gốc hoặc trên 1 trang tính phí ( bán kèm sách online mà )

Có một cuốn nổi tiếng nhất là Cocos2d-x by Exam mình cũng tìm thấy nhưng cũng mắc phải 2 vấn đề trên, nên mình quyết định là tự mình tìm hiểu Engine vậy. Vì đọc sách với code cũ có khi mất thời gian viết lại code cho Engine mới .

Dù sao mình cũng sẽ chia sẻ với các bạn tài liệu này để tham khảo. bạn nào xài Engine cũ cũng rất hữu ích đấy. Trong sách này có 4 Game, mình mới có 1 game đủ source code. Chia sẻ sau nhé

Tin vui cho anh em, đã ra Cocos2d-x V3.0 FINAL

Hix!

Trong thời gian mình miệt mài viết bài về Cocos2d-x V3 RC0, RC1,RC2 thì tại trang chủ đã ra bản Cocos2d-x V3.0 FINAL rồi, vui vãi. Hi vọng là nó sẽ còn được support dài dài

Trong bản FINAL này mọi thứ hầu như đã hoàn thiện tốt phục vụ cho việc làm game của lập trình viên, Thực sự là có quá nhiều thứ hay, nhưng do trình độ có hạn và mới tìm hiểu nên không biết là có gì nổi trội hơn các bản trước không. hehe, Nhưng 1 điều chắc chắn là nó đủ sức làm được những gì 1 game 2D, 2,5D yêu cầu



Tin vui thứ 2 là: trên trang chủ đang tổ chức 1 cuộc thi viết hướng dẫn để quảng bá cho Engine này

Cocos2d-x 3.0 Tutorial Competition On
deadline đến cuối tháng 5. Như vậy là khoảng tháng 7 chúng ta sẽ có những bài Tut chất lượng ( bằng tiếng Anh) để tham khảo rồi. 

Nhưng điều này làm mình cũng hơi e ngại là cùng với chiến dịch quảng bá này liệu mai mốt Engine này có thu phí hay ko?? Haizzz! Nếu thế thì buồn lắm.

Thôi trong thời gian chờ đợi, chúng ta tự mày mò và nghiên cứu những code cũ vậy!

Sunday, April 27, 2014

Bài 7 - Menu, từ cơ bản tới phức tạp (Part 1)

Hi, cả lò! (Trời bắt đầu thành cái lò nung tới nơi rồi)

Mọi người nghiên cứu tới đâu rồi nhỉ, còn ai chưa qua được bước cài đặt không? Mình đảm bảo làm theo mình chắc chắn thành công nhé. Xin thông báo với tất cả 1 tin mừng đó là phiên bản Cocos2dx-3 đã ra phiên bản FINAL rồi nhé, nghĩa là bản chính thức, đã khắc phục được tất cả các lỗi. Vậy chúng ta yên tâm học tiếp thôi. Nắm vững được 1 phiên bản thì sau này có ra V4,V5 cũng không khó để tiếp cận.

Ở bài trước, chúng ta đã học qua 1 Bài về Physic cơ bản trong Game và cách tạo chúng = engine Cocos2dx v3. À, trong Engine này sử dụng 2 thư viện Physic để xây dựng game, đó là Chipmunk, và Box 2D. Bài trước là dựa trên Chipmunk nhé, đơn giản, gần gũi hơn Box 2D. Sau này mình sẽ tìm hiểu nốt cái Box 2D và giới thiệu với mọi người. Giờ thì đi tiếp nào, Trong bài này, mình sẽ hướng dẫn mọi người làm mấy cái Menu có thể thao tác được để thực hiện 1 công việc nào đó.

Bắt đầu thôi. Tạo 1 Project mới tên Menu như sau, mở cmd lên gõ vào

>cocos new menu -p com.vn.menu -l cpp -d f:android/project

Sau khi Project mới được tạo, bạn chạy luôn lệnh này giúp mình

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


Đây là biên dịch lần đầu, mục đích là liên kết tới các thư viện của Engine. Lần biên dịch đầu tiên thường lâu là vì thế. Các lần sau thì nhàn hơn nhiều bởi hầu hết chúng ta chỉ thay đổi ở Class và Resource mà thôi.

B1) Copy code và chạy thử
Bạn mở thư mục Classes theo đường dẫn sau F:/android/project/menu/Classes ( có thể khác trên máy bạn)  có chứa 4 file quen thuộc phải không. Nhưng trong bài này chúng ta sẽ không dùng lớp HelloWorldScene nữa mà thay thế bằng 2 lớp khác là MenuLayer và SceneManger.

Bạn xóa 2 file HelloWorldScene.cpp và HelloWorldScene.h, download file nguồn sau tại ĐÂY và copy paste 4 file trong đó vào thư mục Classes. Tiếp theo bạn mở file AppDelegate.cpp, ở dòng #include thứ 2  bạn thay HelloWorldScene.h =  SceneManager.h, 
bỏ dòng auto scene = HelloWorld::createScene();
và director->runWithScene(scene); đi nhé. 
Thêm vào 1 dòng lệnh sau SceneManager::goMenu(); vào bên dưới 2 dòng trên

Xong rồi, trước khi biên dịch chạy thử bạn mở file Menu.vcxproj theo đường dẫn sau F:/android/project/menu/proj.win32/ rồi tìm "HelloWorldScene.cpp" bạn sẽ thấy 4 tên file cơ bản được đặt ở đây khi biên dịch (HelloWorldScene.h, HelloWorldScene.cpp, AppDelegate.cpp, AppDelegate.h )



Vì ở trên bạn đã xóa HelloWorldScene.h và HelloWorldScene.cpp đi rồi nên ở đây bạn cũng phải xóa đi. Đồng thời thêm vào 4 file SceneManager.h, SceneManager.cpp, MenuLayer.h , MenuLayer.cpp vào Menu.vcxproj để trình biên dịch sẽ xử lý thêm 4 file này khi chúng ta biên dịch lại 1 lần nữa để chạy. Cách thêm thì như hình

************************CHÚ Ý************************
 (1/6/2016)

 Mình thấy nhiều bạn mắc ở chỗ này mở file .vcxproj

Xin đính chính lại là làm việc trên Visual Studio thực sực KHÔNG CẦN MỞ FILE NÀY khi thêm File, hoặc thêm Thư viện,

Hãy dùng tính năng sau

Chuột phải vào tên Project của bạn ( trong window Solution ) chọn Add  ( nằm chính giữa menu luôn )

sẽ có menu phụ hiện lên, hãy chú ý tới 2 lựa chọn

+ New Item ( Ctr + Shif + A ) Cho phép bạn tạo file .H, .CPP mới cho Project
+ Existing Item ( SHif + ALt + A ) Cho phép bạn thêm các file .H, .CPP có sẵn ( của Project khác, hoặc bạn copy từ nơi khác vào Thư mục Class ) vào Project

Xong, bạn sẽ ko phải mở vcxproj một cách Nông dân như trên

Nhưng cũng nên tìm hiểu cấu trúc file của những cái mình sẽ phải làm để tham khảo   chứ nhỉ

Thanks


************************************************************

 



Chạy thử = lệnh

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

Rất tiếc! LỖI 1 đống nhé. Cũng phải thôi vì mã nguồn có lẽ không phù hợp với phiên bản Engine đang dùng, phải sửa lại đôi chút. Hoặc là tác giả của source bị sai mấy câu lệnh chẳng hạn. Căn cứ vào mấy cái lỗi để sửa thôi

B2) Nghiên cứu file nguồn 1 chút nhỉ

Nhìn vào thông báo lỗi, khá nhiều lỗi luôn, và không phải lỗi nào cũng có thẻ hiểu được. Sau 1 thời gian có kinh nghiệm chắc chắn bạn sẽ fix được các lỗi này thôi. Quả thật mình cũng không biết phải diễn giải các lỗi này ra đây thế nào nữa hì. Tốt nhất là kiểm tra lại mã nguồn của chúng ta xem có sai sót gì không.

Ở phần trên sẽ báo có 8 lỗi: Identifier 'Object' .....

Mở 2 file Header là SceneManager.h, MenuLayer.h , thêm vào đó dồng USING_NS_CC; vào dưới các dòng #include, cả 2 file nhé. compile lại xem, build được luôn, nhưng chạy thử file exe trong F:/android/project/menu/bin thì lại báo lỗi stop working.

Theo kinh nghiệm của mình thì, khi Build không gặp lỗi gì, tức là code đã chuẩn theo phiên bản Engine. Nhưng khi chạy mà báo lỗi Stop working thì có thể do 2 lỗi sau, không tương thích với hệ thống ( build trên 32 mang chạy trên 64 chẳng hạn) và lỗi thứ 2 là do Resource ( file hình ảnh, âm thanh, font, ...) đã bị thiếu. 

Trong trường hợp này mình cố tình ko copy 1 file font "Marker Felt.ttf" vào thư mục Resource nên build ok nhưng chạy bị lỗi. Bạn copy file "Marker Felt.ttf" từ F:/android/project/menu/Resource/font ra ngay bên ngoài thư mục Resource ( cùng cấp với mấy hình ảnh HelloWorld đó)


Compile lại xem nào


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

OK nhé


B3) Nghiên cứu Code

Bạn mở 2 file header là SceneManager.h, MenuLayer.h và ngó qua chút: không có gì đặc biệt lắm phải không, ở đó chứa khai báo các hàm hoặc thuộc tính của một lớp. Cách khai báo bạn ôn lại 1 chút trong C++ là hiểu được thôi. Mình sẽ đi vào phần chính ở dưới

(Các bạn theo dõi file CODE nhé, vì nếu chép ra đây thì dài và rối lắm. Chúng ta giải thích là chính thôi)
+ Mở file SceneManager.cpp, trong này có 3 hàm 

void SceneManager::goMenu(), hàm này tạo ra 1 layer ( cái này cũng gọi là lớp nhưng không giống Class nhé. Class là chỉ các đối tượng với thuộc tính và hàm, còn layer giống như 1 mặt phẳng để đặt các thứ khác lên nó, hình dung như thế đi). Sau đó hàm này gọi tiếp 1 hàm void SceneManager::go(Layer* layer)

void SceneManager::go(Layer* layer) thực hiện 2 công việc, truyền layer vừa tạo ở trên cho 1 hàm Scene* SceneManager::wrap(Layer *layer) để xử lý cái layer này,việc xử lý bằng hàm Wrap sẽ trả lại 1 Scene. Sau đó kiểm tra xem có scene nào đang chạy không, nếu có thì thay thế = Scene mới có layer vừa tạo. nếu không có Scene nào đang chạy thì chạy với Scene có layer vừa tạo.

Scene* SceneManager::wrap(Layer *layer) thực hiện công việc là lấy tham số layer truyền vào, đặt lên 1 Scene mới tạo, trả lại giá trị là 1 Scene.

+ Mở file MenuLayer.cpp trong đó cũng lại có 3 hàm

* bool MenuLayer::init(), hàm init luôn trả về bool nhé

Trong này mình sẽ giải thích một số dòng lệnh "lạ"

TTFConfig config_font96("Marker Felt.ttf", 96);

TTFConfig config_font52("Marker Felt.ttf", 52);

//Chình font "Marker Felt.ttf" thành 2 cỡ 96, và 52 (pixel??)

Label *titleLeft = Label::createWithTTF(config_font96, "Menu ");

// Tạo 1 Label ( nhãn )  titleLeft có hiện dòng chữ "Menu" sử dụng font config_font96, các lênh tương tự bên dưới nhé
    
MenuItemFont *startNew = MenuItemFont::create("New Game", CC_CALLBACK_1(MenuLayer::onNewGame, this));

// Tạo biến menu item startNew hiện từ "New Game", khi ấn lên menu item này sẽ gọi hàm onNewGame() của lớp MenuLayer, lệnh dưới tương tụ tạo menu item "Credits"

Menu *menu = Menu::create(startNew, credits, NULL);
// Tạo 1 biến menu có chứa 2 menu item con đã tạo ở trên là startNew  và credits

1 đoạn bên dưới là công việc nhàm chán đặt vị trí trên màn hình = lệnh setPostion(); và đặt các đối tượng vào layer = lệnh this->addChild();

có 1 câu này
 menu->alignItemsVerticallyWithPadding(80.0f); // căn chỉnh theo chiều dọc các đối tượng của biến menu cách nhau 1 khoảng 80 (pixel??)

- 2 hàm bên dưới onNewGame(), onCredits() thực hiện công việc đơn giản là lại gọi hàm tạo 1 Scene mới khi ấn vào 2 menu tạo ở trên

Tổng kết lại, trong bài này học được :

+ Tạo 1 label với font = lệnh
TTFConfig config_font96("Marker Felt.ttf", 96); 
Label *titleLeft = Label::createWithTTF(config_font96, "Menu ");

+ Tạo 1 đối tượng menu item có thể ấn được 
MenuItemFont *startNew = MenuItemFont::create("New Game", CC_CALLBACK_1(MenuLayer::onNewGame, this));

Menu *menu = Menu::create(startNew, credits, NULL);

Xong rồi. 1 bài đơn giản  mà phải diễn giải dài quá các bạn ạ, nếu bài nào mà dài, nhiều đối tượng chắc chết quá



Monday, April 21, 2014

Bài 6 - Ball - Physics cơ bản trong Cocos2dx -v3 (Part2)




Hi cả nhà!

Thời gian qua nhanh quá mà chả làm được cái gì, chán ghê. Cũng tại mình vừa vấp phải mấy vấn đề khó giải quyết trong cocos2dx - V3 nên tìm hiểu mãi mới ra. Trong bài này mình cũng trình bày luôn vấn đề đó là gì. Bây giờ chúng ta cùng tiếp tục bài trước về Physics nhé

Ở bài trước chúng ta đã tạo mới 1 Project Ball rồi đúng không, bây giờ là phần code thể hiện physics trong đó.

Let's go!


Các bạn theo đường dẫn sau: Q/android/project/ball/class, mở file HelloWorldScene.h lên. Code của file đó sẽ như vầy:

#ifndef __HELLOWORLD_SCENE_H__

#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

USING_NS_CC;

class HelloWorld : public cocos2d::Layer

{

public:

Sprite* _ball;

PhysicsWorld* m_world;

void setPhyWorld(PhysicsWorld* world){ m_world = world; };

static cocos2d::Scene* createScene();

virtual bool init();

virtual void onAcceleration(Acceleration* acc, Event* unused_event);

bool onContactBegin(const PhysicsContact &contact);

CREATE_FUNC(HelloWorld);

};


#endif // __HELLOWORLD_SCENE_H__

Các bạn không phải sửa đổi gì nhé, mình sẽ giải thích 1 chút về mấy thứ "là lạ trong đó"cho mọi người"

Sprite* _ball; // là 1 con trỏ kiểu Sprite tên là _ball, con trỏ này để quản lý cái gọi là quả bóng trong chương trình chúng ta.

PhysicsWorld* m_world; // Con trỏ kiểu PhysicsWorld tên m_world, gán cho nó các thuộc tính vật lý

void setPhyWorld(PhysicsWorld* world){ m_world = world; }; //hàm gán thuộc tính vật lý cho m_world,

virtual void onAcceleration(Acceleration* acc, Event* unused_event); // hàm này liên quan tới gia tốc kế thì phải
bool onContactBegin(const PhysicsContact &contact); // Hàm này để phát hiện va chạm giữa 2 quả bóng

Tiếp đến các bạn mở file HelloWorldScene.cpp lên nào (file nguồn các bạn down ở bên dưới nhé, vì mình dán vào đây thì bài dài dòng quá), trong đó bạn chú ý một số đoạn sau,

Trong hàm tạo Scene : Scene* HelloWorld::createScene(){}

auto scene = Scene::createWithPhysics(); // Câu lệnh này tạo 1 Scene gắn thuộc tính Physics
---

auto layer = HelloWorld::create(); // Tạo 1 layer của lớp HelloWorld

layer->setPhyWorld(scene->getPhysicsWorld()); // đặt thuộc tính Physics cho biết m_world của đối tượng layer,

scene->getPhysicsWorld() //nghĩa là lấy Physics của scene rồi gán cho m_world của layer

tiếp theo, hàm init()

_ball = Sprite::create("Ball.jpg", Rect(0, 0, 52, 52)); // Tạo 1 quả bóng nằm trong hình vuông 52 pixel

_ball->setPosition(Point(400,600)); // đặt ở vị trí 400, 600

auto ballBody = PhysicsBody::createCircle(_ball->getContentSize().width / 2); // Tạo 1 khung body có đặc tính vật lý để phát hiện va chạm, khung này dạng tròn có đường kính = nội dung của _ball chia 2.

ballBody->setContactTestBitmask(0x1); // Cái này rất quan trọng, nếu ko có thì hàm onContactBegin ko có tác dụng, tìm trên mạng mãi mới sửa được lỗi này

_ball->setPhysicsBody(ballBody); // Gán body cho _ball

this->addChild(_ball); // thêm vào layer HelloWorld đã tạo ở trên

ball2 được tạo ra tương tự

tiếp theo, đoạn này sẽ tạo ra 1 khung bao quanh màn hình, khi quả bóng chạm vào sẽ dừng lại. nó giống một bức tường ( 1 cái hộp ) vậy thôi, không cần giải thích nhiều nhé, cứ code mà đập thôi

auto edgeSp = Sprite::create();

auto boundBody = PhysicsBody::createEdgeBox(visibleSize, PHYSICSBODY_MATERIAL_DEFAULT, 3);

edgeSp->setPosition(Point(visibleSize.width / 2, visibleSize.height / 2));

edgeSp->setPhysicsBody(boundBody);

this->addChild(edgeSp);

edgeSp->setTag(0);

Tiếp theo, quan trọng nè

auto Listener = EventListenerPhysicsContact::create(); // Biến này để "lắng nghe" các tương tác vật lý xảy ra

Listener->onContactBegin=CC_CALLBACK_1(HelloWorld::onContactBegin,this); // gọi hàm onContactBegin, hàm này sẽ xử lý khi va chạm xảy ra, hàm này là hàm chồng lên( gọi là hàm overide của 1 hàm mẫu đã có của thư viện - bạn nào học C++ sẽ hiểu rõ).

_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

// dòng này để xử lý ông Listener bên trên kia,

Túm lại đoạn trên đây để phát hiện ra tương tác giữa 2 quả bóng bạn tạo ra, rồi gọi hàm onContactBegin để xử lý.

Bạn mới học thì cứ dập khuôn từng đoạn code, tạm thời đừng hỏi sao phải viết thế, viết khác được không ( Haizzz, ko biết giải đáp thế nào nhỉ). Viết khác được, nhưng hãy nắm chắc cái ban đầu đi đã rồi phát triển sau.

Bây giờ tới hàm onContactBegin{}, format của nó chắc chắn phải viết như sau, sau đó thêm gì thì thêm vào trong 2 dấu ngoặc

bool HelloWorld::onContactBegin(const PhysicsContact &contact)

{

return true;

}

thêm đoạn này vào để xóa 2 quả bóng khi chạm nhau

auto ObjA = (Sprite*)contact.getShapeA()->getBody()->getNode();

auto ObjB = (Sprite*)contact.getShapeB()->getBody()->getNode();

this->removeChild(ObjB,true);

this->removeChild(ObjA,true);

tiếp theo, hàm này this->setAccelerometerEnabled(true); // Gia tốc kế của máy điện thoại

Chạy thử nhé, các bạn đừng quên lệnh này nhé

cocos run -s q:android/project/ball -p win32 

Nếu bạn thấy 2 quả bóng đập vào nhau và biến mất là đã thành công

Bạn thử bỏ dòng lệnh ballBody->setContactTestBitmask(0x1); đi xem, 2 quả bóng có va vào nhau nhưng ko có gì xảy ra phải không. Hehe, mỗi dòng lệnh này mà mình tìm kiếm mất gần tuần. HIX

Vấn đề Physic đã giải quyết xong

Nâng cao lên 1 chút nào

Xóa dòng this->setAccelerometerEnabled(true); và layer->setPhyWorld(scene->getPhysicsWorld());, Xóa tiếp hàm onAcceleration, kết quả ko đổi đúng ko, tốc độ rơi vẫn thế (trên win), 2 quả bóng chạm nhau vẫn biến mất. Lệnh này hình như thiết lập gia tốc kế. Các bạn thử thiết lập và xoay màn hình điện thoại xem nhé. Quả bóng sẽ lăn theo hướng rơi xuống cạnh đáy màn hình

Nhưng thử xóa dòng _ball->setPhysicsBody(ballBody); ball2->setPhysicsBody(ball2Body); Bạn sẽ thấy 2 quả bóng đứng im luôn. Có thể thấy hàm này giống như việc đặt vào quả bóng 1 khối lượng nào đó vậy ( chắc tương đương với bán kính). Quên mất vật nặng nhẹ đều rơi như nhau với gia tốc G mà

Bây giờ thêm lại 2 lệnh setPhysicsBody bên trên, rồi thêm dòng lệnh sau: scene->getPhysicsWorld()->setGravity(Vect(0.0f,-5000.0f)); Bạn sẽ thấy quả bóng rơi rất nhanh, đó, chỗ này chính là thiết lập gia tốc trọng lực, sét càng cao thì rơi càng nhanh.

Như vậy qua bài này, bạn đã biết làm thế nào để thiết lập 1 Physics cơ bản cho chương trình rồi nhé. Sang phiên bản mới ( mình đang xài V3 RC2) bạn chỉ cần nắm mấy lệnh cơ bản sau

auto scene = Scene::createWithPhysics(); // Tạo 1 Scene có thuộc tính Physics ( đã bao gồm gia tốc )

scene->getPhysicsWorld()->setGravity(Vect(0.0f,-3000.0f)); // Thay đổi gia tốc, nhớ là phải có dấu "-"

auto ballBody = PhysicsBody::createCircle(_ball->getContentSize().width);

_ball->setPhysicsBody(ballBody);  // thiết lập thuộc tính vật lý ( cụ thể là khối lượng và ranh giới của vật thể )

ballBody->setContactTestBitmask(0x1);  // Thiết lập sự phát hiện va chạm giữa 2 vật

// và đoạn này để lắng nghe sự va chạm nếu có

auto contactListener = EventListenerPhysicsContact::create();

contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);

_eventDispatcher->addEventListenerWithSceneGraphPriority(contactListener, this);

DOWN Mã nguồn và file Resource

Bài 7: Menu - Từ cơ bản tới phức tạp (Part 1)

Monday, April 14, 2014

Bài 5: Ball - Physics cơ bản trong Cocos2dx - V3.1 ( Part 1)

Hi cả nhà!
Chán quá đi, dạo này tình hình sức khỏe đi xuống quá. Sáng nay uống 1 nhúm thuốc các thể loại giờ nôn nao chóng mặt vãi ( Sốc cmn thuôc rồi). Lần trước có 1 lần cũng uống quá liều, may chưa tiêu.

Tay chân mặt mũi, trí óc không mỏi, mà mắt mỏi và choáng quá. Thôi cố viết xong bài này rồi đi nghỉ.

Vậy là chúng ta đã đi qua được 2 bài quan trọng là cài đặt Cocos2dx và HelloWorld trong các phần trước rồi. Các bạn vẫn còn hào hứng cùng tôi đi tiếp không nào. Haizzz, chắc có một số người rớt lại phía sau hoặc bỏ cuộc rồi không biết chừng. Dù thế nào, dù 1 mình tôi cũng sẽ đi tới cùng. :))

Tôi xin nhắc lại với các bạn là: 
1/ Những gì tôi viết trong này hoàn toàn là tham khảo từ các bài code ví dụ trên mạng nước ngoài, nên có thể sẽ không theo 1 hệ thống nào cả, vì tôi ko phải là nhà viết sách chuyên nghiệp, nên không thể hệ thống lại được theo cách tốt nhất. Tôi sẽ ưu tiên cho các bài ngắn dễ hiểu, rồi đến bài dài khó hiểu, vậy thôi, hoặc theo thứ tự thời gian các bài code tôi sưu tầm được.

2/ Vì phiên bản Cocos2dx v3.0 (giờ đã là 3.2 RC0 ) này là phiên bản mới nhất nên chẳng có sách nào đâu. À, có đấy nhưng bằng tiếng Hàn + Trung, đang trong quá trình chuẩn bị dịch sang Anh, nhưng mà chắc chắn là phải mua = tiền, nhưng cũng ko biết mua ở đâu nữa, và chắc phải 1-2 năm nữa Việt Nam mình mới có. Hehê, lúc đó thì chúng nó lại ra phiên bản 4, rồi 5 và rồi chúng ta lại chờ sách. Sao luẩn quẩn vậy? chả lẽ chúng ta cứ phải chờ đợi vào người khác?

3/ Các sách cũ hơn thì hầu như không dùng được vì hồi trước tiền thân của Cocos2d - X ( nhớ là có chữ X nhé ) là Cocos2d - iphone ( cho riêng Iphone ) nên các Sách trước đây viết cho lập trình viên Iphone, các bạn nhé. Code là Oject -C chứ không phải C++ như Cocos2d - X ( đa nền ) như bây giờ. Bạn vẫn có thể sử dụng code Object - C đó để port sang code C++ , nhưng khi đó trình độ và kinh nghiệm ít nhất cũng phải 6 tháng học cocos2d-x nhé. Thôi thì chịu khó học cái mới mẻ đi.

Dài dòng lắm rồi, túm lại là, có cái để học, để làm là tốt lắm rồi, không lại rảnh rỗi sinh nông nổi thì chết.

Bắt đầu thôi

Đầu tiên bạn tạo 1 Project mới cho mình bằng CMD như sau

>cocos new Ball -p com.vn.Ball -l cpp -d Q:/android/project

Giải thích chút, lệnh trên sẽ tạo 1 Project tên Ball trong thư mục Q:/android/project

-p com.vn.Ball là cú pháp package. bạn có thể thay đổi 1 chút nhưng nhất thiết phải có 2 cái dấu chấm (.) như trên nha. Tốt nhất là làm theo mình.
-l cpp: là lựa chọn ngôn ngữ C++
- d Q:/android/project: là thư mục lưu Project thôi

OK, rồi. Bạn thấy đó cái Project Ball lần này cũng chẳng khác gì  cái Project HelloWorld hôm trước cả đâu, không tin bạn vào kiểm tra xem, cấu trúc thư mục rồi file nguồn cũng giống hệt nhau mà. Bạn tự kiểm tra nhé. Nhưng rồi chúng ta sẽ làm cho nó khác đi một chút, đó là thêm physics ( tạm gọi là thuộc tính vật lý đi) vào trong chương trình Ball này.

Physics là gì, tại sao phải thêm Physics?

Đơn giản lắm các bạn ơi. Physics là sự mô phỏng các hiện tượng vật lý trong game sao cho giống với ngoài đời thực. Sự mô phỏng này có thể giống nhiều hay ít tùy thuộc vào ý tưởng game, và quyết định của lập trình viên.

Các physic cơ bản bạn đễ nhận thấy là: Hình ảnh, Âm thanh, gia tốc rơi, chuyển động 1 vật, Va chạm nhau...

Hẹn các bạn bài sau nhé, nay mỏi mắt quá, sẽ sớm lên sóng thôi.


Saturday, April 12, 2014

Bài 4: Hello World. Bài code đầu tiên

Hi mọi người!

Dạo này không hiểu sao ốm yếu quá, ít có thời gian nghiên cứu. Nay sức khỏe đã tạm ổn, mình sẽ tiếp tục giới thiệu với các bạn bài đầu tiên về code. Mà không biết còn ai thắc mắc về cách cài đặt không?

Hiện tại đến thời điểm mình sửa bài này (7-11-2014, đã có Cocos2d-x 3.2 RC0) rồi. Và mình khuyên các bạn là chỉ nên tải và sử dụng các phiên bản có đuôi RC.x trở lên cho tới stable ( thường là ko ghi gì sau đuôi ví dụ 3.1.1 ) chứ ko nên sử dụng các bản Alpha.x hoặc Beta.x vì chúng vẫn còn trong giai đoạn thử nghiệm sẽ mắc nhiều lỗi không đáng có. Và khi mình update các phiên bản ( chỉ việc copy vào thư mục chưa Engine thôi - nội dung trong thư mục engine cũ thì xóa đi ) hầu như không gặp bất kỳ lỗi nào khi compile, run cả trên Win, hoặc Android. Chỉ gặp các lỗi liên quan tới code do thư viện của cocos2d-x có thay đổi 1 chút xíu ở phiên bản mới, sai đâu thì IDE sẽ báo ở đó để biết cách sửa thôi.

=> Cách cài đặt của các phiên bản Engine thế hệ 3.x là giống nhau ( tới thời điểm này ) nhé

Nếu các bạn đã từng học qua các loại ngôn ngữ lập trình, hẳn đã quen với loại bài viết Hello World, Your First Application rồi nhỉ. Ai đã tìm hiểu 1 chút rồi thì có thể xem nhanh qua phần này. Mình bắt đầu nhé.

A - Tạo và chạy thử Project

Đầu tiên, tạo một Project mới với tên Hello World bằng lệnh sau trong cmd

Run/cmd
>cocos new HelloWorld -p com.vn.HelloWorld -l cpp - d q:/android/myproject

Đợi khoảng 5 phút để nó tạo Project mới cho chúng ta

Xong rồi, vào Project mới tạo theo đường dẫn

Q:/android/myproject/helloworld, cấu trúc thư mục trong đó như sau:

Classes <- Quan trọng nhất nhé, nó chứa mã nguồn cpp hay lua tùy thuộc việc bạn chọn ngôn ngữ nào khi dùng lệnh new ở phía trên.
cocos2d <- thư viện của engine Cocos2d - x.
proj.android <- dành cho việc build ứng dụng apk cho Android mobile.
proj.ios_mac  <- dành cho việc build ứng dụng cho Iphone và Mac OS ( Chỉ chạy được trên máy của Apple, hoặc máy cài Mac OS.
proj.linux <- dành cho việc build ứng dụng trên máy Linux.
proj.win32 <- dành cho việc build ứng dụng trên hệ điều hành Window 7, 8
proj.wp8-xaml <- dành cho việc build ứng dụng chạy trên Window phone 8
Resources <- chứa ảnh, font chữ, Map, định nghĩa vật lý,v.v...
.cocos-project.json <- chỉ định việc build project với ngôn ngữ nào, lua hay cpp.
CMakeLists.txt <- Danh sách thư viện phục vụ việc build project.

Tiếp theo chúng ta build và run thử trên Window nhé. Lệnh sau

>cocos run -s q:/android/myproject/helloworld -p win32

(gõ cocos run -h để được help)

Lưu ý: 
1/ Win mình xài là Win 7 32 bít, bạn nào xài XP, Win 7 -  64, Win 8 all, thì mình ko biết nhé. Các bạn thử xem thành công không. (Đã cài đặt và chạy trên win 7 - 64 ngon lành cành đào nhé.). Đã có nhiều bạn chạy Win8 OK rồi nhé

2/ Mình ko chắc xài máy ảo VMWare có chạy được không nhé

3/ Bạn có thể build thành ứng dụng .apk để chạy trên máy ảo Android, hoặc chơi máy thật luôn cho máu

>cocos compile -s q:/android/myproject/helloworld -p android --ap 16
--ap 16 là chỉ định dành cho android 4.1.2 trở lên

cài vào máy ảo

>adb install q:/android/myproject/helloworld/bin/debug/android/helloworld-debug-unligned.apk
hoặc
>cocos run -s q:/android/myproject/helloworld -p android --ap 16

Nếu không báo lỗi nào và xuất hiện ảnh như thế này, nghĩa là bạn đã thành công rồi đó. Mình cam đoan nếu các bạn cài đặt như bài trước của mình thì chắc chắn sẽ thành công.



B - Tìm hiểu Code

Bên trên mới là phần tạo và chạy thử thôi, còn trong phần này chúng ta cùng tìm hiểu những dòng lệnh đầu tiên
Các bạn vào thư mục Classes của Project, trong đó có 4 file
AppDelegate.h, AppDelegate.cpp
HelloWorldScene.h, HelloWorldScene.cpp

Mới đầu mình chỉ nên tìm hiểu 2 file HelloWorldScene.h, HelloWorldScene.cpp thôi nhé. 2 file bên trên có chức năng theo dõi thông số của ứng dụng thôi. Nhưng bạn không thể xóa 2 file này nhé

file HelloWorldScene.h

#ifndef __HELLOWORLD_SCENE_H__
#define __HELLOWORLD_SCENE_H__

#include "cocos2d.h"

class HelloWorld : public cocos2d::Layer
{
public:
    static cocos2d::Scene* createScene();

    virtual bool init();  
    
    void menuCloseCallback(cocos2d::Ref* pSender);
    
    CREATE_FUNC(HelloWorld);
};

#endif // __HELLOWORLD_SCENE_H__

cấu trúc rất giống 1 chương trình C++ phải không, thì nó chính là C++ mà, hehee

Trước khi tìm hiểu code, các bạn nên đọc qua, hoặc ôn lại kiến thức C++ chú nhé. Mình sẽ cố gắng giải thích các hàm chức năng hoặc các điểm mới trong cocos2dx 3 thôi

static cocos2d::Scene* createScene();  //tạo ra một cảnh mới
virtual bool init(); //Khởi tạo 1 đối tượng của lớp HelloWorld
void menuCloseCallback(cocos2d::Ref* pSender); //Nút Tắt ứng dụng
CREATE_FUNC(HelloWorld); //Chưa rõ lắm, nhưng tạm coi là cần phải có đi

file tiếp theo HelloWorldScene.cpp

#include "HelloWorldScene.h"

USING_NS_CC;

// hàm tạo 1 cảnh mới trả về con trỏ Scene*
Scene* HelloWorld::createScene()
{
  
    auto scene = Scene::create();  // tạo 1 đối tượng Scene
    
    auto layer = HelloWorld::create(); // tạo đối tượng HelloWorld

// thêm đối tượng HelloWorld vào Scene
    scene->addChild(layer);

// trả về con trỏ scene
    return scene;
}

// khởi tạo đối tượng HelloWorld
bool HelloWorld::init()
{
    //////////////////////////////
    // kiểm tra khởi tạo lỗi
    if ( !Layer::init() )
    {
        return false;
    }
    
// Lấy kích thước màn, và điểm tọa độ gốc
    Size visibleSize = Director::getInstance()->getVisibleSize();
    Point origin = Director::getInstance()->getVisibleOrigin();


    //tạo nút đóng ứng dụng

    auto closeItem = MenuItemImage::create(
                                           "CloseNormal.png",
                                           "CloseSelected.png",
                                           CC_CALLBACK_1(HelloWorld::menuCloseCallback, this));
    
// Đặt vị trí nút đóng tại điểm tính theo công thức bên dưới
closeItem->setPosition(Point(origin.x + visibleSize.width - closeItem->getContentSize().width/2 ,
                                origin.y + closeItem->getContentSize().height/2));

    // Tạo menu chứa nút đóng ở bên trên, đặt vị trí
    auto menu = Menu::create(closeItem, NULL);
    menu->setPosition(Point::ZERO);
    this->addChild(menu, 1); // thêm menu vào đối tượng HelloWorld

    /////////////////////////////
   // Tạo 1 dòng Text với font arial cỡ 24 pixel
    
    auto label = LabelTTF::create("Hello World", "Arial", 24);
    
    // đặt vị trí Text
    label->setPosition(Point(origin.x + visibleSize.width/2,
                            origin.y + visibleSize.height - label->getContentSize().height));

    // Thêm text vào đối tượng HelloWorld
    this->addChild(label, 1);

    // tạo 1 đối tượng loại sprite ( là các đối tượng có thể di chuyển trong game)
    auto sprite = Sprite::create("HelloWorld.png");

    // Đặt sprite lên vị trí giữa màn hình
    sprite->setPosition(Point(visibleSize.width/2 + origin.x, visibleSize.height/2 + origin.y));

    // Thêm đối tượng Sprite vào HelloWorld
    this->addChild(sprite, 0);
    
   // giá trị trả về của hàm init()
    return true;
}

// Hàm đóng ứng dụng
void HelloWorld::menuCloseCallback(Ref* pSender)
{

Director::getInstance()->end(); // Kết thúc chương trình.

// Nếu là IOS thì gọi lệnh exit(0);#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)

exit(0);

#endif

}

Tới đây, hẳn mọi người đã biết cách tạo và chạy thử 1 project thế nào rồi phải không. Lại còn biết được 1 phần code đơn giản nữa cơ đấy. Trong các bài sau nâng cao hơn sẽ giúp các bạn hiểu sâu hơn về Cocos2dx trong lập trình Game di động.
Bye bye!


Thursday, April 10, 2014

Một số chú ý khi biên dịch project cocos2dx trên window

Hi mọi người!

Mình đã trở lại và bớt ăn hại hơn. Vì, sau 1 thời gian nghiên cứu mày mò, công việc tiến triển khá thuận lợi. Quả thật để sử dụng tốt được Engine dạng mã mở như thế này đã tiêu tốn của mình khá nhiều thời gian, công sức. Có sẵn code toturial rồi mà khi biên dịch còn lỗi tùm lum, tìm rất khổ. Mình tổng kết vào đây những lỗi phổ biến khi biên dịch để các bạn chú ý. Có lỗi nào là cập nhật ngay lỗi đó.

Vì mình làm trên Window nên build file trực tiếp trên ra file exe ( bắt buộc cài VS 2012 trở nên nhé). Không nên xài bản Express các bạn nhé. Crack đầy ra đấy, xài bản miễn phí Express làm gì.

Lệnh CMD

WIN
>cocos compile -s q:/android/myproject/test -p win32
>cocos run -s q:/android/myproject/test -p win32

Android
>cocos compile -s q:/android/myproject/test -p android --ap 1x 
( x từ 0 đến 9 - bắt buộc SDK Manager phải cài bản API 10 ) . --ap ( có 2 dấu ngang)

Lưu ý quan trọng

1 dự án Mẫu bao gồm 4 file cơ bản

AppDelegate.h
AppDelegate.cpp

HelloWorldScene.h
HelloWorldScene.cpp

1/ Cấu trúc file
Trong Window
và 1 file quan trọng là test.vcxproj theo đường dẫn Q:\ANDROID\MyProject\Test\proj.win32 mở và tìm AppDelegate hoặc HelloWorldScene. Bạn sẽ thấy tên 4 file cần để biên dịch nằm ở đây. Nếu thêm 1 file nào mới bạn phải add vào theo đúng cú pháp. nếu thừa hoặc thiếu 1 file nào đó trong này cũng sẽ báo lỗi.

Nếu bạn Build cho Android: Bạn cũng phải bổ sung thêm file mới vào file Android.mk nằm trong đường dẫn sau

ProjectName\proj.android\jni\Android.mk

Trong các file (.h) nên có dòng lệnh USING_NS_CC; ở dưới phần #include, để tránh một số lỗi ( điển hình là PhysicsContact.

2/ Số lưu ý về Function

contactListener->onContactBegin = CC_CALLBACK_1(GameScene::onContactBegin, this);

CC_CALLBACK_1 chứ ko phải là CC_CALLBACK_2

bool GameScene::onContactBegin(const PhysicsContact& contact)
chứ ko phải

bool GameScene::onContactBegin(EventCustom* event, const PhysicsContact& contact)


3/ Build Android

Bạn mở file Android.MK trong prj.android, thêm vào Class mới tạo như sau ( ví dụ file GameOverScene.cpp)









Chú ý dấu "\" ở dòng gần cuối cùng
Dòng cuối cùng ko cần dấu này

4/ Vòng lặp For cho Vector

vector<T> vec;
for(auto i : vec){} // Chuẩn C++ 11

5/ Phiên bản 3.1

Khi bạn download bản Cocos2d-x 3.1 mới nhất về, nếu build các Project cũ sẽ bị lỗi, nhiều lỗi là khác

Bạn cần phải tạo Project mới với v3.1, sau đó copy  Class+ Resource của Project cũ đè vào build là OK

6/ Build project trên Window, file chạy ở đâu?

Nhiều bạn hỏi mình build game trên win xong click ko chạy?

Đó là do các bạn build game trên win xong lại vào thư mục Proj.win32/Debug.win32 để chạy file Exe trong đó. Vâng, bạn có build 1000 lần thì cũng ko thể chạy nổi vì trong đó KHÔNG CÓ RESOURCE cho game nên Force Stop ngay

=> Các bạn phải vào thư mục PUBLISH ( ngang hàng Proj.win32, Class,.. ) đối với Engine 3.1, hoặc vào thư mục BIN ( cũng ngang hàng Proj.win32, Class,...) với Engine 3.0. Hãy nhớ kỹ!

7/ Chỉnh Độ phân giải (Resolution) trên Window

Khi bạn build ra Android, hoạc IOS, thì tỉ lệ khung hình ( độ phân giải - Resolution ) bạn chỉnh trong file AppDelegate.cpp ( game Sushi) rất dễ dàng. Tuy nhiên, và thường thì bạn sẽ build trên win trước để test game. vậy làm sao chỉnh độ phân giải??

Hãy làm như sau, tìm file CCGLView.cpp theo đường dẫn ( Nằm trong game nhé, không phải trong Engine)

YOURGAME\cocos2d\cocos\platform\desktop mở file CCGLView.cpp

search "960" sẽ thấy 1 dòng thế này ( dòng 288 thì phải )

if(ret && ret->initWithRect(viewName, Rect(0, 0, 960, 640), 1)) {

Đây chính là kích thước màn hình game trên Desktop, giờ thì chỉnh bao nhiêu tùy bạn thôi, tùy thuộc game ngang hay dọc mà chỉnh dài x rộng cho hợp lý.
Bạn chưa tin ư? Hãy nhìn, đã đủ 7 cột, 9 hàng chưa ( ở cuối bài 23 bạn build ra không đủ 7 cột, 9 hàng là do chưa chỉnh Resolution )


( Lại bảo ko đúng đi )

8/ Phân biệt các loại Macro CC_CALLBACK_x

Chắc có nhiều bạn từng thắc mắc cái dòng Macro ở trên vẫn hay dùng trong code nghĩa là gì, khi nào dùng phải không.

Xin trả lời: Mình thấy dùng trong mấy trường hợp sau đây

+ Trong menu để gọi tới hàm thực hiện khi nhấn 1 nút, ví dụ
    MenuItemFont *startNew = MenuItemFont::create("New Game", CC_CALLBACK_1(MenuLayer::onNewGame, this));

+ Trong đối tượng bắt sự kiện ( ví dụ Touch, Contact )
    contactListener->onContactBegin = CC_CALLBACK_1(HelloWorld::onContactBegin, this);

+ Trong Action Sequence

asteroid->runAction(Sequence::create(
MoveBy::create(randDuration, Point( - winSize.width - asteroid->getContentSize().width, 0)), 
CallFuncN::create(CC_CALLBACK_1(HelloWorld::setInvisible,this)), 
NULL
));   

Vậy dùng khi nào, ý nghĩa của các số 1,2

Thật ra có 4 Macro CC_CALLBACK_0, CC_CALLBACK_1, CC_CALLBACK_2, CC_CALLBACK_3

Số 0,1,2,3 chính là số tham số truyền vào của hàm được gọi.

Ví dụ hàm setInvisible(float af) thì khi gọi phải dùng CC_CALLBACK_1 ( vì có 1 tham số )

setInvisible(float af, int b)  thì khi gọi phải dùng CC_CALLBACK_2 ( vì có 2 tham số )

tương tự các trường hợp còn lại, và không có thấy CC_CALLBACK_4 à


Update thêm nhiều lắm!

Chúc các bạn sẽ có nhiều game hay!


Saturday, April 5, 2014

Bài 3: Hướng dẫn cài đặt Cocos2d - x V3.x trên Window theo từng bước, 100% Working

Trong bài 3 này mình sẽ hướng dẫn cụ thể các bạn cách cài đặt Engine Cocos2d - x V3.0 RC0 phiên bản mới nhất trên nền Window 7, vì máy mình chỉ có Win 7 thôi. Lưu ý Engine này không dùng với XP nhé. Phiên bản mới nhất tính đến thời điểm sửa bài là 3.2 RC0 ( các bạn chỉ nên sử dụng các phiên bản 0 có mã đằng sau, hoặc có mã RC.x mà ko nên xài các mã Alpha.x, Beta.x nhé). Giờ đã lên 3.3( tháng 12/2014 )

Việc cài đặt Engine này thật sự là khá phức tạp với nhiều người, bởi nó không đơn giản chỉ là chạy file setup.exe, rồi Next, Next, finish. Nó đòi hỏi phải cấu hình hệ thống, cài đặt các thành phần bổ trợ cho nó thì mới có thể chạy được. Và việc chạy nó cũng phải thông qua 1 chương trình Editor (Visual Studio chẳng hạn). Sẽ có bạn thắc mắc sao người phát triển ko làm kiểu file chạy Setup nhỉ? Hoàn toàn làm được nhưng khi đó bộ cài sẽ vài GB hoặc hàng chục GB do tích hợp vào trong nó hàng tá thứ khác ( như Android SDK, NDK, JDK, ...).


Trước đây mình cũng chỉ định cài bản 2.2.3 thôi vì có nhiều tài liệu hướng dẫn trên mạng, nhưng mình khuyên các bạn nên dùng bản mới nhất V3.0, vì bản cũ nêu trên đã lạc hậu cách đây hơn 1 năm rồi. Bản mới có rất nhiều cải tiến hay ho, do đó việc cài đặt cũng phức tạp không kém vì các lệnh , các thiết lập hầu như đổi mới hết. Thôi bắt đầu ngay nào.

1 Điều này mình phải nói trước để các bạn thông cảm là, hệ thống của mình chỉ có Win 7 - 32 bít, Ram 2G ( và 4G - máy công ty) nên nếu các bạn có hệ thống khác như Win 7-64, Win8, MacOS, Linux chỉ đọc tham khảo và cố gắng thử trên máy của các bạn, cách cài cũng gần tương tự thôi, chỉ khác dòng lệnh với từng hệ thống. Chắc vậy

Win7-64, Win8 Các thể loại cài Engine này không vấn đề gì nhé, Cách cài đặt cho phiên bản 3.x là như nhau, được trình bày ở bên dưới. Không dùng cho các bản Alpha, Beta ( Sửa ngày 7..11.14 )

(Sửa ngày 20/12/2014 - Cài đặt cho bản Cocos2d-x 3.3 Final)

* Chuẩn bị nguyên liệu, chú ý down đúng phiên bản cho máy 32 bít hoặc 64 bít

1) Bộ code Cocos2d-x ( không phải bản JS ) V3.0 ( 3.x -Đang max 3.3 - tháng 12/2014 ) FINAL  http://www.cocos2d-x.org/download.

2) Nền tảng Android ( để build apk file cho Android ) :

- ADT + miễn phí Eclipse:

http://developer.android.com/tools/sdk/eclipse-adt.html

Thời điểm hiện tại, Google ko tích hợp bộ SDK cùng Eclipse nữa, bạn phải down Android Studio về cài nhé, trong đó tích hợp SDK, link down đây

http://developer.android.com/sdk/index.html

Dùng bộ Android Studio của GG thì khỏi nói rồi, ai không thích thì cứ dùng Eclipse + Plugin ADT thôi.

- NDK9: https://developer.android.com/tools/sdk/ndk/index.html

* Lưu ý 1 chút, theo link trên thì không còn cho down bản 9, mà chỉ có bản 10, chia 2 platform 32, 64. ( ko nhớ là bản 9 có chia ra thế ko)
Cocos mới nhất 3.2 vẫn chỉ xài r9d trở xuống nhé, bản r10 bị lỗi khi build Android, mọi người chú ý, tìm trên mạng bản r9d-win86_64 mà download Ví dụ http://dl.google.com/android/ndk/android-ndk-r9d-windows-x86_64.zip

- Chú ý: Bản engine 3.3 update lên NDK10 nhé, fix cho Android 5 thì phải

- NDK 10 :http://developer.android.com/tools/sdk/ndk/index.html

- JDK7: ( có bản 8 nhưng mình vẫn xài 7.1), Ai xài 8 thì xài

http://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html

3) ANT 1.9.3 http://ant.apache.org/bindownload.cgi

4) Python 2.7.6 ( không xài 3.4 ): https://www.python.org/download/

5) Visual Studio 2012 ( Khuyên dùng ) - bạn tìm link mạng nhé + Visual Assist X10.8 http://www.vn-zoom.com/f103/red-face-visual-assist-x-10-8-2001-0-ci-hien-thi-cac-ham-cac-bien-cac-doan-chuong-trinh-mot-cach-ro-rang-2829579.html

Visual Assist X10.8 là Plugin để Auto complete code cực hay của Visual. Khuyên dùng sau thời gian học khoảng 1-2 tháng nhé.

* Lưu ý là:

- Bản mới V3.0 - 3.x không cần cài Cygwin như các bản cũ
- Các thành phần JDK, SDK,... Bạn phải down đúng phiên bản 32 bít, 64 bít tương ứng hệ điều hành của mình, trường hợp nào chỉ có 1 phiên bản ( ko ghi gì cả ) thì bạn vẫn cài đặt được cho cả 2 hệ thống 32, 64 (ví dụ ANT, Python)


Bạn làm theo các bước sau đây, đảm bảo cài đặt thành công, vì mình đã làm đi làm lại trên 2 máy mất gần 1 tuần mới thành công, rút ra kinh nghiệm cho mọi người.


Bước 1: Cài đặt JDK, Python như 1à soft thông thường

+ JDK: Cài như soft, nó sẽ tự tạo ra 1 biến trong System Environment,

JAVA_HOME = D:\Program Files\Java\jdk1.7.0_51

Nếu chẳng may xóa mất, bạn phải add lại  = tay

JDK 7, 8 đều OK. Ko nên xài JDK 6

Cài Python 2.7.5 như 1 Soft thông thường, nó sẽ cài vào D:\Python27 hoặc C:\Python27. mặc định window mình cài vào ổ D mà, hix.

Bước 2: Cài NDK, ADT, ANT, Cocos2d-x V3.0 Final - V3.x

NDK, ADT, ANT, Cocos2d-x V3.0 - 3.x thì chỉ việc giải nén vào trong thư mục như thế này

 + ANT:     Q:Android/ANT
 + SDK:     Q:Android/SDK
 + NDK:    Q:Android/NDK
 + Cocos2dx3 : Q:Android/Cocos2dx3

+ Với Android Studio, bạn cài như soft bình thường, rồi tìm đường dẫn của SDK nhé

Chạy file SDK.exe trong Q:\ANDROID\SDK, để cài đặt các bộ SDK của Android lên máy, chú ý là phải cài bản Android 2.3.3 - API 10 là bắt buộc nhé, còn đâu cài thêm bao nhiêu tùy bạn
Trên máy 64 bít buộc phải chạy Eclipse để chạy SDK Manager nha

Lưu ý là khi bạn giải nén ra thư mục, tên nó sẽ dài loằng ngoằng, bạn nên đặt gọn lại như trên để dễ quản lý.
Xong phần này


Bước 3: Thiết lập System Varialbe, RẤT QUAN TRỌNG, 

- Chuột phải Mycomputer/Properties/Advanced System setting/Environment Variables, ta có bảng nhỏ sau


Bạn để ý ở bảng Environment Variables có 2 ô, ô trên dành cho User đang dùng máy, và ô dưới là của System.

Bạn lần lượt thêm vào các biến môi trường sau. Trong này mình có 2 ổ đĩa là D (ổ win) và Q ( chứa data) bạn cần chú ý để thay thế tên ổ đĩa tương ứng trên máy mình.

Ở phần User, thêm vào các biến sau , Click vào nút New bên trên


ANDROID_SDK_ROOT = Q:\ANDROID\SDK\sdk

COCOS_CONSOLE_ROOT = Q:\ANDROID\Cocos2dx3\tools\cocos2d-console\bin;

Path = Q:\android\cocos2dx3\tools\cocos2d-console\bin;

* Lưu ý COCOS_CONSOLE_ROOT , Path  sẽ được tạo ra khi bạn chạy setup.py ( Bước 6)

Ở phần System, thêm vào các biến sau. Click vào nút New bên dưới

ANT_HOME = Q:\ANDROID\ANT

ANT_ROOT = Q:\ANDROID\ANT\bin

NDK_ROOT = Q:\ANDROID\NDK

Path = D:\Python27;D:\Python27\Python.exe;Q:\ANDROID\SDK\sdk\platform-tools;%path%;%ANT_HOME%/bin;

Bổ sung thêm biến này nhé (mới phát hiện)

CLASSPATH.;D:\Program Files\Java\jre6\lib\ext\QTJava.zip. ( có thể là JRE7, hoặc JRE8 tùy bản cài, có dấu "phẩy và chấm phẩy" ở đầu path nhé)

Với JDK 6 khi cài vào sẽ tự có, còn đối với các bạn cài JDK 7, 8 lần đầu thì phải thêm biến CLASSPATH này vào mới Build Android được.

* Lưu ý: Các biến Path, JAVA_HOME, thường là đã có sẵn, bạn chỉ việc bổ sung thêm vào biến Path đoạn trên cho phù hợp.

* Các giá trị của biến môi trường trên, không được có khoảng trắng ở đầu hoặc cuối, sẽ báo lỗi khi biên dịch


Bước 4: Test lại lần nữa

Chạy cmd, gõ vào lệnh

>java
 Nếu 1 đống sổ ra => JDK OK

 >ant --v
 1 đống sổ ra => ANT OK

 >adb
 1 đống => SDK OK

 >python
 hiện phiên bản => Python OK

Bước 5: Cài đặt Visual Studio 2012 và Visual Assist X 10.8 (KHUYÊN DÙNG)

- Cài và crack bình thường theo hướng dẫn trên mạng nhé các bạn nhé, cái này phục vụ cho việc code trên window, ai dùng Eclipse cũng ko sao, nhưng nghe nói là sắp tới ít hỗ trợ Eclipse, do Eclipse có lỗi quản lý gì đó.

- Để build trên window, bạn buộc phải cài VS 2012 nhé ( bản 2013 hơi khó cài với máy nào chưa có EXplorer 10 - hay 11 nhỉ, ko nhớ nữa). Khuyên dùng VS2012 Pro trở lên, mình xài Ultimate. Nhiều người xài VS 2013 cũng OK nhé

Bước 6: Chạy thử

Dùng CMD của Window (khuyên dùng)

D>q:
Q>cd android/cocos2dx3
Q/android/cocos2dx>setup.py

Nếu hiện bảng sau thì đã thành công 99%




Tắt cmd đi

Bật trở lại, Chúng ta bắt đầu SỬ DỤNG Cocos2dx V3.0 Final

Tạo 1 project mới

>cocos new hello -p com.vn.hello -l cpp -d q:/android/project

hoặc

>cocos new hello -l cpp -d q:/android/project


chạy cũng mất gần 5 phút nhé.

Đã xong, chạy thử nào

>cocos run -s q:android/project/hello -p win32

file build ra nằm trong q:android/project/hello/bin ( 3.0 ) ,  q:android/project/hello/publish (>3.1 )

bạn phải có Visual Studio 2012 cài sẵn thì mới dùng lệnh trên được
Lần build đầu tiên mất 5 -8 phút tùy máy , còn những lần sau, chỉ sửa code thì build nhanh thôi

Build cho Android nào, Nếu bạn đã cài SDK ( phải có android 2.3.3 - API 10) thì sẽ thành công thôi

>cocos compile -s q:/android/project/hello -p android --ap 16

hoặc như bên dưới, nó sẽ tự cài vào máy ảo
>cocos run-s q:/android/project/hello -p android --ap 16

Vào Q:\ANDROID\Project\hello\proj.android\bin\debug\android  (hoặc thư mục publish ), chạy file hello-debug.apk bằng máy ảo

>adb install Q:/ANDROID/Project/hello/proj.android/bin/debug/android/hello-debug.apk

hoặc cài trực tiếp vào máy điện thoại thật để test nhé

Vậy là đã Cài đặt thành công Cocos2d - x V3.0 Final - 3.x trên Window

P/S:

Các lệnh mới trên Cocos2d - x V3.0 FINAL - 3.x  (chạy bằng cmd của Window)

Tạo Project mới
cocos new NewProject -p com.vn.NewProject -l cpp -d Q:/android/myproject
(gõ cocos new -h để được help)

Biên dịch chương trình
Cho Android
cocos compile -s Q:/android/myproject/NewProject -p android --ap 16

Cho Window
cocos compile -s Q:/android/myproject/NewProject -p win32

(gõ cocos compile -h để được help)

Chạy chương trình

cocos run -s Q:/android/myproject/NewProject -p win32
cocos run -s Q:/android/myproject/NewProject -p android --ap 16

(gõ cocos run  -h để được help)

MỘT SỐ LƯU Ý KHÁC

Không build được với WIN32 
- Là do trước đó từng cài VS 2010 rùi xóa đi, nhưng vẫn còn trong registry của 64bit. Các bạn nào xài win 64bit bị lỗi này thì uninstall vs2010 rùi vào regedit và vào đây: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft xóa cái VisualStudio đi nhé, tiếp theo vào đây: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft tìm VisualStudio và xóa luôn, sau đó cài vs2012 hoặc vs2013 rồi run cocos lại là xong ^^
(Thanks to Dev Bananaer)

- Không build được Android: 
Bạn cd tới thẳng project của mình rồi dùng lệnh sau để chạy

cocos run -p android -j 4


Đã xong 1 bài rất dài, Nếu các bạn làm theo các bước trên ( Đặc biệt là bước 3) đảm bảo thành công.
nếu bạn nào ko thành công, cứ comment vào đây, mình giúp cho.

Chú ý: mình đã thử cài trên Win 7 64 bít ( do ham hố mới nâng Ram lên 4G), khi cài đặt chú ý down đúng các bản (JDK, NKD.vvv) hỗ trợ win 64 bít, cài như trên là OK. Nhiều bạn cài trên Win8 all cũng OK

+ Chỉ cẩn chú ý 1 điều là, các Project đã build trên Win32 ( chứa trong thư mục cũ ) khi cài win 64 vào không thể build lại được nhé. Nghĩa là bạn ko vác nguyên cái Project từ máy 32 sang máy 64 để build được ( chỉ tính build ra EXE, ko tính APK )

Giải pháp: Chúng ta chỉ việc giữ lại Classes và Resource sau đó tạo mới 1 project, copy lại Classes và Resource + Import các thư viện dùng thêm trong Project vào và build lại trên win 64 là ok. Đã test và thành công

+ Mỗi khi update lên phiên bản Engine version mới, bạn vẫn có thể build được những Project tạo ra bởi Engine version cũ ( Sẽ có lỗi xảy ra nếu version mới sửa đổi lại thư viện hàm ). Khi đó bạn phải cập nhật lại code của mình

+ Ngược lại khi bạn down Engine từ version mới về version cũ hơn ( nghĩ là ổn định hơn ) thì điều trên cũng có thể sẽ xảy ra ( và project lớn sẽ thường xảy ra ) cũng do sự khác nhau về thư viện hàm trong 2 phiên bản. Khi đó bạn cũng phải cập nhật code của mình về đúng cú pháp của phiên bản đó.

=> Tránh thay đổi Version khi chưa hoàn thành 1 Project bạn nhé.

(Đã có Video hướng dẫn ở đây nhé, Và nhớ bổ sung biến CLASSPATH )

(Sửa ngày 20.12.2014)

Bài 4: Chương trình đầu tiên "Hello World"