public override void Draw() { var startingPosition = new Vector2(100, 100); var position = startingPosition; var spacing = 100; GraphicsMgr.CurrentColor = Color.White; // Sprites are affected by current color too. // Sprites can't have static methods. So we are pulling them from sprite group. Default.Monofoxe.Draw(position, Default.Monofoxe.Origin); position += Vector2.UnitX * spacing * 2; // Setting a shader for the sprite. Resources.Effects.Seizure.SetWorldViewProjection( GraphicsMgr.CurrentWorld, GraphicsMgr.CurrentView, GraphicsMgr.CurrentProjection ); GraphicsMgr.CurrentEffect = Resources.Effects.Seizure; // If you want to animate the sprite, you must pass a value from 0 to 1 to it. Default.Fire.Draw(_animation, position, Default.Fire.Origin); GraphicsMgr.CurrentEffect = null; position += Vector2.UnitX * spacing; // You can also access sprite's frame array, if you want to draw a specific frame. Default.Fire[2].Draw(position, Default.Fire.Origin); position += Vector2.UnitX * spacing; // You can scale, rotate srites and set custom origin point. Default.Fire.Draw( 0.4f, position, new Vector2(Default.Fire.Width, Default.Fire.Height) / 2, new Vector2(1, 2) * (float)Math.Sin(_animation * Math.PI * 2 * 2), (float)(359 * _animation), Color.Red // Overrides CurrentColor. ); position += Vector2.UnitX * spacing; // You also can draw only a part of the sprite. Default.Monofoxe.Draw( 0, new Rectangle((int)(position.X), (int)(position.Y), 64, 64), new Rectangle(64, 64, 64, 64), 0, Color.White ); position += Vector2.UnitY * spacing * 1.5f; position.X = 0; // You can extract raw texture from the frames. Note that you will get the whole texture atlas. var texture = Default.Monofoxe[0].Texture; var texturePosition = Default.Monofoxe[0].TexturePosition; // This will give you texture's position on the atlas. // But how are we gonna draw it? Monofoxe can't draw textures by itself. // We can use default Monogame's SpriteBatch for this. // But beforehand we must reset Monofoxe's graphics pipeline. // This method draws all batched graphics and resets internal graphics pipeline mode. GraphicsMgr.SwitchGraphicsMode(GraphicsMode.None); // After it, you can draw anything you like using any method. _batch.Begin( // If you don't want to create new SpriteBatch, you can use GraphicsMgr.Batch instead. SpriteSortMode.Deferred, null, null, null, null, null, GraphicsMgr.CurrentView // Passig current transform matrix to match the camera. ); _batch.Draw(texture, position, GraphicsMgr.CurrentColor); _batch.End(); // After you're done, you can draw anything you like without switching graphics mode again. RectangleShape.Draw(position, position + new Vector2(texture.Width, texture.Height), true); position += Vector2.UnitX * 512; _surface.Draw(position); position += new Vector2(16, 150); GraphicsMgr.CurrentColor = Color.White; Text.CurrentFont = Resources.Fonts.Arial; Text.Draw("This text is drawn using default" + Environment.NewLine + "Monogame spritefont.", position); position += Vector2.UnitY * 48; Text.CurrentFont = Resources.Fonts.FancyFont; Text.Draw("This text is drawn using custom" + Environment.NewLine + "font made from a sprite.", position); }
public override void Draw(Component component) { var tilemap = (BasicTilemapComponent)component; var offsetCameraPos = GraphicsMgr.CurrentCamera.Position - tilemap.Offset - GraphicsMgr.CurrentCamera.Offset / GraphicsMgr.CurrentCamera.Zoom; var scaledCameraSize = GraphicsMgr.CurrentCamera.Size / GraphicsMgr.CurrentCamera.Zoom; var startX = (int)(offsetCameraPos.X / tilemap.TileWidth) - tilemap.Padding; var startY = (int)(offsetCameraPos.Y / tilemap.TileHeight) - tilemap.Padding; var endX = startX + (int)scaledCameraSize.X / tilemap.TileWidth + tilemap.Padding + 2; // One for mama, one for papa. var endY = startY + (int)scaledCameraSize.Y / tilemap.TileHeight + tilemap.Padding + 2; // It's faster to determine bounds for whole region. // Bounding. if (startX < 0) { startX = 0; } if (startY < 0) { startY = 0; } if (endX >= tilemap.Width) { endX = tilemap.Width - 1; } if (endY >= tilemap.Height) { endY = tilemap.Height - 1; } // Bounding. // Telling whatever is waiting to be drawn to draw itself. // If graphics mode is not switched, drawing raw sprite batch may interfere with primitives. GraphicsMgr.SwitchGraphicsMode(GraphicsMode.Sprites); for (var y = startY; y < endY; y += 1) { for (var x = startX; x < endX; x += 1) { // It's fine to use unsafe get, since we know for sure, we are in bounds. var tile = tilemap.GetTileUnsafe(x, y); if (!tile.IsBlank) { var tilesetTile = tile.GetTilesetTile(); if (tilesetTile != null) { var flip = SpriteEffects.None; var offset = Vector2.UnitY * (tilesetTile.Frame.Height - tilemap.TileHeight); var rotation = 0; // A bunch of Tiled magic. /* * Ok, so here's the deal. * Monogame, understandibly, has no diagonal flip, * so it's implemented by offsetting, rotating, and horizontal flipping. * Also, order actually matters. Diagonal flip should always go first. * * Yes, this can be implemented with primitives. * If you've got nothing better to do -- go bananas. * * I'm really sorry, if you'll need to modify this. */ if (tile.FlipDiag) { rotation = -90; offset.Y = -tilemap.TileHeight; offset.X = 0; flip |= SpriteEffects.FlipHorizontally; } if (tile.FlipHor) { // Sprite is rotated by 90 degrees, so X axis becomes Y. if (tile.FlipDiag) { flip ^= SpriteEffects.FlipVertically; } else { flip ^= SpriteEffects.FlipHorizontally; } } if (tile.FlipVer) { if (tile.FlipDiag) { flip ^= SpriteEffects.FlipHorizontally; } else { flip ^= SpriteEffects.FlipVertically; } } // A bunch of Tiled magic. // Mass-drawing srpites with spritebatch is a bit faster. GraphicsMgr.Batch.Draw( tilesetTile.Frame.Texture, tilemap.Offset + new Vector2(tilemap.TileWidth * x, tilemap.TileHeight * y) - offset + tile.Tileset.Offset, tilesetTile.Frame.TexturePosition, Color.White, MathHelper.ToRadians(rotation), Vector2.Zero, Vector2.One, flip, 0 ); } } } } }