Resizing 2D arrays
I started working on a new tile system and editor for my ninja game and realized I’m going to want the ability to change level sizes. I store my tile layouts in a basic 2D array which means that my resizing will have to do a bit of moving things around. After a little bit of work, I came up with a fairly decent (i.e. it works for my few little test cases) extension method for resizing any 2D array, including choosing where you clamp to get the same effect as Paint.NET or Photoshop when you change canvas size but get to choose where the existing data will be in relationship to the resizing.

Anyway, here’s the method. Hope this can save someone else some time. Also if you spot anything wrong about this let me know.
public enum HorizontalClamp
{
Left,
Right,
Center
}
public enum VerticalClamp
{
Top,
Bottom,
Center
}
public static class ArrayExtensions
{
public static T[,] Resize<T>(
this T[,] array,
int newWidth,
int newHeight,
HorizontalClamp xClamp,
VerticalClamp yClamp)
{
// get the current width and height of the array
int width = array.GetLength(0);
int height = array.GetLength(1);
// start/end from the old array
int xStart = 0, xEnd = Math.Min(width, newWidth);
int yStart = 0, yEnd = Math.Min(height, newHeight);
// start/end for new array
int targetX = 0;
int targetY = 0;
// figure out start, end, and target coordinates.
// no check for left or top; those are defaults.
if (xClamp == HorizontalClamp.Right)
{
xStart = Math.Max(width - newWidth, 0);
xEnd = xStart + Math.Min(width, newWidth);
targetX = newWidth - (width - xStart);
}
else if (xClamp == HorizontalClamp.Center)
{
xStart = Math.Max(width / 2 - newWidth / 2, 0);
xEnd = xStart + Math.Min(width, newWidth);
targetX = Math.Max(newWidth / 2 - width / 2, 0);
}
if (yClamp == VerticalClamp.Bottom)
{
yStart = Math.Max(height - newHeight, 0);
yEnd = yStart + Math.Min(height, newHeight);
targetY = newHeight - (height - yStart);
}
else if (yClamp == VerticalClamp.Center)
{
yStart = Math.Max(height / 2 - newHeight / 2, 0);
yEnd = xStart + Math.Min(height, newHeight);
targetY = Math.Max(newHeight / 2 - height / 2, 0);
}
// create our return value
T[,] newArray = new T[newWidth, newHeight];
// copy over the values from the old array to the new array
for (int x1 = targetX, x2 = xStart; x2 < xEnd; x1++, x2++)
{
for (int y1 = targetY, y2 = yStart; y2 < yEnd; y1++, y2++)
{
newArray[x1, y1] = array[x2, y2];
}
}
return newArray;
}
}
Hi Nick, I have followed your blog and your post (here and codeplex) all the time, so I can see that you’ve too much experience in many fields, with that in mind I was wondering if you can clarify some points about XNA due to my next project:
I’m almost ready with the initial part of a lobby interface (on WPF), and started to call what I have done till now in XNA, … but (Maybe I missunderstood) apparently contentmanager is not thread safe and additionally I can’t write to the GPU for more that one thread at a time. I’m not using viewport instead I’m loading one game per thread … till maximum of four (thread.start (new game()).
Scennario:
Lobby:
Shows the user four different king of games (Domino, Cards, Chess, Ludo, just to mention some of them). Each game has many rooms related to them.
* If the player like to join to chess room, then:
Lobby call and load the game in a thread: (thread = new thread(game).start)
* The previous happen for each room where a player like to join.
Now:
- To avoid loading many times (per thread) assets, I like to share contentmanager and loaded just the first time (main thread) when joined to a room and later share. ??
- Is possible that each game (per thread) can write to the gpu and show correctly its concerned game with no problems/throubles?
Please, I like some details (if possible) to understand better this approach.
Thanks in advance
JJ.