Skip to content

Commit 7210b3a

Browse files
authored
Updated flight dynamics and improved button handling performance
changed the steering dynmics of the ship let ship vibrate during afterburner fire optimized performance of dynamic button handling
1 parent 3d3204d commit 7210b3a

File tree

1 file changed

+126
-100
lines changed

1 file changed

+126
-100
lines changed

ThumbCommander/ThumbCommander.py

Lines changed: 126 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111

1212
from machine import freq
1313
# Overclock. It doesn't seem to run above 250MHz
14-
freq(266_000_000)
14+
freq(200_000_000)
1515

1616
from thumbyButton import buttonA, buttonB, buttonU, buttonD, buttonL, buttonR, dpadPressed, inputJustPressed
1717
from thumbyHardware import reset
@@ -94,29 +94,30 @@
9494
0,0,0,0,0,0,0,0,0,0,0,1,2,6,15,30,24,32,96,96,224,192,128,128,0,0,0,0,0,0,0,0,0,0,0,0,0,0,128,128,192,128,128,192,224,208,240,224,224,224,112,112,56,46,14,15,7,3,1,0,0,0,0,0,0,0,0,0,0,0,
9595
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,3,3,3,6,4,4,4,6,6,6,6,6,7,7,7,3,1,1,3,2,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0])
9696

97-
#DEFAULT_KEYS = array('A', #FIRE
98-
# 'B', #SHIFT
99-
# 'L', #MOVE_LEFT
100-
# 'R', #MOVE_RIGHT
101-
# 'D', #MOVE_UP
102-
# 'U', #MOVE_DOWN
103-
# 'U', #AFTERBURNER
104-
# 'D', #BREAK
105-
# 'R', #TARGET_NEXT
106-
# 'L') #TARGET_PREV
97+
DEFAULT_KEYS = array('B', [
98+
ord('A'), # FIRE (index 0)
99+
ord('B'), # SHIFT (index 1)
100+
ord('L'), # MOVE_LEFT (index 2)
101+
ord('R'), # MOVE_RIGHT (index 3)
102+
ord('D'), # MOVE_UP (index 4)
103+
ord('U'), # MOVE_DOWN (index 5)
104+
ord('U'), # AFTERBURNER (index 6)
105+
ord('D'), # BREAK (index 7)
106+
ord('R'), # TARGET_NEXT (index 8)
107+
ord('L') # TARGET_PREV (index 9)
108+
])
107109

108-
DEFAULT_KEYS = {
109-
"FIRE": "A",
110-
"SHIFT": "B",
111-
"MOVE_LEFT": "L",
112-
"MOVE_RIGHT": "R",
113-
"MOVE_UP": "D",
114-
"MOVE_DOWN": "U",
115-
"AFTERBURNER": "U",
116-
"BREAK": "D",
117-
"TARGET_NEXT": "R",
118-
"TARGET_PREV": "L"
119-
}
110+
# Constants for key indexes
111+
KEY_FIRE = const(0)
112+
KEY_SHIFT = const(1)
113+
KEY_MOVE_LEFT = const(2)
114+
KEY_MOVE_RIGHT = const(3)
115+
KEY_MOVE_UP = const(4)
116+
KEY_MOVE_DOWN = const(5)
117+
KEY_AFTERBURNER = const(6)
118+
KEY_BREAK = const(7)
119+
KEY_TARGET_NEXT = const(8)
120+
KEY_TARGET_PREV = const(9)
120121

121122
def copySprite(obj:Sprite):
122123
newSprite = Sprite(obj.width, obj.height,(bytearray(obj.bitmapByteCount), bytearray(obj.bitmapByteCount)),0,0,obj.key,obj.mirrorX,obj.mirrorY)
@@ -260,31 +261,65 @@ def getSprite(z, shape):
260261
OBJECTS[shape].setScale(fpdiv((71<<16)-abs(z), 60<<16))
261262
return OBJECTS[shape]
262263

263-
def button_exists(button_name):
264+
#@micropython.native
265+
def button_exists(button_char:int) -> bool:
264266
try:
265-
for part in button_name:
266-
if not "button" + part in globals():
267-
return False
268-
return True
267+
button_name = "button" + chr(button_char)
268+
return bool(button_name in globals())
269269
except:
270270
return False
271271

272272
def load_keymaps():
273273
try:
274274
with open(loc + "keymap.json", "r") as f:
275275
loaded_keys = json.loads(f.read())
276-
complete_keys = DEFAULT_KEYS.copy()
277-
for key, value in loaded_keys.items():
278-
if button_exists(value):
279-
complete_keys[key] = value
280-
return complete_keys
276+
# Create a new array with default values
277+
complete_keys = array('B', DEFAULT_KEYS)
278+
279+
# Update only valid keys
280+
if "FIRE" in loaded_keys and button_exists(ord(loaded_keys["FIRE"])):
281+
complete_keys[KEY_FIRE] = ord(loaded_keys["FIRE"])
282+
if "SHIFT" in loaded_keys and button_exists(ord(loaded_keys["SHIFT"])):
283+
complete_keys[KEY_SHIFT] = ord(loaded_keys["SHIFT"])
284+
if "MOVE_LEFT" in loaded_keys and button_exists(ord(loaded_keys["MOVE_LEFT"])):
285+
complete_keys[KEY_MOVE_LEFT] = ord(loaded_keys["MOVE_LEFT"])
286+
if "MOVE_RIGHT" in loaded_keys and button_exists(ord(loaded_keys["MOVE_RIGHT"])):
287+
complete_keys[KEY_MOVE_RIGHT] = ord(loaded_keys["MOVE_RIGHT"])
288+
if "MOVE_UP" in loaded_keys and button_exists(ord(loaded_keys["MOVE_UP"])):
289+
complete_keys[KEY_MOVE_UP] = ord(loaded_keys["MOVE_UP"])
290+
if "MOVE_DOWN" in loaded_keys and button_exists(ord(loaded_keys["MOVE_DOWN"])):
291+
complete_keys[KEY_MOVE_DOWN] = ord(loaded_keys["MOVE_DOWN"])
292+
if "AFTERBURNER" in loaded_keys and button_exists(ord(loaded_keys["AFTERBURNER"])):
293+
complete_keys[KEY_AFTERBURNER] = ord(loaded_keys["AFTERBURNER"])
294+
if "BREAK" in loaded_keys and button_exists(ord(loaded_keys["BREAK"])):
295+
complete_keys[KEY_BREAK] = ord(loaded_keys["BREAK"])
296+
if "TARGET_NEXT" in loaded_keys and button_exists(ord(loaded_keys["TARGET_NEXT"])):
297+
complete_keys[KEY_TARGET_NEXT] = ord(loaded_keys["TARGET_NEXT"])
298+
if "TARGET_PREV" in loaded_keys and button_exists(ord(loaded_keys["TARGET_PREV"])):
299+
complete_keys[KEY_TARGET_PREV] = ord(loaded_keys["TARGET_PREV"])
300+
301+
return complete_keys
281302
except:
282-
return DEFAULT_KEYS.copy()
303+
return array('B', DEFAULT_KEYS)
304+
283305

284306
def save_keymaps(keymap):
285307
try:
308+
# Convert array to dictionary for JSON serialization
309+
keymap_dict = {
310+
"FIRE": chr(keymap[KEY_FIRE]),
311+
"SHIFT": chr(keymap[KEY_SHIFT]),
312+
"MOVE_LEFT": chr(keymap[KEY_MOVE_LEFT]),
313+
"MOVE_RIGHT": chr(keymap[KEY_MOVE_RIGHT]),
314+
"MOVE_UP": chr(keymap[KEY_MOVE_UP]),
315+
"MOVE_DOWN": chr(keymap[KEY_MOVE_DOWN]),
316+
"AFTERBURNER": chr(keymap[KEY_AFTERBURNER]),
317+
"BREAK": chr(keymap[KEY_BREAK]),
318+
"TARGET_NEXT": chr(keymap[KEY_TARGET_NEXT]),
319+
"TARGET_PREV": chr(keymap[KEY_TARGET_PREV])
320+
}
286321
with open(loc + "keymap.json", "w") as f:
287-
f.write(json.dumps(keymap))
322+
f.write(json.dumps(keymap_dict))
288323
except:
289324
pass
290325

@@ -329,7 +364,7 @@ def run(self, angle:int=0):
329364
# move forward
330365
if s[4] == 0:
331366
for c in range(2):
332-
s[c] += fpmul((player_angle[c]), player_speed//4)
367+
s[c] += player_angle[c] + (player_speed-65536)
333368
if (s[c] > (200<<16)) or (s[c] < -(200<<16)):
334369
s[c] = -s[c]
335370
s[2] -= fpmul(s[4], player_speed)
@@ -382,7 +417,7 @@ def run(self, laser=[]):
382417
if (a[c] > (1000<<16)) or (a[c] < -(1000<<16)):
383418
a[c+3] = -a[c+3]
384419
a[c] += a[c+3]
385-
a[c] += fpmul((player_angle[c])//2, player_speed)
420+
a[c] += player_angle[c] + (player_speed-65536)
386421
a[2] -= fpmul(a[5], player_speed)
387422

388423
# get sprite in correct size
@@ -481,7 +516,7 @@ def run(self, laser=[]):
481516
# move in x,y,z-axis forward
482517
for c in range(2):
483518
# xy displacement based on player_angle * player_speed
484-
e[c] += (player_angle[c] // 2 * player_speed) >> 16
519+
e[c] += player_angle[c] + (player_speed-65536)
485520
e[2] -= fpmul(2048, player_speed)
486521

487522
# calc displacement of ship form orientation & thrust if not exploding
@@ -513,7 +548,7 @@ def run(self, laser=[]):
513548
else: e[2] = -abs(e[2])
514549

515550
# if space in z axis is ending change ship's x-orientation by 180°
516-
if (e[2] > (70<<16)) or (e[2] < -70<<16):
551+
if (e[2] > (70<<16)) or (e[2] < (-70<<16)):
517552
e[3] = (e[3]+6) % 12
518553
e[2] += sign(e[2])*(-5<<16)
519554

@@ -709,16 +744,11 @@ def move_me(self, enemies):
709744
global player_angle, player_speed, player_target_speed, hudShip
710745
# ticks in ms passed since last call for body inertia calaculation
711746
new_time = ticks_us()
712-
t = (ticks_diff(new_time, self.last_time,)<<16)//1000000
747+
t = (int(ticks_diff(new_time, self.last_time,))<<16)//1000000
713748
self.last_time = new_time
714749

715-
if self.afterburner_time != 0:
716-
ta = (ticks_diff(new_time, self.afterburner_time,)<<16)//1000000
717-
if (ta > 250000):
718-
self.afterburner_time = 0
719-
player_target_speed = 1<<16
720-
if getattr(globals()["button"+KEYMAPS["SHIFT"]], "pressed")():
721-
if getattr(globals()["button"+KEYMAPS["TARGET_NEXT"]], "justPressed")():
750+
if eval("button" + chr(KEYMAPS[KEY_SHIFT])).pressed():
751+
if eval("button" + chr(KEYMAPS[KEY_TARGET_NEXT])).justPressed():
722752
if enemies:
723753
for i in range(len(enemies)):
724754
e = enemies[i]
@@ -729,7 +759,7 @@ def move_me(self, enemies):
729759
break
730760
else:
731761
if enemies[0] != None: enemies[0][8] = 1
732-
elif getattr(globals()["button"+KEYMAPS["TARGET_PREV"]], "justPressed")():
762+
elif eval("button" + chr(KEYMAPS[KEY_TARGET_PREV])).justPressed():
733763
if enemies:
734764
for i in range(len(enemies) -1, -1, -1):
735765
e = enemies[i]
@@ -740,26 +770,26 @@ def move_me(self, enemies):
740770
break
741771
else:
742772
if enemies[0] != None: enemies[len(enemies) -1][8] = 1
743-
elif getattr(globals()["button"+KEYMAPS["AFTERBURNER"]], "justPressed")() and (self.afterburner_time == 0):
744-
player_target_speed = 5<<16;
773+
elif eval("button" + chr(KEYMAPS[KEY_AFTERBURNER])).justPressed() and (self.afterburner_time == 0):
774+
player_target_speed = 7<<16;
745775
self.afterburner_time = new_time
746-
elif getattr(globals()["button"+KEYMAPS["BREAK"]], "justPressed")():
776+
elif eval("button" + chr(KEYMAPS[KEY_BREAK])).justPressed():
747777
player_speed = 1<<16
748-
elif getattr(globals()["button"+KEYMAPS["MOVE_RIGHT"]], "pressed")():
778+
elif eval("button" + chr(KEYMAPS[KEY_MOVE_RIGHT])).pressed():
749779
player_angle[0] -= 1<<16
750780
player_angle[2] = -3
751781
self.cockpit_sprite.x = SHIP_X-1
752-
elif getattr(globals()["button"+KEYMAPS["MOVE_LEFT"]], "pressed")():
782+
elif eval("button" + chr(KEYMAPS[KEY_MOVE_LEFT])).pressed():
753783
player_angle[0] += 1<<16
754784
player_angle[2] = 3
755785
self.cockpit_sprite.x = SHIP_X+1
756-
elif getattr(globals()["button"+KEYMAPS["MOVE_DOWN"]], "pressed")():
786+
elif eval("button" + chr(KEYMAPS[KEY_MOVE_DOWN])).pressed():
757787
player_angle[1] -= 1<<16
758788
self.cockpit_sprite.y = SHIP_Y-1
759-
elif getattr(globals()["button"+KEYMAPS["MOVE_UP"]], "pressed")():
789+
elif eval("button" + chr(KEYMAPS[KEY_MOVE_UP])).pressed():
760790
player_angle[1] += 1<<16
761791
self.cockpit_sprite.y = SHIP_Y+1
762-
elif getattr(globals()["button"+KEYMAPS["FIRE"]], "justPressed")():
792+
elif eval("button" + chr(KEYMAPS[KEY_FIRE])).justPressed():
763793
if (self.laser_energy > 0):
764794
self.laser.append(Laser(player_angle[0], player_angle[1]))
765795
self.target_sprite = Sprite(7,7,(targetactive,targetactiveSHD),CENTER_X-3, CENTER_Y-3,0)
@@ -783,6 +813,14 @@ def move_me(self, enemies):
783813
if player_angle[1] < -2162688: player_angle[1] = -2162688
784814
if player_angle[1] > 2162688: player_angle[1] = 2162688
785815

816+
if self.afterburner_time != 0:
817+
ta = (int(ticks_diff(new_time, self.afterburner_time,))<<16)//1000000
818+
self.cockpit_sprite.x = SHIP_X + choice([1,0,-1])
819+
self.cockpit_sprite.y = SHIP_Y + choice([1,0,-1])
820+
if (ta > 250000):
821+
self.afterburner_time = 0
822+
player_target_speed = 1<<16
823+
786824
player_speed = apply_physics(1<<16, player_target_speed, player_speed, t)
787825
inputJustPressed()
788826

@@ -912,27 +950,27 @@ def __init__(self):
912950
self.update_menu()
913951
self.selected = 0
914952
self.remapping = False
915-
self.current_remap = ""
953+
self.current_remap = 0 # Now using index instead of string
916954
self.background = Stars(20, 4, 0)
917955
display.setFont("/lib/font3x5.bin", 3, 5, 1)
918-
# wait for button release
919-
inputJustPressed()
920956

921957
def update_menu(self):
958+
# Create menu items dynamically from key array
922959
self.settings_items = [
923-
"FIRE: " + KEYMAPS["FIRE"],
924-
"SHIFT: " + KEYMAPS["SHIFT"],
925-
"MOVE LEFT: " + KEYMAPS["MOVE_LEFT"],
926-
"MOVE RIGHT: " + KEYMAPS["MOVE_RIGHT"],
927-
"MOVE UP: " + KEYMAPS["MOVE_UP"],
928-
"MOVE DOWN: " + KEYMAPS["MOVE_DOWN"],
929-
"AFTERBURNER: " + KEYMAPS["SHIFT"]+"+"+KEYMAPS["AFTERBURNER"],
930-
"BREAK: " + KEYMAPS["SHIFT"]+"+"+KEYMAPS["BREAK"],
931-
"TGT NEXT: " + KEYMAPS["SHIFT"]+"+"+KEYMAPS["TARGET_NEXT"],
932-
"TGT PREV: " + KEYMAPS["SHIFT"]+"+"+KEYMAPS["TARGET_PREV"],
960+
"FIRE: " + chr(KEYMAPS[KEY_FIRE]),
961+
"SHIFT: " + chr(KEYMAPS[KEY_SHIFT]),
962+
"MOVE LEFT: " + chr(KEYMAPS[KEY_MOVE_LEFT]),
963+
"MOVE RIGHT: " + chr(KEYMAPS[KEY_MOVE_RIGHT]),
964+
"MOVE UP: " + chr(KEYMAPS[KEY_MOVE_UP]),
965+
"MOVE DOWN: " + chr(KEYMAPS[KEY_MOVE_DOWN]),
966+
"AFTERBURNER: " + chr(KEYMAPS[KEY_SHIFT])+"+"+chr(KEYMAPS[KEY_AFTERBURNER]),
967+
"BREAK: " + chr(KEYMAPS[KEY_SHIFT])+"+"+chr(KEYMAPS[KEY_BREAK]),
968+
"TGT NEXT: " + chr(KEYMAPS[KEY_SHIFT])+"+"+chr(KEYMAPS[KEY_TARGET_NEXT]),
969+
"TGT PREV: " + chr(KEYMAPS[KEY_SHIFT])+"+"+chr(KEYMAPS[KEY_TARGET_PREV]),
933970
"RESET DEFAULTS",
934971
"BACK"
935972
]
973+
936974
def run(self):
937975
global KEYMAPS
938976
display.setFPS(30)
@@ -951,24 +989,29 @@ def run(self):
951989
# Draw title
952990
display.drawText("PRESS NEW KEY FOR:", 2, 2, 1)
953991
display.drawLine(0, 9, 72, 9, 1)
954-
display.drawText(self.current_remap, 16, 14, 3)
992+
993+
# Show which key is being remapped
994+
key_names = ["FIRE", "SHIFT", "MOVE LEFT", "MOVE RIGHT",
995+
"MOVE UP", "MOVE DOWN", "AFTERBURNER",
996+
"BREAK", "TARGET NEXT", "TARGET PREV"]
997+
display.drawText(key_names[self.current_remap], 16, 14, 3)
955998
display.update()
956999

9571000
# Wait for a button press
9581001
while not (buttonA.pressed() or buttonB.pressed() or dpadPressed()):
9591002
pass
9601003

9611004
# Determine which button was pressed
962-
new_key = ""
963-
if buttonA.pressed(): new_key = "A"
964-
elif buttonB.pressed(): new_key = "B"
965-
elif buttonU.pressed(): new_key = "U"
966-
elif buttonD.pressed(): new_key = "D"
967-
elif buttonL.pressed(): new_key = "L"
968-
elif buttonR.pressed(): new_key = "R"
1005+
new_key = 0 # Default value
1006+
if buttonA.pressed(): new_key = ord('A')
1007+
elif buttonB.pressed(): new_key = ord('B')
1008+
elif buttonU.pressed(): new_key = ord('U')
1009+
elif buttonD.pressed(): new_key = ord('D')
1010+
elif buttonL.pressed(): new_key = ord('L')
1011+
elif buttonR.pressed(): new_key = ord('R')
9691012

9701013
# Update mapping if valid
971-
if new_key != "":
1014+
if new_key != 0:
9721015
KEYMAPS[self.current_remap] = new_key
9731016
self.update_menu()
9741017

@@ -1006,29 +1049,11 @@ def run(self):
10061049
# Handle selection
10071050
if self.selected < 10: # Key remapping options
10081051
self.remapping = True
1009-
if self.selected == 0:
1010-
self.current_remap = "FIRE"
1011-
elif self.selected == 1:
1012-
self.current_remap = "SHIFT"
1013-
elif self.selected == 2:
1014-
self.current_remap = "MOVE_LEFT"
1015-
elif self.selected == 3:
1016-
self.current_remap = "MOVE_RIGHT"
1017-
elif self.selected == 4:
1018-
self.current_remap = "MOVE_UP"
1019-
elif self.selected == 5:
1020-
self.current_remap = "MOVE_DOWN"
1021-
elif self.selected == 6:
1022-
self.current_remap = "AFTERBURNER"
1023-
elif self.selected == 7:
1024-
self.current_remap = "BREAK"
1025-
elif self.selected == 8:
1026-
self.current_remap = "TARGET_NEXT"
1027-
elif self.selected == 9:
1028-
self.current_remap = "TARGET_PREV"
1052+
# Set current_remap to the index value instead of string
1053+
self.current_remap = self.selected
10291054
elif self.selected == 10: # Reset defaults
1030-
for key in DEFAULT_KEYS:
1031-
KEYMAPS[key] = DEFAULT_KEYS[key]
1055+
# Reset to default values
1056+
KEYMAPS = array('B', DEFAULT_KEYS)
10321057
# Update menu text
10331058
self.update_menu()
10341059
sleep(0.3)
@@ -1052,6 +1077,7 @@ def run(self):
10521077
# Show the Menu
10531078
game = menu()
10541079

1080+
inputJustPressed()
10551081
if (game == 0):
10561082
# show launch sequence
10571083
launch()

0 commit comments

Comments
 (0)