Ở phần này, chúng ta sẽ tìm hiểu về Array (mảng). Mảng là một cấu trúc dữ liệu được biểu diễn dưới dạng một dãy hữu hạn các phần tử. Khác với một số ngôn ngữ lập trình khác, các phần tử trong MAXScript Array không nhất thiết phải cùng kiểu dữ liệu.
Array là một kiểu cấu trúc dữ liệu quan trọng, đặc biệt là khi làm việc với một số lượng biến lớn. Khi kết hợp cùng vòng lặp, nó sẽ giúp việc quản lý và sử dụng giá trị của các phần tử được dễ dàng và nhanh chóng hơn nhiều.
MỤC LỤC
Lý thuyết chung
Cấu trúc cơ bản
Trong MAXScript, một array có cấu trúc cơ bản như sau:
#(<giá trị>, <giá trị>, ...)
Ví dụ:
#("Hùng", "Đức", "Mạnh", "Quang") -- một array chứa tập hợp tên người #(15, 30, 45, 60) -- một array chứa tập hợp các số tự nhiên #() -- một array trống, không chứa phần tử nào
Một Array có thể chứa 2 hoặc tử trùng giá trị của nhau. Các phần tử không nhất thiết phải cùng kiểu dữ liệu, tuy nhiên, để tiện cho việc quản lý, rất hiếm trường hợp chúng ta cần xây dựng array như vậy. Thay vì đó, thứ được sử dụng thay thế là struct, mà chúng ta sẽ học ở các bài sau.
Thuộc tính của Array
Sau khi xây dựng một array, chúng ta có thể truy xuất và gán dữ liệu cho từng phần tử trong array bằng cách gọi array[x], trong đó x là số thứ tự của phần tử đó trong array. Hãy mở MAXScript Editor lên và nhập vào chuỗi lệnh sau:
arr = #("Hùng", "Đức", "Mạnh", "Quang") -- gán biến arr cho một array tập hợp tên người messageBox arr[1] -- dùng lệnh messageBox để hiển thị thông báo nội dung phần tử đầu tiên
3ds Max sẽ hiển thị thông báo “Hùng”. Bây giờ, hãy thử thay arr[1] bằng arr[5] và chạy lại lệnh. Lần này, bạn sẽ thấy không có thông báo nào hiển thị ra. MAXScript Listener hiển thị thông báo lỗi “Unable to convert: undefined to type: String”. Lý do là vì arr là một array chỉ có 4 phần tử. Phần tử thứ 5 không tồn tại (undefined), vì thể script sẽ báo lỗi.
Bây giờ, hãy chèn thêm dòng lệnh arr[1] = “Tâm” vào giữa dòng số 1 và dòng số 2.
arr = #("Hùng", "Đức", "Mạnh", "Quang")
arr[1] = "Tâm" -- gán biến "Tâm" cho phần tử đầu tiên của arr
messageBox arr[1]
Lần này, khi chạy lệnh, script sẽ không hiển thị thông báo “Hùng” trên màn hình nữa. Thay vào đó nó hiển thị “Tâm”. Vậy là chúng ta có thể ghi đè giá trị của từng phần tử trong array, bằng cách dùng cấu trúc:
array[x] = <giá trị>
Array có một thuộc tính cơ bản là count. Thuộc tính này dùng để đếm số lượng phần tử trong array. Chúng ta sẽ gọi thông số này bằng cách viết array.count. Hãy xem xét ví dụ dưới:
arr = #(1,3,5,6,7,3,4,1,3,8,9,12,4,5,6,7,99)
x = arr.count -- gán số số lượng phần tử của arr cho x
messageBox (arr[x] as string)
Trong ví dụ trên, arr có 17 phần tử, nên lệnh x = arr.count sẽ gán cho x giá trị là 17. Và arr[x] sẽ là phần tử số 17, cũng là phần tử cuối cùng trong array. Khi chạy lệnh, 3ds Max sẽ thông báo trên màn hình “99”.
Kết hợp cùng vòng lặp
Như đã nói ở phần giới thiệu, array rất hiệu quả khi được kết hợp cùng vòng lặp. Chúng ta thậm chí có thể sử dụng vòng lặp để xây dựng 1 array. Trong phần 6, chúng ta đã học cấu trúc cơ bản nhất của vòng lặp For, đó là:
for <số lần lặp> do <câu lệnh>
Vòng lặp For còn có một cách sử dụng khác, đó là:
for <điều kiện / where> collect <giá trị>
Cấu trúc với lệnh do được dùng để chạy một hoặc một tập hợp lệnh trong 1 lần lặp. Còn cấu trúc collect dùng để thu thập một tập hợp giá trị để xây dựng array. Ví dụ câu lệnh sau sẽ thu thập các số tự nhiên trong khoảng từ 1 đến 50 mà chia hết cho 12.
arr = for i = 1 to 50 where (mod i 12 == 0) collect i
Bạn sẽ thấy ở MAXScript Listener hiển thị #(12, 24, 36, 48).
Ví dụ với vòng lặp
Hãy mở 3ds Max và tạo ra 3 bình trà, 3 khối box và 3 khối cylinder.
Trong ví dụ trên, tôi muốn lựa chọn tất cả các khối box trong scene hiện tại, và đổi tên các khối box theo cú pháp “Khoi box so x”.
arr = for obj in geometry where classOf obj == Box collect obj -- tạo arr gồm các khối box for i = 1 to arr.count do arr[i].name = "Khoi box so " + (i as string) -- đổi tên các phần tử select arr -- lựa chọn arr chứa các khối box trong viewport
Các câu lệnh có thể được giải thích kỹ lưỡng như sau:
- Câu lệnh đầu sẽ lọc các geometry có sẵn trong scene hiện tại mà lớp (class) của nó là Box. Trong đó, arr và obj là các từ khóa tùy theo bạn đặt, còn geometry và Box là các từ khóa có sẵn trong 3ds Max. Hãy ghi nhớ những từ khóa có sẵn vì bạn sẽ cần sử dụng nó ở trong những bài học sau.
- Sau câu lệnh đầu, chúng ta sẽ có arr gồm tập hợp các khối box trong scene. Lưu ý arr và Box không có ràng buộc với nhau. Bạn có thể xóa nội dung của arr mà không làm mất các khối box và ngược lại.
- Câu lệnh số 2 sẽ đổi tên từng phần tử của arr. Chúng ta dùng chỉ số i để đánh số thứ tự cho khối box. Vì i là số tự nhiên nên phải convert sang String (i as string) để kết hợp cùng dòng “Khoi box so “. Name là một thuộc tính (properties) của khối Box.
- Lệnh cuối dùng để chọn tất cả các phần tử của arr trong viewport.
Sau khi Evaluate chuỗi lệnh trên, bạn sẽ thấy rằng các khối box sẽ được đổi tên thành Khoi box so 1, Khoi box so 2 và Khoi box so 3. Chúng cũng được chọn trong viewport.
Thực hành ứng dụng
Chúng ta sẽ có 2 bài tập nhỏ để ứng dụng array vào thực tế. Lưu ý: hãy cố gắng giải bài tập trước khi xem lời giải. Dùng chuột bôi đen phần phía dưới mỗi đề bài để thấy đáp án. Nếu có thể, hãy thử nghĩ ra một cách giải khác.
Bài tập số 1
Vẫn trong scene ví dụ trên. Hãy chọn và đổi màu wireframe của các khối trụ. Gợi ý: khối trụ có class là Cylinder và thuộc tính màu wireframe của 1 vật thể là wirecolor. Trong 3ds Max có sẵn các màu được thiết lập từ trước là red, green, blue, white, black, orange, yellow, brown, gray.
arr = for obj in geometry where classOf obj == cylinder collect obj
for c in arr do c.wirecolor = black
Bài tập số 2
Vẫn trong scene ví dụ trên. Hãy chọn các bình trà và đổi thuộc tính segments của các bình trà ngẫu nhiên từ 1 đến 10. Gợi ý: bình trà có class là Teapot và thuộc tính segments của nó là segs. Cú pháp để lấy 1 số random trong khoản từ x đến y là (random x y).
arr = for obj in geometry where classOf obj == teapot collect obj for c in arr do c.segs = (random 1 10)
đây là chuổi nội dung thú vị và có ích nhất. Việc càng nhiều ng Việt có thể tạo các script tạo ra môi trường làm việc năng động sáng tạo và hiệu quả hơn. Rất mong chờ các nội dung tiếp theo của D95. Hi vọng D95 có thể ra thêm các sản phẩm để đặt kênh render element nhanh để gom đèn vào lightmix. Hoặc bấm preset các vật liệu có sẳn thành legacy với setting reflect a, glossines b, refract c….vv để thay đổi tính chất object lúc copy từ su sang max, hình như script copy có phần copy to max legacy nhưng cách hoạt động của nó còn gây lúng túng. Cảm ơn rất nhiều
Cảm ơn bạn đã góp ý!