lingdev
↓ 0 下载LingDev: a Godot / Unity-style game editor written in Ling. 2-D and 3-D scenes, Flash-style timeline and cutscenes, HUDs over 3-D, Ling scripting, audio / music / MIDI, builds for Windows, Linux, macOS, web, Raspberry Pi and LingOS. Ships with Ling Agent (an N64-style spy FPS), Ling Breaker (a 3-D breakout) and Moko's Picture Book (a kawaii storybook platformer).
关键词 game-engine, editor, 3d, 2d, cutscene, timeline, ling, lingos, raspberry-pi
lingfu install lingdev代码 / 文件 (136)
ling/view2d.ling
# view2d.ling - the canvas for 2-D scenes (menus, HUDs): the design frame, nodes drawn as in
# the game, selection with resize handles, drag to move, wheel to zoom, middle-drag to pan.
fn view2d(x, y, w, h) {
bind t = st_get("tl_t", 0.0)
g_rect(x, y, w, h, C_VIEW_BG)
u_clip(x, y, w, h)
bind cw = sc_get("cw", 1280.0)
bind ch = sc_get("ch", 720.0)
bind zoom = st_get("c2_zoom", 1.0)
bind s = min((w - 48.0) / cw, (h - 48.0) / ch) * zoom
bind ox = x + (w - cw * s) * 0.5 + st_get("c2_ox", 0.0)
bind oy = y + (h - ch * s) * 0.5 + st_get("c2_oy", 0.0)
bind hot = u_hot(x, y, w, h) && st_get("bar_busy", 0.0) < 0.5
# canvas
g_rect_a(ox + 4.0, oy + 6.0, cw * s, ch * s, 0.0, 0.4)
g_rect(ox, oy, cw * s, ch * s, sc_get("bg", 1776411.0))
bind bg3 = sc_ex("bg3d", "")
if bg3 != "" { g_text(ox + 8.0, oy + ch * s - 18.0, 10.0, C_TEXT_DIM, "3D background: " + bg3) }
if st_get("view_grid", 1.0) > 0.5 {
bind g = 40.0
bind k = g
while k < cw {
px_line(ox + k * s, oy, ox + k * s, oy + ch * s, C_GRID_MIN, 0.5)
bind k = k + g
}
bind k = g
while k < ch {
px_line(ox, oy + k * s, ox + cw * s, oy + k * s, C_GRID_MIN, 0.5)
bind k = k + g
}
}
g_frame(ox - 1.0, oy - 1.0, cw * s + 2.0, ch * s + 2.0, C_LINE)
hud_draw(t, ox, oy, s, false)
# selection
bind sidx = sel_index()
bind hover_h = ""
if sidx >= 0.0 && nd_is_2d(nd_get(sidx, "kind")) {
bind r = hud_rect(sidx, t)
bind rx = ox + list_get(r, 0) * s
bind ry = oy + list_get(r, 1) * s
bind rw = list_get(r, 2) * s
bind rh = list_get(r, 3) * s
g_frame(rx - 1.0, ry - 1.0, rw + 2.0, rh + 2.0, C_GIZMO)
bind hs = ["tl", "tc", "tr", "cl", "cr", "bl", "bc", "br"]
bind k = 0.0
while k < 8.0 {
bind hn = list_get(hs, k)
bind hx = rx + anchor_fx(hn) * rw
bind hy = ry + anchor_fy(hn) * rh
bind hh = hot && abs(u_mx() - hx) < 6.0 && abs(u_my() - hy) < 6.0
if hh { bind hover_h = hn }
g_rect(hx - 4.0, hy - 4.0, 8.0, 8.0, sel(hh, C_WHITE, C_GIZMO))
bind k = k + 1.0
}
g_text(rx, ry - 14.0, 10.0, C_GIZMO, nd_get(sidx, "name") + " " + num_str(floor(list_get(r, 2))) + "x" + num_str(floor(list_get(r, 3))))
}
# input
if hot {
if u_scroll() != 0.0 && st_get("wheel_used", 0.0) < 0.5 {
st_set("c2_zoom", clampf(zoom * pow(1.12, u_scroll()), 0.2, 6.0))
st_set("wheel_used", 1.0)
}
if u_mpressed() { u_set_active("c2_pan") }
if u_pressed() && u_active() == "" {
if hover_h != "" && sidx >= 0.0 {
u_set_active("c2_resize")
st_set("c2_handle", hover_h)
st_set("c2_id", nd_id(sidx))
undo_push()
st_set("c2_v0", [nd_get(sidx, "px"), nd_get(sidx, "py"), nd_get(sidx, "w"), nd_get(sidx, "h"), u_mx(), u_my()])
} else {
bind pi = view2d_pick(ox, oy, s, t)
if pi >= 0.0 {
bind id = nd_id(pi)
if u_ctrl() { sel_toggle(id) } else if !sel_has(id) { sel_set(id) }
if u_double() {
bind k = nd_get(pi, "kind")
if k == "label" || k == "button" { st_set("insp_field", "txt") modal_text("Text", "node_field", nd_get(pi, "txt")) }
} else if !u_ctrl() {
u_set_active("c2_move")
st_set("c2_id", id)
undo_push()
st_set("c2_v0", [nd_get(pi, "px"), nd_get(pi, "py"), nd_get(pi, "w"), nd_get(pi, "h"), u_mx(), u_my()])
}
} else if !u_ctrl() { sel_clear() }
}
}
if u_rpressed() {
st_set("drop_cx", (u_mx() - ox) / s)
st_set("drop_cy", (u_my() - oy) / s)
ctx_open("canvas", "", u_mx(), u_my())
}
}
if u_active() == "c2_pan" {
if u_mdown() { st_set("c2_ox", st_get("c2_ox", 0.0) + u_dx()) st_set("c2_oy", st_get("c2_oy", 0.0) + u_dy()) } else { u_set_active("") }
}
if u_active() == "c2_move" || u_active() == "c2_resize" {
bind i = nd_find(st_get("c2_id", 0.0))
bind v0 = st_get("c2_v0", [])
if !u_down() || i < 0.0 || len(v0) < 6.0 { u_set_active("") }
else {
bind dx = (u_mx() - list_get(v0, 4)) / s
bind dy = (u_my() - list_get(v0, 5)) / s
bind sn = st_get("snap_on", 1.0) > 0.5 && !u_ctrl()
if u_active() == "c2_move" {
bind nx = list_get(v0, 0) + dx
bind ny = list_get(v0, 1) + dy
if sn { bind nx = round(nx / 8.0) * 8.0 bind ny = round(ny / 8.0) * 8.0 }
set_prop(i, "px", nx)
set_prop(i, "py", ny)
} else {
bind hn = st_get("c2_handle", "br")
bind fx = anchor_fx(hn)
bind fy = anchor_fy(hn)
bind nw = list_get(v0, 2)
bind nh = list_get(v0, 3)
bind nx = list_get(v0, 0)
bind ny = list_get(v0, 1)
if fx > 0.75 { bind nw = max(4.0, list_get(v0, 2) + dx) }
if fx < 0.25 { bind nw = max(4.0, list_get(v0, 2) - dx) bind nx = list_get(v0, 0) + (list_get(v0, 2) - nw) }
if fy > 0.75 { bind nh = max(4.0, list_get(v0, 3) + dy) }
if fy < 0.25 { bind nh = max(4.0, list_get(v0, 3) - dy) bind ny = list_get(v0, 1) + (list_get(v0, 3) - nh) }
if sn { bind nw = round(nw / 8.0) * 8.0 bind nh = round(nh / 8.0) * 8.0 }
set_prop(i, "w", nw)
set_prop(i, "h", nh)
set_prop(i, "px", nx)
set_prop(i, "py", ny)
}
}
}
# drops
if st_get("drop_path", "") != "" && u_in(x, y, w, h) {
st_set("drop_cx", (u_mx() - ox) / s)
st_set("drop_cy", (u_my() - oy) / s)
asset_add_to_scene(st_get("drop_path", ""), true)
st_set("drop_path", "")
}
g_text(x + 12.0, y + 10.0, 11.0, C_TEXT_DIM, sc_get("name", "") + " 2D CANVAS " + num_str(cw) + "x" + num_str(ch) + " zoom " + fmt1(zoom) + " " + st_get("tool", "move"))
if nd_count() < 0.5 { g_text_c(x + w * 0.5, y + h * 0.5 - 8.0, 14.0, C_TEXT_DIM, "Empty menu - Scene > Add 2D Control, or drag an image here") }
u_unclip()
}
fn view2d_pick(ox, oy, s, t) {
bind n = nd_count()
bind i = n - 1.0
while i >= 0.0 {
if nd_is_2d(nd_get(i, "kind")) && nd_get(i, "vis") > 0.5 && nd_get(i, "lock") < 0.5 {
bind r = hud_rect(i, t)
bind rx = ox + list_get(r, 0) * s
bind ry = oy + list_get(r, 1) * s
if u_in(rx, ry, list_get(r, 2) * s, list_get(r, 3) * s) { return i }
}
bind i = i - 1.0
}
return 0.0 - 1.0
}