Tile a texture to a rectangle from the top

301 views Asked by At

I'm trying to tile a texture to a rectangle in a certain way. For example, here is my texture:

enter image description here

Currently, it tiles it to my rectangle such that the texture gets cut off at the top of the rectangle:

enter image description here

I want to tile my texture such that it gets cut off at the bottom of my rectangle:

enter image description here

I use the following logic to create and draw a rectangle in my game and tile it:

public class HoopsGame : Game
{

    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    Body _ground;
    Texture2D _groundTexture;
    World _world;

    public HoopsGame()
    {
        graphics = new GraphicsDeviceManager(this);
    }

    protected override void Initialize()
    {
        Content.RootDirectory = "Content";
        _world = new World(new Vector2(0f, 9.8f));
        int groundHeight = (int)(graphics.GraphicsDevice.Viewport.Height * 0.05);
        Rectangle groundRectangle = new Rectangle(0, graphics.GraphicsDevice.Viewport.Height - groundHeight, graphics.GraphicsDevice.Viewport.Width, groundHeight);
        _ground = BodyFactory.CreateRectangle(_world, groundRectangle.Width, groundRectangle.Height, 0f, groundRectangle);

        base.Initialize();
    }

    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        _groundTexture = Content.Load<Texture2D>("court");
    }

    protected override void UnloadContent()
    {
        Content.Unload();
    }

    protected override void Update(GameTime gameTime)
    {
        base.Update(gameTime);
    }

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

        spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Opaque, SamplerState.LinearWrap, DepthStencilState.Default, RasterizerState.CullNone);
        spriteBatch.Draw(_groundTexture, new Vector2(0, graphics.GraphicsDevice.Viewport.Height - ((Rectangle)_ground.UserData).Height), (Rectangle)_ground.UserData, Color.White);
        spriteBatch.End();

        base.Draw(gameTime);
    }
}
2

There are 2 answers

4
Orren Ravid On

You didn't make it extremely clear, but I assume your brick texture is _groundTexture in the code. I really don't have a lot of experience with microsoft XNA, but since it's a tileable texture, have you considered getting the dimensions of your rectangle, then the dimensions of the tileable texture, then doing an operation like:

//this is of course pseudocode

offset_y = Rectangle_Y_Coordinate % Texture_Y_Coordinate

This modular operation will give you the amount of the texture that will get cut off. For example, if your rectangle has a height of 20 and your texture has a height of 7, you will be left with your texture being mapped a 3rd time but only up to a height of 6 because 20 % 7 = 6.

Then when you map the texture to your rectangle just subtract that y offset when you give it your y coordinate and you should get the desired result. Please let me know if I was a bit unclear. Cheers and good luck.

0
Alexandru On

What worked in the end was using a different Draw method, specifically Draw(Texture2D texture, Rectangle destinationRectangle, Rectangle? sourceRectangle, Color color), and offsetting the source Rectangle's Y coordinate as Orren mentioned:

spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.Opaque, SamplerState.LinearWrap, DepthStencilState.Default, RasterizerState.CullNone);
Rectangle source = (Rectangle)_ground.UserData;
if (source.Height > _groundTexture.Height)
    source.Y += source.Height - _groundTexture.Height;
if (_groundTexture.Height > source.Height)
    source.Y -= _groundTexture.Height - source.Height;
Rectangle destination = new Rectangle(0, graphics.GraphicsDevice.Viewport.Height - ((Rectangle)_ground.UserData).Height, source.Width, source.Height);
spriteBatch.Draw(_groundTexture, destination, source, Color.White);
spriteBatch.End();