Several gamestates: Problem with ortographic camera

I am making a 2d game that has several different game states. I basically add gamestates to a stack, and just call updates and draws to the topmost instance. I start the spritebatch before the draw call, and close it after.

I’ve done so since I have couple of different things going on. Menues. Part where you navigate the world map. Ship to ship combat. Some minigames. A platformer.

From my Game object.

   protected override void LoadContent()
        {
            var viewportAdapter = new BoxingViewportAdapter(Window, GraphicsDevice, 320 * (int)scale, 180 * (int)scale);
            _camera = new OrthographicCamera(viewportAdapter);
            _spriteBatch = new SpriteBatch(GraphicsDevice);
            transformMatrix = _camera.GetViewMatrix() * Matrix.CreateScale(Game1.scale, Game1.scale, 1.0f);
            GameStateManager.Instance.SetContent(Content);
            GameStateManager.Instance.AddScreen(new TitleScreenGameState(GraphicsDevice, _camera));
        }


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

            _spriteBatch.Begin(sortMode: SpriteSortMode.Immediate, samplerState: SamplerState.PointClamp, transformMatrix: transformMatrix);
          
            GameStateManager.Instance.Draw(_spriteBatch);
            base.Draw(gameTime);
            _spriteBatch.End();
        }

The problem I’ve run into is that I am unable to move the monogame extended ortographic camera. Everything renders just fine. Sprites that have the same coordinates as the camera moves, but the view remains fixed and the hero gladly just walks off the screen, never to be seen again.

I have suspected that it’s because I don’t pass the camera as a reference, but I’ve tried calling a static camera from the game class, but that did not fix the issue.

the problem lies in LoadContent
you setup your camera like:

_camera = new OrthographicCamera(viewportAdapter);

You need to update your camera every time you want to move, rotate or scale with code like :

            Transform = 
                        Matrix.CreateTranslation( Origin.X , Origin.Y , 0 ) *
                        Matrix.CreateScale( new Vector3( Scale , Scale , Scale ) ) *
                        Matrix.CreateRotationZ( Rotation ) * 
                        Matrix.CreateTranslation( -Position.X - View.X  , -Position.Y - View.Y  , 0 );

well I used this for 2D camera, but replace the 0 with you Z values for 3d camera, you can change the values to move the camera and update the transformation matrix as you need for your camera view.

1 Like

Thank you! That was just what I needed to wrap my brain around this.

I’ve messed around a bit in my Game file, the way you suggested, but not in the camera I tried to update in the top of the stack. The camera did indeed move around, even in gamestates from the stack.

Something like this made the camera move the way I desired.

transformMatrix = _camera.GetViewMatrix() * Matrix.CreateScale(Game1.scale, Game1.scale, 1.0f) * Matrix.CreateTranslation(new Vector3(testx, testy, 0));

Good. I think I am closer to getting a correct mental model of this. The actual camera is having an effect once it is passed to SpriteBatch.Begin();. Me messing around with the camera I’ve passed as a parameter to my gamestate stack will do nothing. Good. Now I know what tree to bark up.

Do you think I should try to call back to the camera in the Game object, so that I call SpriteBatch.Begin and SpriteBatch.End from the same place all the time, or should I transplant those to my several gamestates?

I usually have a Camera class that will handle everything from Camera calculations, and only set the position and update of that Camera in my Update process in the main game class, try to move out all the non core parts of your game to other parts so it is easier to read later.

1 Like

Ýou’re a treasure. Thank you!