Code tốt là tài liệu tốt nhất của bản thân. Gerald Weinberg
STDIO Tiếp tục chuỗi bài viết giới thiệu về thư viện vật lý trò chơi Box2D. Bài viết này giới thiệu về các loại joint có sẵn trong Box2D về khái niệm, tác dụng, cách khởi tạo, thiết lập cài đặt, và ví dụ về các loại joint này. Trong bài viết, các ví dụ được hỗ trợ bởi Cocos2d-x.
Nội dung bài viết

Giới thiệu

Ở các bài viết Box2D Box2D - Phần 3: Joint :: www.stdio.vn/articles/read/291/box2d-phan-3-joint và Box2D - Phần 4: Joint (Tiếp Theo) :: www.stdio.vn/articles/read/294/box2d-phan-4-joint-tiep-theo, tôi đã giới thiệu về một thành phần trong Box2D là joint và các loại joint có sẵn. Trong bài viết này, tôi sẽ tiếp tục giới thiệu về các loại joint khác có sẵn trong thư viện vật lý trò chơi Box2D.

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 Box2D để 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 tôi hướng đến các lập trình viên đã có kiến thức lập trình cơ bản về thiết kế và làm games 2D, và chưa có kiến thức đương tương.

Nội dung

Trong bài viết này tôi sẽ giới thiệu về các loại joint sau:

  • Prismatic joint.
  • Distance joint.
  • Rope joint.
  • Gear joint.
  • Line joint.
  • Weld joint.

Trong bài viết này, để giới thiệu về các loại joint trên, tôi sử dụng sự hỗ trợ của Cocos2d-x 3.4. Tôi tiếp tục sử dụng project có trong phần trước. Nếu bạn chưa có có thể download phần download của bài viết Box2D - Phần 4: Joint (Tiếp Theo) :: www.stdio.vn/articles/read/294/box2d-phan-4-joint-tiep-theo. Điểm lại những gì cần trong bài viết này:

  • Tạo một physics world.
  • Thêm tính năng debug draw để vẽ hình dạng body của các đối tượng.
  • Thêm touchs event.

Prismatic joint

Là loại joint mà các bodies tham gia vào cố định đến nhau, và chúng chỉ có thể di chuyển dọc theo một trục đã định. Prismatic joint có thể đưa ra các giới hạn để các bodies chỉ có thể di chuyển dọc theo các trục trong một phạm vi cụ thể. Bạn cũng có thể đưa các motor giống như revolute joint để cho các bodies di chuyển ở một tốc độ nhất định với một lực nhất định. Bạn sử dụng prismatic joint trong các trường hợp muốn tạo:

  • Thang máy.
  • Di chuyển cố định.
  • Cửa trượt.
  • Pistons

Ví dụ

Trong class HelloWorld tôi thêm phương thức prismaticJoint() để ví dụ cho joint này.

void HelloWorld::prismaticJoint() {	
	b2PrismaticJointDef prismaticJointDef;
	prismaticJointDef.bodyA = m_bodyA;
	prismaticJointDef.bodyB = m_bodyB;
	prismaticJointDef.collideConnected = true;

	prismaticJointDef.localAnchorA.Set(0, 0);
	prismaticJointDef.localAnchorB.Set(0, 0);

	//prismaticJointDef.enableLimit = true;
	//prismaticJointDef.lowerTranslation = 10;
	//prismaticJointDef.upperTranslation = 100;

	//prismaticJointDef.enableMotor = true;
	//prismaticJointDef.maxMotorForce = 50;
	//prismaticJointDef.motorSpeed = -5;

	m_prismaticJoint = (b2PrismaticJoint*)world->CreateJoint(&prismaticJointDef);
}

Distance joint

Đây là một loại joint dùng để duy trị một khoảng cách giữa hai đối tượng. Đối với mỗi body tham gia vào distance joint sẽ chọn ra một local anchors giống như revolute joint. Khoảng cách giữa hai đối tượng tham gia distance joint chính là khoảng cách giữa hai local anchors này.

Ví dụ

Trong class HelloWorld tôi thêm phương thức distanceJoint() để ví dụ cho joint này.

void HelloWorld::distanceJoint() {	
	b2DistanceJointDef distanceJointDef;
	distanceJointDef.Initialize(m_bodyA, m_bodyB, m_bodyA->GetWorldCenter(), m_bodyB->GetWorldCenter());
	m_distanceJoint = (b2DistanceJoint*)world->CreateJoint(&distanceJointDef);
}

Rope joint

Hãy tưởng tượng rằng bạn có một sợi dây chun, bạn có thể kéo dãn nó. Rope joint có tác dụng giống như cái dây chun này.

Ví dụ

Trong class HelloWold tôi thêm phương thức ropeJoint() để ví dụ cho joint này.

void HelloWorld::ropeJoint() {
	b2RopeJointDef ropeJointDef;
	ropeJointDef.bodyA = m_bodyA;
	ropeJointDef.bodyB = m_bodyB;
	ropeJointDef.localAnchorA.Set(0, 0);
	ropeJointDef.localAnchorB.Set(1, 1);
	ropeJointDef.maxLength = 10;
	ropeJointDef.collideConnected = true;
	m_ropeJoint = (b2RopeJoint*)world->CreateJoint(&ropeJointDef);
}
Phân tích

Về cơ bản, rope joint nhìn rất giống với distance jont ở cách khởi tạo cũng như chức năng. Rope joint khác distance joint ở chỗ:

  • Khoảng cách của distance được tính bởi khoảng cách hai điểm local anchor, còn khoảng cách của Rope joint chính là tính chất maxLenght của định nghĩa define.
  • Khoảng cách giữa hai đối tượng tham gia distance joint là không thay đổi. Còn với rope joint thì khoảng cách đối đa là maxLenght, và khoảng cách tối tiếu khi hai điểm local anchor trùng nhau.

Gear joint

Một gear joint được tạo ra bằng việc kết hợp giữa một revolure joint với prismatic joint.

Ví dụ

Trong class HelloWorld tôi thêm phương thức gearJoint() để ví dụ về loại joint này.

void HelloWorld::gearJoint() {
	b2RevoluteJointDef revoluteJointDef;
	revoluteJointDef1.Initialize(groundBody, m_bodyA, m_bodyA->GetWorldCenter());  
	revoluteJointDef1.bodyA = groundBody;
	revoluteJointDef1.bodyB = m_bodyA;
	revoluteJointDef1.localAnchorA.Set(0, 0);
	revoluteJointDef1.localAnchorB.Set(0, 0);

	m_revoluteJoint = (b2RevoluteJoint*)world->CreateJoint(&revoluteJointDef);

	b2Vec2 worldAxis = b2Vec2(1.0, 0.0);

	b2PrismaticJointDef prismaticJointDef;
	prismaticJointDef.Initialize(groundBody, m_bodyB, m_bodyB->GetWorldCenter(), worldAxis);
	prismaticJointDef.lowerTranslation = -5.0;
	prismaticJointDef.upperTranslation = 2.5;
	prismaticJointDef.enableLimit = true;
	prismaticJointDef.maxMotorForce = 1.0;
	prismaticJointDef.motorSpeed = 0.0;
	prismaticJointDef.enableMotor = true;

	b2PrismaticJoint* prismaticJoint = (b2PrismaticJoint*)world->CreateJoint(&prismaticJointDef);

	b2GearJointDef gearJointDef;

	gearJointDef.joint1 = m_revoluteJoint;
	gearJointDef.joint2 = prismaticJoint;
	gearJointDef.bodyA = m_bodyA;
	gearJointDef.bodyB = m_bodyB;
	gearJointDef.ratio = 2.0 *PI / (300 / PTM_RATIO);

	m_gearJoint = (b2GearJoint*)world->CreateJoint(&gearJointDef); 
Chú ý

Khi bạn khởi tạo một gear joint, các thành phần kết hợp là revolure joint và prismatic joint phải có body tham gia đầu tiên phải là static body.

ss_1

Weld joit

Là loại joint giúp cho các bodies tham gia vào joint luôn cùng hướng với nhau.

Ví dụ

Trong class HelloWorld tôi thêm một phương thức weldJoint() để ví dụ cho joint này.

void HelloWorld::weldJoint() {
	b2WeldJointDef weldJointDef;
	weldJointDef.Initialize(m_bodyA, m_bodyB, m_bodyA->GetWorldCenter());

	m_weldJoint = (b2WeldJoint*)world->CreateJoint(&weldJointDef);
}

Tổng kết

  • Bài viết này đã giới thiệu chi tiết về các joint: Prismatic, distance, rope, gear, weld. Đây chính là các loai joint còn lại có sẵn trong Box2D nhằm giúp bạn mô phỏng những đối tượng, hay hiện tượng phức tạp hơn.
  • Trong các ví dụ, tôi đều có sử dụng mouse joint lên m_bodyA (hình hộp). Bạn có thể click chuột vào và kéo để di chuyển để thấy cách các joint kia hoạt động. Chú ý, nếu bạn có gắng click chuột vào m_bodyB (hình tròn), chương trình sẽ bị crash.

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

JointExample

Tham khảo

http://www.iforce2d.net

Bạn cần hỗ trợ các dự án kết nối không dây?

Quí doanh nghiệp, cá nhân cần hỗ trợ, hợp tác các dự án IoT, kết nối không dây. Vui lòng liên hệ, hoặc gọi trực tiếp 0942.111912.

  • TỪ KHÓA
  • Arduino
  • ESP32
  • ESP8266
  • Wifi
  • Bluetooth
  • Zigbee
  • Raspberry Pi
THẢO LUẬN
ĐÓNG