STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • 0
    • Sao chép

    CBP-3: Khai Báo Component Cơ Bản, Tích Hợp Component vào Entity

    Khai báo component CAnimation để thêm hình ảnh hiển thị cho Entity, đây là một Component tiêu biểu và có liên quan đến một số Component khác nên tôi sẽ hiện thực để độc giả có được cái nhìn tốt nhất về hệ thống Component Base do tôi định nghĩa.
    20/08/2015
    15/09/2020
    6 phút đọc
    CBP-3: Khai Báo Component Cơ Bản, Tích Hợp Component vào Entity

    Giới thiệu

    Sau bài viết trước, component cơ sở CBaseEntity cơ bản đã được giới thiệu và khai báo. Bài viết này tiến hành nâng cấp CBase để định nghĩa Component tiêu biểu nhất và thêm vào Entity để kiểm tra.

    Tiến hành các bước cụ thể đối với CAnimation - Component quản lý hoạt ảnh của Entity.

    Tải project mẫu

    Đây là project ví dụ dùng trong bài viết: CBP-3-2019.zip.

    Project này có thể mở bằng Visual Studio 2019, project này chứa các file mã C++ của CBP, project có thể không tương thích với nhiều môi trường Visual Studio khác nhau nhưng có thể dành để tham khảo.

    Phân tích component quản lý hoạt ảnh

    Phân tích chức năng

    Component quản lý hoạt ảnh của Entity có nhiệm vụ quản lý hình ảnh hiển thị, 1 Entity có thể bao gồm nhiều loại hoạt ảnh khác nhau như đứng, ngồi, di chuyển, nhảy, ...

    Cần đảm bảo rằng Entity sẽ không có hình ảnh khi thiếu CAnimation vì nó nắm giữ thao tác draw của đối tượng game.

    CAnimation không quản lý những hình ảnh không phải là hình ảnh của đối tượng mà nó định nghĩa. Ví dụ: 1 đối tượng quái vật Slime sẽ có CAnimation chứa các hình ảnh về đứng, di chuyển, bị tấn công hay tấn công, ... chứ không chứa các hình ảnh như bụi bay sau bước nhảy, hiệu ứng ánh sáng lấp lánh quanh Slime, hiệu ứng nổ khi bị tấn công, ... các hình ảnh này thuộc về những Entity hiệu ứng sẽ được thêm vào sau này.

    Phân tích chức năng đặc thù

    CAnimation nắm giữ hoạt ảnh của Entity nên cần có phương thức hiển thị hình ảnh của Entity lên màn hình, đặt tên nó là phương thức draw.

    Khai báo cơ bản của CAnimation

    class CAnimation : public CBase
    {
    public: 
    	static CAnimation* addComponentTo(Entity* object, const char* resourcePath);
    
    	virtual int update(float deltaTime);
    	virtual int commandProcess(int command);
    
    	int draw();
    
    private:
    	CAnimation();
    	~CAnimation();
    
    private:
    	vector<FTexture*> m_animate;
    };

    Kế thừa từ CBase

    Như đã đề cập ở CBP-2, tất cả các lớp định nghĩa Component phải được kế thừa từ CBase nhằm thuận tiện cho công tác quản lý ở Entity.

    Phương thức addComponentTo

    Đây là 1 quy tắc riêng về hệ thống Component. Mỗi lớp Component phải có 1 phương thức addComponentTo để khởi tạo Component và thêm vào đối tượng được truyền vào. Do số lượng đối số cần để khởi tạo mỗi loại Component là khác nhau nên không thể khai báo phương thức này thuần ảo ở lớp CBase được.

    Phương thức update, commandProcess

    Đây là 2 phương thức cơ bản cho mỗi Component.

    • Phương thức update tập trung xử lý logic cho component (Animation sẽ tính toán thời gian chuyển frame, Physic sẽ tính toán va chạm, trọng lực, ...).
    • Phương thức commandProcess xử lý những Component Command nhận được từ Entity và đưa ra những phản ứng phù hợp với từng Command.

    Phương thức draw

    Đây là phương thức đặc trưng của CAnimation, phương thức này chịu trách nhiệm vẽ hình ảnh của Entity lên cửa sổ hiển thị.

    Constructor, Destructor

    Phương thức tạo và hủy đối tượng đặt trong tầm vực private nhằm ngăn developer khởi tạo mới Component 1 cách tự do. Ở đây, developer muốn tạo Component mới thì bắt buộc phải thông qua phương thức addComponentTo và cũng trong phương thức này, Component được sinh ra sẽ được thêm vào Entity được truyền vào, đảm bảo không có Component nào vô chủ.

    Thuộc tính m_animate

    Đây là thuộc tính đặc trưng của CAnimation, là nơi lưu trữ các hoạt ảnh hiển thị của Entity.

    Về kiểu dữ liệu FTexture có thể đọc lại bài CBP-1.

    Lưu ý

    Trong phạm vi chủ đề, tôi sẽ không giới thiệu sâu về các kỹ thuật khác, độc giả có thể tùy chỉnh Component sao cho phù hợp nhất với kỹ thuật và phương pháp hiện thực của bản thân, vì những khai báo này là không đầy đủ trong các dự án thật.

    Tích hợp component vào Entity

    File main.cpp, giả định mọi phương thức đã sẵn sàng để sử dụng và tiến hành khai báo như sau:

    Tại khu vực global:

    Entity* g_entity;

    Trong hàm init:

    g_entity = new Entity();
    CAnimation::addComponentTo(g_entity, "Resource\\logo.bmp");

    Trong hàm release:

    delete(g_entity);

    Trong hàm draw:

    g_entity->draw(hdc);

    Trong hàm update:

    g_entity->update(delta);

    Ở tầng developing, chỉ với những thao tác rất đơn giản như vậy là 1 Entity đã sẵn sàng được sử dụng.

    Sâu xuống nội dung các phương thức được sử dụng trên đây, lần lượt tiến hành định nghĩa như sau:

    CAnimation::addComponentTo

    // BASIC INIT FOR ANY TYPE OF COMPONENT
    CAnimation* result = new CAnimation();
    object->addComponent(result);
    result->m_owner = object;
    
    // SPECIAL INIT FOR THIS TYPE OF COMPONENT
    result->m_animate.push_back(new FTexture(resourcePath));
    result->m_currentAnimationIndex = 0; 
    
    return result;

    Tại đây ta thấy nhu cầu sử dụng xuất hiện thêm:

    • m_owner: lưu trữ liên kết đến Entity sử dụng Component này.
    • addComponent: phương thức của Entity nhằm đặt Component này vào danh sách Component mà nó sở hữu.
    • m_currentAnimationIndex: thuộc tính của Component lưu trữ số thứ tự của hoạt ảnh đang sử dụng trong m_animate.

    CAnimation::CAnimation

    m_typeID = ID::COMPONENT::ANIMATION;
    m_animate.clear();

    Tại đây, ta cần thêm m_typeID để lưu trữ ID của component, nhằm phân biệt Component này với các loại Component khác trong danh sách của Entity.

    CAnimation::draw

    m_animate.at(m_currentAnimationIndex)->draw(hdc);

    draw là phương thức có sẵn trong lớp FTexture nhằm vẽ ảnh đã load lên cửa sổ, tọa độ vẽ mặc định là 50, 50.

    Entity::draw

    for (CBase* component : m_components)
    {
    	if (component->getTypeID() == ID::COMPONENT::ANIMATION)
    	{
    		((CAnimation*)component)->draw(hdc);
    		break;
    	}
    }

    Lưu ý đây chỉ là định nghĩa tạm thời của phương thức này, hiện tại phương thức hoạt động bằng cách tìm Component có kiểu CAnimate sau đó ép kiểu trực tiếp để gọi phương thức đặc trưng draw, điều này hoàn toàn không nên. CBP-10 sẽ giải quyết hoàn thiện vấn đề này.

    Tại đây, xuất hiện thêm ID::COMPONENTgetTypeID. Bộ ID và phương thức này dùng để đánh dấu từng loại component trong danh sách Component của Entity, cụ thể, độc giả có thể xem trong ví dụ vì vấn đề này khá đơn giản và dễ hiểu.

    Entity::update

    for (CBase* component : m_components)
    	component->update(delta);

    Phương thức này đơn giản là gọi phương thức update của từng Component mà nó sở hữu, delta là thời gian của vòng lặp game vừa rồi.

    Tổng kết

    Sau bài viết này, chúng ta có 1 kết quả như sau khi chạy chương trình:

    Kết quả lập trình game CBP.

    Đây là định nghĩa của Component đầu tiên, thêm vào đó các thành phần quan trọng như phản ứng, command vẫn chưa có hoặc chưa hoàn chỉnh, gây khó khăn không nhỏ trong việc diễn đạt ý tưởng của hệ thống, qua những bài viết sau, ý tưởng cốt lõi của hệ thống CBP sẽ được thể hiện ngày càng rõ ràng hơn.

    Bài chung series

    0
    Lập Trình Game

    Lập Trình Game

    Kiến thức, kỹ thuật, kinh nghiệm lập trình game.

    Khi bạn nhấn vào liên kết sản phẩm do STDIO đề xuất và mua hàng, STDIO có thể nhận được hoa hồng. Điều này hỗ trợ STDIO tạo thêm nhiều nội dung hữu ích.. Tìm hiểu thêm.

    Đề xuất

    CBP-2: Khai Báo Component Cơ Sở và Entity Cơ Bản
    Tư tưởng của hệ thống Component - Entity trong Component Base ...
    CBP-8: Component Điều Khiển và AI – Component Ra Lệnh
    Component ra lệnh - các Component có khả năng gửi Entity Command cho ...

    Khám phá

    CBP-9: Bộ Khởi Tạo Entity – Factory và Hệ Thống ID
    Tổ chức lại CBP bằng cách tạo ra Factory, sản xuất Entity dựa vào các ID ...
    CBP-4: Giao Tiếp với Entity – Hệ Thống Chỉ Lệnh
    Hướng dẫn về hệ thống chỉ lệnh, bước đầu hiện thực ứng dụng hệ thống chỉ ...
    CBP-5: Truyền và Lấy Thông Số từ Component
    Giao tiếp giữa Component và Entity thông qua Command trong mô hình CBP.
    CBP-7: Cài Đặt Phản Ứng Cho Entity
    Thiết lập phản ứng của Entity nhằm điều khiển các Component trong CBP.
    CBP-0: Giới Thiệu về Component Base Development
    Phương pháp lập trình Hướng thành phần (Component-base Development - ...
    CBP-1: Tổng Quan về Project Ví Dụ
    Giới thiệu về Component Base Programming (CBP) - sơ lược về project ví ...
    CBP-10: Hệ Thống Quản Lý Tập Trung Các Component Đặc Thù
    Hệ thống quản lý tập trung các Component sử dụng phương thức đặc trưng.
    CBP-6: Hàng Đợi Chỉ Lệnh
    Chuẩn hóa các thao tác nhận và xử lý chỉ lệnh từ Component trong mô hình ...
    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020