I am developing a Maui game and I want to set each game level background (Grid but could also be Border\Frame) according to its level type. I want to do so using a sample tile image that will be duplicated to fill the background.
Is this possible out of the box? Or should I write a custom control for it?
For example i'm looking for something like: (More explanation added)
<Border>
<Border.Background>
<Image Source="volcano_tile.png" Mode="Tiled"/>
</Border.Background>
</Border>
volcano_tile.png:
And the expected result would be to fill the entire border background with multiple tiles:
Thanks!
I did not find a standard easy xaml way to do it, so I have implemented a solution using SkiaSharp:
This is my Tester code:
First, I have created a helper class that receives width and height of the wanted target tiled image, and the tileImage itself. Using SKBitmap, it builds and returns the tiled image:
internal class ImageTiler
{
public static SKBitmap CreateTiledImage(int width, int height, SKBitmap tileImage)
{
// Create a new bitmap with the desired dimensions
var tiledBitmap = new SKBitmap(width, height);
using (var canvas = new SKCanvas(tiledBitmap))
{
// Loop through the width and height of the new image
for (int y = 0; y < height; y += tileImage.Height)
{
for (int x = 0; x < width; x += tileImage.Width)
{
// Draw the tile image at the current position
canvas.DrawBitmap(tileImage, x, y);
}
}
}
return tiledBitmap;
}
public static SKBitmap LoadImage(string resourcePath)
{
var assembly = Assembly.GetExecutingAssembly();
var resourceName = $"TilesTester.Resources.Images.{resourcePath}";
//var imageSource = ImageSource.FromFile(resourcePath);
using (var stream = assembly.GetManifestResourceStream(resourceName))
{
return SKBitmap.Decode(stream);
}
}
}
Than I have loaded my resource png tile image, and used the ImageTiler to build and display it using a SKCanvasView:
// Load the image to be tiled
string imagePath = "volcanotile.png";
SKBitmap tileImage = ImageTiler.LoadImage(imagePath);
// Define the dimensions of the new image
int newWidth = 800;
int newHeight = 600;
// Create the tiled image
SKBitmap tiledImage = ImageTiler.CreateTiledImage(newWidth, newHeight, tileImage);
var canvasView = new SKCanvasView();
canvasView.PaintSurface += (sender, args) =>
{
var canvas = args.Surface.Canvas;
canvas.Clear();
canvas.DrawBitmap(tiledImage, new SKRect(0, 0, newWidth, newHeight));
};
// Add the SKImageView as a Content to the page
Content = canvasView;
The result (Modified screenshot after changing to better Tile image and adding dynamic Tile selection):