123 lines
2.8 KiB
Text
123 lines
2.8 KiB
Text
-- 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()
|