Ovvio. Tutto il tuo codice è sincrono. Finché non termina, nessun'altra azione può essere eseguita, compreso il refresh dell'interfaccia. Se vuoi che lo spostamento avvenga asincronamente devi eseguire la routine in un thread diverso, oppure al tick di un timer.
Se decidi di lanciarla su un altro thread, ricorda che non puoi modificare le proprietà dei controlli da quel thread, ma devi passare attraverso il thread che li ha creati.
codice:
private void Timer_Tick(Object sender, EventArgs e)
{
    Controls["oggetto1"].Location = new Point(...);
}
codice:
(new Thread(() => { Sposta("oggetto1", "oggetto2", x0, y0); })).Start()
Altri consigli:
- Quei for sono osceni. Potevi usare Thread.Sleep (che comunque è sconsigliabile).
- Se una variabile si chiama OggettoDaSpostare, si presume che contenga l'oggetto da spostare, non il suo nome. Quindi decidi: o la chiami "NomeOggettoDaSpostare" (o qualcosa di più corto), oppure ne cambi il tipo in Control.
- A cosa servono le coordinate X e Y se l'oggetto viene comunque spostato alle coordinate dell'oggetto padre?
- "Se OggettoDaSpostareX e y sono più distanti dell'oggetto padre" non ha senso. Una coordinata non può essere "più distante" di un oggetto. Distante da cosa, poi? Semmai un oggetto - o un punto - è più distante di un altro oggetto o un altro punto da un ulteriore oggetto o punto.
- Tutti queli if e while sono inutili.
codice:
while ( (currentX != targetX) && (currentY != targetY) )
{
    currentX += (Int32)Math.Sign(targetX - currentX);
    currentY += (Int32)Math.Sign(targetY - currentY);
}
currentX e currentY rappresentano le tue Controls[OggettoDaSpostare].Location.X o .Y. targetX e targetY sono le coordinate da raggiungere.