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.

I have the following camera written:

public class Camera
{
    public Vector2 Position;

    Viewport Viewport;

    public Matrix Transformation
    {
        get
        {
            return Matrix.CreateTranslation(new Vector3(-this.Position.X, -this.Position.Y, 0)) *

            Matrix.CreateRotationZ(0f) *
            Matrix.CreateScale(new Vector3(1f, 1f, 1)) *
            Matrix.CreateTranslation(new Vector3(Viewport.Width * 0.5f, Viewport.Height * 0.5f, 0));
        }
    }

    public Camera(GraphicsDevice device)
    {
        this.Position = Vector2.Zero;

        this.Viewport = device.Viewport;
    }
}

Now while this does work in tutorials where you have all your drawing in the Game.Draw like this:

protected override void Draw(GameTime gameTime)
        {
            this.GraphicsDevice.Clear(Color.SkyBlue);

            this.SpriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, cam.Transformation);

            this.Player.Draw(this.SpriteBatch);
            this.World.Draw(this.SpriteBatch);
            this.Enemies.Draw(this.SpriteBatch);

            this.SpriteBatch.End();

            base.Draw(gameTime);
        }

It fails when you have your code organized in DrawableGameComponents (which I have). Now, technically speaking I could add the Camera as a service in the game, retrieve it in the constructor of my DrawableGameComponents, add it as a field within the Component and then edit the spriteBatch.Begin() within the Draw of each component like it is shown above. So actually that it WOULD look like this:

public class TestComponent : DrawableGameComponent
    {
        Camera Camera;

        SpriteBatch Batch;

        public TestComponent(Game game)
            : base(game)
        {
            this.Camera = (Camera)this.Game.Services.GetService(typeof(Camera));
            this.Batch = (SpriteBatch)this.Game.Services.GetService(typeof(SpriteBatch));
        }

        public override void Draw(GameTime gameTime)
        {
            this.Batch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, this.Camera.Transformation);

            // draw the component

            this.Batch.End();

            base.Draw(gameTime);
        }
    }

But as you might already have guessed this is a bad idea because it's basically redundant.

Is there a way I can maintain this at a central location?

share|improve this question
    
Maybe I'm missing something, but what part of code is redundant? And if you want to do the same thing for all components, you can just create singleton class ;) –  zacharmarz Jul 11 '13 at 18:51
    
It'd be redudant because I had to to the constructor parts and the this.Batch.Begin part in every component. I could create a general class for components but this would great dependencies (a constructor with Game and Camera). Can you add an example for singleton? –  prc322 Jul 11 '13 at 18:56
    
dont use singletons, because they lead to very coupled code (immagine you would need to use it in another project, you would need to transfer every class which the singleton uses, for example a logger-singleton, gets fast really messy –  Quonux Jul 11 '13 at 19:00

3 Answers 3

I would it do the following basic way:

You have components and for each Component-Type you have a Class which does something with the components.

So this means for this particular question that you need a Class which knows the Camera transformation and does have a datastructure (the simplest is a array, followed by list or tree) with all Renderables.

UML style:

+ configure(Camera OfCamera)
+ renderAll()
- renderRenderable(Renderable OfRenderable)
+ add(Renderable Component)
+ remove(Renderable Component)    

- Array<Renderable> Renderables
- Camera OfCamera
share|improve this answer

If you care about constructor redundancy, you can create some base class DGCBase, which will inherit from DrawableGameComponent and every component will inherit it. Members (variables, functions, also constructor), which are common for all components will be in this DGCBase. And special functions will be in specific components.

But this.Batch.Begin will be in every component. Maybe after some time you will want to change it's parameters. But I think that this is not a lot of code to "copy".

Maybe you can create some functions like BeginDraw and EndDraw (which are part of Game class) and call them in each component's Draw function (at the beginning and end).

share|improve this answer
up vote 0 down vote accepted

The answer is simple

In your Game code:

    public override void Draw(GameTime gameTime)
    {
        this.Batch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend, null, null, null, null, this.Camera.Transformation);

        base.Draw(gameTime);

        this.Batch.End();
    }

tl;dr: Call Begin, call base.Draw(), call End. There seems to be the logic to dispatch the Draw and Update methods of all components in the base class Game.

share|improve this answer

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.