Skip to content

Commit b010278

Browse files
authored
Add files via upload
1 parent 3190877 commit b010278

File tree

2 files changed

+198
-0
lines changed

2 files changed

+198
-0
lines changed

Thexecutor/Thexecuter.py

Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
# Thexecutor
2+
3+
# Soundboard type game featuring the sweet scifi sounds of the 80s and 90s.
4+
# These sounds were common on various electonic toys and keychains
5+
# such as the Executor and Echo Keyller.
6+
7+
# Sounds were extracted from this youtube video
8+
# https://www.youtube.com/watch?v=iMzkV-mqoFI
9+
# They were processed in Audacity to boost the volume and increase the pitch
10+
# so that they are a little easier to hear on the Thumby. Encoding details
11+
# are provided in the comments of audio.py
12+
13+
# Special thanks and credit to Transistortester for their audio engine which
14+
# was developed for their Bad Apple demo
15+
16+
# Menu was inspired by Memory Match Thumby game by Ted Frazier
17+
18+
# Bitmaps for the menu were drawn by my 5th grade son. Got to get them while they are young.
19+
20+
# Written by Ace Geiger 2025
21+
22+
from sys import path as syspath
23+
syspath.append("/Games/Thexecutor") #fix imports
24+
25+
import thumby
26+
import audio
27+
from time import sleep_ms
28+
from os import listdir, stat #os.path.isfile doesn't exist in micropython
29+
30+
# Icons
31+
32+
# BITMAP: width: 14, height: 14
33+
blaster = bytearray([80,240,208,208,240,208,208,240,208,208,208,240,240,0,
34+
0,0,0,0,0,0,7,4,5,14,16,16,31,0])
35+
36+
# BITMAP: width: 14, height: 14
37+
assaultRifle = bytearray([7,13,27,55,238,220,184,112,224,192,128,0,0,0,
38+
0,0,0,0,15,9,11,15,63,35,35,63,0,0])
39+
40+
# BITMAP: width: 14, height: 14
41+
freezeRay = bytearray([132,213,74,202,85,68,192,64,64,64,64,64,64,128,
42+
3,6,4,6,5,4,6,5,12,62,34,34,34,63])
43+
44+
# BITMAP: width: 14, height: 14
45+
communicator = bytearray([0,0,0,255,8,136,72,40,72,136,72,248,0,0,
46+
0,0,0,63,37,36,60,36,36,60,44,63,0,0])
47+
48+
# BITMAP: width: 14, height: 14
49+
analyzer = bytearray([48,200,132,66,33,17,145,145,17,33,66,132,200,48,
50+
0,1,2,14,17,41,36,36,41,17,14,2,1,0])
51+
52+
# BITMAP: width: 14, height: 14
53+
bombsAway = bytearray([192,96,176,248,236,244,244,244,252,248,250,238,199,10,
54+
7,15,31,63,63,63,63,63,63,63,31,15,7,0])
55+
56+
# BITMAP: width: 14, height: 14
57+
machineGun = bytearray([252,244,244,252,80,80,248,248,80,80,248,248,80,64,
58+
3,3,3,3,3,1,1,1,1,1,1,1,1,0])
59+
60+
# BITMAP: width: 14, height: 14
61+
autoLaser = bytearray([0,240,8,104,104,8,240,8,240,8,255,248,255,240,
62+
0,0,1,1,1,1,0,1,0,1,1,1,1,0])
63+
64+
#set FPS
65+
thumby.display.setFPS(25)
66+
67+
#initialize
68+
startup = True
69+
exit = False
70+
playaudio = thumby.audio.enabled
71+
table = [0, 0, 0, 0, 0, 0, 0, 0]
72+
selectedSquare = 0# Top left
73+
audioPath = "/Games/Thexecutor/assets/blaster.ima"
74+
audioLoaded = False
75+
76+
#some constants
77+
squareSize = 18
78+
xPadding = 0
79+
yPadding = 2
80+
81+
try:
82+
import emulator
83+
print("Emulator detected - audio disabled")
84+
playaudio = False
85+
except ImportError:
86+
pass
87+
88+
def fullDisplayUpdate():
89+
thumby.display.fill(0)
90+
drawMenu()
91+
drawSelection()
92+
thumby.display.update()
93+
94+
def drawMenu():
95+
thumby.display.blit(blaster, 2, 4, 14, 14, 0, 0, 0)
96+
thumby.display.blit(assaultRifle, 20 , 4, 14, 14, 0, 0, 0)
97+
thumby.display.blit(freezeRay, 38, 4, 14, 14, 0, 0, 0)
98+
thumby.display.blit(communicator, 56, 4, 14, 14, 0, 0, 0)
99+
thumby.display.blit(analyzer, 2, 22, 14, 14, 0, 0, 0)
100+
thumby.display.blit(bombsAway, 20, 22, 14, 14, 0, 0, 0)
101+
thumby.display.blit(machineGun, 38, 22, 14, 14, 0, 0, 0)
102+
thumby.display.blit(autoLaser, 56, 22, 14, 14, 0, 0, 0)
103+
104+
def getPosition(square): # Top left corner of the square
105+
tablePosition = [(square % 4) * squareSize, int(square / 4) * squareSize] # Adjusted for 4 columns
106+
return [int(tablePosition[0] + xPadding), tablePosition[1] + yPadding]
107+
108+
def drawSelection():
109+
position = getPosition(selectedSquare)
110+
thumby.display.drawRectangle(position[0], position[1], squareSize, squareSize, 1)
111+
112+
def updateSelectedSquare(value):
113+
global audioLoaded
114+
if audio.playing == False:
115+
audioLoaded = False #need to load new audio file when selecting new sound
116+
global selectedSquare
117+
global audioPath
118+
newValue = selectedSquare + value
119+
if newValue >= 0 and newValue < len(table):
120+
selectedSquare = newValue
121+
if selectedSquare == 0:
122+
audioPath = "/Games/Thexecutor/assets/blaster.ima"
123+
if selectedSquare == 1:
124+
audioPath = "/Games/Thexecutor/assets/assaultRifle.ima"
125+
if selectedSquare == 2:
126+
audioPath = "/Games/Thexecutor/assets/freezeRay.ima"
127+
if selectedSquare == 3:
128+
audioPath = "/Games/Thexecutor/assets/communicator.ima"
129+
if selectedSquare == 4:
130+
audioPath = "/Games/Thexecutor/assets/analyzer.ima"
131+
if selectedSquare == 5:
132+
audioPath = "Games/Thexecutor/assets/bombsAway.ima"
133+
if selectedSquare == 6:
134+
audioPath = "Games/Thexecutor/assets/machineGun.ima"
135+
if selectedSquare == 7:
136+
audioPath = "Games/Thexecutor/assets/autoLaser.ima"
137+
138+
def userInput():
139+
if thumby.buttonU.justPressed():
140+
updateSelectedSquare(-4) # Move up (4 columns)
141+
if thumby.buttonD.justPressed():
142+
updateSelectedSquare(4) # Move down (4 columns)
143+
if thumby.buttonL.justPressed():
144+
updateSelectedSquare(-1) # Move left
145+
if thumby.buttonR.justPressed():
146+
updateSelectedSquare(1) # Move right
147+
if thumby.buttonA.justPressed(): # Play audio
148+
if audio.playing == False:
149+
if playaudio:
150+
global audioLoaded
151+
audioLoaded = False #need to load file after sound is played
152+
audio.play()
153+
# if audio.playing == True:
154+
# if playaudio:
155+
# audio.stop()
156+
# af = open(audioPath, "rb")
157+
# audiosamples = stat(audioPath)[6] * 2
158+
# audio.load(af,15625,audiosamples)
159+
# audioLoaded = True
160+
161+
if thumby.buttonB.justPressed():
162+
global exit
163+
audio.stop()
164+
sleep_ms(500) #gives time for audio thread to clean itself up
165+
exit = True
166+
167+
#Splash Screen
168+
169+
thumby.display.fill(0)
170+
thumby.display.drawText("Thexecutor", 7, 1, 1)
171+
thumby.display.drawLine(7,10,65,10,1)
172+
thumby.display.drawText("A:Play Sound", 0, 20, 1)
173+
thumby.display.drawText("B:Quit", 20, 32, 1)
174+
thumby.display.update()
175+
176+
while startup:
177+
if thumby.buttonA.justPressed():
178+
startup = False
179+
while thumby.inputPressed():
180+
sleep_ms(5)
181+
if thumby.buttonB.justPressed():
182+
exit = True
183+
startup = False
184+
185+
#Main Loop
186+
187+
while not exit:
188+
fullDisplayUpdate()
189+
userInput()
190+
if audio.playing:
191+
audio.fillbufs()
192+
if (audio.playing == False and audioLoaded == False):
193+
af = open(audioPath, "rb")
194+
audiosamples = stat(audioPath)[6] * 2
195+
audio.load(af,15625,audiosamples)
196+
audioLoaded = True
197+
198+
print("Exiting...")

Thexecutor/arcade_title_video.webm

16.7 KB
Binary file not shown.

0 commit comments

Comments
 (0)