Game Development Community

Changing Tilemap Cells

by Edward LaPlante · in Torque X 2D · 04/10/2008 (7:16 pm) · 5 replies

Has anyone been able to programatically change tilemaps during gameplay?

I'm working on a simple breakout game and trying to remove blocks when the ball hits them. I've got the ball to bounce, but can't figure out how to erase the cell that was hit.

Thanks,

Ed

#1
04/11/2008 (4:36 am)
More info:

I have already got the collision working and a delegate setup to run when the collision occurs.

The collision method is passing in the following:

ourobject = the ball
theirobject = the tileset.

Is there any way to determine which tile is being hit? And, is there anyway to change that tile?
#2
04/14/2008 (1:23 pm)
OK, so I'm almost there. Below is my Collision Delegate. Now my issue is sometimes the GetCollisionMatches method sometimes finds the tiles and sometimes it doesn't. It also sometimes finds the tiles next to the one that is being hit.

I'm going to step through the code to see why tonight.

public static void Kill(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info, ref T2DResolveCollisionDelegate resolve, ref T2DCollisionMaterial physicsMaterial)
{
T2DTileLayer tileLyr = (T2DTileLayer)theirObject;

GarageGames.Torque.Util.ReadOnlyArray objs = tileLyr.GetCollisionMatches
(ourObject);
foreach(T2DTileObject obj in objs)
{
if (obj != null && obj.TileTypeIndex > 0)
{
GetWorldPosition(tileLyr);
string test = obj.TileTypeName;
Type t = obj.GetType();
tileLyr.SetTileByGridCoords((int)obj.GridPosition.X, (int)obj.GridPosition.Y, null);
}
}

}
#3
04/14/2008 (4:37 pm)
Hi! I had a similar problem so here's how I solved it.
I added this method in the T2DTileLayer.cs file.

public bool SetTile(Vector2 worldPos, T2DTileObject tile)
{
float x, y;

x = ((worldPos.X - _position.X) / _tileSize.X) + (_mapSize.X * 0.5f);
y = ((worldPos.Y - _position.Y) / _tileSize.Y) + (_mapSize.Y * 0.5f);

x = MathHelper.Clamp(x, 0.0f, _mapSize.X - 1);
y = MathHelper.Clamp(y, 0.0f, _mapSize.Y - 1);

return SetTileByGridCoords((int)x, (int)y, tile);
}

In the collision callback, you can then do the following
T2DTileLayer tileLyr = (T2DTileLayer)theirObject;
tileLyr.SetTile(info.Position, null);

If you don't get the right tile, you could always get the direction of the collision (info.Position - theirObject.Position) and do the SetTile on a slightly offseted position.

In any case, you seem to already be on the right track.
#4
04/16/2008 (6:02 am)
Here is how I solved it.

I call this method on collision of the ball & tiles in the tilemap.

public static void CheckTiles(T2DSceneObject ourObject, T2DSceneObject theirObject, T2DCollisionInfo info)
{
T2DTileLayer tileLyr = (T2DTileLayer)theirObject;
T2DTileObject collObj = new T2DTileObject();
Vector2 _min = new Vector2(info.Position.X - (ourObject.Size.X * .75f / 2), info.Position.Y - (ourObject.Size.Y * .75f / 2));
Vector2 _max = new Vector2(info.Position.X + (ourObject.Size.X * .75f / 2), info.Position.Y + (ourObject.Size.Y * .75f / 2));
Rectangle ourRect = new Rectangle((int)(_min.X * 1000), (int)(_min.Y * 1000), (int)(ourObject.Size.X * 1000), (int)(ourObject.Size.Y * 1000));

foreach (T2DTileObject obj in tileLyr.GetCollisionMatches(_min, _max))
{
if (obj.TileTypeIndex > 0)
{
Vector2 theirPos = obj.GetWorldPosition(tileLyr);
int _minX = (int)(theirPos.X * 1000) - (int)(tileLyr.TileSize.X * 1000 / 2);
int _minY = (int)(theirPos.Y * 1000) - (int)(tileLyr.TileSize.Y * 1000 / 2);
int _maxX = (int)(theirPos.X * 1000) + (int)(tileLyr.TileSize.X * 1000 / 2);
int _maxY = (int)(theirPos.Y * 1000) + (int)(tileLyr.TileSize.Y * 1000 / 2);
Rectangle theirRect = new Rectangle(_minX, _minY, _maxX - _minX, _maxY - _minY);
if (ourRect.Intersects(theirRect))
{
Game.Instance.Score += (obj.TileTypeIndex * 5);
tileLyr.SetTileByGridCoords((int)obj.GridPosition.X, (int)obj.GridPosition.Y, null);
}
}
}
#5
04/16/2008 (6:05 am)
Moving On:

How do you load a different tile layer? I've saved several layers with different block configurations.