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

    Quản Lý Vị Trí Các Đối Tượng trong Game

    Cấu hình vị trí của các đối tượng trong Game để quản lý game đa màn hình.

    Ryan

    30/03/2015
    29/09/2020
    4 phút đọc
    Quản Lý Vị Trí Các Đối Tượng trong Game

    Thông thường khi khởi tạo 1 đối tượng trong game, các lập trình viên đều khởi tạo 1 vị trí nào đó cho chúng. Điều đó có nghĩa là các đối tượng luôn tồn tại trong game với 1 vị trí nào đó tuỳ thời điểm.

    Vị trí đó được thể hiện qua 2 con số xy, tương ứng với toạ độ của 1 điểm trên mặt phẳng. Tuy nhiên, cùng 1 tọa độ, nhưng khi lên 2 thiết bị có kích thước màn hình khác nhau thì vị trí (so với màn hình) hiển thị trên màn hình cũng khác nhau.

    Hơn nữa, trong games (games cỡ vừa hoặc lớn) không chỉ tồn tại 1 hay là 2 đối tượng mà lại có rất là nhiều, kéo theo việc kiểm soát và chỉnh sửa vị trí cho chúng khi cần thiết là rất khó khăn. Do vậy, việc quản lý các đối tượng trong games được đặc biệt quan tâm.

    Kế thừa từ bài viết Quản Lý Vị Trí Của Các Đối Tượng trong Cocos2d-x, tiến hành hiện thực lại lớp PositionManager.

    Ý tưởng

    Để tiện cho việc quản lý số lượng lớn vị trí của các đối tượng, tiến hành đưa tất cả chúng vào 1 file XML và lưu chúng dưới dạng key/value, đồng thời để hỗ trợ đa màn hình khi load các đối tượng lên game tiến hành thêm đoạn code sau vào hàm applicationDidFinishLaunching()

    // Set the design resolution
    glview->setDesignResolutionSize(width, height, ResolutionPolicy::EXACT_FIT);

    Trong đó:

    • width, height: kích thước background tương ứng được thiết kế.  
    • EXACT_FIT: 1 tuỳ chọn hình ảnh trong game sẽ co giãn theo kích thước của màn hình và không cần tuân theo tỷ lệ ban đầu của thiết kế.

    Hiện thực

    File plist lưu trữ vị trí các đối tượng

    Dưới đây là cấu trúc của 1 file plist để lưu trữ vị trí các đối tượng trong game.

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
           "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>sidebar_background</key>
        <string>-317,768</string>
    	<key>title</key>
        <string>317,1382</string>
    	
    	<key>score_gameplay</key>
        <string>317,768</string>
    	<key>score_lightmap_gamplay</key>
        <string>317,768</string>
    	<key>board_background_gameplay</key>
        <string>1341,768</string>
    	
    	<key>mode_light</key>
        <string>1024,768</string>
    	<key>icon_mode</key>
        <string>1024,768</string>
    </dict>
    </plist>

    PositionManager

    Tiến hành hiện thực lớp PositionManager như sau:

    class PositionManager
    {
    private:
        static PositionManager* m_instance;
        std::map<int, Vec2>		m_objPosMap;
     
    public:
        static PositionManager* getInstance();
    
        PositionManager();
        ~PositionManager();
     
    	void		loadObjectsPosition(const char* pListPath);
    	Vec2		getObjectPosition(int obj_id);
    };

    PositionManager được hiện thực với 2 phương thức chủ yếu là loadObjectsPosition và getObjectPosition

    Phương thức loadObjectsPosition

    Phương thức này load toàn bộ dữ liệu lưu trữ trong file plist và lưu trữ vào biến m_objPosMap.

    void PositionManager::loadObjectsPosition(const char* pListPath)
    {
    	auto objData = FileUtils::getInstance()->getValueMapFromFile(pListPath);
    	auto strToVec2 = [](std::string str) -> Vec2
    	{
    		Vec2 position;
    		int value = 0;
    
    		for (int i = 0; i < str.length(); i++)
    		{
    			if (str[i] != ',')
    			{
    				value *= 10;
    				value += str[i] - '0';
    			}
    			else
    			{
    				position.x = value;
    				value = 0;
    			}
    		}
    		position.y = value;
    		return position;
    	};
    
    	for (int i = 0; i < TOTAL_OBJ; i++)
    	{
    		m_objPosMap[i] = strToVec2(objData.at(OBJ_POS[i]).asString());
    	}
    }

    Trong đó:

    • TOTAL_OBJ: tổng số đối tượng được lưu trữ trong file.
    • OBJ_POS[i]: biến lưu trữ các key ở file plist.

    2 giá trị này sẽ giúp các bạn lấy được ở bên dưới.

    Phương thức getObjectPosition

    Vec2 PositionManager::getObjectPosition(int obj_id)
    {
    	return m_objPosMap.at(obj_id);
    }

    Phương thức getObjectPosition giúp lấy ra vị trí của 1 object khi ta truyền vào 1 obj_id tương ứng, vậy làm thế nào để biết được 1 obj_id nào của 1 đối tượng nào? Dưới đây sẽ hướng dẫn bạn thực hiện điều đó dễ dàng với 1 tool đơn giản do tạo ra trong quá trình thực hiện dự án, giờ sẽ chia sẻ cho các bạn điều đó.

    Tạo config từ các đối tượng lưu trữ trong file plist

    Nhằm tạo ra 1 file config gồm các ID tương ứng với các key  trong file plist, và lấy được 2 giá trị mà bên trên đã nói: TOTAL_OBJ, OBJ_POS[i], hiện thực 1 tool nhỏ bằng Python để tạo ra các config của các đối tượng như sau: 

    Tool

    from plistlib import readPlist
    
    FILE_NAME = 'cnf_objects_pos.plist'
    
    def getDefineStringFromKey(key, id):
        return '#define ID_POS_' + str.upper(key) + ' ' + str(id) + '\n'
    	
    def generateConfigForObject(objFile):
        pl = readPlist(objFile)
        index = 0
    
        obj_key_id = '#define PATH_CONF_OBJ_POS "' + objFile + '"\n'
        obj_key_id += 'extern const char* OBJ_POS[];\n'
        obj_key_name = 'const char* OBJ_POS[] = { \n'
        for key in pl:
            obj_key_id += getDefineStringFromKey(key, index)
            obj_key_name += '\t"' + key + '"' + ',\n'
            index += 1
    
        obj_key_name = obj_key_name[:-2]
        obj_key_name += '\n};\n'
        obj_key_id += '#define TOTAL_OBJ ' + str(index) + '\n'
    
        obj_key_name += '\n\n';
        obj_key_id += '\n\n';
        return obj_key_id, obj_key_name
    	
    res_h = '#ifndef __CONFIG_H__\n#define __CONFIG_H__\n\n'
    res_cpp = '#include "Config.h"\n\n'
    
    t = generateConfigForObject(FILE_NAME)
    res_h += t[0]
    res_cpp += t[1]
    
    res_h += '#endif\t//__CONFIG_H__'
    
    #Write output to file
    f = open('Config.h', 'w')
    f.write(res_h);
    f.close()
    
    f = open('Config.cpp', 'w')
    f.write(res_cpp)
    f.close()

    File Config.h

    #ifndef __CONFIG_H__
    #define __CONFIG_H__
    
    #define PATH_CONF_OBJ_POS "cnf_objects_pos.plist"
    extern const char* OBJ_POS[];
    #define ID_POS_MODE_LIGHT 0
    #define ID_POS_TITLE 1
    #define ID_POS_SIDEBAR_BACKGROUND 2
    #define ID_POS_SCORE_LIGHTMAP_GAMPLAY 3
    #define ID_POS_ICON_MODE 4
    #define ID_POS_BOARD_BACKGROUND_GAMEPLAY 5
    #define ID_POS_SCORE_GAMEPLAY 6
    #define TOTAL_OBJ 7
    
    #endif	//__CONFIG_H__

    File Config.cpp

    #include "Config.h"
    
    const char* OBJ_POS[] = { 
    	"mode_light",
    	"title",
    	"sidebar_background",
    	"score_lightmap_gamplay",
    	"icon_mode",
    	"board_background_gameplay",
    	"score_gameplay"
    };
    
    

    Download tool

    TOOL_DEMO.zip

    0 Bình luận
    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.

    Đề xuất

    Quản Lý Vị Trí Của Các Đối Tượng trong Cocos2d-x
    Hướng dẫn quản lý vị trí các đối tượng trong Cocos2d-x.

    Khám phá

    Thành Phần Hoá Các Đối Tượng Trong Game Với Cocos2d-x
    Hướng dẫn thành phần hoá các đối tượng trong game với Cocos2d-x
    9 Tính Năng Quan Trọng Trong C++11
    C++11 là một phiên bản cải tiến và nâng cấp từ C++98 (hay các bạn vẫn ...
    13/08/2015
    SOLID trong Lập Trình Hướng Đối Tượng
    SOLID trong lập trình hướng đối tượng có giá trị như thế nào trong việc ...
    Sử Dụng Auto Layout Sắp Xếp Các Đối Tượng UI
    Sử dụng AutoLayout để tự động sắp xếp layout và vị trí các component ...
    Giới Thiệu Ứng Dụng Của Làm Mờ Ảnh (Lọc Nhiễu) Trong Bài Toán Nhận Dạng
    Việc chọn phương pháp lọc nhiễu phù hợp sẽ giữ được các đặc trưng quan ...
    26/04/2016
    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
    Tìm hiểu về khái niệm UI và các đối tượng thiết kế UI trong Cocos2d-x ...
    Xây Dựng Game Đa Màn Hình - Gắn Anchor Point cho Các Đối Tượng UI
    Hướng dẫn thao tác gắn Anchor Point hỗ trợ game đa màn hình cho các đối ...
    Lọc Ảnh Bằng Phép Tương Quan Và Tích Chập
    Bài viết mô tả phép lọc ảnh sử dụng tương quan và tích chập trong lĩnh ...
    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.
    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