У меня есть следующие типы данных:
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).
Когда ключ, персонажи перемещаются вправо, влево или прыгают, изменяя свою скорость
. Перемещение осуществляется путем добавления скорости к
коордам
. В настоящее время это написано следующим образом:
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
, конечно.