I am making a simple game in C# using pictureboxes. I want to move a picturebox on a form. Once this picturebox is placed in a new location, I normalize its X,Y coordinates between [0, 1] and then send them to a server. The server does nothing but broadcast those normalized coordinates to all of the connected clients.

Once a client gets the normalized coordinates from the server, it translates them back into screen coordinates so it knows where to place the picturebox. This allows the picturebox to display in the correct spot for both screens, even if the screen sizes are very different.

Here is the code that shows how this process is done: https://pastebin.com/1igRRtKJ

If both screens are the exact same size (specifically if the form sizes I am testing with are the same) then this process works perfectly. However, if one screen size is different than the other (specifically, the form sizes are greatly different) then they don't display quite right.

If one image is placed to be next to another on the small screen, the big screen will show a ton of spacing between them that shouldn't exist. Likewise, if the big screen moves an image to sit next to another one, the small screen will show them overlapping each other which should not happen.

Here are some screenshots illustrating the problem: https://imgur.com/a/y2NTHm3 and https://imgur.com/a/oIV5Huy

Given the code I shared and the problem I am describing, how can I fix this issue? I'd like the pictureboxes to show up in the exact same position on all of the client's screens, even if they are vastly different from each other.

I'm fairly certain the math here is correct. So, I am unsure what the actual problem is. When the screen sizes are different the images will appear approximately where they should go, but not exactly. I'd like to somehow maintain the relative distance, which I thought this would do, but clearly I am missing something. I set the pictureboxes using the location method, which is based on the top-left corner of the picturebox.

Normalize coordinates (client sending the normalized coordinates of the moved image):

normalizedX = picturebox.location.x / (client_width - picturebox.width);
normalizedY = picturebox.location.y / (client_height - picturebox.height);

Translate coordinates (clients getting the normalized coordinates):

adjustedX = normalizedX * (client_width - picturebox.width);
adjustedY = normalizedY * (client_height - picturebox.height);

I'd really love to solve this problem. I have asked this question in several different places, but no one seems to be able to help.

  • \$\begingroup\$ So, I am unsure what the actual problem is. Well a bigger screen just has a lot more space to fill. If you want to maintain distances, don't use normalized coordinates. If you want normalized coordinates you have to scale the images to the screen size to keep all the ratios. \$\endgroup\$
    – tkausl
    Commented Jan 25 at 23:11
  • \$\begingroup\$ Scale the images to the relative screen sizes. \$\endgroup\$
    – tkausl
    Commented Jan 25 at 23:45
  • \$\begingroup\$ I understand that. I just don't know how to do that. I mean, I can set the height and width of the images easily, but how can I compute what values to set the height and width so this works for all screen sizes the way I want it to? I'm hoping you can tell me explicitly how to "Scale the images to the relative screen sizes". \$\endgroup\$ Commented Jan 25 at 23:52
  • \$\begingroup\$ You have to define some "standard" screen size on which all the images have their original sizes and then just scale by (actualScreenWith/standardScreenWidth) and so on. \$\endgroup\$
    – tkausl
    Commented Jan 25 at 23:54

1 Answer 1


The idea of creating a consistent coordinate system between all of the clients was definitely the right idea and my original implementation was correct. The problem was that the images also needed to be scaled relative to the screen size in order to maintain their ratios. Additionally, the program needed to maintain its aspect ratio so that the scaled images would have the correct position and distance for all screen sizes.

With this information in mind, I designed the program to have its initial dimensions be a 16:9 ratio. I still allow users to resize the form, but only from one of the four corners, so that they are forced to update both the height and width when manually resizing the form. Doing all of this ensured that the program was always in a 16:9 ratio (or at least close enough that the distance and positions of images were still really accurate).

So, in summary, if you read the original question and want to achieve the same results, you can think of this as a three step process:

  1. Create a consistent coordinate system between clients
  2. Scale your images in relation to the screen size
  3. Force your program to maintain the supported aspect ratio

Here is a simplified version of the code for each of the three steps so you should be able to follow along and get this working pretty easily.

Normalize coordinates before sending to other clients:

double actualX = pb.Location.X;
double actualY = pb.Location.Y;

double percentageX = actualX / (ClientRectangle.Width - pb.Width);
double percentageY = actualY / (ClientRectangle.Height - pb.Height);

Translate the normalized coordinates to screen coordinates:

double adjustedX = percentageX * (ClientRectangle.Width - pb.Width);
double adjustedY = percentageY * (ClientRectangle.Height - pb.Height);

Scale images (pictureboxes in my case):

// For the reference size I used the default program height/width
double scaleFactor = Math.Min(this.Width / referenceWidth, this.Height / referenceHeight);

// Scale from the original image size
pb.Width = originalWidth;
pb.Height = originalHeight;

// This will work for both scaling up and down
pb.Width = (int)Math.Round(pb.Width * scaleFactor);
pb.Height = (int)Math.Round(pb.Height * scaleFactor);

Maintain aspect ratio:

This isn't something I technically enforced with code. I just recommend designing your program to be in a 16:9 aspect ratio by default and then attempt to enforce this the best you can. I am sure there is a good way to do this, but I just took the easy way out and did as I described above.

This is why the problem was so tricky for me to figure out, because it was not just one single thing causing the problem. It was a combination of them all. So, my original question only really took care of 1/3 of the problem, which is why I just couldn't get it to work the way I wanted. Once I completed the other two steps, things work exactly how I wanted them to.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .