Table of Contents
2D Nodes
The system pyssel/scene-2d gives the scene tree its 2D
nodes, which draw with pyssel/2d in the tree's order: the
walk game of the Scene Tree page is made of them.
-
2D nodes:
runstarts an engine whose tree's root is aviewport. Acanvas-itemdraws itself indrawwith pyssel/2d's functions, and keeps the drawing untilqueue-redraw; anode-2dadds a position, rotation and scale, which apply to its children. Its position and scale are cl-gmathdvec2values, vectors of double-floats, as Godot's are in its double-precision builds, so that a node a million units out still moves by a hundredth:node-positionreturns a copy, or fills a vector given, and(setf node-position)copies one in, advec2and not avec2.node-x,node-y,node-scale-x,node-scale-yandnode-rotationread one number as a double-float and set it from any real, as(incf (s2d:node-x player) step)does. They are inline, so that the doubles stay unboxed and moving a node allocates nothing. A real is taken as the double-float it is: Lisp reads0.1as a single-float, 0.10000000149011612 as a double, so write0.1d0for a tenth. Canvas items are drawn in the tree's order, children over their parents. Hiding a node draws it again; moving, turning or stretching one draws nothing again, as its canvas is placed anew by its global transform as it is drawn, but what it drew on the pixels, as raster text, when it moves off them, and what it drew for the scale, as a polygon's anti-aliased edges, when it turns or stretches. That placement is worked out in double-floats, so a node a million units out, under a view panned there, is drawn as precisely as one near the origin. A canvas item draws in either mode, whatever its class, sodrawdraws what the node's properties say: while a game's scene is edited, as in the editor, its nodes do not behave andreadyhas not run, so adrawmethod that draws whatreadymakes asksnode-behaves-pfirst and draws less while it is false. A drawing that fails keeps what the item drew before,canvas-item-draw-errorsays why, and the editor's Scene dock marks the node. A viewport's size,viewport-size, is its content's, which its controls are laid out in: its window's, unless its content scale stretches it (below). Its title is its window's,viewport-title. A game sets both through its tree's root rather than its engine, so it does the same wherever it plays:(setf viewport-title), andset-viewport-size, which asks for the window's size, asset-engine-sizedoes (see Engines). So it goes fullscreen, with(setf viewport-fullscreen), and holds the pointer, with(setf viewport-pointer-mode)::confinedkeeps it in the window,:capturedhides it and keeps it still, its motion coming as amotion-event'sevent-relative-xandevent-relative-y, the mouse's own, as a camera that follows the mouse wants. The window holds the pointer while it has the focus, so the mode lasts until set again. Acanvas-item-clipmethod clips a canvas item's descendants to a rectangle in its coordinates, as a scroll container shows part of its content; the clips of nested items intersect.global-transformreturns the cl-gmathdmat3x2, of double-floats, that takes a node's coordinates to its canvas's, as Godot'sget_global_transform: the canvas of the canvas layer it is under, or else its viewport's own;canvas-transformtakes the canvas on to the viewport's coordinates, andglobal-transform-with-canvasdoes both.local-transformis a node's own. -
Picking, as Godot's editor picks:
(s2d:canvas-items-at viewport x y)lists the canvas items under a point of a viewport's coordinates, topmost first, children over their parents and the items of higher canvas layers over those of lower ones, each through its canvas's transform, and(s2d:canvas-items-in-rect viewport x y width height)those whose rectangles lie wholly inside a rectangle, as a drag selects them. Both meet only what the viewport draws: its shown items, not those of the viewports inside it, as popups', nor internal children; and only within their ancestors' clips, as they are drawn: an item is under a point only where a clip shows it, and in a rectangle only what a clip shows of it counts, so one a clip hides wholly, as one scrolled out of sight, is not taken, where Godot's box selection takes it. An item's rectangle,canvas-item-rect, in its own coordinates, is the box around what it drew, which turns with it, unless its class'scanvas-item-edit-rectmethod gives one, as Godot's_edit_get_rectdoes: a control gives its own, so that it is picked where it draws nothing. Throughglobal-transform-with-canvas, a turned item's rectangle is the parallelogram it is, and so it is tested. An item without one, as an empty 2D node, is picked as Godot's editor picks it when asked: under a point withincanvas-items-at's:grab-distanceof its origin, and in a rectangle by its origin withcanvas-items-in-rect's:origins t. -
Zooming and panning: a viewport's canvas transform, as Godot's
Viewport.canvas_transform, a camera's, is a zoom,viewport-canvas-scale, a double-float, and a pan,viewport-canvas-offset, advec2copied in and out asnode-positionis: a point of the viewport's own canvas, of its canvas items outside canvas layers, is drawn at the point times the scale plus the offset, in the viewport's coordinates. It applies to the viewport's own canvas and to the canvas layers that follow it, not to the other layers nor to the windows embedded in it. Its global canvas transform, as Godot'sViewport.global_canvas_transform,viewport-global-canvas-scaleandviewport-global-canvas-offset, zooms and pans everything it draws, canvas layers too, from its coordinates to the units of what it draws into, as the editor's view of a scene does. A new zoom of either draws the items again for the new size, as a new display scale does, so raster text stays sharp; a pan draws nothing again, however far it goes, so a camera may follow a player through a level hundreds of thousands of units long. Controls are laid out in the viewport's size, whatever its transforms, and get the pointer through them, as Godot's get it through their canvas's transform: a control takes the pointer where it is drawn, in its own coordinates, and a popup, a tooltip or the input method's caret goes where the control is drawn, as large as it is drawn.target-to-viewporttakes a point of what the viewport draws into, such as the pointer's, back through the global canvas transform to the viewport's coordinates, andviewport-to-targetthe other way;target-to-canvastakes it on to a node's canvas, as a game finds the point of its world under the pointer, andcanvas-to-targetback. The points of the viewport and of canvases are double-floats, as a world far out needs; those of what the viewport draws into, single-floats.canvas-zoomis the zoom a node's canvas is drawn at. -
Content scale, as Godot's window has it: a viewport with a window of its own, the engine's or a popup's, stretches its content over the window from a base size,
viewport-content-scale-widthbyviewport-content-scale-height, asviewport-content-scale-modesays::disabled, by default, leaves it as it is;:canvas-itemsdraws it stretched at the window's resolution, so text stays sharp;:viewportdraws it at the base size and stretches the picture without smoothing, as pixel art wants.viewport-content-scale-aspectkeeps its shape,:ignoreby default,:keep, with black bars where the window's shape differs,:keep-widthand:keep-height, which let it grow the other way, or:expand, which lets it grow either way;:integerviewport-content-scale-stretchstretches it by whole times only;viewport-content-scale-factormakes it larger besides, and alone scales it while the mode is:disabled.viewport-sizeis then the content's size, which its controls are laid out in, and the pointer reaches its nodes and controls in its coordinates. The windows embedded in it, its popups and dialogs, are placed in its coordinates and stretched with it; a popup in a window of its own is drawn at its own scale, as Godot's is. A game's project gives its root these (see Projects).target-to-viewporttakes a point of the window back through the stretch, its margins and the global canvas transform. -
Canvas layers: a
canvas-layer, as Godot's CanvasLayer, draws the canvas items under it on a canvas of its own, over the viewport's own canvas items if itscanvas-layer-layeris above 0, by default 1, or under them below 0, and through a transform of its own rather than the viewport's canvas transform, so that an interface over a game stays put as a camera moves:(let ((hud (make-instance 's2d:canvas-layer :name "hud"))) (sc:add-child root hud) (sc:add-child hud (make-instance 'ui:label :text "Score: 0")))Its transform is
canvas-layer-offset,canvas-layer-rotationandcanvas-layer-scale, as a 2D node's, in double-floats too, applied as it is drawn, so that moving or turning it draws nothing again, and a new scale only records its items again for the new size. Withcanvas-layer-follow-viewport-enabledit moves with the viewport's canvas transform too,canvas-layer-follow-viewport-scaletimes as much about the middle of the viewport, as a background further away does; a tree being edited leaves that scale out, as Godot's editor does.canvas-layer-final-transformtakes its canvas to the viewport's coordinates.canvas-layer-visiblehides its items, and the layer emitsvisibility-changed. Its items' global transforms start at it, so the 2D nodes above it move them not and the canvas items above it hide them not. Their controls take the pointer through its transform, those of the topmost canvas first; layers of one layer are drawn in the tree's order, those at 0 over the viewport's own items.map-canvasesgoes through a viewport's canvases in the order they are drawn. Godot draws a following layer's scale about the viewport's middle but gives its controls the pointer without it; Pyssel gives them the pointer as the layer is drawn.
Getting started
The core
Drawing
Scenes
User interface
Games and the editor
- Playing a Game
- Projects
- The Editor
- The File System Dock
- The Script Screen
- The REPL
- The Debugger
- Lisp Text
- Code Services
- Project Manager
- Undo and Redo
- Exporting
The project