The Atari ST used a different architecture , today we put all graphics assets into the video card which has its own GPU so all textures are not in you main CPU and the graphics card also has its own memory to store all the graphics, so that’s why pulling data from the graphics card is slow compared to the Atari ST. Still the resolution was way smaller than current graphics, so I think is not fair to compare both.

In one of my games I put 1000s of units on screen in real time like this, and I used circle collision though it was not perfect it was ok, and all enemies had different shapes

I saw your rectangle image example, you can actually rotate every single rectangle to fit the shape to your units, then rotate them to check collision , that should do the job. Though it will be a little bit slow but given the number of units you have you can optimize it easily, I don’t think you will be drawing more than 1000 units in one map so it will still be fast.

Anyway, I haven’t tested this but it should be something like this:

```
public static bool CheckCollision(Rectangle rect1, float angle1, Rectangle rect2, float angle2)
{
// Calculate the four corners of each rectangle
Vector2[] corners1 = CalculateCorners(rect1, angle1);
Vector2[] corners2 = CalculateCorners(rect2, angle2);
// Check if any of the corners of rectangle 1 are inside rectangle 2
for (int i = 0; i < corners1.Length; i++)
{
if (IsPointInsidePolygon(corners1[i], corners2))
return true;
}
// Check if any of the corners of rectangle 2 are inside rectangle 1
for (int i = 0; i < corners2.Length; i++)
{
if (IsPointInsidePolygon(corners2[i], corners1))
return true;
}
// If none of the corners are inside the other rectangle, there is no collision
return false;
}
private static Vector2[] CalculateCorners(Rectangle rect, float angle)
{
// Calculate the four corners of the rectangle
Vector2[] corners = new Vector2[4];
corners[0] = new Vector2(rect.Left, rect.Top);
corners[1] = new Vector2(rect.Right, rect.Top);
corners[2] = new Vector2(rect.Right, rect.Bottom);
corners[3] = new Vector2(rect.Left, rect.Bottom);
// Rotate the corners around the center of the rectangle
Vector2 center = new Vector2(rect.Center.X, rect.Center.Y);
for (int i = 0; i < corners.Length; i++)
{
corners[i] = RotatePoint(corners[i], center, angle);
}
return corners;
}
private static Vector2 RotatePoint(Vector2 point, Vector2 center, float angle)
{
// Rotate a point around another point by a given angle
float sin = (float)Math.Sin(angle);
float cos = (float)Math.Cos(angle);
Vector2 translated = new Vector2(point.X - center.X, point.Y - center.Y);
Vector2 rotated = new Vector2(
translated.X * cos - translated.Y * sin,
translated.X * sin + translated.Y * cos);
return new Vector2(rotated.X + center.X, rotated.Y + center.Y);
}
private static bool IsPointInsidePolygon(Vector2 point, Vector2[] polygon)
{
// Check if a point is inside a polygon using the ray casting algorithm
bool inside = false;
for (int i = 0, j = polygon.Length - 1; i < polygon.Length; j = i++)
{
if (((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y)) &&
(point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X))
{
inside = !inside;
}
}
return inside;
}
```

I think this may work, test it and let me know.