Endlosschleife spricht ja sehr dafür, dass CheckCollision eine Tautologie (also immer wahr) ist. Der Grund dafür könnte in dieser Zeile liegen:
if ... and ((Items[index].isPlayer = True) and (py < 480) or (Items[index].isPlayer = False) and (py < 280))
Ich bin mir nicht sicher wie der Compiler die booleschen Operatoren abarbeitet. Konvention ist ja, dass das "Und" stärker bindet als das "Oder", aber ich meine mich erinnern zu können, dass Delphi die beiden gleichwertig behandelt ("wer zuerst kommt, mahlt zuerst). Probier mal eine andere Klammerung:
if ... and (((Items[index].isPlayer = True) and (py < 480)) or ((Items[index].isPlayer = False) and (py < 280)))
Hilft das?
PS: Mit unübersichtlich meinte ich nicht so sehr den Code an sich, sondern eher die, ähm, minimalistische Variablenbenennung.