У меня есть эти типы данных:
data PointPlus = PointPlus
{ coords :: Point
, velocity :: Vector
} deriving (Eq)
data BodyGeo = BodyGeo
{ pointPlus :: PointPlus
, size :: Point
} deriving (Eq)
data Body = Body
{ geo :: BodyGeo
, pict :: Color
} deriving (Eq)
Это базовый тип данных для персонажей, врагов, объектов и т.д. в моей игре (ну, я просто имею два прямоугольника в качестве игрока и земли прямо сейчас: p).
Когда клавиша, символы перемещаются вправо, влево или прыгают, меняя ее velocity
. Перемещение выполняется добавлением velocity
в coords
. В настоящее время он написан следующим образом:
move (PointPlus (x, y) (xi, yi)) = PointPlus (x + xi, y + yi) (xi, yi)
Я просто беру PointPlus
часть моего Body
, а не всего Body
, иначе это будет:
move (Body (BodyGeo (PointPlus (x, y) (xi, yi)) wh) col) = (Body (BodyGeo (PointPlus (x + xi, y + yi) (xi, yi)) wh) col)
Лучше ли первая версия move
? В любом случае, если move
изменяет только PointPlus
, должна существовать другая функция, которая вызывает его внутри нового Body
. Я объясню: есть функция update
, которая вызывается для обновления состояния игры; он передает текущее состояние игры, единственное Body
на данный момент и возвращает обновленный Body
.
update (Body (BodyGeo (PointPlus xy (xi, yi)) wh) pict) = (Body (BodyGeo (move (PointPlus xy (xi, yi))) wh) pict)
Это щекочет меня. Все сохраняется в пределах Body
, кроме PointPlus
. Есть ли способ избежать этой полной "реконструкции" вручную? Как в:
update body = backInBody $ move $ pointPlus body
Без определения backInBody
, конечно.