STDIO
Tìm kiếm gần đây

    Nội dung

    Chipmunk - Phần 3: Constraints

    23/01/2015
    Chipmunk - Phần 3: Constraints
    Tiếp tục loạt bài viết giới thiệu về thư viện vật lý trò chơi Chipmunk. Trong bài viết này tôi sẽ giới thiệu về constraints và các loại constraint có sẵn trong thư viện chipmunk.

    Giới thiệu

    Trong các bài viết Chipmunk - Phần 1: Giới Thiệu :: www.stdio.vn/articles/read/277/chipmunk-phan-1-gioi-thieu và Chipmunk - Phần 2: Một Số Thuật Ngữ Và Khái Niệm :: www.stdio.vn/articles/read/292/chipmunk-phan-2-mot-so-thuat-ngu-va-khai-niem, tôi đã giới thiệu về các thuật ngữ và các khái niệm cơ bản có trong thư viện vật lý Chipmunk. Trong bài viết này tôi sẽ tiếp tục giới thiệu tiếp một thành phần đó chính là constraints. Constraints sẽ giúp cho lập trình viên có thể mô phỏng những hiện tượng vật lý phức tạp hơn, đáp ứng nhu cầu trong games hơn. Sau bài viết này tôi tin bạn sẽ có những trải nghiệm thú vị.

    Tiền đề bài viết

    Trong nhiều games hiện nay, việc mô phỏng thế giới vật lý vào trong games không còn gì xa lạ. Bài viết này nằm trong loạt bài viết giới thiệu về thư viện vật lý trò chơi Chipmunk để giúp bạn mô phỏng các hiện tượng vật lý vào trong games.

    Bài viết nằm trong những loạt bài viết của chương trình Tự Học Cocos2d-x 3.x.x:: www.stdio.vn/programs/content/2/lap-trinh-game-voi-cocos2dx của Stdio.vn :: www.stdio.vn.

    Đối tượng hướng đến

    Bài viết này tôi hướng đến những bạn đã có kiến thức cơ bản về lập trình games với cocos2d-x.

    Constraints

    • Một constraints là thứ dùng để mô tả làm thế nào để hai đối tượng có thể tương tác với nhau. Bạn có thể nghĩ rằng constraints giống như các khớp trên cơ thể của bạn.
    • Tất cả các loại loại constraints có sẵn trong Chipmunk đều có lớp cha là PhysicsJoint.  

    Thuộc tính chung

    Tất cả các loại joint có sẵn trong Chipmunk đều có lớp cha là class PhysicsJoint. Vì vậy các joint có các thuộc tính chung sau:

    • Body: Trong tất cả các loại joint đều có hai bodies. Một bodies trong joint đó có thể là static. 
    • Collision Enable: Thuộc tính xác định xem các bodies tham gia vào joint có va chạm được với nhau hay không. Mặc định là false.
    • Max force: Giá trị thiết lập lực tối đa giữa các bodies.

    Xóa một joint

    Để xóa một joint trong Chipmunk. Bạn có thể dùng một trong những cách sau đây.

    m_joint->removeForWorld();              
    m_world->removeJoint(m_joint, true);
    m_world->removeAllJiont(true);
    
    Phân tích
    • Dòng 1: Với m_joint là một Joint được tạo. Bạn remove joint này ra khỏi Physics World.
    • Dòng 2: Từ Physics World, bạn remove một joint. Ở phương thức này có hai tham số:
      Joint: Tên joint bạn muốn remove.
      Destroy: Giá trị xác định xem bạn muốn remove joint bạn muốn ra khỏi physics world hay không? Giá trị mặc định là true.
    • Dòng 3: Từ Physics World, bạn remove tất cả các Joint đã được tạo và hiện đang tồn tại trong Physics World. Phương thức này có một tham số là destroy (Giá trị xác định xem bạn muốn remove tất cả các jont có trong physics world hay không?). Giá trị mặc định là true.

    Khởi tạo một joint

    Vì tất cả các Joint đều có chung lớp cha, vậy nên các joint đều được khởi tạo bằng phương thức construct(). Sau đó đều được thêm vô Physics World hiện tại bằng phương thước addJoint().

    PhysicsJointPin* joint = PhysicsJointPin::construct(bodyA, bodyB, location);
    m_world->addJoint(joint);
    

    Constraints type

    Pin joints

    Pin joints là joint mà bạn sẽ phải thiết lập một điểm xác định (Điểm pin). Các đối tượng tham gia vào sẽ liên kết với nhau bằng điểm pin này. Chúng có thể quay quanh điểm pin.

    PhysicsJointPin* m_joint = PhysicsJointPin::construct(m_bodyA, m_bodyB, location);

    Hoặc:

    PhysicsJointPin* m_joint = PhysicsJointPin::construct(m_bodyA, m_bodyB, anchr1, anchr2);
    Phân tích
    • m_bodyA, m_bodyB: Các bodies tham gia Pin Joint.
    • Có 2 cách để thiết lập điểm pin của các bodies.
      - Cách 1: Thiết lập một giá trị trên màn hình. Ở ví dụ trên là tham số location
      - Cách 2: Thiết lập hai giá trị Local Anchor của các bodies. Sau đó khi khởi tạo. Điểm Local Anchor của body tham số đầu tiên (m_bodyA) sẽ di chuyển trùng với điểm Local Anchor của body tham số thứ hai (m_bodyB). Từ đó ra được điểm pin.
    Chú ý

    Trong quá trình các bodies di chuyển. Bạn có thể thấy rằng đôi lúc điểm pin sẽ có 2 điểm. Đây chính là các điểm Local Anchor của các bodies tham gia vào joint.

    ss_1

    Distance joints

    Là joint có tác dụng thiết lập một khoảng cách giữa hai bodies.

    PhysicsJointDistance* m_joint = PhysicsJointDistance::construct(m_bodyA, m_bodyB, anchr1, anchr2);
    Phân tích

    Khoảng cách giữa hai bodies này được tính bằng khoảng cách giữa các điểm Local Anchor của các bodies. Ở trên là giữa điểm anchr1 (m_bodyA) và anchr2 (m_bodyB).

    ss_2

    Fixed joints

    Bạn có thể dễ dàng khởi tạo một Fixed Joint như sau:

    PhysicsJointFixed* joint = PhysicsJointFixed::construct(ballBody, paddleBody, location);

    Fixed Joint cũng giống như Pin Joint. Nhưng khác nhau ở chỗ:

    • Fixed Joint chỉ cần xác định một điểm location trên màn hình. Vì vậy chỉ có một cách tạo joint này. Còn với Pin Joint là có hai cách khởi tạo.
    • Nếu bạn cố gắng di chuyển một body trong Fixed Joint. Từ một điểm location sẽ có hai điểm, và dao động của hai điểm này mạnh hơn ở Pin Joint.

    Limit joints

    Limit Joints khá giống với Distance Joints, nhưng khác ở chỗ là khoảng cách của  có thể thay đổi. Bạn có thể tưởng tượng rằng Limit Joint là một sợi dây chun nối các bodies lại.

    PhysicsJointLimit * m_joint = PhysicsJointLimit::construct(ballBody, paddleBody, anchr1, anchr2);
    

    Hoặc:

    PhysicsJointLimit * m_joint = PhysicsJointLimit::construct(ballBody, paddleBody, anchr1,anchr2,
                                                                lengMin, lengMax);
    Phân tích
    • Với phương thức khởi tạo đầu tiên, khoảng cách xa nhất giữa hai bodies là khoảng cách giữa hai điểm Local Anchor. Khoảng cách gần nhất là 0.
    • Với phương thức khởi tạo thứ hai, đã có thêm hai tham số lengMin và lengMax lần lượt là khoảng cách xa nhất và gần nhất giữa hai bodies.
    • Với các điểm local anchor là các điểm xác định với hệ tạo độ gốc gắn với body của nó. Vì vậy cách tạo thứ nhất thường gây ra kết quả không như mong muốn. Tôi khuyến khích cách thứ hai để khởi tạo một Limit Joint.

    Spring joints

    Spring Joints cũng giống như Distance Joints hay Limit Joints. Cũng là kết nối giữa hai bodies, nhưng không phải bằng một khoảng cách nhất định hay co giãn giống như sợi dây chun. Ở đây kết nối giữa hai bodies bằng một cái lò xò.

    PhysicsJointSpring * joint = PhysicsJointSpring::construct(ballBody, paddleBody, 
                                                               anchr1, anchr2, stiffness, damping);

    Với hai tham số stiffness và dampint là thiết lập tính chất của lò xò.

    Groove joints

    Bạn có hai bodies tham gia vào joint. Một body gắn với một đoạn thằng. Một body gắn với một Local Anchor. Khi bạn thiết lập một Groove Joint và cố gắng di chuyển một trong các bodies thì điểm Local Anchor này sẽ di chuyển trên đoạn thẳng.

    PhysicsJointGroove * joint = PhysicsJointGroove::construct(ballBody, paddleBody,
                                                              grooveA, grooveB, anchr2);
    Chú ý
    • Để tìm đoạn thằng (màu xanh dương) thì cần 2 tham số là grooveA và grooveB lần lượt là điểm đầu và cuối của đoạn thẳng.
    • Điểm Local Anchor (màu xanh lá) được xác định từ body tham số thứ hai (paddleBody).
    • Khi khởi tạo một Groove Joint. Nếu điểm Local Anchor không nằm trên đoạn thẳng. Lúc này đoạn thẳng sẽ dịch chuyển sao cho phù hợp để điểm Local Anchor nằm trên đoạn thẳng.

    ss_3

    Tác động vào bodies trong physics world

    Làm sao để bạn có thể tác động vào một body trong Physics World. Trong Chipmunk không có một joint này giống như Mouse Joints trong Box2D mà bạn có thể sử dụng để làm điều này. Nhưng bạn không cần lo lắng. Bạn chỉ việc kết hợp Pin Joints với Touches Event để có thể giúp bạn. Đoạn code dưới đây giúp bạn có thể giữ click mouse vào body đã chọn là di chuyển body đó theo vị trí của mouse.

    std::unordered_map<int, Node*> _mouses;
    
    bool onTouchBegan(Touch* touch, Event* event)
    {
    	auto location = touch->getLocation();
    	auto arr = m_world->getShapes(location);
    
    	PhysicsBody* body = nullptr;
    	for (auto& obj : arr)
    	{
    		if ((obj->getBody()->getTag() & DRAG_BODYS_TAG) != 0)
    		{
    			body = obj->getBody();
    			break;
    		}
    	}
    
    	if (body != nullptr)
    	{
    		Node* mouse = Node::create();
    		mouse->setPhysicsBody(PhysicsBody::create(PHYSICS_INFINITY, PHYSICS_INFINITY));
    		mouse->getPhysicsBody()->setDynamic(false);
    		mouse->setPosition(location);
    		this->addChild(mouse);
    		Vec2 anchr1 = Vec2(0, 0);
    		Vec2 anchr2 = Vec2(0, 0);
    		PhysicsJointPin* joint = PhysicsJointPin::construct(mouse->getPhysicsBody(), body, location);
    		joint->setMaxForce(5000.0f * body->getMass());
    		m_world->addJoint(joint);
    		_mouses.insert(std::make_pair(touch->getID(), mouse));
    
    		return true;
    	}
    	return false; 
    }
    
    void onTouchEnded(Touch* touch, Event* event)
    {
    	auto it = _mouses.find(touch->getID());
    
    	if (it != _mouses.end())
    	{
    		this->removeChild(it->second);
    		_mouses.erase(it);
    	}
    }
    
    void onTouchMoved(Touch* touch, Event* event){
    	auto it = _mouses.find(touch->getID());
    
    	if (it != _mouses.end())
    	{
    		it->second->setPosition(touch->getLocation());
    	}
    }

    Tổng kết

    Ở bài viết này tôi đã giới thiệu về một số joints có sẵn trong Chipmunk. Ở bài viết tiếp theo tôi sẽ giới thiệu các joints còn lại. Ở phần download là project của tôi ví dụ về Pin Joints. Với các joint còn lại chỉ còn là việc bạn thiết lập các tham số sao cho đúng với mục đích thiết kế của bạn.

    Mọi thắc mắc bạn có thể bình luận tại bài viết hoặc liên hệ với Trương Đạt :: www.stdio.vn/users/index/11/truong-dat.

    Download

    Constraints_Example

    Tham khảo

    http://www.cocos2d-x.org

    Thảo luận

    Đăng nhập

    Bài viết liên quan

    Chipmunk - Phần 4: Constraints (Tiếp Theo)

    Chipmunk - Phần 4: Constraints (Tiếp Theo)

    Tiếp tục loạt bài viết giới thiệu về thư viện vật lý trò chơi Chipmunk. Trong bài viết này tôi sẽ giới thiệu về constraints và các loại constraint ...

    Trương Xuân Đạt

    23/01/2015

    Chipmunk - Phần 5: Ray Casting

    Chipmunk - Phần 5: Ray Casting

    Tiếp tục loạt bài viết giới thiệu về thư viện vật lý trò chơi Chipmunk. Trong bài viết này tôi sẽ giới thiệu về một thành phần mới là Ray Casting ...

    Trương Xuân Đạt

    23/01/2015

    Chipmunk - Phần 2: Một Số Thuật Ngữ Và Khái Niệm

    Chipmunk - Phần 2: Một Số Thuật Ngữ Và Khái Niệm

    Tiếp tục loạt bài viết giới thiệu thư viện vật lý trò chơi Chipmunk. Tìm hiểu về một số khái niệm và thuật ngữ trong Chipmunk, cách di chuyển các bodies, va ...

    Trương Xuân Đạt

    23/01/2015

    Chipmunk - Phần 1: Giới Thiệu

    Chipmunk - Phần 1: Giới Thiệu

    Bài viết này trong loạt bài viết của tôi giới thiệu về thư viện vật lý trò chơi Chipmunk. Trong bài viết này sẽ giới thiệu các khái niệm và thuật ...

    Trương Xuân Đạt

    23/01/2015

    Hiện Thực Game Zero Với Unity - Phần 3 - Điểm Số Và Progress Timer

    Hiện Thực Game Zero Với Unity - Phần 3 - Điểm Số Và Progress Timer

    Tiếp tục chuỗi bài viết Hướng Dẫn Hiện Thực Game Zero Với Unity, ở phần trước, tôi đã giới thiệu và hướng dẫn các bạn cách hiện thực gameplay của game Zero. Trong phần 3 ...

    Rye Nguyen

    10/08/2015

    UI - Phần 2: Thiết Kế UI Trong Cocos2d-x 3.x.x

    UI - Phần 2: Thiết Kế UI Trong Cocos2d-x 3.x.x

    Ở bài viết UI Phần I: Khái Niệm Và Một Số Đối Tượng Để Thiết Kế UI Trong Cocos2d-x 3.x.x, tôi đã giới thiệu cho các bạn UI là gì? Các thành phần của UI,… và đối tượng ...

    Trương Xuân Đạt

    23/01/2015

    Box2D - Phần 1: Giới Thiệu Và Một Số Thuật Ngữ Và Khái Niệm

    Box2D - Phần 1: Giới Thiệu Và Một Số Thuật Ngữ Và Khái Niệm

    Giới thiệu về engine vật lý sử dụng trong games là Box2D. Giới thiệu Box2D, các khái niệm, cách thành phần liên quan, cách khởi tạo và thao tác với một số thành phần ...

    Trương Xuân Đạt

    23/01/2015

    Học SEO Trong 1 Ngày - Phần 3

    Học SEO Trong 1 Ngày - Phần 3

    Sau bước phân tích keyword theo hướng người dùng, đây là bước bắt tay vào kỹ thuật để đáp ứng các vấn đề SEO (On-Page SEO).

    STDIO SolutionsSEO

    11/07/2020

    Box2D - Phần 2: Thuật Ngữ Và Khái Niệm

    Box2D - Phần 2: Thuật Ngữ Và Khái Niệm

    Tiếp tục loạt bài viết tìm hiểu về thư viện vật lý trò chơi Box2D. Trong bài viết này giới thiệu về collision, bắt sự kiện collision, collision filtering và hiện thực, ...

    Trương Xuân Đạt

    23/01/2015

    Xử Lý Với File JSON Trong Cocos2d-x 3.x.x

    Xử Lý Với File JSON Trong Cocos2d-x 3.x.x

    JSON đóng góp vai trò quan trọng trong nhiều lĩnh vực cũng như lập trình game trong việc tăng hiệu suất của chương trình, giúp lập trình viên dễ dàng đọc và viết, dễ phân ...

    Lê Viết Duy

    12/06/2017

    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
    [email protected]

    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