Two facts about the canvas, and then some shapes.
The origin is the top-left, and y grows downward. A larger y is lower on the screen. This trips everyone once and then never again.
Colors run from 0 to 1, not 0 to 255. This is the single most common thing to get wrong, because most of the internet's LÖVE code predates the change and uses 0–255.
love.graphics.setColor(1, 0.7, 0.1)Red, green, blue, and optionally alpha, each from 0 to 1. If you find a snippet online that says setColor(255, 180, 25), divide everything by 255. Passing 255 does not error — it clamps to 1, so every color comes out pure white and nothing tells you why.
love.graphics.rectangle("fill", 100, 100, 200, 120)love.graphics.rectangle("line", 100, 100, 200, 120)love.graphics.circle("fill", 200, 160, 30)love.graphics.line(0, 0, 800, 600)rectangle(mode, x, y, width, height) — x and y are the top-left corner, not the middle.circle(mode, x, y, radius) — here x and y are the middle. The inconsistency is real and worth remembering.line(x1, y1, x2, y2, ...) — as many points as you like, joined in order.The first argument is always "fill" or "line" — solid or outline. Draw the fill first and the outline second, or the fill covers the outline.
This is the part that behaves unlike anything in Unit 1. setColor does not draw anything and does not belong to any shape. It changes a setting that stays changed until something changes it back.
love.graphics.setColor(1, 0, 0)love.graphics.rectangle("fill", 10, 10, 50, 50)love.graphics.rectangle("fill", 70, 10, 50, 50)Both squares are red. One setColor, two shapes. The same is true of setLineWidth and setFont.
The bug this causes is always the same shape: something you drew is mysteriously the wrong color, because code above it set a color and never set it back. When that happens, read upward, not at the shape itself.
The habit that prevents it is to set the color immediately before every group of shapes, even when you think you already know what it is. It costs one line and saves a hunt.
setBackgroundColor belongs in love.load, not in draw — it is a setting, not a drawing call. LÖVE wipes the window to that color before every single love.draw.
Which means each frame is drawn from scratch. Nothing you drew last frame is still there. That sounds wasteful and is the reason animation works at all: to move something, you do not move it — you draw it somewhere else next frame. Activity 2.3 is entirely built on that.
love.graphics.getWidth() and getHeight() report the window size. Use them instead of typing 800 and 600, so that changing conf.lua does not silently break your layout.
Keep working in the same skynest folder. You are drawing an instrument panel.
love.load.-- main.lua
function love.load() love.graphics.setBackgroundColor(0.05, 0.05, 0.1)end
function love.draw() love.graphics.setColor(0.2, 0.6, 0.9) love.graphics.rectangle("fill", 100, 100, 200, 120)endsetColor lines and see which shape changes. That is the state machine.-- main.lua
function love.load() love.graphics.setBackgroundColor(0.05, 0.05, 0.1)end
function love.draw() love.graphics.setColor(0.2, 0.6, 0.9) love.graphics.rectangle("fill", 100, 100, 200, 120)
love.graphics.setColor(1, 1, 1) love.graphics.setLineWidth(3) love.graphics.rectangle("line", 100, 100, 200, 120)
love.graphics.setColor(1, 0.7, 0.1) love.graphics.circle("fill", 200, 160, 30)endlove.graphics.getWidth() / 2 rather than a hard-coded 400.-- main.lua
function love.load() love.graphics.setBackgroundColor(0.05, 0.05, 0.1)end
function love.draw() love.graphics.setColor(0.2, 0.6, 0.9) love.graphics.rectangle("fill", 100, 100, 200, 120)
love.graphics.setColor(1, 1, 1) love.graphics.setLineWidth(3) love.graphics.rectangle("line", 100, 100, 200, 120)
love.graphics.setColor(1, 0.7, 0.1) love.graphics.circle("fill", 200, 160, 30)
love.graphics.setColor(1, 1, 1) love.graphics.print("REACTOR NOMINAL", love.graphics.getWidth() / 2 - 55, 260)endlove.graphics.getFont():getWidth(text), and it will be exact for any string.local panel = { x = 100, y = 100, w = 200, h = 120 } — and use its fields everywhere. Activity 1.10, and it is how every object in the rest of this unit is stored.drawPanel(x, y, w, h) function and call it three times at different positions. Your love.draw becomes three lines.
Four shapes and a label, drawn in the order the code lists them. The outline sits on top of the fill because it is drawn second.
On a near-black background you should have:
If everything is white, you used 0–255 values. If the outline is missing, it was drawn before the fill and got covered. If the circle is off-center, check that you added half the width and height to the rectangle's corner.