-
Notifications
You must be signed in to change notification settings - Fork 2
/
sfml.ml
144 lines (122 loc) · 3.17 KB
/
sfml.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
module Stone = Color
open OcsfmlSystem
open OcsfmlWindow
open OcsfmlGraphics
open OcsfmlAudio
open Types
open Bigarray
let ( $ ) f x = f x
module C = struct
let size = 20.0
end
let font = new font (`File "resources/sansation.ttf")
let pause_message = new text ~font
~character_size:40
~position:(170.0, 150.0)
~color:Color.white
~string:"Paused: Press p to unpause"
~style:[Bold]
()
let dead_message = new text ~font
~character_size:40
~position:(170.0, 150.0)
~color:Color.white
~string:"Dead: Press space to start the game"
~style:[Bold]
()
let top_left row col =
(C.size *. (float_of_int col), C.size *. (float_of_int row))
let color_of_stone color =
let s x = int_of_float (x *. 255.0) in
let (r, g, b) = Stone.rgb color in
Color.rgb (s r) (s g) (s b)
let rect_of row col color =
let position = top_left row col in
let size = (C.size, C.size) in
let fill_color = color_of_stone color in
new rectangle_shape ~size ~position
~outline_thickness: 1.0
~outline_color: Color.white
~fill_color
()
let draw_board (display: render_window) w =
let open World in
let open Board in
let bgcolor = Color.rgb 0 0 0 in
display#clear ~color:bgcolor ();
let b = w.board in
for r = 0 to b.rows - 1 do
for c = 0 to b.cols - 1 do
match b.grid.(r).(c) with
| Some color -> begin
let rect = rect_of r c color in
display#draw rect
end
| None -> ()
done
done;
match w.state with
| Paused _ -> display#draw pause_message
| Dead -> display#draw dead_message
| _ -> ()
let test_tetris () =
let open World in
Random.self_init () ;
let game_width = 600 in
let game_height = 800 in
let vm = VideoMode.create ~w:game_width ~h:game_height () in
let app = new render_window vm "Ocsfml - Tetris" in
let global_clock = new clock in
let world = World.make default_configuration 0 in
let update action =
let t = Time.as_seconds global_clock#restart in
Tetris.update world t action;
in
let rec event_loop () =
match app#poll_event with
| Some e ->
let open Event in
begin
match e with
| KeyPressed { code = KeyCode.Escape }
| Closed -> app#close
| KeyPressed { code = code ; _ } ->
begin
let action = match code with
| KeyCode.Up -> Some(Rotate)
| KeyCode.Down -> Some(Down)
| KeyCode.Left -> Some(Left)
| KeyCode.Right -> Some(Right)
| KeyCode.Space -> Some(Drop)
| KeyCode.P -> Some(Pause)
| _ -> None
in
update action
end
| _ -> ()
end ;
event_loop ()
| None -> ()
in
let draw w =
if w.dirty then draw_board app w
in
let timed_update () =
let tau = Time.as_milliseconds global_clock#get_elapsed_time in
if (tau > 50) then update None
in
let rec main_loop () =
if app#is_open
then
begin
event_loop ();
timed_update ();
draw world;
app#display;
main_loop ()
end
in
main_loop ();
Gc.full_major () ;
font#destroy
let _ = test_tetris ()