StdGameDef.dcl 9.88 KB
Newer Older
Peter Achten's avatar
Peter Achten committed
1
2
definition module StdGameDef

3
4
5
6
7
8
9
10
//	********************************************************************************
//	Clean Standard Game library, version 1.2
//	
//	StdGameDef contains all the type definitions needed to specify a game.
//	********************************************************************************


from	StdFunc			import St
Peter Achten's avatar
Peter Achten committed
11
12
from	StdOverloaded	import zero
from	StdString		import String
13
from	StdIOBasic		import Point2, Size, IdFun
Peter Achten's avatar
Peter Achten committed
14
from	StdMaybe		import Maybe, Just, Nothing
15
16
17
from	StdPictureDef	import Colour, RGB, RGBColour, Black, White, 
                               DarkGrey, Grey, LightGrey, Red, Green,
                               Blue, Cyan, Magenta, Yellow
Peter Achten's avatar
Peter Achten committed
18
19
import	StdGSt

20

Peter Achten's avatar
Peter Achten committed
21
22
23
24
25
:: GameAttribute gs
   = ScreenSize Size     // screen resolution, default 320x240
   | ColorDepth Int      // screen color depth, default 8 (256 colors)

:: Game gs
26
27
28
   = { levels        :: [Level (GSt gs)]        // levels
     , quitlevel     :: St (GSt gs) Bool        // True quits the game
     , nextlevel     :: St (GSt gs) Int         // new level if >0 (0 quits)
29
     , textitems     :: St (GSt gs) [GameText]  // all game text items
Peter Achten's avatar
Peter Achten committed
30
31
32
     }

:: Level state
33
34
35
36
37
38
39
   = { boundmap      :: !BoundMap               // static bounds map in a level
     , initpos       :: !Point2                 // center of screen in boundmap
     , layers        :: ![Layer]                // all layers [back..front]
     , objects       :: ![GameObject state]     // all other objects in the level
     , music         :: !Maybe Music            // background music
     , soundsamples  :: ![SoundSample]          // list of sound samples
     , leveloptions  :: !LevelOptions           // level options
Peter Achten's avatar
Peter Achten committed
40
41
42
     }

:: LevelOptions
43
44
45
46
47
   = { fillbackground:: !Maybe Colour    // fill the screen before drawing layers
     , escquit       :: !Bool            // quit the level when pressing Esc key
     , debugscroll   :: !Bool            // enable scrolling with arrow keys
     , fadein        :: !Bool            // fade in from black
     , fadeout       :: !Bool            // fade out to black
Peter Achten's avatar
Peter Achten committed
48
49
50
     }

:: Music
51
52
53
   = { musicfile     :: !String          // MIDI file
     , restart       :: !Bool            // restart the music when it ends?
     , continue      :: !Bool            // music continues after end of level
Peter Achten's avatar
Peter Achten committed
54
55
56
     }

:: SoundSample
57
58
59
   = { soundid       :: !SoundID         // id for the sample (any number)
     , soundfile     :: !String          // WAV file
     , soundbuffers  :: !Int             // max times sample can be played together
Peter Achten's avatar
Peter Achten committed
60
61
62
63
64
65
     }

:: SoundID
   :== Int

:: BoundMap
66
67
68
69
70
   = { map        :: ![{#Int}] // map of all static bounds
     , blocksize  :: !Size     // size of the map units (in pixels)
     , objstart   :: !Int      // min. value for objects (lower values are ignored)
     , startobjx  :: !Int      // X-distance from screen when to initialise objects
     , startobjy  :: !Int      // Y-distance from screen when to initialise objects
Peter Achten's avatar
Peter Achten committed
71
72
73
74
75
76
77
78
79
     }

:: GameRegion
   :== [Int]

:: Bounds
   :== Int

:: DirectionSet
80
81
82
83
   = { top        :: !Bool
     , left       :: !Bool
     , bottom     :: !Bool
     , right      :: !Bool
Peter Achten's avatar
Peter Achten committed
84
85
86
     }

:: Layer
87
88
89
90
   = { bmp        :: !GameBitmap     // bitmap that contains all the tiles
     , layermap   :: !LayerMap       // map of the tiles in the level
     , sequences  :: ![TileSequence] // tiles that change repeatedly
     , movement   :: !Movement       // function to scroll the layer
Peter Achten's avatar
Peter Achten committed
91
92
93
     }

:: GameTime
94
   :== Int                          // time in frames
Peter Achten's avatar
Peter Achten committed
95
96

:: GameBitmap
97
98
99
100
   = { bitmapname :: !String        // bitmap that contains smaller blocks
     , unitsize   :: !Size          // size of these blocks (width, height)
     , dimensions :: !(!Int,!Int)   // number of blocks (horizontal, vertical)
     , transparent:: !Maybe Point2  // position of a transparent pixel
Peter Achten's avatar
Peter Achten committed
101
102
103
104
105
     }

:: LayerMap
   :== [{#Int}]  // map of block numbers in a bitmap
                 // 0: empty; 1..n: block number; n+1..2n: mirror block;
106
                 // 2n+1..3n: upside down; 3n+1..4n: mirror and upsidedown;
Peter Achten's avatar
Peter Achten committed
107
108
109
110
                 // -1..-m: block sequence number
                 // (n = # blocks in gamebitmap; m = # sequences)

:: TileSequence
111
   :== (!Int, Sequence)   // block sequence number, Sequence
Peter Achten's avatar
Peter Achten committed
112
113

:: Sequence
114
   :== [(Int, Int)]   // tile number, duration
Peter Achten's avatar
Peter Achten committed
115
116

:: Movement
117
   :== Point2 GameTime -> Point2    // calculate layer's position from game position
Peter Achten's avatar
Peter Achten committed
118
119
120
121
122

:: SpriteID
   :== Int

:: Sprite
123
124
125
   = { bitmap   :: !GameBitmap      // sprites may have their own bitmap
     , sequence :: !Sequence        // seqence of blocks
     , loop     :: !Bool            // if FALSE, callback animation function
Peter Achten's avatar
Peter Achten committed
126
     }
127

128
129
:: GameObject gs
   = E. state:
130
     { objectcode :: !ObjectCode    // code for object type (0 AutoInitObject)
Peter Achten's avatar
Peter Achten committed
131
     , sprites    :: ![Sprite]      // sprite 1..n
132
     , init       :: !SubCode !Point2 !GameTime !gs -> GameObjectState state gs
133
134
135
136
     , done       :: !(GameObjectState state gs)    -> gs
     , move       :: !                                         ObjectFun state gs
     , animation  :: !                                         ObjectFun state gs
     , touchbound :: !DirectionSet MapCode                  -> ObjectFun state gs
137
     , collide    :: !DirectionSet ObjectCode GameObjectRec -> ObjectFun state gs
138
139
140
     , frametimer :: !                                         ObjectFun state gs
     , keydown    :: !KeyCode                               -> ObjectFun state gs
     , keyup      :: !KeyCode                               -> ObjectFun state gs
141
     , userevent  :: !EventCode !EventPar !EventPar         -> ObjectFun state gs
142
     }
143

144
:: *GameObjectState state gs
145
146
147
   = { st :: state             // object state
     , or :: GameObjectRec     // object record
     , gs :: gs                // game state
Peter Achten's avatar
Peter Achten committed
148
     }
149

150
151
:: ObjectFun state gs
   :== IdFun (GameObjectState state gs)
Peter Achten's avatar
Peter Achten committed
152

153
:: ObjectCode
Peter Achten's avatar
Peter Achten committed
154
155
   :== Int

156
:: SubCode
Peter Achten's avatar
Peter Achten committed
157
158
159
160
161
162
163
164
   :== Int

:: MapCode
   :== Int

:: KeyCode
   :== Int

165
:: EventCode
Peter Achten's avatar
Peter Achten committed
166
167
168
169
170
171
172
173
174
175
176
177
   :== Int

:: EventPar
   :== Int

:: FVXY
   = { fvx  :: !FV
     , fvy  :: !FV
     }

:: FV
   = Factor !Real
178
   | Value  !Real
Peter Achten's avatar
Peter Achten committed
179
180
181
182
183
184

:: RealXY
   = { rx :: !Real
     , ry :: !Real
     }

185
:: GameObjectRec
Peter Achten's avatar
Peter Achten committed
186
   = { active              :: !Bool            // move and check collisions?
187
     , subcode             :: !SubCode         // object's sub-code
Peter Achten's avatar
Peter Achten committed
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
     , size                :: !Size            // the actual size
     , pos                 :: !Point2          // current position
     , offset              :: !Point2          // relative offset for sprite
     , currentsprite       :: !Int             // current animation sequence
     , displayoptions      :: !DisplayOptions  // invisible/mirror etc.
     , ownbounds           :: !Bounds          // bound(s) of the object (bits)
     , bouncebounds        :: !Bounds          // just bounce against these bounds
     , collidebounds       :: !Bounds          // call collide func for these bounds
     , forgetdistance      :: !Point2          // make object inactive at distance
     , framecounter        :: !GameTime        // frame counter
     , layer               :: !LayerPosition   // layer the object moves in front of
     , acceleration        :: !RealXY          // x/y acceleration
     , speed               :: !RealXY          // object's x/y speed
     , bounce              :: !FVXY            // x/y bounce at static bounds * 256
     , maxspeed            :: !RealXY          // x/y maximum speed
     , slowdown            :: !FVXY            // x/y slow down
     , skipmove            :: !Int             // acceleration delay
     , options             :: !ObjectOptions   // object options
     }

:: DisplayOptions
209
210
211
212
213
   = { blink               :: !Bool            // object blinks
     , stretch             :: !Bool            // stretch sprite to fit in size
     , mirrorleftright     :: !Bool            // mirror the sprite
     , mirrorupdown        :: !Bool            // draw sprite up side down
     , rotation            :: !Rotation        // rotation
Peter Achten's avatar
Peter Achten committed
214
215
216
217
218
219
220
     }

:: Rotation
   = NoRotation | Rotate90 | Rotate180 | Rotate270

:: ObjectOptions
   = { ignorelevelbounds   :: !Bool         // object can move out of the level
221
     , checkkeyboard       :: !Bool         // allow key down event for this object
Peter Achten's avatar
Peter Achten committed
222
223
224
225
     , allowkeyboardrepeat :: !Bool         // allow pressed key to repeat
     , static              :: !Bool         // object always moves with screen
     , hdirection          :: !HDirection   // horizontal direction of the object
     , vdirection          :: !VDirection   // vertical direction of the object
226
227
228
229
     , automirrorleftright :: !Bool         // mirror if horizontal direction change
     , automirrorupdown    :: !Bool         // mirror if vertical direction change
     , freeze              :: !Bool         // no movement until framecounter is 0
     , removemapcode       :: !Bool         // remove the object from the map
Peter Achten's avatar
Peter Achten committed
230
231
232
233
234
235
236
237
238
239
240
     }

:: HDirection
   = DirLeft | DirRight

:: VDirection
   = DirUp | DirDown

:: LayerPosition
   = InFront | AtLayer Int

241
242
:: GameText
   = { format    :: !String        // text to display or format string for value
Peter Achten's avatar
Peter Achten committed
243
244
245
246
247
248
249
250
251
     , value     :: Maybe Int      // value to display
     , position  :: !Point2        // position on screen
     , style     :: !Style         // style to write the text in
     , color     :: Colour         // color for the text
     , shadow    :: Maybe Shadow   // shadow
     , alignment :: Alignment      // text alignment
     }

:: Alignment
252
253
   = { xyfromscreencenter :: !(!Bool,!Bool) // center position on the screen
     , xycentered         :: !(!Bool,!Bool) // center text around position
Peter Achten's avatar
Peter Achten committed
254
255
256
     }

:: Style
257
258
259
260
   = { fontname :: !String                  // any font name
     , fontsize :: !Int                     // size of the text
     , bold     :: !Bool                    // bold
     , italic   :: !Bool                    // italic
Peter Achten's avatar
Peter Achten committed
261
262
263
     }

:: Shadow
264
265
   = { shadowpos   :: !Point2               // relative position of text shadow
     , shadowcolor :: !Colour               // color of the shadow
Peter Achten's avatar
Peter Achten committed
266
267
268
269
     }

instance zero RealXY
instance zero Alignment