Samples Gallery & Reference > Games
Lights On by FellippeHeitor
(1/1)
bplus:
Lights On
Author: @FellippeHeitor
Source: github/FellippeHeitor
URL: https://github.com/FellippeHeitor/LightsOn/releases
Version: 1.0 Sept, 2018
Tags: [Puzzle]
Description:
This is a logic puzzle, the goal is to get all the lights on. Starts out easy enough... :-))
Source Code:
--- Code: QB64: ---'Lights On'A game by Fellippe Heitor - [member=2]FellippeHeitor[/member] - fellippe@qb64.org''Original concept by Avi Olti, Gyora Benedek, Zvi Herman, Revital Bloomberg, Avi Weiner and Michael Ganor'https://en.wikipedia.org/wiki/Lights_Out_(game)''Assets sources acknowledged inside SUB GameSetup OPTION _EXPLICIT $EXEICON:'./assets/lightson.ico'_ICON CONST true = -1, false = NOT true TYPE obj i AS INTEGER j AS INTEGER x AS INTEGER y AS INTEGER w AS INTEGER h AS INTEGER IsOn AS _BYTE lastSwitch AS SINGLE lastHint AS SINGLEEND TYPE RANDOMIZE TIMER DIM SHARED Arena AS LONG, OverlayScreen AS LONG, Bg AS LONGDIM SHARED LightOn(1 TO 9) AS LONG, LightOff(1 TO 9) AS LONGDIM SHARED RestartIcon AS LONG, MouseCursor AS LONGDIM SHARED Ding AS LONG, Piano AS LONG, Switch AS LONG, Bonus AS LONGDIM SHARED Arial AS LONG, FontHeight AS INTEGERDIM SHARED maxGridW AS INTEGER, maxGridH AS INTEGERDIM SHARED lights(1 TO 20, 1 TO 20) AS objDIM SHARED start!, moves AS INTEGER, m$DIM SHARED i AS INTEGER, j AS INTEGER, Level AS INTEGERDIM SHARED k AS LONG, Alpha AS INTEGERDIM SHARED maxW AS INTEGER, maxH AS INTEGERDIM SHARED MinMoves AS INTEGER, Score AS _UNSIGNED LONGDIM SHARED TryAgain AS _BYTE, TutorialMode AS _BYTEDIM SHARED lightID AS INTEGERREDIM SHARED Button(1 TO 1) AS obj, Caption(1 TO UBOUND(Button)) AS STRING 'from p5js.bas - sound systemTYPE new_SoundHandle handle AS LONG sync AS _BYTEEND TYPEREDIM SHARED loadedSounds(0) AS new_SoundHandle GameSetupIntro DO SetLevel DO UpdateScore UpdateArena _DISPLAY k = _KEYHIT IF k = 27 THEN SYSTEM _LIMIT 30 LOOP UNTIL Victory 'Give time for the last set of bulbs to light up DIM LastBulbs AS SINGLE LastBulbs = TIMER DO UpdateArena _DISPLAY LOOP UNTIL TIMER - LastBulbs > .3 EndScreenLOOP SUB Intro 'Show intro IF isLoaded(LightOn(1)) AND isLoaded(LightOff(1)) THEN _DEST OverlayScreen CLS , 0 COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH("Lights On!") / 2, _HEIGHT - FontHeight * 2), "Lights On!" _DEST 0 _PUTIMAGE (_WIDTH / 2 - _WIDTH(LightOff(1)) / 2, 0), LightOff(1) _DELAY .5 Alpha = 0 p5play Piano _FONT 8 DO IF Alpha < 255 THEN Alpha = Alpha + 5 ELSE EXIT DO _SETALPHA Alpha, , OverlayScreen _CLEARCOLOR _RGB32(0, 0, 0), OverlayScreen _SETALPHA Alpha, , LightOn(1) _PUTIMAGE (_WIDTH / 2 - _WIDTH(LightOn(1)) / 2, 0), LightOn(1) _PUTIMAGE , OverlayScreen COLOR _RGBA32(255, 255, 255, Alpha), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH("Fellippe Heitor, 2017") / 2, _HEIGHT - FontHeight * 1.5), "Fellippe Heitor, 2017" _DISPLAY _LIMIT 20 LOOP _FONT 16 IF _FILEEXISTS("lightson.dat") = false AND isLoaded(MouseCursor) THEN 'offer tutorial on the first run DIM ii AS INTEGER _DEST OverlayScreen CLS , 0 m$ = "Show instructions?" COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 1, _HEIGHT / 2 - FontHeight * 2 + 1), m$ COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - FontHeight * 2), m$ _DEST 0 DO _PUTIMAGE (_WIDTH / 2 - _WIDTH(LightOn(1)) / 2, 0), LightOn(1) _PUTIMAGE , OverlayScreen FOR ii = 4 TO 5 IF Hovering(Button(ii)) THEN LINE (Button(ii).x + 5, Button(ii).y + 5)-STEP(Button(ii).w, Button(ii).h), _RGB32(0, 0, 0), BF LINE (Button(ii).x, Button(ii).y)-STEP(Button(ii).w, Button(ii).h), _RGB32(255, 255, 255), BF ELSE LINE (Button(ii).x, Button(ii).y)-STEP(Button(ii).w, Button(ii).h), _RGBA32(255, 255, 255, 170), BF END IF COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (Button(ii).x + Button(ii).w / 2 - _PRINTWIDTH(Caption(ii)) / 2, Button(ii).y + Button(ii).h / 2 - FontHeight / 2), Caption(ii) NEXT IF _MOUSEBUTTON(1) THEN WHILE _MOUSEBUTTON(1): ii = _MOUSEINPUT: WEND IF Hovering(Button(5)) THEN EXIT DO ELSEIF Hovering(Button(4)) THEN TutorialMode = true ShowTutorial OPEN "lightson.dat" FOR OUTPUT AS #1 CLOSE #1 TutorialMode = false EXIT DO END IF END IF _DISPLAY _LIMIT 30 LOOP END IF END IFEND SUB SUB ClickPause DO k = _KEYHIT WHILE _MOUSEINPUT: WEND IF _MOUSEBUTTON(1) THEN WHILE _MOUSEBUTTON(1): i = _MOUSEINPUT: WEND EXIT DO END IF _DISPLAY _LIMIT 30 LOOP UNTIL k = 27 OR k = 13END SUB SUB CenteredText (Text$) DIM tWidth AS INTEGER, tHeight AS INTEGER tWidth = _PRINTWIDTH(Text$) + 20 tHeight = FontHeight * 3 LINE (_WIDTH / 2 - tWidth / 2, _HEIGHT / 2 - tHeight / 2)-STEP(tWidth - 1, tHeight - 1), _RGBA32(255, 255, 255, 200), BF COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(Text$) / 2 + 1, _HEIGHT / 2 - FontHeight / 2 + 1), Text$ COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(Text$) / 2, _HEIGHT / 2 - FontHeight / 2), Text$END SUB SUB StatusText (Text$) COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 255) CLS _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(Text$) / 2, _HEIGHT - FontHeight * 1.5), Text$END SUB SUB GameSetup 'Acknowledgements: '-------------------------------------------------------------------------------------------------------------------- 'Light bulb images from https://blog.1000bulbs.com/home/flip-the-switch-how-an-incandescent-light-bulb-works 'End level bg from http://blog-sap.com/analytics/2013/06/14/sap-lumira-new-software-update-general-availability-of-cloud-version-and-emeauk-flash-sale-at-bi2013/ 'Ding sound: https://www.freesound.org/people/Flo_Rayen/sounds/191835/ 'Bonus sound: http://freesound.org/people/LittleRobotSoundFactory/sounds/274183/ 'Piano sound: https://www.freesound.org/people/FoolBoyMedia/sounds/352655/ 'Switch sound: https://www.freesound.org/people/Mindloop/sounds/253659/ 'App icon: http://www.iconarchive.com/show/small-n-flat-icons-by-paomedia/light-bulb-icon.html 'Restart icon: http://www.iconarchive.com/show/windows-8-icons-by-icons8/Computer-Hardware-Restart-icon.html 'Mouse cursor icon: http://www.iconarchive.com/show/windows-8-icons-by-icons8/Very-Basic-Cursor-icon.html '-------------------------------------------------------------------------------------------------------------------- 'Load assets: Arena = _NEWIMAGE(600, 600, 32) 'Arial = _LOADFONT("arial.ttf", 24) LightOn(1) = loadImage("assets/lighton.png") LightOn(2) = loadImage("assets/lighton300.png") LightOn(3) = loadImage("assets/lighton120.png") LightOn(4) = loadImage("assets/lighton86.png") LightOn(5) = loadImage("assets/lighton67.png") LightOn(6) = loadImage("assets/lighton60.png") LightOn(7) = loadImage("assets/lighton55.png") LightOn(8) = loadImage("assets/lighton35.png") LightOn(9) = loadImage("assets/lighton30.png") LightOff(1) = loadImage("assets/lightoff.png") LightOff(2) = loadImage("assets/lightoff300.png") LightOff(3) = loadImage("assets/lightoff120.png") LightOff(4) = loadImage("assets/lightoff86.png") LightOff(5) = loadImage("assets/lightoff67.png") LightOff(6) = loadImage("assets/lightoff60.png") LightOff(7) = loadImage("assets/lightoff55.png") LightOff(8) = loadImage("assets/lightoff35.png") LightOff(9) = loadImage("assets/lightoff30.png") Bg = loadImage("assets/bg.jpg") RestartIcon = loadImage("assets/restart.png") MouseCursor = loadImage("assets/mouse.png") Ding = loadSound("assets/ding.wav") Piano = loadSound("assets/piano.ogg") Switch = loadSound("assets/switch.wav") Bonus = loadSound("assets/bonus.wav") IF isLoaded(Bg) THEN _SETALPHA 30, , Bg IF Arial > 0 THEN FontHeight = _FONTHEIGHT(Arial) ELSE FontHeight = 16 IF Arial > 0 THEN _FONT Arial _DEST OverlayScreen _FONT Arial _DEST 0 END IF 'Screen setup: SCREEN _NEWIMAGE(600, 600 + FontHeight * 2, 32) DO UNTIL _SCREENEXISTS: _LIMIT 30: LOOP _TITLE "Lights On" + CHR$(0) OverlayScreen = _NEWIMAGE(_WIDTH / 2, _HEIGHT / 2, 32) 'Set buttons: REDIM Button(1 TO 5) AS obj, Caption(1 TO UBOUND(Button)) AS STRING DIM b AS INTEGER b = b + 1: Caption(b) = "Try again" Button(b).y = _HEIGHT / 2 + FontHeight * 11.5 Button(b).w = _PRINTWIDTH(Caption(b)) + 40 Button(b).x = _WIDTH / 2 - 10 - Button(b).w Button(b).h = 40 b = b + 1: Caption(b) = "Next level" Button(b).y = _HEIGHT / 2 + FontHeight * 11.5 Button(b).w = _PRINTWIDTH(Caption(b)) + 40 Button(b).x = _WIDTH / 2 + 10 Button(b).h = 40 b = b + 1: Caption(b) = "Restart level" IF isLoaded(RestartIcon) THEN Button(b).w = _WIDTH(RestartIcon) + 20 Button(b).h = FontHeight * 2 Button(b).x = _WIDTH - Button(b).w - 10 Button(b).y = _HEIGHT - FontHeight - Button(b).h / 2 ELSE Button(b).h = FontHeight * 2 Button(b).w = _PRINTWIDTH(Caption(b)) + 20 Button(b).x = _WIDTH - 10 - Button(b).w Button(b).y = _HEIGHT - Button(b).h END IF b = b + 1: Caption(b) = "Yes" Button(b).y = _HEIGHT / 2 - FontHeight / 2 Button(b).w = _PRINTWIDTH(Caption(b)) + 40 Button(b).x = _WIDTH / 2 - 10 - Button(b).w Button(b).h = 40 b = b + 1: Caption(b) = "No" Button(b).y = _HEIGHT / 2 - FontHeight / 2 Button(b).w = _PRINTWIDTH(Caption(b)) + 40 Button(b).x = _WIDTH / 2 + 10 Button(b).h = 40END SUB FUNCTION loadImage& (file$) DIM tempHandle& IF _FILEEXISTS(file$) = 0 THEN EXIT FUNCTION tempHandle& = _LOADIMAGE(file$, 32) IF tempHandle& = -1 THEN 'load failed tempHandle& = 0 END IF loadImage& = tempHandle&END FUNCTION FUNCTION isLoaded%% (imgHandle&) isLoaded%% = imgHandle& < -1END FUNCTION SUB SetLevel IF NOT TryAgain THEN Level = Level + 1 DIM LevelSettings AS INTEGER IF Level <= 15 THEN LevelSettings = Level ELSE LevelSettings = _CEIL(RND * 13) + 2 SELECT CASE LevelSettings CASE 1 maxGridW = 1 maxGridH = 2 MinMoves = 2 lightID = 2 CASE 2 maxGridW = 2 maxGridH = 2 MinMoves = 1 lightID = 2 CASE 3, 4 maxGridW = 4 maxGridH = 5 MinMoves = 11 lightID = 3 CASE 5 maxGridW = 5 maxGridH = 7 MinMoves = 65 lightID = 4 CASE 6 maxGridW = 10 maxGridH = 10 MinMoves = 65 lightID = 6 CASE 7, 8 maxGridW = 7 maxGridH = 9 MinMoves = 90 lightID = 5 CASE 9, 10 maxGridW = 7 maxGridH = 11 MinMoves = 130 lightID = 7 CASE 11, 12 maxGridW = 9 maxGridH = 11 MinMoves = 90 lightID = 7 CASE 13, 14 maxGridW = 11 maxGridH = 17 MinMoves = 180 lightID = 8 CASE ELSE maxGridW = 20 maxGridH = 20 MinMoves = 230 lightID = 9 END SELECT maxW = _WIDTH(Arena) / maxGridW maxH = _HEIGHT(Arena) / maxGridH FOR i = 1 TO maxGridW FOR j = 1 TO maxGridH lights(i, j).x = i * maxW - maxW lights(i, j).y = j * maxH - maxH lights(i, j).w = maxW - 1 lights(i, j).h = maxH - 1 lights(i, j).i = i lights(i, j).j = j lights(i, j).IsOn = false NEXT NEXT DIM rndState AS INTEGER FOR rndState = 1 TO maxGridW / 3 i = _CEIL(RND * maxGridW) j = _CEIL(RND * maxGridH) SetState lights(i, j) NEXT start! = TIMER moves = 0END SUB SUB EndScreen UpdateArena _DEST 0 _PUTIMAGE (0, 0), Arena DIM EndAnimationStep AS INTEGER, FinalBonus AS _BYTE DIM SlideOpen AS INTEGER, SlideVelocity AS SINGLE DIM Snd1 AS _BYTE, Snd2 AS _BYTE, Snd3 AS _BYTE DIM FinalLamp1!, FinalLamp2!, FinalLamp3! DIM SkipEndAnimation AS _BYTE DIM BgXOffset AS SINGLE, BgYOffset AS SINGLE DIM BgXSpeed AS SINGLE, BgYSpeed AS SINGLE Snd1 = false: Snd2 = false: Snd3 = false FinalBonus = false IF isLoaded(LightOn(3)) THEN _SETALPHA 255, , LightOn(3) Alpha = 0 TryAgain = false EndAnimationStep = 1 SkipEndAnimation = false BgXSpeed = .5 BgYSpeed = .3 IF isLoaded(Bg) THEN BgXOffset = _WIDTH(Bg) - _WIDTH * 1.5 BgYOffset = _HEIGHT(Bg) - _HEIGHT * 1.5 END IF p5play Piano DO WHILE _MOUSEINPUT: WEND IF EndAnimationStep < 70 THEN _DEST OverlayScreen CLS , 0 m$ = "Level" + STR$(Level) + " - All Lights On!" COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 1, _HEIGHT / 2 - 80 - FontHeight + 1), m$ COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 - 80 - FontHeight), m$ m$ = "Moves used:" + STR$(moves) COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 1, _HEIGHT / 2 + FontHeight * 2.5 + 1), m$ COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 + FontHeight * 2.5), m$ m$ = "Score:" + STR$(Score) COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 1, _HEIGHT / 2 + FontHeight * 3.5 + 1), m$ COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 + FontHeight * 3.5), m$ END IF _DEST 0 BgXOffset = BgXOffset + BgXSpeed BgYOffset = BgYOffset + BgYSpeed IF isLoaded(Bg) THEN IF BgXOffset < 0 OR BgXOffset + _WIDTH - 1 > _WIDTH(Bg) THEN BgXSpeed = BgXSpeed * -1 IF BgYOffset < 0 OR BgYOffset + _HEIGHT - 1 > _HEIGHT(Bg) THEN BgYSpeed = BgYSpeed * -1 _PUTIMAGE (0, 0)-STEP(_WIDTH - 1, _HEIGHT - 1), Bg, , (BgXOffset, BgYOffset)-STEP(_WIDTH - 1, _HEIGHT - 1) END IF SELECT CASE EndAnimationStep CASE 1 IF Alpha < 255 THEN Alpha = Alpha + 10 ELSE EndAnimationStep = 2: SlideOpen = 0: SlideVelocity = 30: Alpha = 0 IF NOT isLoaded(Bg) THEN LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(255, 255, 0, Alpha), BF LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(255, 255, 255, Alpha), BF END IF _PUTIMAGE , OverlayScreen CASE 2 IF NOT isLoaded(Bg) THEN LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(255, 255, 255, 30), BF SlideVelocity = SlideVelocity - .2 IF SlideVelocity < 1 THEN SlideVelocity = 1 IF SlideOpen < 600 THEN SlideOpen = SlideOpen + SlideVelocity ELSE SlideOpen = 600 EndAnimationStep = 3 i = _WIDTH / 2 - (SlideOpen / 3.5) j = _HEIGHT / 2 - SlideOpen / 5 + FontHeight * 1.5 END IF _PUTIMAGE , OverlayScreen DIM b AS INTEGER b = map(SlideOpen, 0, 600, 255, 0) LINE (0, _HEIGHT / 2 - 125 + FontHeight * 1.5)-STEP(SlideOpen, 130), _RGB32(255, 255, 255), BF LINE (0, _HEIGHT / 2 - 120 + FontHeight * 1.5)-STEP(SlideOpen, 120), _RGB32(b * 1.5, b * 1.5 - 50, 0), BF CASE IS >= 3 EndAnimationStep = EndAnimationStep + 1 IF NOT isLoaded(Bg) THEN LINE (0, 0)-(_WIDTH, _HEIGHT), _RGBA32(255, 255, 255, 40), BF _PUTIMAGE , OverlayScreen LINE (0, _HEIGHT / 2 - 125 + FontHeight * 1.5)-STEP(SlideOpen, 130), _RGB32(255, 255, 255), BF LINE (0, _HEIGHT / 2 - 120 + FontHeight * 1.5)-STEP(SlideOpen, 120), _RGB32(b, b - 20, 0), BF IF isLoaded(LightOff(3)) THEN _PUTIMAGE (i, j), LightOff(3) _PUTIMAGE (i + SlideOpen / 5, j), LightOff(3) _PUTIMAGE (i + (SlideOpen / 5) * 2, j), LightOff(3) END IF IF EndAnimationStep >= 3 THEN IF MinMoves <= MinMoves * 3 THEN IF Snd1 = false THEN p5play Ding: Snd1 = true IF EndAnimationStep = 4 THEN FinalLamp1! = TIMER: Score = Score + 20 IF EndAnimationStep <= 20 THEN Score = Score + 10 IF NOT SkipEndAnimation THEN p5play Switch END IF IF isLoaded(LightOn(3)) THEN _SETALPHA constrain(map(TIMER - FinalLamp1!, 0, .3, 0, 255), 0, 255), , LightOn(3) _PUTIMAGE (i, j), LightOn(3) ELSE LINE (i, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(111, 227, 39), BF LINE (i, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(0, 0, 0), B END IF END IF END IF IF EndAnimationStep > 20 THEN IF moves <= MinMoves * 2 THEN IF Snd2 = false THEN p5play Ding: Snd2 = true IF EndAnimationStep = 21 THEN FinalLamp2! = TIMER: Score = Score + 20 IF EndAnimationStep <= 40 THEN Score = Score + 10 IF NOT SkipEndAnimation THEN p5play Switch END IF IF isLoaded(LightOn(3)) THEN _SETALPHA constrain(map(TIMER - FinalLamp2!, 0, .3, 0, 255), 0, 255), , LightOn(3) _PUTIMAGE (i + SlideOpen / 5, j), LightOn(3) ELSE LINE (i + SlideOpen / 5, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(111, 227, 39), BF LINE (i + SlideOpen / 5, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(0, 0, 0), B END IF END IF END IF IF EndAnimationStep > 40 THEN IF moves <= MinMoves THEN IF Snd3 = false THEN p5play Ding: Snd3 = true IF EndAnimationStep = 41 THEN FinalLamp3! = TIMER: Score = Score + 20 IF EndAnimationStep <= 60 THEN Score = Score + 10 IF NOT SkipEndAnimation THEN p5play Switch END IF IF isLoaded(LightOn(3)) THEN _SETALPHA constrain(map(TIMER - FinalLamp3!, 0, .3, 0, 255), 0, 255), , LightOn(3) _PUTIMAGE (i + (SlideOpen / 5) * 2, j), LightOn(3) ELSE LINE (i + (SlideOpen / 5) * 2, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(111, 227, 39), BF LINE (i + (SlideOpen / 5) * 2, j)-STEP(SlideOpen / 5, SlideOpen / 5), _RGB32(0, 0, 0), B END IF END IF END IF IF EndAnimationStep > 60 THEN IF FinalBonus = false THEN FinalBonus = true IF moves < MinMoves THEN Score = Score + 50 p5play Bonus END IF ELSE IF moves < MinMoves THEN m$ = "Strategy master! +50 bonus points!" COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2 + 1, _HEIGHT / 2 + FontHeight * 9.5 + 1), m$ COLOR _RGB32(255, 255, 255), 0 _PRINTSTRING (_WIDTH / 2 - _PRINTWIDTH(m$) / 2, _HEIGHT / 2 + FontHeight * 9.5), m$ END IF END IF END IF END SELECT 'Buttons IF EndAnimationStep > 60 THEN DIM ii AS INTEGER FOR ii = 1 TO 2 IF Hovering(Button(ii)) THEN LINE (Button(ii).x + 5, Button(ii).y + 5)-STEP(Button(ii).w, Button(ii).h), _RGB32(0, 0, 0), BF LINE (Button(ii).x, Button(ii).y)-STEP(Button(ii).w, Button(ii).h), _RGB32(255, 255, 255), BF ELSE LINE (Button(ii).x, Button(ii).y)-STEP(Button(ii).w, Button(ii).h), _RGBA32(255, 255, 255, 20), BF END IF 'COLOR _RGB32(255, 255, 255), 0 '_PRINTSTRING (Button(ii).x + Button(ii).w / 2 - _PRINTWIDTH(Caption(ii)) / 2 + 1, Button(ii).y + Button(ii).h / 2 - FontHeight / 2 + 1), Caption(ii) COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (Button(ii).x + Button(ii).w / 2 - _PRINTWIDTH(Caption(ii)) / 2, Button(ii).y + Button(ii).h / 2 - FontHeight / 2), Caption(ii) NEXT END IF _DISPLAY k = _KEYHIT IF k = 13 AND EndAnimationStep > 60 THEN EXIT DO IF k = 27 THEN SYSTEM IF _MOUSEBUTTON(1) AND EndAnimationStep > 60 THEN WHILE _MOUSEBUTTON(1): ii = _MOUSEINPUT: WEND IF Hovering(Button(1)) THEN TryAgain = true EXIT DO ELSEIF Hovering(Button(2)) THEN EXIT DO END IF ELSEIF _MOUSEBUTTON(1) THEN SkipEndAnimation = true END IF IF NOT SkipEndAnimation THEN _LIMIT 30 LOOPEND SUB SUB UpdateArena DIM imgWidth AS INTEGER, imgHeight AS INTEGER DIM FoundHover AS _BYTE imgHeight = lights(1, 1).h imgWidth = imgHeight _DEST Arena CLS FOR i = 1 TO maxGridW FOR j = 1 TO maxGridH IF isLoaded(LightOff(lightID)) THEN _PUTIMAGE (lights(i, j).x + lights(i, j).w / 2 - imgWidth / 2, lights(i, j).y), LightOff(lightID) END IF IF lights(i, j).IsOn THEN IF isLoaded(LightOn(lightID)) THEN IF TIMER - lights(i, j).lastSwitch < .3 THEN _SETALPHA constrain(map(TIMER - lights(i, j).lastSwitch, 0, .3, 0, 255), 0, 255), , LightOn(lightID) ELSE _SETALPHA 255, , LightOn(lightID) END IF _PUTIMAGE (lights(i, j).x + lights(i, j).w / 2 - imgWidth / 2, lights(i, j).y), LightOn(lightID) ELSE LINE (lights(i, j).x, lights(i, j).y)-STEP(lights(i, j).w, lights(i, j).h), _RGB32(111, 227, 39), BF END IF END IF IF Hovering(lights(i, j)) AND FoundHover = false AND TutorialMode = false THEN FoundHover = true LINE (lights(i, j).x, lights(i, j).y)-STEP(lights(i, j).w, lights(i, j).h), _RGBA32(255, 255, 255, 100), BF CheckState lights(i, j) END IF LINE (lights(i, j).x, lights(i, j).y)-STEP(lights(i, j).w, lights(i, j).h), , B NEXT NEXT _DEST 0 _PUTIMAGE (0, 0), ArenaEND SUB SUB UpdateScore DIM seconds% COLOR _RGB32(0, 0, 0), _RGB32(255, 255, 255) CLS IF TIMER > start! THEN seconds% = TIMER - start! ELSE seconds% = 86400 - start: start! = TIMER END IF m$ = "Level:" + STR$(Level) + " (" + LTRIM$(STR$(maxGridW)) + "x" + LTRIM$(STR$(maxGridH)) + ") Moves:" + STR$(moves) + " Time elapsed:" + STR$(seconds%) + "s" _PRINTSTRING (10, _HEIGHT - FontHeight * 1.5), m$ IF Hovering(Button(3)) THEN LINE (Button(3).x, Button(3).y)-STEP(Button(3).w - 1, Button(3).h - 1), _RGB32(127, 127, 127), BF IF _MOUSEBUTTON(1) THEN WHILE _MOUSEBUTTON(1): i = _MOUSEINPUT: WEND IF Hovering(Button(3)) THEN TryAgain = true: SetLevel END IF END IF END IF IF isLoaded(RestartIcon) THEN _PUTIMAGE (Button(3).x + Button(3).w / 2 - _WIDTH(RestartIcon) / 2, Button(3).y + Button(3).h / 2 - _HEIGHT(RestartIcon) / 2), RestartIcon ELSE COLOR _RGB32(0, 0, 0), 0 _PRINTSTRING (Button(3).x + Button(3).w / 2 - _PRINTWIDTH(Caption(3)) / 2, Button(3).y + Button(3).h / 2 - FontHeight / 2), Caption(3) END IFEND SUB FUNCTION Victory%% DIM i AS INTEGER, j AS INTEGER FOR i = 1 TO maxGridW FOR j = 1 TO maxGridH IF lights(i, j).IsOn = false THEN EXIT FUNCTION NEXT NEXT Victory%% = trueEND FUNCTION SUB CheckState (object AS obj) DIM i AS INTEGER IF _MOUSEBUTTON(1) THEN WHILE _MOUSEBUTTON(1): i = _MOUSEINPUT: WEND IF Hovering(object) THEN p5play Switch moves = moves + 1 SetState object END IF END IFEND SUB SUB SetState (object AS obj) DIM ioff AS INTEGER, joff AS INTEGER ioff = -1 joff = 0 IF object.i + ioff > 0 AND object.i + ioff < maxGridW + 1 AND object.j + joff > 0 AND object.j + joff < maxGridH + 1 THEN lights(object.i + ioff, object.j + joff).IsOn = NOT lights(object.i + ioff, object.j + joff).IsOn lights(object.i + ioff, object.j + joff).lastSwitch = TIMER END IF ioff = 1 joff = 0 IF object.i + ioff > 0 AND object.i + ioff < maxGridW + 1 AND object.j + joff > 0 AND object.j + joff < maxGridH + 1 THEN lights(object.i + ioff, object.j + joff).IsOn = NOT lights(object.i + ioff, object.j + joff).IsOn lights(object.i + ioff, object.j + joff).lastSwitch = TIMER END IF ioff = 0 joff = -1 IF object.i + ioff > 0 AND object.i + ioff < maxGridW + 1 AND object.j + joff > 0 AND object.j + joff < maxGridH + 1 THEN lights(object.i + ioff, object.j + joff).IsOn = NOT lights(object.i + ioff, object.j + joff).IsOn lights(object.i + ioff, object.j + joff).lastSwitch = TIMER END IF ioff = 0 joff = 1 IF object.i + ioff > 0 AND object.i + ioff < maxGridW + 1 AND object.j + joff > 0 AND object.j + joff < maxGridH + 1 THEN lights(object.i + ioff, object.j + joff).IsOn = NOT lights(object.i + ioff, object.j + joff).IsOn lights(object.i + ioff, object.j + joff).lastSwitch = TIMER END IFEND SUB FUNCTION Hovering%% (object AS obj) WHILE _MOUSEINPUT: WEND Hovering%% = _MOUSEX > object.x AND _MOUSEX < object.x + object.w AND _MOUSEY > object.y AND _MOUSEY < object.y + object.hEND FUNCTION SUB MoveMouse (sx AS INTEGER, sy AS INTEGER, dx AS INTEGER, dy AS INTEGER) DIM stepX AS SINGLE, stepY AS SINGLE DIM i AS _BYTE CONST maxSteps = 30 stepX = (dx - sx) / maxSteps stepY = (dy - sy) / maxSteps FOR i = 1 TO maxSteps sx = sx + stepX sy = sy + stepY UpdateArena _PUTIMAGE (sx, sy), MouseCursor _DISPLAY _LIMIT 30 NEXTEND SUB SUB ShowTutorial DIM i AS INTEGER, j AS INTEGER DIM mx AS INTEGER, my AS INTEGER DIM StepNumber AS INTEGER, TotalSteps AS INTEGER Level = 2 SetLevel TotalSteps = 5 StatusText "Tutorial Mode - Click to proceed" UpdateArena StepNumber = StepNumber + 1 CenteredText "(" + LTRIM$(STR$(StepNumber)) + "/" + LTRIM$(STR$(TotalSteps)) + ") Your goal is to turn all light bulbs on." mx = 400 my = 400 _PUTIMAGE (mx, my), MouseCursor _DISPLAY ClickPause IF k = 27 THEN Level = 0: EXIT SUB FOR i = 1 TO maxGridW FOR j = 1 TO maxGridH lights(i, j).IsOn = false NEXT NEXT UpdateArena StepNumber = StepNumber + 1 CenteredText "(" + LTRIM$(STR$(StepNumber)) + "/" + LTRIM$(STR$(TotalSteps)) + ") However, you can't simply switch a light bulb on or off directly." mx = 400 my = 400 _PUTIMAGE (mx, my), MouseCursor _DISPLAY ClickPause IF k = 27 THEN Level = 0: EXIT SUB UpdateArena StepNumber = StepNumber + 1 CenteredText "(" + LTRIM$(STR$(StepNumber)) + "/" + LTRIM$(STR$(TotalSteps)) + ") You click a light bulb to turn the surrounding ones on/off." _PUTIMAGE (mx, my), MouseCursor _DISPLAY ClickPause IF k = 27 THEN Level = 0: EXIT SUB MoveMouse mx, my, lights(2, 2).x + lights(2, 2).w / 2, lights(2, 2).y + lights(2, 2).h / 2 SetState lights(2, 2) p5play Switch DO UpdateArena _PUTIMAGE (mx, my), MouseCursor _DISPLAY LOOP UNTIL TIMER - lights(2, 1).lastSwitch > .3 UpdateArena _PUTIMAGE (mx, my), MouseCursor StepNumber = StepNumber + 1 CenteredText "(" + LTRIM$(STR$(StepNumber)) + "/" + LTRIM$(STR$(TotalSteps)) + ") Continue until all light bulbs are on." _DISPLAY ClickPause IF k = 27 THEN Level = 0: EXIT SUB MoveMouse mx, my, lights(3, 2).x + lights(3, 2).w / 2, lights(3, 2).y + lights(3, 2).h / 2 SetState lights(3, 2) p5play Switch DO UpdateArena _PUTIMAGE (mx, my), MouseCursor _DISPLAY LOOP UNTIL TIMER - lights(3, 1).lastSwitch > .3 UpdateArena StepNumber = StepNumber + 1 _PUTIMAGE (mx, my), MouseCursor CenteredText "(" + LTRIM$(STR$(StepNumber)) + "/" + LTRIM$(STR$(TotalSteps)) + ") Simple right? Click to start." _DISPLAY ClickPause Level = 0 EXIT SUBEND SUB 'functions below are borrowed from p5js.bas:FUNCTION map! (value!, minRange!, maxRange!, newMinRange!, newMaxRange!) map! = ((value! - minRange!) / (maxRange! - minRange!)) * (newMaxRange! - newMinRange!) + newMinRange!END FUNCTION FUNCTION min! (a!, b!) IF a! < b! THEN min! = a! ELSE min! = b!END FUNCTION FUNCTION max! (a!, b!) IF a! > b! THEN max! = a! ELSE max! = b!END FUNCTION FUNCTION constrain! (n!, low!, high!) constrain! = max(min(n!, high!), low!)END FUNCTION FUNCTION loadSound& (file$) IF _FILEEXISTS(file$) = 0 THEN EXIT FUNCTION DIM tempHandle&, setting$ STATIC totalLoadedSounds AS LONG setting$ = "vol" SELECT CASE UCASE$(RIGHT$(file$, 4)) CASE ".WAV", ".OGG", ".AIF", ".RIF", ".VOC" setting$ = "vol,sync,len,pause" CASE ".MP3" setting$ = "vol,pause,setpos" END SELECT tempHandle& = _SNDOPEN(file$, setting$) IF tempHandle& > 0 THEN totalLoadedSounds = totalLoadedSounds + 1 REDIM _PRESERVE loadedSounds(totalLoadedSounds) AS new_SoundHandle loadedSounds(totalLoadedSounds).handle = tempHandle& loadedSounds(totalLoadedSounds).sync = INSTR(setting$, "sync") > 0 loadSound& = tempHandle& END IFEND FUNCTION SUB p5play (soundHandle&) DIM i AS LONG FOR i = 1 TO UBOUND(loadedSounds) IF loadedSounds(i).handle = soundHandle& THEN IF loadedSounds(i).sync THEN _SNDPLAYCOPY soundHandle& ELSE IF NOT _SNDPLAYING(soundHandle&) THEN _SNDPLAY soundHandle& END IF END IF NEXTEND SUB
Navigation
[0] Message Index
Go to full version