|
カテゴリ:プログラミング
pythonでテトリスを作ろうとするとどうなるのか、検索すると以下のサイトが見つかった。
https://kusakarism.info/?p=11314 python標準モジュールのtkinterを使用し、わずか140行ほどで書かれていて感動した。 リンク先の動画でも丁寧に説明されていて勉強になった。 コーディングのキーポイントは、横12、縦21のマス目の状態を空間とブロックに識別し、横の両端1列ずつと下端1列をブロックとして白で表示、その内側を空間として黒で表示することにある。 7種類のテトロミノ(T字やL字のブロック)が積み上がるとその場所はブロックとなり、テトロミノがブロックと当たると移動や回転ができないようになっている。 1列がすべてブロックとなると、その段を消去して、順次上のブロックが落ちるようになっている。 操作性もよくて、快適に遊べる。 コードをみると操作方法がわかるが、カーソルキーで左右と下への移動、スペースキーで回転になっている。 せっかくなので、Timerと次のブロックが表示されるように改変してみた。 -----以下コード、コピー&ペーストで動作したので、よかったらお試しください。 #################### Rough TETRIS #################### # https://kusakarism.info/?p=11314 # import tkinter as tk import random from tkinter import messagebox SIZE = 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 result def 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=180 def 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")) #Next lab_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() -----ここまで にほんブログ村 お気に入りの記事を「いいね!」で応援しよう
最終更新日
2024年01月08日 13時13分22秒
コメント(0) | コメントを書く
[プログラミング] カテゴリの最新記事
|