-- Learn to Program with Singe -- Lesson 17: Light Guns dofile("Singe/Framework.singe") overlaySetResolution(discGetWidth(), discGetHeight()) local FIRST_FRAME = 20 local LAST_FRAME = 400 local TARGET_SIZE = 96 local HIT_SCORE = 100 local FLASH_TIME = 12 local targets = { { first = 40, last = 110, x = 80, y = 110 }, { first = 120, last = 190, x = 470, y = 140 }, { first = 200, last = 270, x = 290, y = 250 }, { first = 280, last = 360, x = 150, y = 300 }, } local aimX = overlayGetWidth() / 2 local aimY = overlayGetHeight() / 2 local score = 0 local shots = 0 local hits = 0 local flash = 0 local flashX = 0 local flashY = 0 local drawAim = singeWantsCrosshairs() local function drawCrosshair(x, y) colorForeground(255, 255, 255, 255) overlayCircle(x, y, 10) overlayLine(x - 18, y, x - 4, y) overlayLine(x + 4, y, x + 18, y) overlayLine(x, y - 18, x, y - 4) overlayLine(x, y + 4, x, y + 18) end local function targetIsUp(target, frame) return not target.hit and frame >= target.first and frame <= target.last end local function startRound() score = 0 shots = 0 hits = 0 flash = 0 for _, target in ipairs(targets) do target.hit = false end discSkipToFrame(FIRST_FRAME) end function onInputPressed(what, device) if what == SWITCH_START1 then startRound() return end if what ~= SWITCH_BUTTON3 then return end local x, y = mouseGetPosition(device or 0) local frame = discGetFrame() shots = shots + 1 for _, target in ipairs(targets) do if targetIsUp(target, frame) and collidePointRect(x, y, target.x, target.y, TARGET_SIZE, TARGET_SIZE) then target.hit = true hits = hits + 1 score = score + HIT_SCORE flash = FLASH_TIME flashX = x flashY = y return end end end function onOverlayUpdate() local frame = discGetFrame() if frame >= LAST_FRAME then startRound() frame = FIRST_FRAME end aimX, aimY = mouseGetPosition(0) overlayClear() for _, target in ipairs(targets) do if targetIsUp(target, frame) then colorForeground(255, 200, 0, 255) overlayBox(target.x, target.y, target.x + TARGET_SIZE - 1, target.y + TARGET_SIZE - 1) overlayCircle(target.x + TARGET_SIZE / 2, target.y + TARGET_SIZE / 2, TARGET_SIZE / 3) end end if flash > 0 then colorForeground(255, 255, 255, 255) overlayCircle(flashX, flashY, 30 - flash * 2) flash = flash - 1 end overlayPrint(2, 1, "SCORE " .. score .. " HITS " .. hits .. "/" .. shots .. " FRAME " .. frame) if drawAim then drawCrosshair(aimX, aimY) end return OVERLAY_UPDATED end startRound()