以下简化的数据类型是游戏所有对象的基础:
data Object = Object { logic :: Logic, picture :: Picture }
data Logic = Logic { geometry :: Geometry, someAttributes :: SomeAttributes }
data Geometry = Geometry { coords :: Point, size :: Point }
data SomeAttributes = SomeAttributes { life :: Int, hasGravity :: Bool }
对象由函数创建:
hero position = Object
(Logic
(Geometry position (Point 25 55))
(SomeAttributes 100 True))
PictureConstructor1
enemy position = Object
(Logic
(Geometry position (Point 25 25))
(SomeAttributes 3 True))
PictureConstructor2
bullet position = Object
(Logic
(Geometry position (Point 5 5))
(SomeAttributes 0 False))
PictureConstructor3
--etc. for blocks and everything else
游戏结构示例:
[hero (Point 0 0), enemy (Point 50 0), enemy (Point 100 0), block (Point 0 (negate 30)), block (Point 50 (negate 30)), block (Point 100 (negate 30))]
然后,一个advance
函数获取这个列表并应用重力,碰撞,......,从而使对象移动,死亡,......这个函数是类型的[Object] -> [Object]
,但它不会改变所有的字段Object
:只有coords
并且life
被改变,例如,而size
和始终保持不变,不受影响。hasGravity
这个常量数据代表了某种“特定属性”,或者类属性,但是“实例”携带它们,不安全,内存大,序列化不实用。
我想创建一个类型类,每个实例都会提供它们的“常量”和可以更改的字段的构造函数。我想不出比这更好的了:
class Object a where
size :: Point
baseLife :: Point
hasGravity :: Bool
picture :: Picture
data Hero = Hero { coords :: Point, currentLife :: Int }
instance Object Hero where
size = Point 25 55
baseLife = 100
hasGravity = True
picture = PictureConstructor1
setHero a@(Hero xy _) = Hero xy (baseLife a)
它更轻、更安全,但相当丑陋,因为它失去了结构(不再有逻辑、几何......)。我想如果它们存在的话我会使用 lambda 类型:p。
请分享您对如何解决这些问题或您可以考虑的替代模型的想法。