我有这些数据类型:
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)
我只需要获取我的Body
的PointPlus
部分,而不是整个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
。
move
函数呢?它最好是接受整个Body
还是只有它的PointPlus
部分? - L01man