我们正在创建一个俄罗斯方块游戏,并在BBC micro:bit上运行。
游戏中落下的俄罗斯方块将基于以下四种形状:
游戏规则如下:按钮A:将当前方块移动到左侧
按钮B:将当前方块移动到右侧
按钮A和B同时:顺时针旋转当前方块
视频演示
游戏将使用mico:bit的LED屏幕,其由5*5的25个LED组成。
每个LED可以打开(值:9表示最大亮度)或关闭(值:0)
并显示边界部分(未落下的方块)
Python代码将使用二维数组(Python中的列表)来存储主屏幕显示(7×5)和当前方块(2×2)
下载此代码,您可以使用micro:bit网站上的Python编辑器。
Python代码
frommicrobitimport*
fromrandomimportchoice
#Setupthetetrisgrid
grid=[[1,0,0,0,0,0,1],[1,0,0,0,0,0,1],[1,0,0,0,0,0,1],[1,0,0,0,0,0,1],[1,0,0,0,0,0,1],[1,1,1,1,1,1,1]]
#Storealistof4bricks,eachbrickisa2x2grid
bricks=[[9,9],[9,0]],[[9,9],[0,9]],[[9,9],[9,9]],[[9,9],[0,0]]
#selectabrickrandomlyandpositionitatthecenter/topofthegrid(y=0,x=3)
brick=choice(bricks)
x=3
y=0
frameCount=0
#Afunctiontoreturnthemaximumoftwovalues
defmax(a,b):
ifa>=b:
returna
else:
returnb
#Afunctiontohidethe2x2brickontheLEDscreen
defhideBrick():
ifx>0:
display.set_pixel(x-1,y,grid[y][x])
ifx0andy<4:
display.set_pixel(x-1,y+1,grid[y+1][x])
ifx<5andy0:
display.set_pixel(x-1,y,max(brick[0][0],grid[y][x]))
ifx0andy<4:
display.set_pixel(x-1,y+1,max(brick[1][0],grid[y+1][x]))
ifx0)or(grid[y+1][x]>0andpixel10>0)or(grid[y][x+1]>0andpixel01>0)or(grid[y+1][x+1]>0andpixel11>0)):
hideBrick()
brick[0][0]=pixel10
brick[1][0]=pixel11
brick[1][1]=pixel01
brick[0][1]=pixel00
showBrick()
#Afunctiontomove/translatethebrick
defmoveBrick(delta_x,delta_y):
globalx,y
move=False
#Checkifthemoveifpossible:nocollisionwithotherblocksorbordersofthegrid
ifdelta_x==-1andx>0:
ifnot((grid[y][x-1]>0andbrick[0][0]>0)or(grid[y][x+1-1]>0andbrick[0][1]>0)or(grid[y+1][x-1]>0andbrick[1][0]>0)or(grid[y+1][x+1-1]>0andbrick[1][1]>0)):
move=True
elifdelta_x==1andx0andbrick[0][0]>0)or(grid[y][x+1+1]>0andbrick[0][1]>0)or(grid[y+1][x+1]>0andbrick[1][0]>0)or(grid[y+1][x+1+1]>0andbrick[1][1]>0)):
move=True
elifdelta_y==1andy0andbrick[0][0]>0)or(grid[y+1][x+1]>0andbrick[0][1]>0)or(grid[y+1+1][x]>0andbrick[1][0]>0)or(grid[y+1+1][x+1]>0andbrick[1][1]>0)):
move=True
#Ifthemoveispossible,updatex,ycoordinatesofthebrick
ifmove:
hideBrick()
x+=delta_x
y+=delta_y
showBrick()
#ReturnTrueorFalsetoconfirmifthemovetookplace
returnmove
#Afunctiontocheckforandremovecompletedlines
defcheckLines():
globalscore
removeLine=False
#checkeachlineoneatatime
foriinrange(0,5):
#If5blocksarefilledin(9)thenalineiscomplete(9*5=45)
if(grid[i][1]+grid[i][2]+grid[i][3]+grid[i][4]+grid[i][5])==45:
removeLine=True
#Incrementthescore(10ptsperline)
score+=10
#Removethelineandmakealllinesabovefallby1:
forjinrange(i,0,-1):
grid[j]=grid[j-1]
grid[0]=[1,0,0,0,0,0,1]
ifremoveLine:
#RefreshtheLEDscreen
foriinrange(0,5):
forjinrange(0,5):
display.set_pixel(i,j,grid[j][i+1])
returnremoveLine
gameOn=True
score=0
showBrick()
#MainProgramLoop-iteratesevery50ms
whilegameOn:
sleep(50)
frameCount+=1
#Captureuserinputs
ifbutton_a.is_pressed()andbutton_b.is_pressed():
rotateBrick()
elifbutton_a.is_pressed():
moveBrick(-1,0)
elifbutton_b.is_pressed():
moveBrick(1,0)
#Every15framestrytomovethebrickdown
ifframeCount==15andmoveBrick(0,1)==False:
frameCount=0
#Themovewasnotpossible,thebrickstaysinposition
grid[y][x]=max(brick[0][0],grid[y][x])
grid[y][x+1]=max(brick[0][1],grid[y][x+1])
grid[y+1][x]=max(brick[1][0],grid[y+1][x])
grid[y+1][x+1]=max(brick[1][1],grid[y+1][x+1])
ifcheckLines()==Falseandy==0:
#Thebrickhasreachedthetopofthegrid-GameOver
gameOn=False
else:
#selectanewbrickrandomly
x=3
y=0
brick=choice(bricks)
showBrick()
ifframeCount==15:
frameCount=0
#EndofGame
sleep(2000)
display.scroll("GameOver:Score:"+str(score))
注意:测试此代码时,您可能希望删除一些#注释,尤其是当您的micro:bit返回“内存已满”错误时。