The way this is usually handled in games is something called a transformation hierarchy.
Here objects are arranged in a parent-child relationship, where each object's position, rotation, etc is specified in a local coordinate system relative to its parent's transformation. So to arrange square B so that it stays attached to the corner of square A, you'd set B as a child of A - then B will follow it wherever it goes, by inheriting the motion of A.
To keep the math consistent, these transformations are usually converted to matrices. Then computing the resulting "local to world" transformation (ie from B's local coordinates to A's coordinates to your stage / scene / canvas / world) is just a matter of multiplying each matrix up the parent chain.
For a typical 2D case, an object with local scale factors of \$(S_x, S_y)\$, a rotation of \$\theta\$ radians, and a translation of \$(T_x, T_y)\$ units relative to its parent could be represented by a local transform matrix like this:
$$
M_{toParent} = \begin{bmatrix}
S_x \cdot cos(\theta) & -S_y \cdot sin(\theta) & T_x \\
S_x \cdot sin(\theta) & S_y \cdot cos(\theta) & T_y \\
0 & 0 & 1
\end{bmatrix}
$$
Then you can transform any point \$(P_x, P_y)\$ from the original object into its parent's coordinate system by multiplying it by this matrix (with an extra 1 added as a "z" coordinate to enable translations)
$$
P_{parentSpace} = M_{toParent} \cdot \begin{pmatrix}P_x \\ P_y \\ 1\end{pmatrix}
$$
You can compute a single matrix representing the entire transformation up the parent chain by multiplying those matrices together:
this.M_toWorld = this.M_toParent
currentTransform = this.parent
while(currentTransform != null)
{
M_toWorld = currentTransform.M_toParent * this.M_toWorld;
currentTransform = currentTransform.parent;
}
Or, you can do it recursively:
if(this.parent == null)
this.M_toWorld = this.M_toParent
else
this.M_toWorld = this.parent.M_toWorld * this.M_toParent
Now instead of walking up the whole chain anytime you want to transform a point, you can use this M_toWorld
matrix as a shortcut:
P_worldSpace = M_toWorld * P
Any time an object moves, you need to update its transform and cascade these changes down its tree/DAG of child objects, ensuring that they all move together.