Ở những phần trước, chúng ta đã khám phá nhiều khía cạnh khác nhau của MAXScript, từ các thao tác cơ bản đến những kỹ thuật nâng cao. Một trong các kỹ thuật cơ bản đã được nhắc tới là câu lệnh điều kiện if-then, đã được đề cập tới trong phần 9 của loạt bài viết này.
Trong phần 12 này, chúng ta sẽ đi sâu vào cách sử dụng các câu lệnh xử lý điều kiện điều kiện. Đây sẽ là thứ bạn sẽ thường xuyên phải sử dụng để xử lý các tình huống khác nhau trong script.
Ngoài ra, chúng ta cũng sẽ học thêm về case of – một cấu trúc lệnh điều kiện nâng cao, giúp bạn có thêm nhiều lựa chọn hơn để xử lý dữ liệu đầu vào.
Hãy mở MAXScript Editor lên và cùng bắt đầu.
MỤC LỤC
Câu lệnh if – then – else
Câu lệnh điều kiện if – then – else trong MAXScript rất dễ hiểu, gần giống với ngôn ngữ tự nhiên của con người. Chúng có cú pháp như sau:
if <điều kiện> then <biểu thức 1> else <biểu thức 2>
Trong đó:
- <điều kiện> là một biểu thức trả về giá trị boolean (true hoặc false).
- <biểu thức 1> sẽ được thực hiện nếu điều kiện là true.
- <biểu thức 2> sẽ được thực hiện nếu điều kiện là false.
Lưu ý rằng, cụm else <biểu thức 2> không bắt buộc. Câu lệnh vẫn chạy bình thường với cặp if…then. Khi <điều kiện> không được đáp ứng, sẽ không có gì xảy ra.
Ví dụ cơ bản
Hãy xem xét ví dụ sau. Giả sử bạn muốn kiểm tra xem giá trị của một biến có lớn hơn 10 hay không, và in ra kết quả phù hợp. Chúng ta sẽ viết như sau:
x = 15 if x > 10 then messageBox "Giá trị lớn hơn 10" else messageBox "Giá trị không lớn hơn 10"
Trong ví dụ này, vì giá trị của x là 15 (lớn hơn 10), nên 3ds Max sẽ hiện ra thông báo “Giá trị lớn hơn 10”.
Bạn hãy thử với các con số khác nhau để kiểm tra cách script xử lý các điều kiện.
Điều kiện kết hợp
<điều kiện> không nhất thiết chỉ gồm 1 điều kiện duy nhất. Bạn cũng có thể sử dụng các toán tử logic như and hoặc or để kết hợp nhiều điều kiện thành một nhóm điều kiện trong câu lệnh if_then_else. Ví dụ với and:
a = 5 b = 20 if (a < 10 and b > 10) then messageBox "Cả hai điều kiện đều đúng" else messageBox "Một hoặc cả hai điều kiện sai"
Với and, tất cả các điều kiện phải được thỏa mãn để câu lệnh trả về true. Ở ví dụ cụ thể trên, cả hai điều kiện đều đúng (5 < 10 và 20 > 10), nên 3ds Max sẽ thông báo “Cả hai điều kiện đều đúng”.
Tương tự với or:
a = 15 b = 5 if (a > 10 or b > 10) then messageBox "Một trong hai số lớn hơn 10" else messageBox "Không số nào lớn hơn 10"
Với or, chỉ cần một trong các điều kiện thỏa mã, câu lệnh sẽ trả về true. Vì a > 10, cho nên MAXScript sẽ ngay lập tức trả về true, mà không xem xét các điều kiện phía sau. 3ds Max thông báo rằng: “Một trong hai số lớn hơn 10”.
Ngoài ra, bạn cũng có thể dùng not để biểu thị một điều kiện ngược lại. Ví dụ: not a < 5 tương đương với a > 5. Hoặc not (a + b) = 18 tương đương (a + b) != 18.
Trong các ví dụ trên, tôi chỉ nêu việc kết hợp hai điều kiện. Trong thực tế, bạn có thể kết hợp nhiều hơn 2 điều kiện. Ví dụ:
local a = 5 local b = 15 local c = 35 if (a < 10 and (b > 10 or c < 30)) then messageBox "Đúng!" else messageBox "Sai!"
Hãy chú ý tới các cặp dấu ngoặc tôi khoanh màu. Với điều kiện này, ta có a < 10 (đúng) và (b > 10 or c < 30) cũng đúng (do có b > 10). Vì thế 3ds Max hiển thị kết quả “Đúng!” khi chạy lệnh.
Sử dụng if – then – else lồng nhau
Bạn có thể lồng nhiều câu lệnh if – then – else để kiểm tra nhiều điều kiện khác nhau trong một khối mã. Ví dụ như sau:
x = 15 if x < 10 then messageBox "x nhỏ hơn 10" else if x < 20 then messageBox "x nằm trong khoảng 10 đến 20" else messageBox "x lớn hơn hoặc bằng 20"
Kết quả của đoạn mã này sẽ là “x nằm trong khoảng 10 đến 20” vì x = 15. Bạn có thể lồng vô hạn số cặp if – then, tuy nhiên, câu lệnh sẽ càng ngày càng dài và khó kiểm soát. Trong trường hợp đó, case là thay thế hoàn hảo cho câu lệnh if – then.
Câu lệnh case of
Câu lệnh case of trong MAXScript cho phép bạn lựa chọn giữa nhiều trường hợp khác nhau, dựa trên giá trị của một biểu thức, hoặc điều kiện. Nó có hai dạng cú pháp cơ bản như sau:
case <biểu thức> of ( <giá trị 1>: <biểu thức 1> <giá trị 2>: <biểu thức 2> <giá trị 3>: <biểu thức 3> ... <giá trị n>: <biểu thức 3> default: <biểu thức mặc định> )
case of ( <điều kiện 1>: <biểu thức 1> <điều kiện 2>: <biểu thức 2> <điều kiện 3>: <biểu thức 3> ... <điều kiện n>: <biểu thức 3> default: <biểu thức mặc định> )
Case giúp chúng ta viết câu lệnh điều kiện một cách có tổ chức, dễ chỉnh sửa và thay thế. Trong cú pháp đầu tiên, <biểu thức> sẽ được so sánh lần lượt với <giá trị 1>, <giá trị 2>,…, cho đến <giá trị n>. Nếu kết quả bằng nhau, biểu thức tương ứng sẽ được thực hiện. Nếu <biểu thức> không trùng với bất kỳ giá trị nào được liệt kê, câu lệnh sẽ cho ra kết quả theo khai báo <biểu thức mặc định>.
Còn trong cú pháp thứ 2, các <điều kiện> sẽ lần lượt được kiểm tra từ trên xuống dưới. Nếu một trong các điều kiện thỏa mãn, MAXScript sẽ thực hiện biểu thức tương ứng với điều kiện. Tương tự, nếu không điều kiện nào thỏa mãn, <biểu thức mặc định> sẽ được thực hiện.
Hãy cùng tôi đi vào phần ví dụ.
Ví dụ cơ bản case <biểu thức> of
Giả sử tôi có số tự nhiên đầu vào x, với 1 < x < 8. Tức là x nằm trong khoảng [2-7]. Ta cần viết một câu lệnh để xác định ngày trong tuần tương ứng với x. Ví dụ, nếu x=3, kết quả trả về sẽ là “Thứ 3”. Ta có thể viết bằng if-then lồng nhau, nhưng nó khá dài dòng với các từ khóa lặp đi lặp lại:
if x == 2 then messageBox "Thứ 2" else if x == 3 then messageBox "Thứ 3" else if x == 4 then messageBox "Thứ 4" else if x == 5 then messageBox "Thứ 5" else if x == 6 then messageBox "Thứ 6" else if x == 7 then messageBox "Thứ 7" else if x == 8 then messageBox "Chủ Nhật" else messageBox "Giá trị không hợp lệ"
Trong khi đó, chúng ta có thể viết lại bằng case of như sau:
case x of ( 2: messageBox "Thứ 2" 3: messageBox "Thứ 3" 4: messageBox "Thứ 4" 5: messageBox "Thứ 5" 6: messageBox "Thứ 6" 7: messageBox "Thứ 7" 8: messageBox "Chủ Nhật" default: messageBox "Giá trị không hợp lệ" )
Cách viết với case of rất đơn giản về dễ hiểu, do đó nó thích hợp với trường hợp chúng ta cần xử lý nhiều điều kiện. Lúc này chúng ta có thể nhanh chóng bổ sung hoặc loại bỏ các điều kiện khác, mà không cần bổ sung hoặc loại bỏ các từ khóa if – then.
Ví dụ cơ bản case of
Chúng ta sẽ cùng xem xét 1 ví dụ khác. Ta sẽ kiểm tra xem số đầu vào x xem là số âm hay dương:
- x là số âm: Nếu x < 0, 3ds Max sẽ thông báo “x là một số âm”.
- x là số dương: Nếu x > 0, 3ds Max sẽ thông báo “x là một số dương”.
- x bằng 0: Nếu x = 0, 3ds Max sẽ thông báo “x là bằng 0”.
Code trên có thể được viết như sau:
case of ( (x < 0): messageBox "x là một số âm" (x > 0): messageBox "x là một số dương" default: messageBox "x là bằng 0" )
Trong ví dụ này, ta sẽ viết một giao diện đơn giản trong MAXScript để người dùng có thể nhập số để kiểm tra, thay vì sử dụng biến cho trước.
rollout checkNumberRollout "Kiểm tra số" ( editText numInput "Nhập số:" width:150 button btnCheck "Kiểm tra" width:150 on btnCheck pressed do ( x = numInput.text as float case of ( (x < 0): messageBox "Số bạn nhập là một số âm" (x > 0): messageBox "Số bạn nhập là một số dương" default: messageBox "Số bạn nhập bằng 0" ) ) ) createDialog checkNumberRollout
Hãy thực thi câu lệnh trên trong MAXScript Edittor. Trong cửa sổ ‘Kiểm tra số’ hiện ra, hãy thử nhập thử một vài giá trị để kiểm tra.
Hãy thử với các con số khác nhau để kiểm tra cách script xử lý các điều kiện. Kiểm tra cả với trường hợp giá trị nhập vào không hợp lệ, ví dụ như một ký tự đặc biệt, hoặc một chữ cái.
So sánh case of và if – then – else
Qua các ví dụ trên, có thể thấy rằng case of và if – then – else có các cách tác dụng hoàn toàn tương đồng, và có thể thay thế cho nhau. Điểm khác biệt giữa chúng chỉ là ở cách viết:
- if – then – else là câu lệnh dễ hiểu, tự nhiên và thân thiện nhưng chỉ phù hợp khi số lượng các trường hợp cần kiểm tra ít.
- case of mặc dù cách viết phức tạp hơn, nhưng nó hiệu quả khi bạn phải xử lý nhiều trường hợp khác nhau, giúp mã ngắn gọn và dễ đọc.
Thực tế, bạn cũng có thể kết hợp cả câu lệnh trên để tăng mức linh hoạt cao hơn nữa. Ví dụ, bạn có thể dùng if – then như một bộ lọc thô, sau đó mới cho luồng dữ liệu vào trong case of để xử lý.
Bài tập thực hành
Ở trên, chúng ta mới nói về xử lý số liệu và văn bản. Trong bài tập này, chúng ta sẽ thử xử lý các vật thể trong 3ds Max, và đưa ra kết quả tùy vào từng trường hợp. Nếu có thể, hãy thử nghĩ ra một cách giải khác.
Bài tập số 1
Tạo một giao diện với một nút bấm “Kiểm tra Hình Hộp”. Khi người dùng nhấn nút này, chương trình sẽ kiểm tra có vật thể nào đang chọn không. Và nếu có vật thể đang chọn, thì nó có phải là khối ‘Box’ không. Nếu vật thể không phải là hình hộp, hiển thị thông báo lỗi. Gợi ý: điều kiện kiểm tra là classof obj, == Box
Bài tập số 2
Vẫn ở chương trình kiểm tra hình hộp trên. Nếu vật thể là hình hộp, sử dụng case of để kiểm tra thể tích của hình hộp.
- Nếu lớn hơn 2000, hiển thị “Thể tích rất lớn”.
- Nếu lớn hơn 1000 nhưng nhỏ hơn hoặc bằng 2000, hiển thị “Lớn”.
- Nếu lớn hơn 500 nhưng nhỏ hơn hoặc bằng 1000, hiển thị “Trung bình”.
- Nếu lớn hơn 100 nhưng nhỏ hơn hoặc bằng 500, hiển thị “Nhỏ”.
- Nếu nhỏ hơn hoặc bằng 100, hiển thị “Rất nhỏ”.
Gợi ý, nếu obj là khối box, thì các thuộc tính về kích rộng, cao, dài của obj lần lượt là obj.width, obj.height và obj.length.
Lời giải
Như đã nói ở trên, hàm if – then – else và case có thể chuyển đổi và sử dụng kết hợp trong cùng một khối lệnh. Lời giải ở dưới chỉ mang tính tham khảo, nếu có thể, hãy tìm cách viết lại theo logic của mình.
rollout boxCheckRollout "Kiểm Tra Thể Tích Hình Hộp" ( button btnCheck "Kiểm tra Hình Hộp" width:150 on btnCheck pressed do ( local obj = selection[1] if (obj != undefined and classOf obj == Box) then ( volume = obj.width * obj.height * obj.length case of ( (volume > 2000): messageBox "Rất lớn " (volume > 1000): messageBox "Lớn" (volume > 500): messageBox "Trung bình" (volume > 100): messageBox "Nhỏ" default: messageBox "Rất nhỏ" ) ) else messageBox "Lỗi lựa chọn!" ) ) createDialog boxCheckRollout
Chúc các bạn thành công.