Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from tkinter import *
- from random import randrange as rnd, choice
- import time
- root = Tk()
- root.geometry('550x700+800+50')
- canv = Canvas(bg='white')
- canv.pack(fill=BOTH,expand=1)
- canv.create_rectangle(50,50,350,650,width=5)
- m = 30 # размер клетки
- x0 = 50
- y0 = 50
- nr = 20 # высота
- nc = 10 # ширина
- colors = ['white','green'] # цвет пустой и закрашенной клетки
- fig_colors = ['red','red','orange','blue','#F600DA','black','black'] # цвета фигур. Повторяются, потому что Z и L по две
- a = [[0 for r in range(nc)] for r in range(nr)] # массив клеток
- speed = 1 # скорость, любые вещественные положительные значения, чем больше, тем быстрее
- points = 0 # очки
- canv.create_text(420,400,text='Скорость:', font = 'Arail 10')
- canv.create_text(433,450,text='Очки:', font = 'Arail 10')
- figs = [] # список фигур L,L,T,4,|,z,z
- fig = [((0,0),(0,1),(0,2),(1,2)),((0,1),(1,1),(2,1),(2,0)),((0,0),(1,0),(1,1),(1,2)),((0,0),(0,1),(1,0),(2,0))] #"L-1"
- figs.append(fig)
- fig = [((1,0),(1,1),(1,2),(0,2)),((0,0),(1,0),(2,0),(2,1)),((0,0),(1,0),(0,1),(0,2)),((0,0),(0,1),(1,1),(2,1)),] #"L-2"
- figs.append(fig)
- fig = [((1,0),(1,1),(1,2),(2,1)),((0,1),(1,1),(1,2),(2,1)),((1,0),(1,1),(0,1),(1,2)),((1,1),(0,2),(1,2),(2,2))] #"T"
- figs.append(fig)
- fig = [((1,1),(1,2),(2,1),(2,2))] #"4"
- figs.append(fig)
- fig = [((0,0),(0,1),(0,2),(0,3)),((0,1),(1,1),(2,1),(3,1))] #"|"
- figs.append(fig)
- fig = [((0,0),(0,1),(1,1),(1,2)),((1,0),(2,0),(0,1),(1,1))] #"Z-1"
- figs.append(fig)
- fig = [((1,0),(1,1),(0,1),(0,2)),((1,1),(2,1),(0,0),(1,0))] #"Z-2"
- figs.append(fig)
- mode = 'game' # изменяется при конце игры, обеспечивает выход из цикла
- def check(): # проверка, не конец ли игры
- global mode
- k = 0
- for c in range(nc): # считать клетки в верней строке
- k += a[0][c]
- if k > 0:
- mode = 'end game' # конец, если хотя бы одна клетка в верхней строке заполнена
- def new_fig(): # создать новую фигуру
- global current_fig, r,c, current_fig_number, current_fig_turn
- r = 0 # строка левого верхнего угла падающей фигуры
- c = 2 # столбец левого верхнего угла падающей фигуры
- current_fig_number = rnd(len(figs)) # номер фигуры
- current_fig_turn = rnd(len(figs[current_fig_number])) # номер поворота фигуры
- current_fig = figs[current_fig_number][current_fig_turn] # сама фигура (клетки, которые нужно закрасить)
- def paint_fig(): # отрисовать падающую фигуру
- for dr, dc in current_fig:
- rr = r + dr
- cc = c + dc
- x = x0 + cc*m
- y = y0 + rr*m
- canv.create_rectangle(x,y,x+m,y+m,outline='gray',fill=fig_colors[current_fig_number],tag='cells')
- def paint():
- canv.delete('cells') # удалить все ячейки
- canv.delete('points') # удалить значения очков и скорости
- for rr in range(0,nr):
- for cc in range(nc):
- x = x0 + cc*m
- y = y0 + rr*m
- canv.create_rectangle(x,y,x+m,y+m,outline='gray',fill=colors[a[rr][cc]],tag='cells')
- paint_fig()
- canv.create_text(480,400,text=speed,tag='points', font = 'Arail 10')
- canv.create_text(480,450,text=points,tag='points', font = 'Arail 10')
- canv.update()
- def delete_lines(): # удаление заполненных строк, если возможно, подсчет очков
- global points, speed
- lines = 0
- for r in range(nr):
- k = 0
- for c in range(nc):
- k += a[r][c]
- if k == nc:
- lines += 1
- for rr in range(r,0,-1):
- for c in range(nc):
- a[rr][c] = a[rr-1][c]
- if lines == 1: # очки считаются нелинейно. Больше строк за один раз - больше очков
- points += 1
- elif lines == 2:
- points += 3
- elif lines == 3:
- points += 5
- elif lines == 4:
- points += 10
- speed = max(points//20,1) # скорость определяется количеством очков. max - чтобы вначале скорость не оказалась равна нулю
- def fix_fig(): # перенос клеток фигуры в основной массив "а"
- global current_fig, t1
- for dr,dc in current_fig:
- a[r+dr][c+dc] = 1
- current_fig = []
- check()
- def move_left(): # смещение фигуры влево
- global c
- move = True # предположим, что фигуру можно переместить влево
- for dr,dc in current_fig:
- if not (c+dc-1 >= 0 and a[r+dr][c+dc-1] == 0): # если слева от фигуры стена или непустые клетки, то не перемещать
- move = False
- break
- if move:
- c -= 1
- def move_right(): # смещение фигуры вправо
- global c
- move = True
- for dr,dc in current_fig:
- if not (c+dc+1 < nc and a[r+dr][c+dc+1] == 0):
- move = False
- if move:
- c += 1
- def turn_left(): # поворот фигуры
- global current_fig, current_fig_number, current_fig_turn
- # рассчитать номер поворота фигуры
- next_current_fig_turn = current_fig_turn - 1
- if next_current_fig_turn < 0:
- next_current_fig_turn = len(figs[current_fig_number])-1
- ##
- next_current_fig = figs[current_fig_number][next_current_fig_turn]
- move = True # предположим, что повернуть можно
- for dr, dc in next_current_fig:
- if r+dr >= nr or c+dc >= nc or a[r+dr][c+dc] == 1: # если после поворота клетки фигуры наложатся на занятые клетки, то поворачивать нельзя
- move = False
- break
- if move:
- current_fig_turn = next_current_fig_turn # запомнить новый номер повтора
- current_fig = figs[current_fig_number][current_fig_turn] # взять новый набор клеток фигуры
- def tick(): # смещение падающей фигуры на строку вниз и проверки
- global r,c
- stop = False # предположим, что фигуре есть куда падать
- for dr,dc in current_fig:
- if r+dr+1 >= nr or a[r+dr+1][c+dc] == 1: # если снизу есть хотя бы одна занятая клетка, но остановить фигуру
- stop = True
- break
- if stop: # если нужно остановится
- fix_fig() # внести клетки из фигуры в основной массив
- delete_lines() # удалить строки, если это возможно
- new_fig() # запустить новую фигуру
- else:
- r += 1 # иначе просто сместить фигуру вниз на одну строку
- new_fig() # создать новую фигуру и начать игру
- def keyDown(event): # действия при нажатии клавиши
- global speed, old_speed
- #print(event.keycode)
- if event.keycode == 40 or event.keycode == 116: # если нажата кл. вниз, тогда взять новую скорость (быструю)
- old_speed = speed
- speed = 40
- if event.keycode == 38 or event.keycode == 111: # вверх - поворот
- turn_left()
- if event.keycode == 37 or event.keycode == 113:
- move_left()
- if event.keycode == 39 or event.keycode == 114:
- move_right()
- def keyUp(event): # действия при отпускании клавиши
- global speed
- if event.keycode == 40 or event.keycode == 116: # если кл. вниз отпущена, то вернуть нормальную скорость
- speed = old_speed
- root.bind('<Key>',keyDown) # привязать реакцию на нажатие клавиши к соотв. функции
- root.bind('<KeyRelease>',keyUp) # привязать реакцию на отпускание клавиши к соотв. функции
- frame_to_tick = 0 # счетчик кадров до смещения падающей фигуры на строку вниз
- while mode == 'game': #
- if frame_to_tick <= 0:
- frame_to_tick = 30 # 30 - значит одна строка за 0,03*30=0,9сек на скорости speed = 1
- tick()
- frame_to_tick -= speed # чем больше speed, тем быстрее будет смещение на строку вниз
- paint() # обновить экран
- time.sleep(0.03) # задержка на 3 сотых секунды
- canv.create_text(200,350,text='Game over', font = 'Arial 40') # надпись "Конец игры"
- mainloop()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement