Guest User

Untitled

a guest
Jan 16th, 2020
84
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 18.58 KB | None | 0 0
  1. def net_game(screen, settings):
  2. """Функция, которая запускает игру"""
  3. import pygame
  4. from figure import Figure
  5. from board import Board
  6. from random import choice
  7. from client import MessageSenderAndReceiver
  8. import sys
  9.  
  10. pygame.init()
  11.  
  12. width, height = 1200, 600
  13.  
  14. # Читаем правила и определяем глобальные параметры
  15. for opt, key in settings.items():
  16. if opt == 'music':
  17. if key == 'Да':
  18. play_music = True
  19. else:
  20. play_music = False
  21.  
  22. if opt == 'username':
  23. username = key
  24.  
  25. # Other options
  26.  
  27. def terminate(kill=False):
  28. """Выход из программы"""
  29. nonlocal running
  30.  
  31. if int(record) < int(current_score):
  32. record_file.close()
  33. new = open('record.txt', 'w')
  34. new.write(current_score)
  35. new.close()
  36.  
  37. running = False
  38. if kill:
  39. pygame.quit()
  40. sys.exit()
  41.  
  42. def draw_all_for_enemy(enemy_board_data, enemy_score, enemy_level):
  43. draw_enemy_board(enemy_board_data)
  44.  
  45. enemy_score_label = font.render('Счёт: ' + enemy_score, 1, pygame.Color('#42aaff'))
  46. enemy_level_label = font.render('Уровень: ' + enemy_level, 1, pygame.Color('green'))
  47.  
  48. screen.blit(enemy_score_label, (980, 330))
  49. screen.blit(enemy_level_label, (980, 450))
  50.  
  51.  
  52. def update_display():
  53. """Обновление игрового поля"""
  54.  
  55. nonlocal current_level_label, current_score_label # Переменные - информаторы
  56.  
  57. screen.fill(pygame.Color('white'))
  58.  
  59. # Обновляем текущие результаты
  60. current_score_label = font.render('Счёт: ' + current_score, 1, pygame.Color('#42aaff'))
  61. current_level_label = font.render('Уровень: ' + current_level, 1, pygame.Color('green'))
  62.  
  63. # Рисуем текущие результаты
  64. x_coord = (board.left_space + board.width) * board.size + 50
  65.  
  66. figure_to_draw.draw_next_in_the_rect(x_coord + 75, board.size * 2)
  67. board_to_draw_figure_on = Board(figure_to_draw.width, figure_to_draw.height,
  68. figure_to_draw.size, x_coord + 75, board.size * 2, figure_to_draw.screen, True)
  69. board_to_draw_figure_on.draw()
  70. screen.blit(record_label, (x_coord, 210))
  71. screen.blit(current_score_label, (x_coord, 330))
  72. screen.blit(current_level_label, (x_coord, 450))
  73.  
  74. # Рисуем использованные фигуры
  75. for figure in used_figures:
  76. figure.draw()
  77.  
  78. draw_enemy_board(enemy_board_data)
  79.  
  80. # Рисуем текущую фигуру
  81. current_figure.draw()
  82.  
  83. # Рисуем поле
  84. board.draw()
  85.  
  86. pygame.display.update()
  87.  
  88. def check_field():
  89. """Проверка на заполнение полной линии фигурами"""
  90.  
  91. nonlocal current_score # Переменная для изменения текущего результата
  92.  
  93. to_del = [] # В этом списке хранятся номера строк для удаления
  94.  
  95. for row in range(board.height):
  96. if 0 not in board.field[row]: # Если все элементы заполнены
  97. to_del.append(row)
  98.  
  99. for figure in used_figures:
  100. # В фигуре остаются только квадратики, не принадлежащие удаленной линии
  101. figure.chosen_points = list(
  102. filter(lambda point: point[1] + figure.top != row, figure.chosen_points))
  103.  
  104. # Если вершина фигуры находится выше удаленной линии, то надо сдвинуть её на ряд вниз
  105. if figure.top < row:
  106. for ind in range(len(figure.chosen_points)):
  107. x, y = figure.chosen_points[ind]
  108. if y + figure.top > row: # Если часть фигуры находится ниже удаленной линии
  109. figure.chosen_points[ind] = [x,
  110. y - 1] # Она поднимается вверх, т.е. приближается к верху
  111. figure.top += 1 # Опускаем низ на один элемент
  112.  
  113. # В зависимости от количества удаленных линий зачисляем пользователю очки
  114. if len(to_del) == 1:
  115. current_score = str(int(current_score) + 10)
  116. if len(to_del) == 2:
  117. current_score = str(int(current_score) + 30)
  118. if len(to_del) == 3:
  119. current_score = str(int(current_score) + 60)
  120. if len(to_del) == 4:
  121. current_score = str(int(current_score) + 100)
  122.  
  123. # Проигрываем мелолию, если параметр play_music стоит в позиции True
  124. if to_del and play_music:
  125. ended_string_sound.play()
  126.  
  127. for el in to_del: # Удаляем заполненные строки и добавляем пустые сверху
  128. del board.field[el]
  129. board.field.insert(0, [0] * board.width)
  130.  
  131. def check_to_lose():
  132. """Проверка на проигрыш"""
  133.  
  134. if 1 in board.field[0]: # Если часть фигуры содержится на верхней линии
  135.  
  136. # Проигрываем мелодии
  137. if play_music:
  138. lose_sound.play()
  139. pygame.mixer.music.stop()
  140.  
  141. # Выводим сообщение о проигрыше
  142. lose_font = pygame.font.Font(None, 150)
  143. lose_label = lose_font.render('You lost!', 1, pygame.Color('pink'))
  144.  
  145. screen.blit(lose_label, (width // 2 - 200, height // 2 - 100))
  146. pygame.display.update()
  147.  
  148. # Если мы побили рекорд, то обновляем его
  149. if int(record) < int(current_score):
  150. record_file.close()
  151. new_record_file = open('record.txt', 'w')
  152. new_record_file.write(current_score)
  153. new_record_file.close()
  154.  
  155. # Ждём 6 секунд для проигрывания мелодии
  156. pygame.time.delay(6000)
  157. terminate()
  158.  
  159. def manage_with_event(event):
  160. # В зависимости от типа события двигаем фигуру
  161.  
  162. if event.key == pygame.K_LEFT: # Двигаем фигуру влево
  163. current_figure.move_left()
  164. update_display()
  165. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  166. current_figure, board.width,
  167. board.height)
  168. + '!!!' + current_score + '!!!' + current_level)
  169.  
  170. if event.key == pygame.K_RIGHT: # Двигаем фигуру вправо
  171. current_figure.move_right()
  172. update_display()
  173. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  174. current_figure, board.width,
  175. board.height)
  176. + '!!!' + current_score + '!!!' + current_level)
  177.  
  178. if event.key == pygame.K_DOWN: # Двигаем фигуру вниз
  179. current_figure.move_down()
  180. update_display()
  181. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  182. current_figure, board.width,
  183. board.height)
  184. + '!!!' + current_score + '!!!' + current_level)
  185.  
  186. if event.key == pygame.K_a: # Поворачиваем фигуру на 90 градусов против часовой
  187. current_figure.rotate_to_left()
  188. update_display()
  189. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  190. current_figure, board.width,
  191. board.height)
  192. + '!!!' + current_score + '!!!' + current_level)
  193.  
  194. if event.key == pygame.K_s: # Поворачиваем фигуру на 90 градусов по часовой
  195. current_figure.rotate_to_right()
  196. update_display()
  197. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  198. current_figure, board.width,
  199. board.height)
  200. + '!!!' + current_score + '!!!' + current_level)
  201.  
  202. def make_board_matrix(list_of_figures, current_figure, width, height):
  203. """Составляет матрицу поля для отправки"""
  204.  
  205. matrix = [['.'] * width for _ in range(height)]
  206.  
  207. for figure in list_of_figures:
  208. for x, y in figure.chosen_points:
  209. if figure.top + y < 0:
  210. continue
  211. matrix[figure.top + y][figure.left + x] = figure.text_color
  212.  
  213. if current_figure:
  214. for x, y in current_figure.chosen_points:
  215. if current_figure.top + y < 0:
  216. continue
  217. matrix[current_figure.top + y][current_figure.left + x] = current_figure.text_color
  218.  
  219. for i in range(len(matrix)):
  220. matrix[i] = ''.join(matrix[i])
  221.  
  222. return ';'.join(matrix)
  223.  
  224. def draw_enemy_board(field):
  225. """Рисует поле соперника по заданной матрице"""
  226.  
  227. # Задаём отступы
  228. x_space = enemy_board.left_space * enemy_board.size
  229. y_space = enemy_board.top_space * enemy_board.size
  230.  
  231. pygame.draw.rect(screen, pygame.Color('white'), [x_space, y_space, enemy_board.width * enemy_board.size,
  232. enemy_board.height * enemy_board.size])
  233.  
  234. for x in range(len(field[0])):
  235. for y in range(len(field)):
  236. if field[y][x] == '.': # Если клетка свободна
  237. continue
  238. else:
  239. pygame.draw.rect(screen, letter_to_color[field[y][x]], [x_space + x * board.size,
  240. y_space + y * board.size, board.size, board.size])
  241.  
  242. enemy_board.draw()
  243.  
  244. def receive_messages(client):
  245. if client.received: # Если есть непрочитанные сообщения
  246. field, score, level = client.received.split('!!!') # Получение данных
  247. field = field.split(';')
  248.  
  249. # Нет непрочитанных сообщений
  250. client.received = None
  251.  
  252. return field, score, level
  253.  
  254. return (False, False, False)
  255.  
  256. clock = pygame.time.Clock()
  257. fps = 200
  258. frames_done = 0
  259.  
  260. current_level = '1'
  261. figure_added = 0
  262.  
  263. board = Board(10, 20, 25, 3, 1, screen)
  264.  
  265. enemy_board = board.copy()
  266. enemy_board.left_space = 25
  267. enemy_board.top_space = 1
  268. enemy_board_data = make_board_matrix([], None, board.width, board.height).split(';')
  269. enemy_score = '0'
  270. enemy_level = '1'
  271.  
  272. # Экземпляр класса для отправки сообщений
  273. message_sender_and_receiver = MessageSenderAndReceiver()
  274. enemy = input()
  275. message_sender_and_receiver.send_message('registration:{}'.format(username))
  276. message_sender_and_receiver.send_message('start_game_with:{}'.format(enemy))
  277.  
  278. while not message_sender_and_receiver.found_a_pair:
  279. pass
  280.  
  281. # Загружаем мелодии
  282. lose_sound = pygame.mixer.Sound('sounds/lose.wav')
  283. figure_down_sound = pygame.mixer.Sound('sounds/figure_down.wav')
  284. ended_string_sound = pygame.mixer.Sound('sounds/ended_string.wav')
  285. pygame.mixer.music.load('sounds/background_music.wav')
  286.  
  287. if play_music:
  288. pygame.mixer.music.play(-1)
  289. pygame.mixer.music.set_volume(0.25)
  290.  
  291. # Создаём образцы фигур
  292. square = Figure(2, 2, pygame.Color('yellow'), 'y', board.size, [(0, 0), (1, 0), (0, 1), (1, 1)], board, screen)
  293. stick = Figure(1, 4, pygame.Color('#42aaff'), 'b', board.size, [(0, 0), (0, 1), (0, 2), (0, 3)], board, screen)
  294. something_left = Figure(3, 2, pygame.Color('red'), 'r', board.size, [(0, 1), (1, 1), (1, 0), (2, 0)], board, screen)
  295. something_right = Figure(3, 2, pygame.Color('green'), 'g', board.size, [(0, 0), (1, 0), (1, 1), (2, 1)], board, screen)
  296. t_letter = Figure(3, 2, pygame.Color('purple'), 'p', board.size, [(0, 0), (1, 0), (2, 0), (1, 1)], board, screen)
  297. l_letter_left = Figure(2, 3, pygame.Color('pink'), 'i', board.size, [(0, 0), (0, 1), (0, 2), (1, 2)], board, screen)
  298. l_letter_right = Figure(2, 3, pygame.Color('orange'), 'o', board.size, [(1, 0), (1, 1), (1, 2), (0, 2)], board, screen)
  299.  
  300. # Словарь цветов для отрисовки поля врага
  301. letter_to_color = {'r': pygame.Color('red'), 'y': pygame.Color('yellow'), 'g': pygame.Color('green'),
  302. 'p': pygame.Color('purple'), 'i': pygame.Color('pink'),
  303. 'o': pygame.Color('orange'), 'b': pygame.Color('#42aaff')}
  304.  
  305. # Из этого списка будут выбираться фигуры для вывода на экран
  306. possible_figures = [square, stick, something_left, something_right, t_letter, l_letter_left,
  307. l_letter_right]
  308.  
  309. # Загружаем данные прошлых игр
  310. record_file = open('record.txt')
  311. record = record_file.read()
  312. current_score = '0'
  313.  
  314. # Создаём окна для вывода информации
  315. font = pygame.font.Font(None, 50)
  316. record_label = font.render('Рекорд: ' + record, 1, pygame.Color('red'))
  317. current_score_label = font.render('Счёт: ' + current_score, 1, pygame.Color('#42aaff'))
  318. current_level_label = font.render('Уровень: ' + current_level, 1, pygame.Color('green'))
  319.  
  320. used_figures = [] # Хранит использованные фигуры
  321.  
  322. let_next_figure = False # Флаг, обозначающий возможность запустить новую фигуру
  323.  
  324. current_figure = choice(possible_figures).copy() # Выбираем текущую фигуру
  325. figure_to_draw = choice(possible_figures).copy() # Выбираем фигуру для отрисовки в отдельной части экрана
  326. update_display()
  327.  
  328. running = True
  329. while running: # Основной игровой цикл
  330.  
  331. for event in pygame.event.get():
  332. if event.type == pygame.QUIT:
  333. terminate(True)
  334.  
  335. if event.type == pygame.KEYDOWN:
  336. manage_with_event(event)
  337.  
  338. field_to_draw, score, level = receive_messages(message_sender_and_receiver)
  339.  
  340. if field_to_draw:
  341. enemy_board_data = field_to_draw
  342. enemy_level = level
  343. enemy_score = score
  344.  
  345. draw_all_for_enemy(enemy_board_data, enemy_score, enemy_level)
  346. pygame.display.update()
  347.  
  348. if frames_done >= 200: # Каждые 200 итераций обновляем картинку
  349. # Отправляем данные противнику
  350. message_sender_and_receiver.send_message('message:' + make_board_matrix(used_figures,
  351. current_figure, board.width, board.height)
  352. + '!!!' + current_score + '!!!' + current_level)
  353.  
  354. # Если мы не можем никуда пойти, то появляется новая фигура
  355. if not (current_figure.can_move and current_figure.move()):
  356. used_figures.append(current_figure) # Добавляем фигуру в список для отрисовки
  357. let_next_figure = True # Ждём новую фигуру
  358.  
  359. # Проигрываем мелодию
  360. if play_music:
  361. figure_down_sound.play()
  362.  
  363. figure_added += 1 # Количество фигур увеличивается
  364. current_score = str(int(current_score) + 1) # За каждую фигуру + одно очко
  365.  
  366. if figure_added % int(current_level) ** 2 == 0: # Увеличиваем уровень через определенное число фигур
  367. current_level = str(int(current_level) + 1)
  368. figure_added = 0
  369.  
  370. check_field() # Проверка на заполнение линии фигурами
  371. update_display() # Обновление экрана
  372. check_to_lose() # Проверка на проигрыш
  373. frames_done = 0 # Заново начинаем отсчёт кадров
  374.  
  375. if let_next_figure: # Добавляем новую фигуру
  376. current_figure = figure_to_draw # Обновляем новую фигуру
  377. figure_to_draw = choice(possible_figures).copy() # Выбираем фигуру для отрисовки
  378. let_next_figure = False # Не ждём новую фигуру
  379.  
  380. clock.tick(fps) # Следим на контролем времени
  381. frames_done += int(current_level) # С каждым уровнем число кадров увеличивается на большее число
Advertisement
Add Comment
Please, Sign In to add comment