2026-04-14 17:21:59 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"strconv"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"tinygo.org/x/tinydraw"
|
|
|
|
|
"tinygo.org/x/tinyfont"
|
|
|
|
|
"tinygo.org/x/tinyfont/freemono"
|
|
|
|
|
"tinygo.org/x/tinyfont/freesans"
|
|
|
|
|
"tinygo.org/x/tinyfont/proggy"
|
|
|
|
|
|
|
|
|
|
qrcode "github.com/skip2/go-qrcode"
|
|
|
|
|
)
|
|
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
var (
|
|
|
|
|
advOptY = int16(24)
|
|
|
|
|
advOptHeight = int16(10)
|
|
|
|
|
)
|
|
|
|
|
|
2026-04-14 17:21:59 +00:00
|
|
|
func adventure() {
|
|
|
|
|
quit := false
|
|
|
|
|
s := 0
|
|
|
|
|
score := 0
|
|
|
|
|
money := 0
|
|
|
|
|
costume := 0
|
|
|
|
|
pancake := false
|
|
|
|
|
talk := false
|
|
|
|
|
opinion := 0
|
|
|
|
|
selected := int16(0)
|
2026-04-17 16:43:42 +00:00
|
|
|
|
|
|
|
|
if displayWidth <= 240 {
|
|
|
|
|
advOptY = 54
|
|
|
|
|
advOptHeight = 20
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-14 17:21:59 +00:00
|
|
|
for {
|
2026-04-17 16:43:42 +00:00
|
|
|
println("SCENE", s)
|
2026-04-14 17:21:59 +00:00
|
|
|
scene(s)
|
|
|
|
|
selected = 0
|
|
|
|
|
score += s
|
|
|
|
|
if s == 5 {
|
|
|
|
|
costume = 1
|
|
|
|
|
} else if s == 3 {
|
|
|
|
|
talk = true
|
|
|
|
|
} else if s == 6 {
|
|
|
|
|
pancake = true
|
|
|
|
|
} else if s == 8 {
|
|
|
|
|
money += 689
|
|
|
|
|
costume = 2
|
|
|
|
|
} else if s == 17 {
|
|
|
|
|
money += 5
|
|
|
|
|
} else if s == 20 {
|
|
|
|
|
opinion = 57
|
|
|
|
|
} else if s == 21 {
|
|
|
|
|
opinion = 37
|
|
|
|
|
} else if s == 22 {
|
|
|
|
|
opinion = 21
|
|
|
|
|
} else if s == 25 {
|
|
|
|
|
myNameIs(YourName)
|
|
|
|
|
} else if s == 27 {
|
|
|
|
|
if costume == 0 {
|
|
|
|
|
s = 30
|
|
|
|
|
} else if costume == 1 {
|
|
|
|
|
s = 28
|
|
|
|
|
} else {
|
|
|
|
|
s = 29
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
} else if s == 32 {
|
|
|
|
|
s = 34
|
|
|
|
|
if talk {
|
|
|
|
|
s = 33
|
|
|
|
|
}
|
|
|
|
|
continue
|
|
|
|
|
} else if s == 41 {
|
|
|
|
|
showGameStats(score, money, costume, opinion, pancake, talk)
|
|
|
|
|
} else if s == 42 {
|
|
|
|
|
showGameQR()
|
|
|
|
|
} else if s == 44 {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
tinydraw.FilledCircle(&display, 10, displayHeight-advOptY-4+advOptHeight*selected, 3, colorWhite)
|
2026-04-14 17:21:59 +00:00
|
|
|
for {
|
2026-04-17 16:43:42 +00:00
|
|
|
getInput()
|
2026-04-14 17:21:59 +00:00
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
if selected > 0 && ((!buttonsOldState[buttonLeft] && buttonsState[buttonLeft]) ||
|
|
|
|
|
(!buttonsOldState[buttonUp] && buttonsState[buttonUp])) {
|
|
|
|
|
tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorBlack)
|
2026-04-14 17:21:59 +00:00
|
|
|
selected--
|
2026-04-17 16:43:42 +00:00
|
|
|
tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorWhite)
|
|
|
|
|
} else if selected < 2 && ((!buttonsOldState[buttonRight] && buttonsState[buttonRight]) ||
|
|
|
|
|
(!buttonsOldState[buttonDown] && buttonsState[buttonDown])) {
|
|
|
|
|
tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorBlack)
|
2026-04-14 17:21:59 +00:00
|
|
|
selected++
|
2026-04-17 16:43:42 +00:00
|
|
|
tinydraw.FilledCircle(&display, 10, displayHeight-4-advOptY+advOptHeight*selected, 3, colorWhite)
|
|
|
|
|
} else if !buttonsOldState[buttonA] && buttonsState[buttonA] {
|
2026-04-14 17:21:59 +00:00
|
|
|
if selected == 0 {
|
|
|
|
|
s = sceneData[s].sceneA
|
|
|
|
|
if s == 1 {
|
|
|
|
|
money += 385
|
|
|
|
|
} else if s == 2 {
|
|
|
|
|
money += 335
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
} else if selected == 1 {
|
|
|
|
|
s = sceneData[s].sceneB
|
|
|
|
|
if s == 1 {
|
|
|
|
|
money += 600
|
|
|
|
|
} else if s == 2 {
|
|
|
|
|
money += 550
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
} else {
|
|
|
|
|
s = sceneData[s].sceneC
|
|
|
|
|
if s == 1 {
|
|
|
|
|
money += 1050
|
|
|
|
|
} else if s == 2 {
|
|
|
|
|
money += 970
|
|
|
|
|
}
|
|
|
|
|
break
|
|
|
|
|
}
|
2026-04-17 16:43:42 +00:00
|
|
|
} else if goBack() {
|
|
|
|
|
quit = true
|
|
|
|
|
break
|
2026-04-14 17:21:59 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
time.Sleep(200 * time.Millisecond)
|
|
|
|
|
}
|
|
|
|
|
if quit {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func scene(s int) {
|
|
|
|
|
display.FillScreen(colorWhite)
|
|
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
ss := splitBefore(sceneData[s].description, 0)
|
2026-04-14 17:21:59 +00:00
|
|
|
for i := int16(0); i < int16(len(ss)); i++ {
|
2026-04-17 16:43:42 +00:00
|
|
|
if displayWidth <= 240 {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 6, 16+i*10, ss[i], colorBlack)
|
|
|
|
|
} else {
|
|
|
|
|
tinyfont.WriteLine(&display, &freemono.Regular9pt7b, 6, 16+i*16, ss[i], colorBlack)
|
|
|
|
|
}
|
2026-04-14 17:21:59 +00:00
|
|
|
}
|
|
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
display.FillRectangle(0, displayHeight-advOptY-9, displayWidth, advOptY+9, colorBlack)
|
2026-04-14 17:21:59 +00:00
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
// OPTION A
|
|
|
|
|
ss = splitBefore(sceneData[s].optionA, 3)
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY, ss[0], colorWhite)
|
|
|
|
|
if len(ss) > 1 {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+10, ss[1], colorWhite)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OPTION B
|
|
|
|
|
ss = splitBefore(sceneData[s].optionB, 3)
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight, ss[0], colorWhite)
|
|
|
|
|
if len(ss) > 1 {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight+10, ss[1], colorWhite)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OPTION C
|
|
|
|
|
ss = splitBefore(sceneData[s].optionC, 3)
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight*2, ss[0], colorWhite)
|
|
|
|
|
if len(ss) > 1 {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 20, displayHeight-advOptY+advOptHeight*2+10, ss[1], colorWhite)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tinydraw.Circle(&display, 10, displayHeight-advOptY-4, 4, colorWhite)
|
|
|
|
|
tinydraw.Circle(&display, 10, displayHeight-advOptY+advOptHeight-4, 4, colorWhite)
|
|
|
|
|
tinydraw.Circle(&display, 10, displayHeight-advOptY+(advOptHeight)*2-4, 4, colorWhite)
|
2026-04-14 17:21:59 +00:00
|
|
|
|
|
|
|
|
display.Display()
|
|
|
|
|
}
|
|
|
|
|
|
2026-04-17 16:43:42 +00:00
|
|
|
func splitBefore(str string, offset int) []string {
|
2026-04-14 17:21:59 +00:00
|
|
|
l := len(str)
|
|
|
|
|
a := 0
|
2026-04-17 16:43:42 +00:00
|
|
|
s := make([]string, 0)
|
|
|
|
|
lineW := 28 - offset
|
|
|
|
|
if displayWidth <= 240 {
|
|
|
|
|
lineW = 40 - offset
|
|
|
|
|
}
|
2026-04-14 17:21:59 +00:00
|
|
|
for {
|
2026-04-17 16:43:42 +00:00
|
|
|
if l <= lineW {
|
2026-04-14 17:21:59 +00:00
|
|
|
s = append(s, str[a:a+l])
|
|
|
|
|
break
|
|
|
|
|
} else {
|
2026-04-17 16:43:42 +00:00
|
|
|
for i := lineW; i > 0; i-- {
|
2026-04-14 17:21:59 +00:00
|
|
|
if string(str[a+i]) == " " {
|
|
|
|
|
s = append(s, str[a:a+i])
|
|
|
|
|
a = a + i + 1
|
|
|
|
|
l = l - i - 1
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return s
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func showGameStats(score, money, costume, opinion int, pancake, talk bool) {
|
|
|
|
|
|
|
|
|
|
c := "SCORE: " + strconv.Itoa(score)
|
|
|
|
|
w32, _ := tinyfont.LineWidth(&freesans.Bold9pt7b, c)
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, (displayWidth-int16(w32))/2, 26, c, colorBlack)
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 50, "Money spent: "+strconv.Itoa(money)+" EUR", colorBlack)
|
|
|
|
|
|
|
|
|
|
c = "YOURSELF"
|
|
|
|
|
if costume == 1 {
|
|
|
|
|
c = "UNICORN PIJAMA"
|
|
|
|
|
} else if costume == 2 {
|
|
|
|
|
c = "DELUXE TUXEDO"
|
|
|
|
|
}
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 60, "You were dressed as: "+c, colorBlack)
|
|
|
|
|
|
|
|
|
|
c = "NO pancakes"
|
|
|
|
|
if pancake {
|
|
|
|
|
c = "37 pancakes"
|
|
|
|
|
}
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 70, "Your breakfast: "+c, colorBlack)
|
|
|
|
|
|
|
|
|
|
if talk {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 80, "You DID give a talk (and it was awesome)", colorBlack)
|
|
|
|
|
} else {
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 80, "You did NOT give a talk (sad noises)", colorBlack)
|
|
|
|
|
}
|
|
|
|
|
tinyfont.WriteLine(&display, &proggy.TinySZ8pt7b, 10, 90, "Your opinion is "+strconv.Itoa(opinion)+"% popular", colorBlack)
|
|
|
|
|
|
|
|
|
|
display.Display()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func showGameQR() {
|
|
|
|
|
|
|
|
|
|
// https://tinyurl.com/gceuADV
|
|
|
|
|
qr, err := qrcode.New("https://tinyurl.com/gceuADV", qrcode.Medium)
|
|
|
|
|
if err != nil {
|
|
|
|
|
println(err, 123)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qrbytes := qr.Bitmap()
|
|
|
|
|
size := int16(len(qrbytes))
|
|
|
|
|
|
|
|
|
|
factor := int16(displayHeight / len(qrbytes))
|
|
|
|
|
|
|
|
|
|
bx := (displayWidth - size*factor)
|
|
|
|
|
by := (displayHeight - size*factor) / 2
|
|
|
|
|
display.FillScreen(colorWhite)
|
|
|
|
|
for y := int16(0); y < size; y++ {
|
|
|
|
|
for x := int16(0); x < size; x++ {
|
|
|
|
|
if qrbytes[y][x] {
|
|
|
|
|
display.FillRectangle(bx+x*factor, by+y*factor, factor, factor, colorBlack)
|
|
|
|
|
} else {
|
|
|
|
|
display.FillRectangle(bx+x*factor, by+y*factor, factor, factor, colorWhite)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 30, "SCAN &", colorBlack)
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 50, "SHARE", colorBlack)
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 70, "YOUR", colorBlack)
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 90, "SCORE", colorBlack)
|
|
|
|
|
tinyfont.WriteLine(&display, &freesans.Bold9pt7b, 10, 110, "ONLINE", colorBlack)
|
|
|
|
|
|
|
|
|
|
display.Display()
|
|
|
|
|
}
|