Add a transformation matrix to spriteBatch.Draw().

Instead of having every drawable object know how to transform itself based on
the camera position, we pass in a transformation matrix to spriteBatch.Draw().
Unfortunately MonoGame only lets us specify a translation that works over an
entire SpriteBatch.Begin() call, so we need to begin & end separately for
objects that *aren't* supposed to translate at the same rate as the camera.

Fixes #39.

GitOrigin-RevId: afab72c39236b1b46fe1597412209981ddae9c7c
This commit is contained in:
Colin McMillen 2020-02-04 17:37:42 -05:00
parent 6b9890b6f7
commit ff0c9ddc26
5 changed files with 17 additions and 14 deletions

View File

@ -10,6 +10,7 @@ namespace SemiColinGames {
public int Width { get => bbox.Width; }
public int Height { get => bbox.Height; }
public int Left { get => bbox.Left; }
public int Top { get => bbox.Top; }
public void Update(Point player, int worldWidth) {
int diff = player.X - bbox.Center.X;

View File

@ -98,13 +98,12 @@ namespace SemiColinGames {
}
}
public static void Draw(SpriteBatch spriteBatch, Camera camera) {
public static void Draw(SpriteBatch spriteBatch) {
if (!Enabled) {
return;
}
foreach (var debugRect in rects) {
var rect = debugRect.Rect;
rect.Offset(-camera.Left, 0);
var color = debugRect.Color;
// top side
spriteBatch.Draw(
@ -123,7 +122,7 @@ namespace SemiColinGames {
Point[] points = Line.Rasterize(line.Start, line.End);
foreach (var point in points) {
spriteBatch.Draw(
whiteTexture, new Rectangle(point.X - camera.Left, point.Y, 1, 1), line.Color);
whiteTexture, new Rectangle(point.X, point.Y, 1, 1), line.Color);
}
}
}

View File

@ -294,14 +294,13 @@ namespace SemiColinGames {
}
}
public void Draw(SpriteBatch spriteBatch, Camera camera) {
public void Draw(SpriteBatch spriteBatch) {
int index = SpriteIndex(pose);
Rectangle textureSource = new Rectangle(index * spriteWidth, 0, spriteWidth, spriteHeight);
Vector2 spriteCenter = new Vector2(spriteWidth / 2, spriteHeight / 2 + spriteCenterYOffset);
SpriteEffects effect = facing == Facing.Right ?
SpriteEffects.FlipHorizontally : SpriteEffects.None;
Vector2 drawPos = new Vector2(position.X - camera.Left, position.Y);
spriteBatch.Draw(texture, drawPos, textureSource, Color.White, 0f, spriteCenter,
spriteBatch.Draw(texture, position.ToVector2(), textureSource, Color.White, 0f, spriteCenter,
Vector2.One, effect, 0f);
}
}

View File

@ -144,15 +144,20 @@ namespace SemiColinGames {
bgSource = new Rectangle(
(int) (camera.Left * 0.5), 0, camera.Width, camera.Height);
spriteBatch.Draw(grasslandBg1, bgTarget, bgSource, Color.White);
spriteBatch.End();
// Set up transformation matrix for drawing world objects.
Matrix transform = Matrix.CreateTranslation(-camera.Left, -camera.Top, 0);
spriteBatch.Begin(SpriteSortMode.Deferred, null, SamplerState.LinearWrap, null, null, null, transform);
// Draw player.
player.Draw(spriteBatch, camera);
player.Draw(spriteBatch);
// Draw foreground tiles.
world.Draw(spriteBatch, camera);
world.Draw(spriteBatch);
// Draw debug rects & lines.
Debug.Draw(spriteBatch, camera);
Debug.Draw(spriteBatch);
// Aaaaand we're done.
spriteBatch.End();

View File

@ -42,9 +42,8 @@ namespace SemiColinGames {
public Rectangle Position { get; private set; }
public Terrain Terrain { get; private set; }
public void Draw(SpriteBatch spriteBatch, Camera camera) {
Vector2 drawPos = new Vector2(Position.Left - camera.Left, Position.Top);
spriteBatch.Draw(texture, drawPos, textureSource, Color.White);
public void Draw(SpriteBatch spriteBatch) {
spriteBatch.Draw(texture, Position.Location.ToVector2(), textureSource, Color.White);
}
private Rectangle TextureSource() {
@ -125,9 +124,9 @@ namespace SemiColinGames {
new Vector2(Width + 1, 0), new Vector2(1, float.MaxValue));
}
public void Draw(SpriteBatch spriteBatch, Camera camera) {
public void Draw(SpriteBatch spriteBatch) {
foreach (Tile t in tiles) {
t.Draw(spriteBatch, camera);
t.Draw(spriteBatch);
}
}