Giới thiệu
Box2D là cái tên mà mọi người biết đến là engine vật lý 2D tốt nhất hiện nay, điều này có thể hơi khó tưởng tượng khi có rất nhiều engine được đặt tên theo tên của các loài động vật, nhưng cái tên cũng chỉ là cái tên. Engine này khá nhẹ, hiệu quả, mạnh và tính tương thích cao, miễn phí và là mã nguồn mở. Website chính thức của Box2D là http://www.box2d.org .
Một engine vật lý mô phỏng môi trường vật lý của các object sao cho giống thật nhất. Mặc dù nó có thể được sử dụng cho các ứng dụng khác, Box2D được tạo ra chủ yếu làm thư viện sử dụng trong game. Engine này được viết và bảo trì bởi Erin Catto khi một ngày ông không hài lòng về engine vật lý mà ông đang làm việc.
Box2D được viết bằng C++, nhưng được chuyển sang nhiều ngôn ngữ khác bởi cộng đồng người sử dụng. Dưới đây là một số loại của Box2D, chúng ta có thể tìm hiểu thêm tại http://www.box2d.org/links.html :
- (Flash) http://www.box2dflash.org/
- (Flash) http://www.sideroller.com/wck/
- (Java) http://www.jbox2d.org/
- (Python) http://code.google.com/p/pybox2d/
- (Javascript) http://box2d-js.sourceforge.net/
- (C#) http://code.google.com/p/box2dx/
Engine vật lý không phải là một game engine. Box2D rất mạnh trong việc mô phỏng vật lý nhưng nó không được thiết kế để tận dụng sức mạnh đồ họa, network, xây dựng game hoặc load game level. Để đáp ứng những nhu cầu này, chúng ta có thể xem một trong những link dưới đây : - cocos2d iPhone : http://code.google.com/p/cocos2d-iphone/
- Citrus engine : http://citrusengine.com/
- Corona SDK : http://www.anscamobile.com/corona/
- Game salad : http://gamesalad.com/
- Pixelwave (iOS) : http://www.pixelwave.org/docs/Introduction_to_Pixelwave
- Dragonfire SDK : http://www.dragonfiresdk.com/
BODIES
Bodies là một đối tượng cơ sở trong lớp vật lý, nhưng chúng không phải là thứ chúng ta có thể thấy chúng chạy vòng quanh và va chạm với các đối tượng khác.
Chúng ta có thể xem body là các thuộc tính của một đối tượng mà chúng ta không thể thấy (draw) hoặc va chạm được (collide with). Những thuộc tính ẩn này gồm : - Mass : khối lượng
- Velocity : vận tốc và hướng di chuyển
- Rotational inertia : quán tính quay
- Angular velocity : vận tốc tiếp tuyến và độ lớn của vận tốc
- Location : vị tri
- Angle : hướng của vật thể
Mặc dù chúng ta đều biết tất cả đặc tính của một đối tượng, chúng ta vẫn không biết được nó như thế nào và cách mà nó xảy ra khi va chạm với các đối tượng khác. Để thiết lập kích thước và hình dạng của một đối tượng chúng ta sử dụng fixtures, chúng ta sẽ bàn đến fixtures ở phần sau.
Có 3 loại body : static (tĩnh), dynamic (động) và kinematic (động học). Hai loại đầu khá dễ hiểu khi đọc tên trong khi loại cuối cùng khá khó hiểu. Trước hết chúng ta thử tạo một đối tượng sử dụng dynamic body.
Tạo một body
Đầu tiên body được định nghĩa, sau đó sử dụng nó để tạo một body object.Điều này khá tiện khi chúng ta muốn tạo ra nhiều body giống nhau hoặc tương đương nhau. Dưới đây là code khởi tạo một body :
b2BodyDef myBodyDef;
myBodyDef.type = b2_dynamicBody; //this will be a dynamic body
myBodyDef.position.Set(0, 20); //set the starting position
myBodyDef.angle = 0; //set the starting angle
Lưu ý là body không có kích thước, hình dạng, vì vậy chúng ta không định nghĩa chúng ở đây. Có thể bạn sẽ tự hỏi tại sao không định nghĩa thuộc tính Mass – thong thường chúng ta thường định nghĩa thuộc tính mass cho một body bằng cách thêm một fixture vào body đó (sẽ được mô tả ở phần sau). Bây giờ chúng ta sẽ định nghĩa một thể hiện body :
b2Body* dynamicBody = m_world->CreateBody(&mybodydef);
Ở đây chúng ta sử dụng biến m_world là một đối tượng b2World. Đối tượng world giống như quản lý toàn bộ mọi thứ trong Box2D, nó xử lý việc tạo và xóa các đối tượng vật lý. Chúng ta sẽ xem xét các thuộc tính của B2Word sau. Bây giờ chúng ta đã có 1 body, nhưng một body cơ bản vẫn là một đối tượng cơ sở như đã nói ở phần đầu, vì vậy nếu chúng ta build và run chương trình chúng ta sẽ không thấy gì cả.
Để thiết lập kích thước, hình dạng cho một body chúng ta add fixture vào body đó. Ngoài ra, chúng sẽ mặc định ảnh hưởng thuộc tính mass của body. Một body có thể có nhiều fixture được add vào, mỗi fixture được add vào sẽ gây ảnh hưởng đến toàn bộ mass của body đó. Bây giờ chúng ta sẽ add một fixture đơn giản vào body mà chúng ta vừa tạo, một hình vuông :
b2PolygonShape boxShape;
boxShape.SetAsBox(1,1);
b2FixtureDef boxFixtureDef;
boxFixtureDef.shape = &boxShape;
boxFixtureDef.density = 1;
dynamicBody->CreateFixture(&boxFixtureDef);
Mặc dù hiện tại chúng ta có thể bỏ qua phần lớn code ở trên, tuy nhiên chúng ta cần lưu ý đến thuộc tính density. Thuộc tính mass được tính bằng cách lấy diện tích của fixture nhân với density của chúng. (density : mức độ dày đặc của một vật)
Bây giờ khi chạy chương trình, chúng ta sẽ thấy một hình vuông nhỏ rơi xuống dưới, chúng ta có thể sử dụng chuột để click vào nó và ném chúng xung quanh, nhấn phím R nếu nó rơi mất khỏi màn hình. Body dynamic có thể di chuyển, xoay và bị tương tác bởi trọng lực.

Thiết lập các thuộc tính của body
Bây giờ chúng ta sẽ thêm một số thuộc tính đã được nhắc ở phần đầu. Ví dụ chúng ta sẽ thay đổi vị trí và góc :
dynamicBody->SetTransform( b2Vec2( 10, 20 ), 1 );
Lúc này body sẽ ở vị trí (10, 20) theo trục tọa độ OpenGL (Gốc tọa độ ở góc dưới bên trái) và xoay 1 radian ngược chiều kim đồng hồ. Box2D sử dụng radian để đo độ lớn của góc, vì vậy nếu muốn chuyển từ radian sang độ và ngược lại chúng ta có thể dùng như sau :
#define DEGTORAD 0.0174532925199432957f
#define RADTODEG 57.295779513082320876f
dynamicBody->SetTransform( b2Vec2( 10, 20 ), 45 * DEGTORAD ); //45 degrees counter-clockwise
Chúng ta cũng có thể thiết lập vận tốc tịnh tiến và vận tốc tiếp tuyến của body :
dynamicBody->SetLinearVelocity( b2Vec2( -5, 5 ) ); //moving up and left 5 units per second
dynamicBody->SetAngularVelocity( -90 * DEGTORAD ); //90 degrees per second clockwise
Static bodies
Bây giờ chúng ta sẽ xem tác dụng của static body. Bởi vì chúng ta đã định nghĩa một body và một fixture, chúng ta có thể sử dụng lại chúng và thay đổi một số đặc tính cần thiết :
myBodyDef.type = b2_staticBody; //this will be a static body
myBodyDef.position.Set(0, 10); //slightly lower position
b2Body* staticBody = m_world->CreateBody(&myBodyDef); //add body to world
staticBody->CreateFixture(&boxFixtureDef); //add fixture to body
Lưu ý rằng chúng ta không cần phải thay đổi tất cả thuộc tính của fixture. Chạy chương trình và chúng ta sẽ thấy một hình vuông khác trên màn hình, nhưng làn này nó không di chuyển. Ngoài ra, chúng ta có thể setTransform để thay đổi vị trí cho static body nhưng không thể thiết lập vận tốc cho static body được, nó sẽ không có tác dụng.

Kinematic bodies
Cuối cùng, chúng ta sẽ xem kinematic body là gì. Như chúng ta thấy, dynamic bodies di chuyển và static bodies đứng yên. Khi một static body va chạm một dynamic body, static body luôn luôn giữ nguyên vị trí, và dynamic body sẽ bị phản lại vì vậy chúng không thể chồng lên nhau được. Kinematic body cũng khá giống với static body ở điểm khi chúng va chạm với một dynamic body nó luôn luôn giữ vị trí của nó và dynamic body bị dội ngược lại. Điểm khác biệt là kinematic body có thể di chuyển.
Chúng ta có thể thiết lập một kinematic body như sau :
myBodyDef.type = b2_kinematicBody; //this will be a kinematic body
myBodyDef.position.Set(-18, 11); // start from left side, slightly above the static body
b2Body* kinematicBody = m_world->CreateBody(&myBodyDef); //add body to world
kinematicBody->CreateFixture(&boxFixtureDef); //add fixture to body
kinematicBody->SetLinearVelocity( b2Vec2( 1, 0 ) ); //move right 1 unit per second
kinematicBody->SetAngularVelocity( 360 * DEGTORAD ); //1 turn per second counter-clockwise

Body trên màn hình có thể di chuyển và xoay, nhưng nó không chịu tác dụng của trọng lực, và không bị ảnh hưởng khi va chạm với một dynamic body. Lưu ý rằng khi nó va chạm với một static body, không có sự tương tác giữa chúng.
Trong hầu hết các game, dynamic body được sử dụng cho player và các nhân vật khác trong game, static body được sử dụng cho tường, nền đất và các thứ khác. Kinematic body được sử dụng cho những body có thể di chuyển và xoay nhưng không bị ảnh hưởng khi va chạm với dynamic body.
To be continue…










