-
-
Save sshine/0c7c3bcc1560279530da to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(* | |
* TODO: | |
* - Collision detection | |
* - Handle larger maps than 32x24 tiles by scrolling the map | |
* - Display field of view based on actual system clock time | |
* - Event rate limiting (avoid duplicate events after each other) | |
*) | |
(* Why does ML not have this already? *) | |
infixr $ | |
fun f $ x = f x | |
local | |
fun foldli' f i e [] = e | |
| foldli' f i e (x::xs) = foldli' f (i+1) (f (i, x, e)) xs | |
in | |
fun foldli f = foldli' f 0 | |
end | |
(* Random numbers *) | |
;load "Random"; | |
val rng = Random.newgen () | |
(* Game logic *) | |
datatype drawable = Grass | Rock | Water | Tree | Door | |
type PlayerPos = int * int | |
datatype gamestate = GameState of PlayerPos | |
fun getPlayerPos (GameState pp) = pp | |
fun getMapPos (0, 0) ((x::_)::_) = x | |
| getMapPos (x, 0) ((_::xs)::_) = getMapPos (x-1, 0) [xs] | |
| getMapPos (x, y) (_::ys) = getMapPos (x, y-1) ys | |
| getMapPos _ _ = Grass | |
fun addp (x1,y1) (x2,y2) = (x1+x2,y1+y2) | |
fun move p1 (GameState p2) gameMap = | |
let val p' = addp p1 p2 in | |
case getMapPos p' gameMap of | |
Grass => GameState p' | |
| _ => GameState p2 | |
end | |
val element = | |
fn #" " => Grass | |
| #"#" => Rock | |
| #"~" => Water | |
| #"T" => Tree | |
| #"D" => Door | |
fun withFile f fname = | |
let val fd = TextIO.openIn fname | |
in (f (TextIO.inputAll fd) before TextIO.closeIn fd) | |
handle Io x => raise Io x | |
| exn => (TextIO.closeIn fd; raise exn) | |
end | |
fun getmap fname = | |
let fun isBreak c = (c = #"\r" orelse c = #"\n") | |
in withFile (fn s => map (map element o explode) (String.tokens isBreak s)) fname | |
end | |
(* MosGame stuff *) | |
;load "MosGame"; | |
(* MEDIC! *) | |
structure M = MosGame | |
structure E = M.Event | |
structure D = M.Draw | |
structure I = M.Image | |
(*structure C = M.Colors*) | |
(* Initialize screen *) | |
val _ = M.init () | |
val disp = M.Display.create_display (640, 480) | |
(* Drawing functions *) | |
val squareSize = 20 | |
fun gridCoords (i, j) = (squareSize*i, squareSize*j) | |
fun draw fs = | |
app (fn f => ignore $ f ()) fs | |
before M.Display.flip disp | |
fun drawbox (i,j) color = | |
let val (x,y) = gridCoords (i,j) | |
val rect = D.FilledRectangle((x, y), (squareSize, squareSize)) | |
in D.draw_rectangle disp rect color | |
end | |
fun drawcircle (i,j) color = | |
let val (x,y) = gridCoords (i,j) | |
fun drawsymb (i, j) symb = | |
case symb of | |
Grass => drawbox (i,j) M.Green | |
| Rock => drawbox (i,j) M.DarkGray | |
| Water => drawbox (i,j) M.Blue | |
| Tree => drawbox (i,j) (M.RGB (0, 140, 0)) | |
| Door => drawbox (i,j) (M.RGB (128, 64, 0)) | |
fun drawMap m _ = | |
foldli (fn (j, rows, _) => | |
foldli (fn (i, symb, _) => | |
drawsymb (i, j) symb) () rows) () m | |
fun drawPlayer (x,y) _ = | |
drawcircle (x,y) M.Black | |
(* Game loop *) | |
fun process gameState gameMap = | |
case E.poll () of | |
NONE => gameState | |
| SOME E.QuitEvent => (quit (); gameState) | |
| SOME (E.KeyboardEvent data) => handleKey data gameState gameMap | |
| SOME _ => gameState | |
and handleKey (state, symb, modifiers) gameState gameMap = | |
if state <> E.KeyPressed then gameState else | |
case symb of | |
E.KeyQ => (quit (); gameState) | |
| E.KeyW => move (0,~1) gameState gameMap | |
| E.KeyA => move (~1,0) gameState gameMap | |
| E.KeyS => move (0,1) gameState gameMap | |
| E.KeyD => move (1,0) gameState gameMap | |
| _ => gameState | |
(*******************) | |
fun loop gameState gameMap = | |
(draw [ drawMap gameMap (getPlayerPos gameState) | |
, drawPlayer (getPlayerPos gameState)]; | |
loop (process gameState gameMap) gameMap) | |
fun run _ = | |
let val jungle = getmap "jungle.txt" | |
in loop (GameState (6,6)) jungle | |
end | |
val _ = run () |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment