我刚刚在Micro:bit上为一个高中/高中编码俱乐部创造了我的第一个小事实或敢于/旋转瓶子游戏。我想介绍使用oop / classes / objects而不是(dreaded)全局变量。游戏在https://create.withcode.uk/之类的模拟器上运行得很好,但在Micro:bit本身上,一旦我尝试将任何东西放入类中,我就会遇到内存分配错误。微比特的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()
答案 0 :(得分:0)
您的代码太大了,无法容纳微比特。微比特受16KB of RAM的限制。要减小代码的大小,您可以: