Basic multi node type
This commit is contained in:
@@ -1,34 +0,0 @@
|
||||
-- scripts/box.lua
|
||||
-- Autonomous bouncing box.
|
||||
-- Edit vx, vy, or the color below, save the file, and watch it update live!
|
||||
|
||||
local vx, vy = 2050, 110 -- ← try cranking these up
|
||||
local size = 60
|
||||
local r, g, b = 255, 180, 50 -- ← golden amber box
|
||||
|
||||
function on_init()
|
||||
log("Box ready – bouncing at vx=" .. vx .. " vy=" .. vy)
|
||||
end
|
||||
|
||||
function on_update(dt)
|
||||
self_x = self_x + vx * dt
|
||||
self_y = self_y + vy * dt
|
||||
|
||||
-- Bounce off the four walls (respecting the editor panel)
|
||||
if self_x < 0 or self_x + size > 1055 then
|
||||
vx = -vx
|
||||
self_x = math.max(0, math.min(1055 - size, self_x))
|
||||
end
|
||||
if self_y < 0 or self_y + size > 720 then
|
||||
vy = -vy
|
||||
self_y = math.max(0, math.min(720 - size, self_y))
|
||||
end
|
||||
end
|
||||
|
||||
function on_render()
|
||||
draw_rect(self_x, self_y, size, size, r, g, b)
|
||||
|
||||
-- Velocity debug overlay
|
||||
local speed_label = "v=" .. math.floor(math.sqrt(vx * vx + vy * vy))
|
||||
draw_text(speed_label, self_x + 4, self_y + size / 2 - 6, 12, 0, 0, 0)
|
||||
end
|
||||
@@ -0,0 +1,46 @@
|
||||
-- scripts/enemy_rect.lua
|
||||
-- RectNode: bounces around, changes color on bounce.
|
||||
-- Try editing vx/vy or the color while the engine is running!
|
||||
|
||||
local vx, vy = 180, 130
|
||||
|
||||
---@param self RectNode
|
||||
function on_init(self)
|
||||
self.x = 600
|
||||
self.y = 300
|
||||
-- self.color already set by engine (passed in addRectNode),
|
||||
-- but we can override it here.
|
||||
self.color = { r = 220, g = 60, b = 60, a = 255 }
|
||||
end
|
||||
|
||||
---@param self RectNode
|
||||
---@param dt number
|
||||
function on_update(self, dt)
|
||||
self.x = self.x + vx * dt
|
||||
self.y = self.y + vy * dt
|
||||
|
||||
if self.x < 0 or self.x + self.width > 1030 then
|
||||
vx = -vx
|
||||
self.x = math.max(0, math.min(1030 - self.width, self.x))
|
||||
-- Flash yellow on bounce
|
||||
self.color = { r = 240, g = 220, b = 50, a = 255 }
|
||||
end
|
||||
if self.y < 0 or self.y + self.height > 720 then
|
||||
vy = -vy
|
||||
self.y = math.max(0, math.min(720 - self.height, self.y))
|
||||
self.color = { r = 240, g = 220, b = 50, a = 255 }
|
||||
end
|
||||
|
||||
-- Fade back to red
|
||||
self.color.r = math.min(220, self.color.r + 180 * dt)
|
||||
self.color.g = math.max(60, self.color.g - 300 * dt)
|
||||
self.color.b = math.max(60, self.color.b - 200 * dt)
|
||||
end
|
||||
|
||||
---@param self RectNode
|
||||
function on_render(self)
|
||||
-- Label over auto-drawn rect
|
||||
draw_text("Enemy", self.x + 4, self.y + 18, 13, 255, 210, 210)
|
||||
local spd = math.floor(math.sqrt(vx * vx + vy * vy))
|
||||
draw_text("v=" .. spd, self.x + 4, self.y + 34, 10, 200, 200, 200)
|
||||
end
|
||||
@@ -0,0 +1,114 @@
|
||||
---@meta engine
|
||||
---
|
||||
--- LSP type stubs for the Zig engine API.
|
||||
--- This file is NEVER executed — it only exists so lua-language-server
|
||||
--- can provide autocomplete, type checking, and inline docs.
|
||||
---
|
||||
--- Usage in your scripts:
|
||||
--- ---@param self RectNode (or NodeBase for base nodes)
|
||||
|
||||
-- ─── Color type ──────────────────────────────────────────────────────────────
|
||||
|
||||
---@class Color
|
||||
---@field r number Red 0-255
|
||||
---@field g number Green 0-255
|
||||
---@field b number Blue 0-255
|
||||
---@field a number Alpha 0-255
|
||||
|
||||
-- ─── Node self types ─────────────────────────────────────────────────────────
|
||||
|
||||
---@class NodeBase
|
||||
---@field x number World X position (read/write)
|
||||
---@field y number World Y position (read/write)
|
||||
|
||||
--- Extends NodeBase with rectangle geometry.
|
||||
--- The engine draws the rect each frame; modify fields to change it.
|
||||
---@class RectNode : NodeBase
|
||||
---@field width number Rectangle width
|
||||
---@field height number Rectangle height
|
||||
---@field color Color Fill color (r/g/b/a subtable)
|
||||
|
||||
-- ─── Drawing ─────────────────────────────────────────────────────────────────
|
||||
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param w number
|
||||
---@param h number
|
||||
---@param r number Red 0-255
|
||||
---@param g number Green 0-255
|
||||
---@param b number Blue 0-255
|
||||
---@param a? number Alpha 0-255 (default 255)
|
||||
function draw_rect(x, y, w, h, r, g, b, a) end
|
||||
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param radius number
|
||||
---@param r number
|
||||
---@param g number
|
||||
---@param b number
|
||||
---@param a? number
|
||||
function draw_circle(x, y, radius, r, g, b, a) end
|
||||
|
||||
---@param text string
|
||||
---@param x number
|
||||
---@param y number
|
||||
---@param size number Font size in pixels
|
||||
---@param r number
|
||||
---@param g number
|
||||
---@param b number
|
||||
---@param a? number
|
||||
function draw_text(text, x, y, size, r, g, b, a) end
|
||||
|
||||
---@param x1 number
|
||||
---@param y1 number
|
||||
---@param x2 number
|
||||
---@param y2 number
|
||||
---@param r number
|
||||
---@param g number
|
||||
---@param b number
|
||||
---@param a? number
|
||||
function draw_line(x1, y1, x2, y2, r, g, b, a) end
|
||||
|
||||
-- ─── Input ───────────────────────────────────────────────────────────────────
|
||||
|
||||
--- Returns true while key is held.
|
||||
---@param key integer Use Key.X constants
|
||||
---@return boolean
|
||||
function key_down(key) end
|
||||
|
||||
--- Returns true only on the first frame the key is pressed.
|
||||
---@param key integer
|
||||
---@return boolean
|
||||
function key_pressed(key) end
|
||||
|
||||
--- Returns true while mouse button is held. 0=left 1=right 2=middle
|
||||
---@param button integer
|
||||
---@return boolean
|
||||
function mouse_down(button) end
|
||||
|
||||
---@return number
|
||||
function mouse_x() end
|
||||
|
||||
---@return number
|
||||
function mouse_y() end
|
||||
|
||||
-- ─── Key constants ───────────────────────────────────────────────────────────
|
||||
|
||||
---@class KeyTable
|
||||
---@field LEFT integer
|
||||
---@field RIGHT integer
|
||||
---@field UP integer
|
||||
---@field DOWN integer
|
||||
---@field SPACE integer
|
||||
---@field W integer
|
||||
---@field A integer
|
||||
---@field S integer
|
||||
---@field D integer
|
||||
|
||||
---@type KeyTable
|
||||
Key = {}
|
||||
|
||||
-- ─── Utility ─────────────────────────────────────────────────────────────────
|
||||
|
||||
---@param message string
|
||||
function log(message) end
|
||||
@@ -0,0 +1,39 @@
|
||||
-- scripts/healthbar.lua
|
||||
-- RectNode: the engine draws the green bar automatically.
|
||||
-- This script drives the HP logic and recolors/resizes the bar.
|
||||
|
||||
local max_hp = 100
|
||||
local hp = 100
|
||||
|
||||
---@param self RectNode
|
||||
function on_init(self)
|
||||
self.x = 20
|
||||
self.y = 20
|
||||
self.width = 200
|
||||
self.height = 20
|
||||
self.color = { r = 60, g = 200, b = 80, a = 255 }
|
||||
log("HealthBar ready")
|
||||
end
|
||||
|
||||
---@param self RectNode
|
||||
---@param dt number
|
||||
function on_update(self, dt)
|
||||
-- Slow drain (replace with real damage events)
|
||||
hp = math.max(0, hp - 4 * dt)
|
||||
|
||||
-- Shrink bar proportionally
|
||||
self.width = (hp / max_hp) * 200
|
||||
|
||||
-- Green → red as HP drops
|
||||
local t = hp / max_hp
|
||||
self.color.r = math.floor((1 - t) * 220)
|
||||
self.color.g = math.floor(t * 200)
|
||||
self.color.b = 40
|
||||
end
|
||||
|
||||
---@param self RectNode
|
||||
function on_render(self)
|
||||
-- Label drawn on top of the auto-rendered bar
|
||||
local label = "HP: " .. (math.floor(hp)) .. (" / ") .. max_hp
|
||||
draw_text(label, self.x + 4, self.y + 4, 12, 240, 240, 240)
|
||||
end
|
||||
+24
-33
@@ -1,42 +1,33 @@
|
||||
-- scripts/player.lua
|
||||
-- Globals provided each frame by the engine:
|
||||
-- self_x, self_y ← read AND write to move the node
|
||||
-- API: draw_rect draw_circle draw_text draw_line
|
||||
-- key_down key_pressed mouse_down mouse_x mouse_y
|
||||
-- log(msg)
|
||||
-- Base node: the script handles all drawing.
|
||||
|
||||
local speed = 200
|
||||
local width = 40
|
||||
local height = 50
|
||||
local cr, cg, cb = 80, 160, 255 -- ← try changing this color and saving!
|
||||
local speed = 200
|
||||
local w, h = 40, 50
|
||||
|
||||
function on_init()
|
||||
log("Player init at " .. self_x .. ", " .. self_y)
|
||||
-- self_x/self_y already hold the last known position,
|
||||
-- so hot-reload doesn't teleport the player back to origin.
|
||||
---@param self NodeBase
|
||||
function on_init(self)
|
||||
log("Player spawned at " .. (self.x) .. ", " .. (self.y))
|
||||
end
|
||||
|
||||
function on_update(dt)
|
||||
if key_down(Key.RIGHT) or key_down(Key.D) then self_x = self_x + speed * dt end
|
||||
if key_down(Key.LEFT) or key_down(Key.A) then self_x = self_x - speed * dt end
|
||||
if key_down(Key.DOWN) or key_down(Key.S) then self_y = self_y + speed * dt end
|
||||
if key_down(Key.UP) or key_down(Key.W) then self_y = self_y - speed * dt end
|
||||
---@param self NodeBase
|
||||
---@param dt number
|
||||
function on_update(self, dt)
|
||||
if key_down(Key.RIGHT) or key_down(Key.D) then self.x = self.x + speed * dt end
|
||||
if key_down(Key.LEFT) or key_down(Key.A) then self.x = self.x - speed * dt end
|
||||
if key_down(Key.DOWN) or key_down(Key.S) then self.y = self.y + speed * dt end
|
||||
if key_down(Key.UP) or key_down(Key.W) then self.y = self.y - speed * dt end
|
||||
|
||||
-- Clamp to game area (leave the editor panel free)
|
||||
self_x = math.max(0, math.min(1055, self_x))
|
||||
self_y = math.max(0, math.min(665, self_y))
|
||||
self.x = math.max(0, math.min(1030, self.x))
|
||||
self.y = math.max(0, math.min(665, self.y))
|
||||
end
|
||||
|
||||
function on_render()
|
||||
-- Body
|
||||
draw_rect(self_x, self_y, width, height, cr, cg, cb)
|
||||
|
||||
-- Eyes (white + pupil)
|
||||
draw_circle(self_x + 11, self_y + 14, 6, 255, 255, 255)
|
||||
draw_circle(self_x + 29, self_y + 14, 6, 255, 255, 255)
|
||||
draw_circle(self_x + 13, self_y + 14, 3, 0, 0, 0)
|
||||
draw_circle(self_x + 31, self_y + 14, 3, 0, 0, 0)
|
||||
|
||||
-- Label
|
||||
draw_text("Player", self_x, self_y - 16, 11, 180, 220, 255)
|
||||
---@param self NodeBase
|
||||
function on_render(self)
|
||||
draw_rect(self.x, self.y, w, h, 80, 160, 255)
|
||||
-- eyes
|
||||
draw_circle(self.x + 11, self.y + 14, 6, 255, 255, 255)
|
||||
draw_circle(self.x + 29, self.y + 14, 6, 255, 255, 255)
|
||||
draw_circle(self.x + 13, self.y + 14, 3, 0, 0, 0)
|
||||
draw_circle(self.x + 31, self.y + 14, 3, 0, 0, 0)
|
||||
draw_text("Player", self.x, self.y - 16, 11, 180, 220, 255)
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user