Значение переменной ref можно получить напрямую, не обращаясь к свойству value, потому что Ref - это обёртка, которая автоматически приводит к доступу к значению при обращении к самому объекту Ref.
Чрезмерная структурированность кода в методе moveEnemies, когда работа с полями x и y объекта Enemy, может быть вызвана попыткой использования неоптимального подхода к работе с Ref объектами. Использование forEach в данном случае не требует использования .value при обращении к enemy.x и enemy.y, потому что forEach преобразует каждый элемент массива в его значение, поэтому необходимости в явном обращении к .value нет.
Поведение, когда условие if (enemy.hp > 0) выполняется без проблем, а операция присвоения enemy.x += 1 вызывает ошибку типов из-за требования явного доступа к .value, объясняется особенностями работы с Ref объектами. Для обхода этой проблемы можно добавить геттер к объекту или метод для присвоения значений к x.value вместо x, что поможет избежать ошибок типов и сделает код более понятным и безопасным.