我有这些数据类型:
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)
我只是参加PointPlusmy 的一部分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,则必须有另一个函数在 new 中调用它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。