1
\$\begingroup\$

I am wondering how this would be possible, if at all.

In the image below:

enter image description here

The light brows tiles are ground, while the dark brown is background, so the player can pass over those tiles.

Here's the for loops that draws the level:

        float scale = 1f;

        for (row = 0; row < currentLevel.Rows; row++)
        {
            for (column = 0; column < currentLevel.Columns; column++)
            {
                Tile tile = (Tile)currentLevel.GetTile(row, column);
                if (tile == null) { continue; }

                Texture2D texture = tile.Texture;

                spriteBatch.Draw(texture, new Microsoft.Xna.Framework.Rectangle(
                    (int)(column * currentLevel.CellSize.X * scale),
                    (int)(row * currentLevel.CellSize.Y * scale),
                    (int)(currentLevel.CellSize.X * scale),
                    (int)(currentLevel.CellSize.Y * scale)), Microsoft.Xna.Framework.Color.White);
            }
        }

Here's what I have so far to determine where to create a Rectangle:

    Microsoft.Xna.Framework.Rectangle[,,,] groundBounds = new Microsoft.Xna.Framework.Rectangle[?, ?, ?, ?];

        int tileSize = 20;
        int screenSizeInTiles = 30;

        var tilePositions = new System.Drawing.Point[screenSizeInTiles, screenSizeInTiles];

        for (int x = 0; x < screenSizeInTiles; x++)
        {
            for (int y = 0; y < screenSizeInTiles; y++)
            {
                tilePositions[x, y] = new System.Drawing.Point(x * tileSize, y * tileSize);
                groundBounds[x, y, tileSize, tileSize] = new Microsoft.Xna.Framework.Rectangle(x, y, 20, 20);
            }
        }

First off, I'm not sure how to initialize the array groundBounds (I don't know how big to make it). Also, I'm not entirely sure how to go about adding information to groundBounds.

I want to add a Rectangle for each tile in the level. Preferably I'd only make a Rectangle for those tiles accessible by the player, and not background tiles, but that's for a different day.

FYI, the map was made with a freeware program called Realm Factory.

\$\endgroup\$
  • 5
    \$\begingroup\$ Wow, four-dimensional array. Haven't seen those before. \$\endgroup\$ – user9790 Dec 17 '12 at 3:01
  • \$\begingroup\$ How do you calculate collisions? The tileSize's in the groundBounds index don't make much sense to me. \$\endgroup\$ – Archy Dec 17 '12 at 7:30
  • \$\begingroup\$ Well, the tileSize's are for the length and width of the Rectangle. As for collision, I am unable to complete it until I get this part working. \$\endgroup\$ – Fiona Dec 17 '12 at 23:37
  • \$\begingroup\$ After some thought, maybe a jagged array would be better instead of a 4D array? \$\endgroup\$ – Fiona Dec 17 '12 at 23:38
2
\$\begingroup\$

Working with tile size should be enough. You can calculate where your character is by

Math.floor(playerPos.x/tileSize.width); // tilesize is usually equal in width and height
Math.floor(playerPos.y/tileSize.height);

Let's say our map is 800 pixels wide. And our Tiles are 100 pixels wide. Let's assume there goes 8 tiles in a row.

if our players x position is 350 we get Math.floor(350/100) = 3;

Here is an image sized on actual scale for proof (note that your array starts at 0, so 3 is still position 4): enter image description here

This will give you an integer which can be used as an index for your grid. Check what tiletype it is and handle the appropriate action.

int indexX = Math.floor(playerPos.x/tileSize);
int indexY = Math.floor(playerPos.y/tileSize);

Tile tile = currentLevel[indexY][indexX]; // [Row][Column] < [y][x]
//or in your case:
Tile tile = (Tile)currentLevel.GetTile(indexY,indexX);

//Check tile do your thang. Make stuff happen.

It looks like you're not keeping the position in the Tile object. ( might wanna check the properties it could be that there is a "point" or x and y property you can store its location in.

If you want to retrieve the position manually just multiply with your indices:

int posX = indexX*tileSize;
int posY = indexY*tileSize;
//And if you need your rectangle
Microsoft.Xna.Framework.Rectangle tileRect = new Microsoft.Xna.Framework.Rectangle(posX,posY,tileSize,tileSize);
| improve this answer | |
\$\endgroup\$
  • \$\begingroup\$ Sorry I made a mistake in explaining the calculation. Fixed it \$\endgroup\$ – Sidar Dec 18 '12 at 2:44
  • \$\begingroup\$ Is there any way to do collision detection without making a rectangle for every single tile? \$\endgroup\$ – Fiona Dec 18 '12 at 2:56
  • \$\begingroup\$ Why do you need a rectangle? You can easily retrieve the tile position in the tile object right? you already have the size. You can just use the tile properties. ( depending on the properties your tile has ). \$\endgroup\$ – Sidar Dec 18 '12 at 3:03
  • \$\begingroup\$ What do you mean by tile object? In the XML file that is loaded from, the tile positions are obfuscated. \$\endgroup\$ – Fiona Dec 18 '12 at 3:11
  • \$\begingroup\$ It looks like you're not keeping the position in "Tile". You can retrieve the position by multiplying the indexX and indexY by tilSize. First check what type of tile it is. Then check if collision is needed. If you really need to use a rectangle you can make a local variable when collision is happening and then pass it off to whatever function needs it. \$\endgroup\$ – Sidar Dec 18 '12 at 3:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.