Thiết kế hệ thống camera


8

Suy nghĩ về một trò chơi thông thường, không quan trọng loại trò chơi, rất có thể chúng ta cần một số loại máy ảnh. Ví dụ:

  • Camera gỡ lỗi: được điều khiển bằng bàn phím và chuột, với điều đó chúng ta có thể di chuyển xung quanh ở bất kỳ nơi nào trong cảnh.
  • Camera theo kịch bản: với điều đó chúng ta có thể hướng dẫn camera di chuyển xung quanh, theo một đường dẫn xác định.
  • Máy ảnh cầu thủ.
  • ...

Mỗi loại máy ảnh này có chức năng cập nhật riêng. Hệ thống dễ nhất (và xấu) là có một lớp trình quản lý camera với chức năng cập nhật chung và các chức năng cập nhật chuyên biệt cho mọi loại camera. Bên trong chức năng cập nhật chung, chúng ta có một câu lệnh chuyển đổi, dựa trên loại máy ảnh, gọi chức năng cập nhật thích hợp.

Thay vì điều này tôi đã nghĩ đến một cách tiếp cận khác: mô hình chiến lược. Chúng tôi di chuyển từng hành vi camera (phương pháp cập nhật) trong một lớp thích hợp thực hiện giao diện chung. Trong trình quản lý camera, chúng tôi có một thành viên cho giao diện đó và chúng tôi có thể thiết lập bất kỳ hành vi nào chúng tôi muốn.

Bạn nghĩ gì về điều này? Những hệ thống khác mà bạn đề nghị cho tôi? Cảm ơn.

Thông tin bổ sung: có khả năng thực sự là tôi cần nhiều hơn một camera hoạt động, ví dụ như để phản chiếu. Nói tóm lại, tôi cũng phải tính đến điều đó.


Chỉ cần nhìn thấy ghi chú thông tin bổ sung của bạn. Kiểm tra chỉnh sửa của tôi sau đó.
David Gouveia

Câu trả lời:


11

Các mô hình chiến lược có vẻ như là một đặt cược tốt cho tôi. Để tiến thêm một bước, người quản lý máy ảnh của bạn nên không biết gì về các loại máy ảnh cụ thể. Ví dụ, bạn sẽ đăng ký và thay đổi cài đặt máy ảnh bằng id (Tôi đã sử dụng một chuỗi để linh hoạt nhưng cũng có thể là enum hoặc int) (không có bất kỳ kiểm tra lỗi nào):

public interface ICamera
{
    void Update(float dt);
    Matrix View { get; }
}

public class CameraManager
{
    private Dictionary<string, ICamera> cameras;
    private ICamera currentCamera;

    public void RegisterCamera(string id, ICamera camera) { cameras[id] = camera; }
    public void SetCamera(string id) { currentCamera = cameras[id]; }

    public void Update(float dt) { currentCamera.Update(dt); }
    public Matrix View { get { return currentCamera.View; } }
}

public class DebugCamera : ICamera {}
public class PlayerCamera : ICamera {}
public class ScriptedCamera : ICamera {}

void Test()
{
    // Create camera manager
    CameraManager cameraManager = new CameraManager();

    // Register cameras
    cameraManager.RegisterCamera("Debug", new DebugCamera());
    cameraManager.RegisterCamera("Player", new PlayerCamera());
    cameraManager.RegisterCamera("Scripted", new ScriptedCamera());

    // Change active camera
    cameraManager.SetCamera("Player");
}

Biên tập

Thông tin bổ sung: có khả năng thực sự là tôi cần nhiều hơn một camera hoạt động, ví dụ như để phản chiếu. Nói tóm lại, tôi cũng phải tính đến điều đó.

Đó là tầm thường để thêm. Chỉ cần thay đổi currentCamerathành:

List<ICamera> activeCameras = new List<ICamera>();

Thay đổi SetCamerathành ToggleCamera (hoặc thêm boolean vào SetCamera, lựa chọn của bạn):

void ToggleCamera(string id)
{
    ICamera camera = cameras[id];
    if(activeCameras.Contains(camera))
        activeCameras.Remove(camera);
    else
        activeCameras.Add(camera);
}

Và thay đổi Updatephương pháp để cập nhật tất cả các camera đang hoạt động thay vì chỉ một camera hiện tại:

void Update(float dt) { activeCameras.ForEach(c => c.Update(dt)); }

Trong ví dụ của tôi, bạn cũng cần thay thế thuộc Viewtính bằng một GetViewphương thức lấy id của máy ảnh làm tham số. Nhưng đó là một chi tiết phụ thuộc vào giao diện máy ảnh của bạn:

// You could optionally add a check to see if the camera is active
Matrix GetView(string id) { return cameras[id].View; }

Vâng, tôi thích cách tiếp cận của bạn. Thực tế, trong câu hỏi của tôi, tôi đã quên rằng người quản lý máy ảnh không biết gì về các loại máy ảnh cụ thể, nếu không, chúng tôi có một tuyên bố chuyển đổi khác cho điều đó.
bí ẩn

Nhân tiện, tôi nhận thấy rằng bạn có hai câu hỏi nhưng không bao giờ chấp nhận một câu trả lời. Bạn có biết làm thế nào được thực hiện? Đó là nút ngay bên dưới nút downvote.
David Gouveia

Đừng điên cuồng thiết kế quá mức một giải pháp, thêm tiêm phụ thuộc, nhà máy của các nhà máy, ngôn ngữ kịch bản miền máy ảnh; bạn biết ý tôi là gì =) LƯU Ý: Hoàn toàn có thể bạn muốn có nhiều hơn 1 camera được gắn vào một cảnh, đừng tự khóa mình vào một API không cho phép khái niệm đó.
Patrick Hughes

@PatrickHughes, bạn nói đúng. Có lẽ tôi sẽ cần nhiều hơn một camera gắn liền với cảnh (được thêm vào câu hỏi của tôi).
enigma

1
Để có nhiều camera, tôi khuyên bạn nên vẽ những gì mỗi camera nhìn thấy vào RenderTarget, sau đó sử dụng SpriteBatch để vẽ từng camera, Rõ ràng là chia tỷ lệ cho từng camera tùy thuộc vào số lượng camera.
FrenchyNZ
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.