pythonでテトリス
pythonでテトリスを作ろうとするとどうなるのか、検索すると以下のサイトが見つかった。https://kusakarism.info/?p=11314python標準モジュールのtkinterを使用し、わずか140行ほどで書かれていて感動した。リンク先の動画でも丁寧に説明されていて勉強になった。コーディングのキーポイントは、横12、縦21のマス目の状態を空間とブロックに識別し、横の両端1列ずつと下端1列をブロックとして白で表示、その内側を空間として黒で表示することにある。7種類のテトロミノ(T字やL字のブロック)が積み上がるとその場所はブロックとなり、テトロミノがブロックと当たると移動や回転ができないようになっている。1列がすべてブロックとなると、その段を消去して、順次上のブロックが落ちるようになっている。操作性もよくて、快適に遊べる。コードをみると操作方法がわかるが、カーソルキーで左右と下への移動、スペースキーで回転になっている。せっかくなので、Timerと次のブロックが表示されるように改変してみた。-----以下コード、コピー&ペーストで動作したので、よかったらお試しください。#################### Rough TETRIS ##################### https://kusakarism.info/?p=11314# import tkinter as tkimport randomfrom tkinter import messageboxSIZE = 30 #ブロックのサイズmoveX = 4 #テトロミノ表示位置(横)moveY = 0 #テトロミノ表示位置(縦)type1 = random.randint(0, 6) #テトロミノのタイプnext1 = random.randint(0, 6) #次のテトロミノtimer = 800 #ゲームスピードコントロールscore = 0 #スコアcolor = ["magenta", "blue", "cyan", "yellow", "orange", "red", "green", "black", "white"]#テトロミノデータtetroT = [-1, 0, 0, 0, 1, 0, 0, 1]tetroJ = [-1, 0, 0, 0, 1, 0, 1, 1]tetroI = [-1, 0, 0, 0, 1, 0, 2, 0]tetroO = [ 0, 0, 1, 0, 0, 1, 1, 1]tetroL = [-1, 0, 0, 0, 1, 0,-1, 1]tetroZ = [-1,-1, 0,-1, 0, 0, 1, 0]tetroS = [ 0, 0, 1, 0, 0, 1,-1, 1]tetro = [tetroT, tetroJ, tetroI, tetroO, tetroL, tetroZ, tetroS]#フィールドデータfield=[]for y in range(22): sub=[] for x in range(12): if x==0 or x==11 or y==21: sub.append(8) else: sub.append(7) field.append(sub) #落ちるテトロミノを表示する関数def drawTetris(): for i in range(4): x=(tetro[type1][i*2]+moveX)*SIZE y=(tetro[type1][i*2+1]+moveY)*SIZE can.create_rectangle(x, y, x+SIZE, y+SIZE, fill=color[type1])#次のテトロミノを表示する関数def nextTetro(): can_next.delete("all") for i in range(4): x=(tetro[next1][i*2]+1)*SIZE y=(tetro[next1][i*2+1]+1)*SIZE can_next.create_rectangle(x, y, x+SIZE, y+SIZE, fill=color[next1])#フィールドを表示する関数 1が壁、0が空間def drawField(): for i in range(21): for j in range(12): outLine=0 if color[field[i+1][j]]=="white" else 1 can.create_rectangle(j*SIZE, i*SIZE, (j+1)*SIZE, (i+1)*SIZE, fill=color[field[i+1][j]], width=outLine)#テトロミノを動かす関数def keyPress(event): global moveX, moveY afterX=moveX afterY=moveY afterTetro=[] afterTetro.extend(tetro[type1]) if event.keysym=="Right": afterX+=1 elif event.keysym=="Left": afterX-=1 elif event.keysym=="Down": afterY+=1 elif event.keysym=="space": afterTetro.clear() for i in range(4): afterTetro.append(tetro[type1][i*2+1]*(-1)) afterTetro.append(tetro[type1][i*2]) judge(afterX, afterY, afterTetro) #アタリ判定関数呼び出しdef judge(afterX, afterY, afterTetro): #アタリ判定をする関数 global moveX, moveY result=True for i in range(4): x=afterTetro[i*2]+afterX y=afterTetro[i*2+1]+afterY if field[y+1][x]!=7: result=False if result==True: moveX=afterX moveY=afterY tetro[type1].clear() tetro[type1].extend(afterTetro) return resultdef dropTetris(): global moveX, moveY, type1, next1, timer afterTetro=[] afterTetro.extend(tetro[type1]) result=judge(moveX, moveY+1, afterTetro) if result==False: for i in range(4): x=tetro[type1][i*2]+moveX y=tetro[type1][i*2+1]+moveY field[y+1][x]=type1 deleteLine() type1=next1 #次のテトロミノを落とす next1=random.randint(0,6) #can_next.delete("all") moveX=4 moveY=0 can.after(timer, dropTetris) timer-=2 if timer<140: timer=180def deleteLine(): global score for i in range(1, 21): if 7 not in field[i]: for j in range(i): for k in range(12): field[i-j][k]=field[i-j-1][k] score+=800-timer for i in range(1, 11): if 7!=field[1][i]: messagebox.showinfo("information", "GAME OVER!") exit()#################### ゲームループ #################### win=tk.Tk()win.geometry("340x760")win.title("TETRIS")can=tk.Canvas(win, width=12*SIZE, height=21*SIZE)can.place(x=-10, y=130)can_next=tk.Canvas(win, width=4*SIZE, height=4*SIZE, bg="black") #次のテトロミノ表示位置can_next.place(x=110, y=0)var=tk.StringVar()lab_score = tk.Label(win, textvariable=var, fg="blue", bg="white", font=("", "12")) #得点表示lab_score.place(x=0, y=730)var1=tk.StringVar()lab_timer = tk.Label(win, textvariable=var1, fg="blue", bg="white", font=("", "12")) #タイマー表示lab_timer.place(x=200, y=730)lab_next = tk.Label(win, text="Next", fg="black", bg="white", font=("", "15")) #Nextlab_next.place(x=50, y=50)win.bind("<Any KeyPress>", keyPress)def gameLoop(): can.delete("all") var.set(f"score: {score}") var1.set(f"timer: {timer}") drawField() drawTetris() nextTetro() can.after(10, gameLoop)gameLoop()dropTetris()win.mainloop()-----ここまでにほんブログ村