Đầu tiên ta sẽ phân tích và xây dựng hàm view hàm sẽ hiển thị giao diện ngƣời dùng, hàm đƣợc khai báo với 2 tham số đó là: Một cặp số nguyên là giá trị chiều rộng và cao của cửa sổ màn hình, tham số thứ 2 là các đối tƣợng và trạng thái của trò chơi.
180 view : (Int,Int) -> Data -> Element
181 view (w,h) ({ball,img1,img2,state} as game) = 182 let
...
203 in ...
Với biểu thức let phía bên trong giúp ngƣời lập trình có thể định nghĩa các hàm và thực thi giá trị của chúng. Biểu thức in sẽ hiển thị tất cả các thành phần đồ họa và xử lý, cập nhật các giá trị tính toán trong chƣơng trình.
Các yếu tố đồ họa của trò chơi gồm: Một sân bóng bằng cách lấy một ảnh nền từ trong thƣ mục đƣờng dẫn chứa ảnh đó.
207 toForm (image 960 500 "image/Ground.jpg")
Sau đó ta tạo các đối tƣợng của trò chơi bao gồm: 2 ngƣời chơi và một quả bóng.
59 209 , make red ball (oval 20 20)
210 , toForm playerImage1 211 |> move(img1.x,img1.y)
212 , toForm playerImage2 213 |> move(img2.x,img2.y)
Ta cùng xét lại đoạn mã trên, việc tạo ra quả bóng ta dùng hàm make, chức năng hàm này sẽ giúp tạo các đối tƣợng dạng hình khối (shape), tô mầu và di chuyển nó theo tín hiệu đầu vào.
263 make color obj shape =
264 shape
265 |> filled color
266 |> move (obj.x, obj.y)
Với 2 cầu thủ ta không dùng hàm make để tạo, chúng sẽ tải ảnh theo đƣờng dẫn làm cho hình ảnh cầu thủ di chuyển động hơn và mƣợt mà hơn.
184 verb1 = if (img1.vx == 0 && img1.vy == 0) || (img2.vx == 0 &&
img2.vy == 0) then "stand" else "walk"
187 dir1 = case img1.dir of 188 Right -> "right12.gif" 189 Left -> "left1.png" 190 Down -> "down1.png" 191 Up -> "up1.gif" 192 dir2 = case img2.dir of 193 Right -> "right2.gif" 194 Left -> "left2.gif" 195 Down -> "down2.png" 196 Up -> "up2.gif"
198 src1 = "image/"++ verb1 ++ "/" ++ dir1 199 src2 = "image/"++ verb1 ++ "/" ++ dir2 201 playerImage1 = image 80 80 src1
202 playerImage2 = image 80 80 src2
Tiếp theo chúng ta sẽ xây dựng 2 khung thành. 216 ,filled white (rect goal.w goal.h)
217 |> move(-halfWidth + goal.w/2, 0)
218 ,filled white (rect goal.w goal.h)
219 |> move(halfWidth - goal.w/2, 0)
60
Chiều rộng và chiều cao của sân bóng và chiều rộng và chiều cao của khung thành đƣợc gắn giá trị.
175 (gameWidth,gameHeight) = (800,400) 176 (halfWidth,halfHeight) = (400,200) 177 goal = {w = 1, h =120}
178 gameOver = 5
Cuối cùng là các dòng text sẽ đƣợc in ra để thông báo hƣớng dẫn chơi và bảng điểm (score) của đội chơi. Hàm txt1 sẽ hiển thị một dòng văn bản ra màn hình.
251 txt1 : (Text.Text -> Text.Text) -> String -> Element 252 txt1 string = 253 Text.fromString string 254 |> Text.color black 255 |> Text.height 20 256 |> Text.bold 257 |> Text.monospace 258 |> leftAligned
260 msg = " SPACE to start, N to Restartgame, Hình 3.4: Giao diện chính của trò chơi
61
261 ↑ ↓ ← → and wasd to move,
262 Enter to shoot of player1 and Shift to shoot of player2"
Các dòng văn bản hƣớng dẫn sẽ đƣợc in lên một ảnh nền đƣợc tải từ trong thƣ mục ảnh vào.
224 , toForm (image 960 96 "image/intruction2.gif")
225 |> move (0,-gameHeight/2 - 90)
227 , toForm (if state == Play then spacer 1 1 else txt1 msg)
228 |> move (150,-gameHeight/2 - 90)
Ngoài việc dùng hàm để hiện thị văn bản, ngƣời lập trình vẫn có thể hiển thị văn bản ra ngoài màn hình bằng cú pháp.
235 toForm (centered (
236 Text.fromString (if (img1.score < gameOver && img2.score <
gameOver) then "" else "Game Over!")
237 |> Text.color red 238 |> Text.bold 239 |> Text.height 68
240 ))
Dòng lệnh trên sẽ hiển thị chữ “Game Over!” ra ngoài màn hình khi trò chơi kết thúc.
62