Lập trình UI
UI thuộc về từng người chơi, nên được điều khiển bằng ClientScript. Bạn có thể dựng UI trong KHIM Engine (Thiết kế UI) rồi lập trình, hoặc dựng hoàn toàn bằng code.
Gọi tới UI dựng trong KHIM Engine
Mỗi người chơi nhận một bản của mọi thứ dưới UI khi vào game. ClientScript nằm bên trong một đối tượng UI có đối tượng đó là script.parent:
-- ClientScript bên trong Canvas "Shop"
local shop = script.parent
local buy = shop.Panel.BuyButton
buy.clicked:connect(function()
net.send("buy", "Sword")
end)ClientScript khác tìm nó trong gui của người chơi:
local shop = players.me.gui:waitFor("Shop")
shop.visible = falseDựng UI bằng code
-- ClientScript: bộ đếm xu ở đầu màn hình
local canvas = new("Canvas", players.me.gui)
local label = new("Label", canvas)
label.anchor = vec2(0.5, 0)
label.position = dim(0.5, 0, 0, 80) -- giữa màn hình, cách mép trên 80 điểm
label.size = dim.px(200, 40)
label.text = "Xu: 0"
label.textSize = 22
label.textColor = rgb(255, 255, 255)
label.backgroundColor = rgb(20, 20, 20)
label.backgroundTransparency = 0.3
new("Corner", label).radius = 12
net.on("coinCollected", function(total)
label.text = "Xu: " .. total
end)Kích thước và vị trí: dim
UI được dàn bằng giá trị dim - một scale (tỉ lệ của cha) và một offset (điểm UI) cho X và Y:
dim(xScale, xOffset, yScale, yOffset)
dim(0.5, 0, 0, 40) -- rộng nửa cha, cao 40 điểm
dim.scale(1, 1) -- bằng cả cha
dim.px(200, 50) -- 200 x 50 điểmanchor (một vec2, 0 tới 1) là điểm của đối tượng mà position đặt vào: vec2(0.5, 0.5) là canh giữa.
Điểm UI to lên theo tỉ lệ HUD của người chơi, nên bố cục trông như nhau trên màn hình lớn. camera.viewportSize cho kích thước màn hình tính bằng điểm UI.
Thuộc tính chung
Mọi đối tượng UI (Panel, Label, Button, TextInput, Image, ImageButton...):
| Thành viên | |
|---|---|
position, size | dim |
anchor | vec2 |
backgroundColor, backgroundTransparency | Hộp nền |
visible | Hiện hay ẩn |
zIndex | Vẽ đè lên cái thấp hơn (không bao giờ nằm dưới cha) |
layoutOrder | Thứ tự trong ListLayout hay GridLayout sắp theo LayoutOrder |
Đối tượng chữ (Label, Button, TextInput) có thêm text, textColor, textSize, textAlign ("Left", "Center", "Right"), textWrapped, textScaled và font ("Default", "Bold", "Display").
Hình ảnh có thêm image (tên hình - "coin", "icon-star"... - hoặc "asset:123"), imageColor, imageTransparency.
Nút bấm và ô nhập
button.clicked:connect(function() print("đã bấm") end) -- Button, ImageButton
box.focusLost:connect(function(enterPressed) -- TextInput
if enterPressed then print("đã gõ: " .. box.text) end
end)
box.placeholder = "Nhập mã"Các điều khiển riêng của KHIM:
local bar = new("ProgressBar", canvas) -- máu, kinh nghiệm, đang tải
bar.min, bar.max, bar.value = 0, 100, 75
bar.fillColor = rgb(80, 220, 120)
local slider = new("SliderInput", canvas) -- người chơi kéo
slider.min, slider.max, slider.step = 0, 1, 0.05
slider.changed:connect(function(value) print("âm lượng", value) end)
local toggle = new("Toggle", canvas) -- bật/tắt
toggle.text = "Nhạc"
toggle.changed:connect(function(on) print("nhạc", on) end)Đối tượng bố cục
Đặt chúng bên trong một đối tượng UI để sắp xếp hay trang trí:
local list = new("ListLayout", panel)
list.direction = "Vertical" -- hoặc "Horizontal"
list.padding = 8 -- số điểm giữa các con
list.alignX = "Center"
list.sortOrder = "LayoutOrder" -- hoặc "Name"
local grid = new("GridLayout", panel)
grid.cellSize = dim.px(80, 80)
grid.cellPadding = dim.px(6, 6)
local pad = new("Padding", panel)
pad.top, pad.bottom, pad.left, pad.right = 10, 10, 12, 12
new("Corner", panel).radius = 10
local border = new("Border", panel)
border.color = rgb(255, 255, 255)
border.thickness = 2
border.transparency = 0.6
local grad = new("Gradient", panel)
grad.color0 = rgb(40, 40, 60)
grad.color1 = rgb(10, 10, 20)
grad.rotation = 90 -- từ trên xuống| Bổ trợ | Thành viên |
|---|---|
AspectRatio | aspectRatio, aspectType ("FitWithinMaxSize", "ScaleWithParentSize"), dominantAxis |
Scale | scale - vẽ nó và nội dung to hay nhỏ hơn (tween để làm hiệu ứng rê chuột) |
SizeLimit | minSize, maxSize (vec2, điểm) |
TextSizeLimit | minTextSize, maxTextSize |
Border | applyTo = "Text" viền quanh chữ thay vì quanh hộp |
Gradient | colorMid, midpoint - màu thứ ba ở giữa |
Danh sách cuộn
ScrollPanel cuộn nội dung bằng con lăn chuột hoặc kéo:
local scroller = new("ScrollPanel", canvas)
scroller.size = dim.px(300, 400)
scroller.automaticCanvasSize = "Y" -- tự lớn ra cho vừa nội dung
new("ListLayout", scroller).padding = 6
for i = 1, 20 do
local row = new("Button", scroller)
row.size = dim(1, 0, 0, 40)
row.text = "Món " .. i
endNút trong ScrollPanel chỉ được bấm khi thả tay mà không kéo, nên lướt cửa hàng bằng ngón tay sẽ không mua nhầm.
Hiệu ứng chuyển động cho UI
Đối tượng UI tween như part:
panel.position = dim(0.5, 0, 1.2, 0) -- nằm ngoài mép dưới
panel:tween({position = dim(0.5, 0, 0.5, 0)}, {time = 0.4, style = "Back", direction = "Out"})
local grow = new("Scale", button)
-- khi rê chuột, script có thể tween grow.scale từ 1 lên 1.1Hiện menu trong game góc nhìn thứ nhất
Ở góc nhìn thứ nhất hoặc khoá camera, con trỏ bị giữ ở giữa. Thả nó ra khi menu mở:
input.onKey("B", function()
shop.visible = not shop.visible
input.mouseFree = shop.visible
end)Chữ trong world
Với chữ gắn vào một part - tên, giá, thanh máu trên đầu quái - dùng Billboard trên part thay vì UI màn hình.