2010-07-24 26 views
6

Tôi hiện đang tích hợp hệ thống thành phần thực thể, như được thấy here, với công cụ vật lý và công cụ đồ họa. Điều này là tốt cho đến khi gần đây quyết định rằng vật lý nên được chạy trong chủ đề riêng của nó. (Cảm ơn Glenn Fiedler!)Làm cách nào để làm cho chuỗi hệ thống thực thể thành phần của tôi an toàn?

Vì bây giờ tôi chỉ đơn giản là khóa một mutex được chia sẻ bởi tất cả các hệ thống phụ khi truy cập các thành phần.

Snippet từ vòng lặp vật lý:

lock_guard<mutex> lock(m_EntMutex); 
entitymap::iterator it; 
for (it = m_Ents.begin(); it != m_Ents.end(); ++it) 
{ 
    // Get physics component from entity 
    // This is guaranteed to work (component must exist for it to present in the map) 
    shared_ptr<comp_phys> phys(static_cast<comp_phys*>(it->second->getComponent(COMP_PHYS).lock().get())); 
    // Get resulting Box2D vector 
    b2Vec2 vec = phys->getBody()->GetPosition(); 

    // Get position component from entity 
    // Same as above, but this is the component shared with the graphics subsystem 
    shared_ptr<comp_pos> pos(static_cast<comp_pos*>(it->second->getComponent(COMP_POS).lock().get())); 
    // Update position component from Box2D vector 
    pos->setPosition(vec.x, vec.y, 0); 
} 

Snippet từ vòng lặp đồ họa:

lock_guard<mutex> lock(m_EntMutex); 
entitymap::iterator it; 
for (it = m_Ents.begin(); it != m_Ents.end(); ++it) 
{ 
    // Get position component from entity 
    // This is shared with the physics subsystem 
    shared_ptr<comp_pos> pos(static_cast<comp_pos*>(it->second->getComponent(COMP_POS).lock().get())); 
    // Get position from position component 
    doubleVec3 vec = p->getPosition(); 

    // Get graphics component from entity 
    shared_ptr<comp_gfx> gfx(static_cast<comp_gfx*>(it->second->getComponent(COMP_GFX).lock().get())); 
    // Update graphics component from position component 
    gfx->getObject()->getParentSceneNode()->setPosition(float(vec.x), float(vec.y), float(vec.z)); 
} 

Đây rõ ràng là một thực hiện rất ngây thơ, vì vậy tôi cố gắng làm cho các thành phần cá nhân có mutexes riêng của họ. Nó có vẻ là sự lựa chọn hiệu suất hợp lý, nhưng sau đó các kết quả vật lý (được truy vấn thông qua các thành phần vị trí) sẽ không luôn luôn nhất quán và đáng tin cậy.

Cách hiệu quả nhất để hoàn thành quá trình cập nhật trơn tru là gì? Tôi có nên để nó cập nhật toàn bộ thế giới trong một lần hay làm một cái gì đó tăng thêm?

Chỉnh sửa: Tôi nhận thấy rằng lược đồ chuyển đổi con trỏ không hoàn thiện, nhưng chúng ta hãy giả định rằng các con trỏ là hợp lệ.

Trả lời

2

Khi nói đến công cụ vật lý chạy trong công cụ trò chơi, tôi đề nghị bạn có một điểm đồng bộ một lần cho mỗi khung nơi bạn sao chép qua các vị trí/bất kỳ thông tin nào bạn có thể cần từ hệ thống vật lý vào hệ thống thành phần của bạn. Gọi nó là dubbel-buffering nếu bạn muốn. Một ví dụ bên trong và bên ngoài của vị trí của bạn (ma trận thế giới/vận tốc, vv).

Tối đa một khung thời gian trễ trên các vị trí vật lý không phải là điều mà bất kỳ người chơi nào sẽ nhận thấy.

Lưu ý khác, tôi thích triển khai các công cụ vật lý theo cách sử dụng càng nhiều chủ đề càng tốt trong khi phần còn lại của công cụ trò chơi tốt nhất không làm gì cả. Bullet và Havok dường như làm việc tốt nhất với giải pháp này.

+0

Tôi nên thêm rằng bạn muốn ngừng động cơ vật lý của mình tích hợp khi bạn thực hiện các điểm đồng bộ hóa. – Simon

+2

Tôi đồng ý. Có nhiều điểm đồng bộ có thể trông hiệu quả nhưng bạn vẫn cần phải tạo một rào cản trước khi vẽ cảnh, đánh bại mục đích của các khóa mỗi thành phần. Cũng lưu ý rằng bạn thường muốn cho phép vật lý chạy trên tốc độ khung hình khác với đồ họa. Tôi sẽ tập trung vào một khóa cho mỗi lần cập nhật vật lý và cho phép công cụ trò chơi nội suy từ dữ liệu vật lý gần đây trên mỗi khung đồ họa. –

Các vấn đề liên quan