次の単純化されたデータ型は、ゲームのすべてのオブジェクトのベースです。
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
...たとえば、whileとは常に一定のままで、そのままです。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)
より軽量で安全ですが、構造が失われているため、かなり醜いです (ロジック、ジオメトリなどはもうありません)。ラムダ型が存在する場合は使用すると思います:p。
これらの問題を解決する方法や、考えられる代替モデルについてのアイデアを共有してください。