我刚刚在 Micro:bit 上为高中/高中编码俱乐部创建了我的第一个小真相或敢于/旋转瓶游戏。我想介绍使用 oop/classes/objects 而不是(可怕的)全局变量。该游戏在https://create.withcode.uk/等模拟器上运行良好,但在 Micro:bit 本身上,当我尝试将几乎所有内容放入类时,我就会遇到内存分配错误。microbit的16KB RAM不够用吗?还是我错误地声明了课程?
来自前端和一点 PHP/SQL,我是 Python/内存知识的菜鸟,因此感谢您的帮助。
如果我在每个函数中使用全局变量,它就可以正常工作。
这是代码:
from microbit import *
import random
#timer current function
#Global variables
class game:
gsTime = 3000
timerPrev = 0
numOfPlayers = 0
maxPlayers = 8
stage = 'start'
minSpinTime = 3000
class player:
#Which player is currently selected
selected = 0
#Player position display
def pos1(): display.set_pixel(2, 4, 9)
def pos2(): display.set_pixel(2, 0, 9)
def pos3(): display.set_pixel(0, 2, 9)
def pos4(): display.set_pixel(4, 2, 9)
def pos5(): display.set_pixel(0, 4, 9)
def pos6(): display.set_pixel(4, 0, 9)
def pos7(): display.set_pixel(0, 0, 9)
def pos8(): display.set_pixel(4, 4, 9)
#Array of all player positions
positions = [
[pos1, 1, Image.ARROW_S],
[pos2, 5, Image.ARROW_N],
[pos3, 3, Image.ARROW_W],
[pos4, 7, Image.ARROW_E],
[pos5, 2, Image.ARROW_SW],
[pos6, 6, Image.ARROW_NE],
[pos7, 4, Image.ARROW_NW],
[pos8, 8, Image.ARROW_SE]
]
positionsOrdered = []
class buttons:
pressed = False
class spinner:
completeSpins = 0
isCompleteSpin = False
rdTime = 0
stage = 'start'
stageStarted = False
gameCall = game()
playerCall = player()
buttonsCall = buttons()
spinnerCall = spinner()
#Return a random range of numbers
def rdRange(minMult,maxMult,base):
return random.randint(base*minMult, base*maxMult)
#return sort key of list
def getKey(item):
return item[1]
#Timer function
def timer(timeElapsed, onCompleteFunc):
if running_time() - gameCall.timerPrev >= timeElapsed:
onCompleteFunc()
#Position Players Start is true
def positionPlayersStartTrue():
game.stage = 'positionPlayers'
def selectNumOfPlayers(gteOrLte):
game.timerPrev = running_time()
if gteOrLte == 'gte':
if gameCall.numOfPlayers >= gameCall.maxPlayers:
game.numOfPlayers = 1
else:
game.numOfPlayers += 1
else:
if gameCall.numOfPlayers <= 1:
game.numOfPlayers = maxPlayers
else:
game.numOfPlayers -= 1
display.show(str(gameCall.numOfPlayers)) #Have to convert int to string before passing to display.show func
buttons.pressed = True
#Ask for number of players up to maxPlayers.
def setPlayerNum():
#If B is pressed increment by 1 up the max players and cycle back to 1
if button_b.was_pressed():
selectNumOfPlayers('gte')
#If A is pressed decrement by 1 down to 1 and then cycle back to maxPlayers var
elif button_a.was_pressed():
selectNumOfPlayers('lte')
elif buttonsCall.pressed == False:
#Ask how many players
display.show('#?')
else:
timer(gameCall.gsTime, positionPlayersStartTrue)
#display the position of players
def positionPlayers():
buttons.pressed = False
display.clear()
for i in range(gameCall.numOfPlayers):
el = player.positions[i]
player.positionsOrdered.append(el)
el[0]()
player.positionsOrdered.sort(key=getKey)
while buttonsCall.pressed == False:
startSpin()
#start the spin - useful for starting the spin after one spin was complete too
def startSpin():
if button_a.was_pressed() or button_b.was_pressed():
buttons.pressed = True
game.stage = 'spin'
#Spin start
def spin():
if spinnerCall.stage == 'start' and spinnerCall.stageStarted == False:
game.timerPrev = running_time()
spinner.rdTime = rdRange(200, 700, gameCall.numOfPlayers)
spinner.stageStarted = True
print(spinner.rdTime)
for i in range(gameCall.numOfPlayers):
display.clear()
el = player.positionsOrdered[i]
el[0]()
if i + 1 == gameCall.numOfPlayers:
spinner.completeSpins += 1
spinner.isCompleteSpin = True
else:
spinner.isCompleteSpin = False
if spinnerCall.stage == 'start':
if (running_time() - gameCall.timerPrev >= (gameCall.minSpinTime + spinnerCall.rdTime)) and (spinnerCall.isCompleteSpin == True):
spinner.stage = 'slow'
spinner.stageStarted = False
sleep(200)
#Slower spin to emulate spinner slowing down as it comes near to stopping. Should probably use some clever-er maths here instead.
elif spinner.stage == 'slow':
if spinnerCall.stageStarted == False:
game.timerPrev = running_time()
spinner.rdTime = rdRange(500, 900, gameCall.numOfPlayers)
spinner.stageStarted = True
print(spinnerCall.rdTime)
if running_time() - gameCall.timerPrev >= spinnerCall.rdTime:
spinner.stage = 'stop'
spinner.stageStarted = False
sleep(400)
elif spinner.stage == 'stop':
player.selected = i
game.stage = 'selectedPlayer'
# reset spinner stage for next spin
spinner.stage = 'start'
break
#Player has been selected
def selectedPlayer():
el = playerCall.positionsOrdered[playerCall.selected]
sleep(200)
display.show(el[2])
sleep(200)
display.clear()
while True:
#CALL FUNCTIONS
if gameCall.stage == 'start':
setPlayerNum()
elif gameCall.stage == 'positionPlayers' and buttonsCall.pressed == True:
positionPlayers()
elif gameCall.stage == 'spin':
spin()
elif gameCall.stage == 'selectedPlayer':
#print('this one is selected ', playerCall.selected)
selectedPlayer()
#start spin again if button is pressed
startSpin()