Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

Thinking about a common game, doesn't matter the type of the game, it's very likely that we need some camera type. For example:

  • Debug camera: controlled by keyboard and mouse, with that we are able to move around in any place of our scene.
  • Scripted camera: with that we can instruct the camera to move around, following a determinate path.
  • Player camera.
  • ...

Each of these camera types has its own update function. The easiest (and bad) system,is to have a camera manager class with a generic update function and specialized update functions for every camera type. Inside the generic update function we have a switch statement that, based on the camera type, calls the proper update function.

Instead of this I've thought to another approach: strategy pattern. We move each camera behavior (update method) in an appropriate class that implements a common interface. In the camera manager we have a member to that interface, and we can set dinamically any behavior we want.

What do you think about that? What other systems do you suggest me? Thanks.

Additional info: there is the are real possibility that I need more than one camera active, for example for reflections. In short, I must take account also of that.

share|improve this question
    
Just saw your additional info note. Check my edit then. –  David Gouveia Dec 20 '11 at 20:49
add comment

1 Answer

up vote 10 down vote accepted

The strategy patterns seems like a good bet to me. To take it a step further, your camera manager should remain ignorant of the concrete camera types. You would register and change camera implementations externally by id (I used a string for flexibility but could be an enum or an int too), for instance (without any error checking):

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");
}

Edit

Additional info: there is the are real possibility that I need more than one camera active, for example for reflections. In short, I must take account also of that.

That's trivial to add. Just change currentCamera to:

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

Change SetCamera to ToggleCamera (or add a boolean to SetCamera, your choice):

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

And change the Update method to update all active cameras instead of only the current one:

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

In my example, you'd also need to replace the View property with a GetView method taking the id of the camera as parameter. But that's a detail that depends on your camera interface anyway:

// You could optionally add a check to see if the camera is active
Matrix GetView(string id) { return cameras[id].View; }
share|improve this answer
    
Yes, I like your approach. In fact, in my question, I've forgotten that the camera manager don't knows anything about the specific camera types, otherwise we have another switch statement for that. –  Andrea Benedetti Dec 20 '11 at 17:03
    
By the way, I noticed that you have two questions but never accepted an answer. Do you know how that's done? It's the button right below the downvote button. –  David Gouveia Dec 20 '11 at 18:07
    
Just don't go crazy over-engineering a solution, adding dependency injection, factory of factories, camera domain scripting languages; you know what I mean =) NOTE: It's entirely possible that you want more than 1 camera attached to a scene, don't lock yourself into an API that won't allow that concept. –  Patrick Hughes Dec 20 '11 at 19:09
    
@PatrickHughes, you're right. Probably I will need more than one camera attached to the scene (added in my question). –  Andrea Benedetti Dec 20 '11 at 20:45
1  
For having multiple cameras, I would recommend drawing what each camera sees to a RenderTarget, then using SpriteBatch to draw each one, Obviously scaling each one depending on how many cameras there are. –  Twitchy Dec 21 '11 at 1:07
show 3 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.