Trong lập trình, việc gom nhóm các đối tượng để thực hiện từng chức năng riêng biệt là rất cần thiết. Việc phân chia các đối tượng và xử lý riêng biệt theo chức năng không chỉ giúp mã nguồn đỡ phức tạp mà còn tối ưu cho giai đoạn bảo trì sản phẩm sau này. Bài viết này nhằm chia sẻ về phương pháp lập trình này và cách hiện thực nó trong Cocos2d-x.
Tư tưởng thành phần hoá
Trong quá trình phát triển ứng dụng, việc phát sinh ra lỗi ở 1 thành phần nào đó trong ứng dụng là điều không thể tránh khỏi. Dự án càng lớn, việc phát hiện lỗi và chi phí cần sử dụng càng trở nên phức tạp hơn. Do đó nên quản lý dự án thành các thành phần riêng biệt.
Trong thực tế, đối với Project Sins phân chia Scene Gameplay thành các thành phần chính như sau:
- Background: hình ảnh nền của game. Background trong Sins bao gồm 1 bức ảnh tĩnh cùng với 1 số hiệu ứng đặc biệt.
- Sidebar: cột hiển thị thông tin bên trái của màn hình. Tại đây quản lý các thông số về Score, Highscore và 1 số button tuỳ chỉnh khác.
- Gameboard: khu vực chơi chính của game, quản lý các Sin, các hiệu ứng của Sin và hiệu ứng khác.
Ngoài ra còn có các component hỗ trợ như Popup, Notification,…
Với cách hiện thực này, các chức năng sẽ được gom nhóm lại để phát triển riêng biệt.
Các thành viên trong nhóm phát triển sẽ hiếm gặp tình trạng xung đột do nhiều người cùng thực hiện 1 công việc giống nhau. Mặt khác, khi cần bổ sung 1 chức năng, chẳng hạn như thêm 1 hiệu ứng vào background, sẽ dễ dàng nhận biết vị trí hiện thực của chức năng đó.
Hiện thực trong Cocos2d-x
Phần hiện thực chỉ nêu ra 1 số điểm cần lưu ý khi sử dụng phương pháp này trong Cocos2d-x.
Lớp SceneGamePlay của Project Sins được hiện thực như sau:
class SceneGamePlay : public SceneBase { public: static cocos2d::Scene* createScene(); virtual bool init(); virtual void onExit(); CREATE_FUNC(SceneGamePlay); protected: private: Sidebar* m_sidebar; Background* m_background; GameBoard* m_gameboard; };
3 Scene này bao gồm 3 component chính là:
- Sidebar
- Background
- GameBoard
Mỗi component là 1 node riêng biệt kế thừa từ Node của Cocos2d-x. Hiện thực các component này như sau:
class Background : public Node { public: virtual bool init(); virtual void onExit(); CREATE_FUNC(Background); protected: Sprite* m_background; NodeGrid* m_gridNodeTarget; Size m_visibleSize; Point m_origin; private: };
class Sidebar : public Node { public: virtual bool init(); virtual void onExit(); CREATE_FUNC(Sidebar); protected: Sprite* m_title; Sprite* m_background; };
class GameBoard : public Node { public: virtual bool init(); virtual void onExit(); CREATE_FUNC(GameBoard); protected: Sprite* m_gameboard; };
Không quá đi sâu vào phần hiện thực, việc sử dụng các component này rất đơn giản.
Trong SceneGamePlay.cpp, khởi tạo các component này bằng phương thức create()
và addChild
vào scene theo các lớp tương ứng:
m_background = Background::create(); this->addChild(m_background, Z_BACKGROUND); m_sidebar = Sidebar::create(); this->addChild(m_sidebar, Z_SIDEBAR); m_gameboard = GameBoard::create(); this->addChild(m_gameboard, Z_GAMEBOARD);
Đối với các thành phần riêng trong game, thao tác thực hiện cũng tương tự theo các bước:
- Khởi tạo component kế thừa từ Node.
- Cài đặt các phương thức
create()
,init()
,onExit()
và các phương thức cần thiết khác. - Sử dụng như 1 đối tượng bình thường, sử dụng thao tác
addChild
vào đối tượng khác để hiển thị và xử lý cho đối tượng đó.
Download Demo
Project Demo dưới đây là các thư mục Classes và Resources trong 1 project Cocos2d-x.
Khởi tạo project Cocos2d-x trên Windows trước và thay thế 2 folder tương ứng trong Demo.