🐍 ПишСм ВСтрис Π½Π° Python с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Pygame

Π˜Π·ΡƒΡ‡Π°Π΅ΠΌ основныС возмоТности Pygame Π² процСссС создания lite-вСрсии ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· самых популярных ΠΈΠ³Ρ€ Π² ΠΌΠΈΡ€Π΅.
🐍 ПишСм ВСтрис Π½Π° Python с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ Pygame

Pygame – самоС популярноС Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ для создания 2D ΠΈΠ³Ρ€ Π½Π° Python: Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Π² сСбя ΡƒΠ΄ΠΎΠ±Π½Ρ‹Π΅ инструмСнты для рисования, Ρ€Π°Π±ΠΎΡ‚Ρ‹ с изобраТСниями, Π²ΠΈΠ΄Π΅ΠΎ, спрайтами, ΡˆΡ€ΠΈΡ„Ρ‚Π°ΠΌΠΈ ΠΈ Π·Π²ΡƒΠΊΠΎΠΌ, для ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ событий ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹ ΠΈ ΠΌΡ‹ΡˆΠΈ. Π“Π»Π°Π²Π½Ρ‹Π΅ прСимущСства Pygame – Π»Π΅Π³ΠΊΠΎΡΡ‚ΡŒ обучСния ΠΈ ΡΠΊΠΎΡ€ΠΎΡΡ‚ΡŒ Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ. И хотя Pygame Π½Π΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ для коммСрчСской Ρ€Π°Π·Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ ΠΈΠ³Ρ€, это ΠΈΠ΄Π΅Π°Π»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ для обучСния Π½Π°Ρ‡ΠΈΠ½Π°ΡŽΡ‰ΠΈΡ…. Π—Π΄Π΅ΡΡŒ ΠΌΡ‹ рассмотрим созданиС ΠΊΠ»ΠΎΠ½Π° ВСтриса. ΠŸΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΈΠ³Ρ€Ρ‹ находится здСсь.

Установка Pygame

Pygame Π½Π΅ Π²Ρ…ΠΎΠ΄ΠΈΡ‚ Π² ΡΡ‚Π°Π½Π΄Π°Ρ€Ρ‚Π½ΡƒΡŽ поставку Python. Для установки достаточно Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π² cmd ΠΊΠΎΠΌΠ°Π½Π΄Ρƒ py -m pip install -U pygame --user. ΠŸΠΎΠ»Π½Ρ‹ΠΉ Ρ€Π°Π·ΠΌΠ΅Ρ€ ΠΏΠ°ΠΊΠ΅Ρ‚Π° – Ρ‡ΡƒΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ 8 Мб.

ΠžΠ±Π·ΠΎΡ€ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°

Основной экран ВСтриса
Основной экран ВСтриса

Π˜Π³Ρ€ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ»Π΅ прСдставляСт собой ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½Ρ‹ΠΉ «стакан», Π² ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ свСрху ΠΏΠ°Π΄Π°ΡŽΡ‚ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ – стилизованныС Π±ΡƒΠΊΠ²Ρ‹ L, S, Z, J, O, I ΠΈ T.

Π‘ΡƒΠΊΠ²Ρ‹-Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² ВСтрисС
Π‘ΡƒΠΊΠ²Ρ‹-Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² ВСтрисС

КаТдая Π±ΡƒΠΊΠ²Π° состоит ΠΈΠ· 4 Π±Π»ΠΎΠΊΠΎΠ²:

Π€ΠΈΠ³ΡƒΡ€Ρ‹ ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ΠΎΠ² описаны Π² 2D-списках 5 Ρ… 5
Π€ΠΈΠ³ΡƒΡ€Ρ‹ ΠΈ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ΠΎΠ² описаны Π² 2D-списках 5 Ρ… 5

Π˜Π³Ρ€ΠΎΠΊ управляСт Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ΠΌ Ρ„ΠΈΠ³ΡƒΡ€ Π²Π½ΠΈΠ· – Π΄Π²ΠΈΠ³Π°Π΅Ρ‚ ΠΈΡ… Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²Π»Π΅Π²ΠΎ (Π½ΠΎ Π½Π΅ Π²Π²Π΅Ρ€Ρ…), ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Π΅Ρ‚ Π½Π° 90 градусов, ΠΏΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ ускоряСт ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ΠΌ/ΡƒΠ΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ΠΌ клавиши ↓ ΠΈΠ»ΠΈ ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎ сбрасываСт Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π½Π° Π΄Π½ΠΎ Π½Π°ΠΆΠ°Ρ‚ΠΈΠ΅ΠΌ Enter.

ΠŸΡ€ΠΈΠ·Π΅ΠΌΠ»Π΅Π½ΠΈΠ΅ΠΌ считаСтся ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° Ρ„ΠΈΠ³ΡƒΡ€Π° ΠΏΠ°Π΄Π°Π΅Ρ‚ Π½Π° Π΄Π½ΠΎ стакана ΠΈΠ»ΠΈ Π½Π° элСмСнт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€. ПослС этого ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° провСряСт, Π²Ρ‹Π·Π²Π°Π»ΠΎ Π»ΠΈ ΠΏΡ€ΠΈΠ·Π΅ΠΌΠ»Π΅Π½ΠΈΠ΅ ΠΏΠΎΠ»Π½ΠΎΠ΅ (Π±Π΅Π· пустот) Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ ряда элСмСнтов. Π—Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Π΅ ряды (ΠΈΡ… ΠΌΠΎΠΆΠ΅Ρ‚ Π±Ρ‹Ρ‚ΡŒ ΠΎΡ‚ 1 Π΄ΠΎ 4 Π²ΠΊΠ»ΡŽΡ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ) ΡƒΠ΄Π°Π»ΡΡŽΡ‚ΡΡ; находящиСся Π½Π°Π΄ Π½ΠΈΠΌΠΈ элСмСнты ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π²Π½ΠΈΠ· Π½Π° ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ рядов, сколько Π±Ρ‹Π»ΠΎ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΎ ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΎ; Π²Π²Π΅Ρ€Ρ…Ρƒ стакана добавляСтся ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅Π΅ количСство пустых рядов. ПослС удалСния 10 Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… рядов происходит ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π½Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠΉ ΡƒΡ€ΠΎΠ²Π΅Π½ΡŒ, ΠΈ ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€ ускоряСтся.

ВсС экраны ΠΈΠ³Ρ€Ρ‹
ВсС экраны ΠΈΠ³Ρ€Ρ‹
Π‘ΠΎΠ»ΡŒΡˆΠ΅ ΠΏΠΎΠ»Π΅Π·Π½Ρ‹Ρ… ΠΌΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»ΠΎΠ² Π²Ρ‹ Π½Π°ΠΉΠ΄Π΅Ρ‚Π΅ Π½Π° нашСм Ρ‚Π΅Π»Π΅Π³Ρ€Π°ΠΌ-ΠΊΠ°Π½Π°Π»Π΅ Β«Π‘ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° питониста»

ΠžΡΠ½ΠΎΠ²Π½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈΠ³Ρ€Ρ‹

ΠŸΡ€Π΅ΠΆΠ΄Π΅ всСго ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΡƒΠ΅ΠΌ Π½ΡƒΠΆΠ½Ρ‹Π΅ ΠΌΠΎΠ΄ΡƒΠ»ΠΈ:

        import pygame as pg
import random, time, sys
from pygame.locals import *
    

Π—Π°Ρ‚Π΅ΠΌ опрСдСляСм основныС константы – ΠΊΠ°Π΄Ρ€ΠΎΠ²ΡƒΡŽ частоту fps, высоту ΠΈ ΡˆΠΈΡ€ΠΈΠ½Ρƒ ΠΎΠΊΠ½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹, Ρ€Π°Π·ΠΌΠ΅Ρ€ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта Ρ„ΠΈΠ³ΡƒΡ€-Π±ΡƒΠΊΠ² block (20 Ρ… 20 пиксСлСй), ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ стакана, символ для обозначСния пустых ячССк Π½Π° ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠΌ ΠΏΠΎΠ»Π΅:

        fps = 25
window_w, window_h = 600, 500
block, cup_h, cup_w = 20, 20, 10

    

К Ρ€Π°Π·ΠΌΠ΅Ρ€Ρƒ Π±Π°Π·ΠΎΠ²ΠΎΠ³ΠΎ элСмСнта block ΠΏΡ€ΠΈΠ²ΡΠ·Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΎΡΡ‚Π°Π»ΡŒΠ½Ρ‹Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ³ΠΎ поля: ΡˆΠΈΡ€ΠΈΠ½Π° ΠΈ высота стакана, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Ρ€Π°Π²Π½Ρ‹ 10 ΠΈ 20 Π±Π»ΠΎΠΊΠΎΠ² соотвСтствСнно; ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° ΠΈΠ³Ρ€ΠΎΠΊ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ β†’ ΠΈΠ»ΠΈ ←, Ρ„ΠΈΠ³ΡƒΡ€Π° пСрСмСщаСтся Π½Π° 1 Π±Π»ΠΎΠΊ Π² Π½ΡƒΠΆΠ½ΡƒΡŽ сторону.

ΠŸΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€Ρ‹ side_freq ΠΈ down_freq Π·Π°Π΄Π°ΡŽΡ‚ врСмя, ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠ΅ затрачиваСтся Π½Π° ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² сторону ΠΈΠ»ΠΈ Π²Π½ΠΈΠ·, Ссли ΠΈΠ³Ρ€ΠΎΠΊ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ Π½Π°ΠΆΠ°Ρ‚ΠΎΠΉ:

        side_freq, down_freq = 0.15, 0.1
    

Для размСщСния стакана ΠΈ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… надписСй, Π° Ρ‚Π°ΠΊΠΆΠ΅ для ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚Π°Ρ†ΠΈΠΈ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚ Π½Π°ΠΌ Ρ‚Π°ΠΊΠΆΠ΅ понадобятся константы side_margin ΠΈ top_margin – пСрвая Π·Π°Π΄Π°Π΅Ρ‚ Π΄ΠΈΡΡ‚Π°Π½Ρ†ΠΈΡŽ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΏΡ€Π°Π²ΠΎΠΉ ΠΈ Π»Π΅Π²ΠΎΠΉ сторонами ΠΎΠΊΠ½Π° ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ ΠΈ стаканом; вторая опрСдСляСт расстояниС ΠΌΠ΅ΠΆΠ΄Ρƒ Π²Π΅Ρ€Ρ…Π½Π΅ΠΉ Π³Ρ€Π°Π½ΠΈΡ†Π΅ΠΉ стакана ΠΈ ΠΎΠΊΠ½ΠΎΠΌ:

        side_margin = int((window_w - cup_w * block) / 2)
top_margin = window_h - (cup_h * block) - 5

    

Π¨Π°Π±Π»ΠΎΠ½Ρ‹ ΠΈ Ρ†Π²Π΅Ρ‚ Ρ„ΠΈΠ³ΡƒΡ€

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΊΠ°ΠΆΠ΄ΡƒΡŽ Ρ„ΠΈΠ³ΡƒΡ€Ρƒ-Π±ΡƒΠΊΠ²Ρƒ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠ²ΠΎΡ€Π°Ρ‡ΠΈΠ²Π°Ρ‚ΡŒ Π½Π° 90 градусов, всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ ΠΏΠΎΠ²ΠΎΡ€ΠΎΡ‚ΠΎΠ² описаны Π² словарС figures с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ Π²Π»ΠΎΠΆΠ΅Π½Π½Ρ‹Ρ… списков, элСмСнты ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… состоят ΠΈΠ· строк: символом x ΠΎΡ‚ΠΌΠ΅Ρ‡Π΅Π½Ρ‹ занятыС ячСйки, o – пустыС. ΠšΠΎΠ»ΠΈΡ‡Π΅ΡΡ‚Π²ΠΎ Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠΉ зависит ΠΎΡ‚ Ρ„ΠΎΡ€ΠΌΡ‹ Π±ΡƒΠΊΠ²Ρ‹: Ρƒ O, ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Π±ΡƒΠ΄Π΅Ρ‚ всСго ΠΎΠ΄ΠΈΠ½ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

        'O': [['ooooo',
       'ooooo',
       'oxxoo',
       'oxxoo',
       'ooooo']]

    

ΠŸΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ каТдая Ρ„ΠΈΠ³ΡƒΡ€Π° состоит ΠΈΠ· 4 Π±Π»ΠΎΠΊΠΎΠ², Ρ€Π°Π·ΠΌΠ΅Ρ€ шаблона Π΄ΠΎΠ»ΠΆΠ΅Π½ Π±Ρ‹Ρ‚ΡŒ 5 Ρ… 5: fig_w, fig_h = 5, 5.

Π¦Π²Π΅Ρ‚Π° Ρ„ΠΈΠ³ΡƒΡ€ Π·Π°Π΄Π°ΡŽΡ‚ΡΡ двумя ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ°ΠΌΠΈ: colors ΠΈ lightcolors. ПослСдний Π²ΠΊΠ»ΡŽΡ‡Π°Π΅Ρ‚ Ρ‡ΡƒΡ‚ΡŒ Π±ΠΎΠ»Π΅Π΅ свСтлыС ΠΎΡ‚Ρ‚Π΅Π½ΠΊΠΈ Ρ‚Π΅Ρ… ΠΆΠ΅ Ρ†Π²Π΅Ρ‚ΠΎΠ², Ρ‡Ρ‚ΠΎ ΠΈ colors – для создания псСвдо 2.5 D эффСкта.

FPS ΠΈ ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΡŒ

Pygame нСмилосСрдно Π½Π°Π³Ρ€ΡƒΠΆΠ°Π΅Ρ‚ процСссор: ΠΌΠΎΠΆΠ½ΠΎ ΡΡ‚ΠΎΠ»ΠΊΠ½ΡƒΡ‚ΡŒΡΡ с ситуациСй, ΠΊΠΎΠ³Π΄Π° нСбольшая ΠΈΠ³Ρ€Π° с ΠΏΡ€ΠΎΡΡ‚Π΅ΠΉΡˆΠ΅ΠΉ Π³Ρ€Π°Ρ„ΠΈΠΊΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ CPU Π½Π° 100% ΠΈ Π½Π°Π³Ρ€Π΅Π²Π°Π΅Ρ‚ достаточно ΠΌΠΎΡ‰Π½Ρ‹ΠΉ ΠΊΠΎΠΌΠΏΡŒΡŽΡ‚Π΅Ρ€ Π³ΠΎΡ€Π°Π·Π΄ΠΎ сильнСС, Ρ‡Π΅ΠΌ 3D-ΡˆΡƒΡ‚Π΅Ρ€, написанный Π½Π΅ Π½Π° Python:). ΠŸΡ€ΠΎΠ±Π»Π΅ΠΌΠ° Ρ€Π΅ΡˆΠ°Π΅Ρ‚ΡΡ созданиСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° pygame.time.Clock(), ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ вызываСтся Π² основном Ρ†ΠΈΠΊΠ»Π΅ ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ с Π½ΡƒΠΆΠ½ΠΎΠΉ fps – ΠΊΠ°Π΄Ρ€ΠΎΠ²ΠΎΠΉ частотой.

Π¨Ρ€ΠΈΡ„Ρ‚Ρ‹

ΠœΠΎΠ΄ΡƒΠ»ΡŒ Pygame поставляСтся с ΠΎΠ΄Π½ΠΈΠΌ ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠΌ – freesansbold.ttf. ΠŸΡ€ΠΈ этом Pygame способСн ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Π»ΡŽΠ±Ρ‹Π΅ Π΄Ρ€ΡƒΠ³ΠΈΠ΅ ΡˆΡ€ΠΈΡ„Ρ‚Ρ‹ – ΠΊΠ°ΠΊ установлСнныС Π² систСмС, Ρ‚Π°ΠΊ ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡ‹Π΅ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² Ρ€Π°ΠΌΠΊΠ°Ρ… ΠΊΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½ΠΎΠ³ΠΎ ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π°. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ список всСх ΡˆΡ€ΠΈΡ„Ρ‚ΠΎΠ², установлСнных Π² систСмС, достаточно Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ pygame.font.get_fonts().

ΠŸΠΎΠ΄ΠΊΠ»ΡŽΡ‡ΠΈΡ‚ΡŒ ΡˆΡ€ΠΈΡ„Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ трСмя способами:

Если ΡˆΡ€ΠΈΡ„Ρ‚ установлСн ΠΈ находится Π² ΠΏΠ°ΠΏΠΊΠ΅ Windows\Fonts\, ΠΊΠ°ΠΊ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, стандартный Arial – Π½ΡƒΠΆΠ½ΠΎ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ pygame.font.SysFont: pygame.font.SysFont('arial', 15).

Если ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Π² ΠΏΡ€ΠΎΠ΅ΠΊΡ‚Π΅ – ΡƒΠΊΠ°ΠΆΠΈΡ‚Π΅ ΠΊ Π½Π΅ΠΌΡƒ ΠΏΡƒΡ‚ΡŒ Π² pygame.font.Font('/User/Tetris/game.ttf', 18).

Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ ΠΏΡƒΡ‚ΡŒ, ΠΌΠΎΠΆΠ½ΠΎ ΠΏΠΎΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ ΡˆΡ€ΠΈΡ„Ρ‚ Π² ΠΎΠ΄Π½Ρƒ ΠΏΠ°ΠΏΠΊΡƒ с ΠΏΡ€ΠΎΠ΅ΠΊΡ‚ΠΎΠΌ: pygame.font.Font('game.ttf', 18)

ΠŸΠ°ΡƒΠ·Π°, экран ΠΏΠ°ΡƒΠ·Ρ‹ ΠΈ ΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΠΎΡΡ‚ΡŒ

ΠŸΠ°ΡƒΠ·Π° Π² нашСй ΠΈΠ³Ρ€Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚ ΠΏΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ΠΏΡ€ΠΎΠ±Π΅Π»Π° event.key == K_SPACE. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΏΠΎΠΊΠ°Π·Π°Ρ‚ΡŒ Β«Π½Π΅Π°ΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒΒ» ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹ Π²ΠΎ врСмя ΠΏΠ°ΡƒΠ·Ρ‹, Π½ΡƒΠΆΠ½ΠΎ Π·Π°Π»ΠΈΡ‚ΡŒ ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ΅ ΠΏΠΎΠ»Π΅ Ρ†Π²Π΅Ρ‚ΠΎΠΌ.

Π’ΠΎ врСмя ΠΏΠ°ΡƒΠ·Ρ‹ экран заливаСтся ΠΏΠΎΠ»ΡƒΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ синим Ρ†Π²Π΅Ρ‚ΠΎΠΌ
Π’ΠΎ врСмя ΠΏΠ°ΡƒΠ·Ρ‹ экран заливаСтся ΠΏΠΎΠ»ΡƒΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½Ρ‹ΠΌ синим Ρ†Π²Π΅Ρ‚ΠΎΠΌ

Π—Π°Π»ΠΈΠ²ΠΊΡƒ ΡΠΏΠ»ΠΎΡˆΠ½Ρ‹ΠΌ Ρ†Π²Π΅Ρ‚ΠΎΠΌ Ρ€Π΅Π°Π»ΠΈΠ·ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‡Π΅Π½ΡŒ просто, Π½ΠΎ ΠΏΠΎΠ»ΡƒΠΏΡ€ΠΎΠ·Ρ€Π°Ρ‡Π½ΡƒΡŽ заставку ΡΠ΄Π΅Π»Π°Ρ‚ΡŒ слоТнСС – ΠΊΠ°ΠΊ Π½ΠΈ странно, ΠΌΠ΅Ρ‚ΠΎΠ΄ draw Π² Pygame Π΄ΠΎ сих ΠΏΠΎΡ€ Π½Π΅ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ эту ΠΎΠΏΡ†ΠΈΡŽ. Π•ΡΡ‚ΡŒ нСсколько способов Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ этой ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹. ΠœΡ‹ Π²ΠΎΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ прСдусматриваСт созданиС Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΠΉ повСрхности с ΠΏΠΎΠΏΠΈΠΊΡΠ΅Π»ΡŒΠ½Ρ‹ΠΌ Π°Π»ΡŒΡ„Π°-смСшСниСм, ΠΈ ΠΏΠΎΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΡƒΡŽ Π·Π°Π»ΠΈΠ²ΠΊΡƒ экрана ΠΏΠ°ΡƒΠ·Ρ‹ Ρ†Π²Π΅Ρ‚ΠΎΠΌ с Π½Π°Π»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π½Π° ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ ΠΎΠΊΠ½Π° ΠΈΠ³Ρ€Ρ‹:

        pause = pg.Surface((600, 500), pg.SRCALPHA)  
pause.fill((0, 0, 255, 127)) 
display_surf.blit(pause, (0, 0))

    

Π­ΠΊΡ€Π°Π½ ΠΏΠ°ΡƒΠ·Ρ‹ Ρ‚Π°ΠΊΠΆΠ΅ активируСтся Π² случаС ΠΏΡ€ΠΎΠΈΠ³Ρ€Ρ‹ΡˆΠ°, вмСстС с сообщСниСм Π˜Π³Ρ€Π° Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Π°.

Ѐункция main()

Π­Ρ‚Π° функция ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ Π·Π° созданиС Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… Π³Π»ΠΎΠ±Π°Π»ΡŒΠ½Ρ‹Ρ… констант, ΠΈΠ½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΡƒΠ΅Ρ‚ ΠΌΠΎΠ΄ΡƒΠ»ΡŒ Pygame, рисуСт стартовоС ΠΎΠΊΠ½ΠΎ ΠΈΠ³Ρ€Ρ‹, Π²Ρ‹Π·Ρ‹Π²Π°Π΅Ρ‚ запуск ВСтриса runTetris() ΠΈ Π² случаС нСобходимости ΠΎΡ‚ΠΎΠ±Ρ€Π°ΠΆΠ°Π΅Ρ‚ сообщСниС ΠΎ ΠΏΡ€ΠΎΠΈΠ³Ρ€Ρ‹ΡˆΠ΅:

        def main():
	global fps_clock, display_surf, basic_font, big_font
	pg.init()
	fps_clock = pg.time.Clock()
	display_surf = pg.display.set_mode((window_w, window_h))
	basic_font = pg.font.Font('freesansbold.ttf', 18)
	big_font = pg.font.Font('freesansbold.ttf', 45)
	pg.display.set_caption('ВСтрис Lite')
	showText('ВСтрис Lite')
	while True: # Π½Π°Ρ‡ΠΈΠ½Π°Π΅ΠΌ ΠΈΠ³Ρ€Ρƒ
    	runTetris()
    	pauseScreen()
    	showText('Π˜Π³Ρ€Π° Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Π°')
    

Основной ΠΊΠΎΠ΄ ВСтриса

Код ΠΈΠ³Ρ€Ρ‹ располагаСтся Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ runTetris():

        def runTetris():
	cup = emptycup()
	last_move_down = time.time()
	last_side_move = time.time()
	last_fall = time.time()
	going_down = False
	going_left = False
	going_right = False
	points = 0
	level, fall_speed = calcSpeed(points)
	fallingFig = getNewFig()
	nextFig = getNewFig()
    

ΠŸΡ€ΠΈ запускС вызываСтся функция рисования пустого стакана emptycup(), Π° возмоТности двиТСния Π²Π»Π΅Π²ΠΎ, Π²ΠΏΡ€Π°Π²ΠΎ ΠΈ Π²Π½ΠΈΠ· ΡƒΡΡ‚Π°Π½Π°Π²Π»ΠΈΠ²Π°ΡŽΡ‚ΡΡ Π½Π° False:

        	going_down = False
	going_left = False
	going_right = False

    

Π­Ρ‚ΠΈ значСния Π±ΡƒΠ΄ΡƒΡ‚ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ Π½Π° True Π²ΠΎ врСмя ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠΈ событий ΠΊΠ»Π°Π²ΠΈΠ°Ρ‚ΡƒΡ€Ρ‹, Ссли Π±ΡƒΠ΄Π΅Ρ‚ установлСно, Ρ‡Ρ‚ΠΎ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π² Π½ΡƒΠΆΠ½ΠΎΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ:

        for event in pg.event.get():
    if event.type == KEYUP:
    

Π“Π»Π°Π²Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» ΠΈΠ³Ρ€Ρ‹

Основной Ρ†ΠΈΠΊΠ» ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ всС основныС события, связанныС с Π³Π΅Π½Π΅Ρ€Π°Ρ†ΠΈΠ΅ΠΉ Ρ„ΠΈΠ³ΡƒΡ€, Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ΠΌ Π²Π½ΠΈΠ· ΠΈ ΠΏΠΎΠΊΠ°Π·ΠΎΠΌ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹:

        while True:
    	if fallingFig == None:
        	fallingFig = nextFig
        	nextFig = getNewFig()
        	last_fall = time.time()
        	if not checkPos(cup, fallingFig):
            	return
    	quitGame()

    

ПослС призСмлСния ΠΊΠ°ΠΆΠ΄ΠΎΠΉ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ fallingFig устанавливаСтся Π½Π° None, послС Ρ‡Π΅Π³ΠΎ Β«ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ Ρ„ΠΈΠ³ΡƒΡ€Π°Β» nextFig, ΡƒΠΆΠ΅ показанная Π² ΠΏΡ€Π΅Π²ΡŒΡŽ, становится Β«ΠΏΠ°Π΄Π°ΡŽΡ‰Π΅ΠΉΒ» fallingFig. Π‘Π»Π΅Π΄ΡƒΡŽΡ‰Π°Ρ Ρ„ΠΈΠ³ΡƒΡ€Π° для ΠΏΡ€Π΅Π²ΡŒΡŽ гСнСрируСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ getNewFig(). КаТдая новая ΠΏΠ°Π΄Π°ΡŽΡ‰Π°Ρ Ρ„ΠΈΠ³ΡƒΡ€Π° гСнСрируСтся Π² ΠΏΠΎΠ·ΠΈΡ†ΠΈΠΈ, которая располоТСна Ρ‡ΡƒΡ‚ΡŒ Π²Ρ‹ΡˆΠ΅ стакана. Ѐункция checkPos() Π²Π΅Ρ€Π½Π΅Ρ‚ False, Ссли стакан ΡƒΠΆΠ΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ Π½Π°ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ, Ρ‡Ρ‚ΠΎ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ· Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ, послС Ρ‡Π΅Π³ΠΎ появится сообщСниС Π˜Π³Ρ€Π° Π·Π°ΠΊΠΎΠ½Ρ‡Π΅Π½Π°. Π­Ρ‚Π° ΠΆΠ΅ функция checkPos() провСряСт, находится Π»ΠΈ Ρ„ΠΈΠ³ΡƒΡ€Π° Π² Π³Ρ€Π°Π½ΠΈΡ†Π°Ρ… стакана ΠΈ Π½Π΅ натыкаСтся Π»ΠΈ Π½Π° элСмСнты Π΄Ρ€ΡƒΠ³ΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€.

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ΠΌ

ΠžΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° всСх событий происходит Π² ΡƒΠΆΠ΅ упомянутом Ρ†ΠΈΠΊΠ»Π΅:

        for event in pg.event.get():
    if event.type == KEYUP:
    

Π¦ΠΈΠΊΠ» ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°Π΅Ρ‚ ΠΏΠ°ΡƒΠ·Ρƒ ΠΈ опрСдСляСт ΠΌΠΎΠΌΠ΅Π½Ρ‚, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΈ отпускаСт клавиши со стрСлками. Если клавиши β†’, ← ΠΈ ↓ Π½Π΅ Π½Π°ΠΆΠ°Ρ‚Ρ‹, значСния ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ… ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… ΠΌΠ΅Π½ΡΡŽΡ‚ΡΡ Π½Π° False:

                    	elif event.key == K_LEFT:
                	going_left = False
            	elif event.key == K_RIGHT:
                	going_right = False
            	elif event.key == K_DOWN:
                	going_down = False
    

Π£ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ΠΌ Ρ„ΠΈΠ³ΡƒΡ€ происходит Π² Π²Π΅Ρ‚ΠΊΠ΅ elif event.type == KEYDOWN: Ссли Π½Π°ΠΆΠ°Ρ‚Π° клавиша со стрСлкой ΠΈ функция checkPos() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ True, ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ измСняСтся Π½Π° ΠΎΠ΄ΠΈΠ½ Π±Π»ΠΎΠΊ Π² ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ:

        if event.key == K_LEFT and checkPos(cup, fallingFig, adjX=-1):
    fallingFig['x'] -= 1
    going_left = True
    going_right = False
    last_side_move = time.time()

    

Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½Π΅ отпускаСт ΠΊΠ»Π°Π²ΠΈΡˆΡƒ, ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅Π΅ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅Ρ‰Π΅Π½ΠΈΠ΅ Π½Π° ΠΎΠ΄ΠΈΠ½ Π±Π»ΠΎΠΊ ΠΏΡ€ΠΎΠΈΠ·ΠΎΠΉΠ΄Π΅Ρ‚ Π² соотвСтствии со значСниями side_freq ΠΈ down_freq. Π‘Π»ΡƒΡ‡Π°ΠΉ, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ Π² Ρ‚Π΅Ρ‡Π΅Π½ΠΈΠ΅ Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… сСкунд, ΠΌΡ‹ рассмотрим Π½ΠΈΠΆΠ΅.

ΠŸΡ€ΠΈ Π½Π°ΠΆΠ°Ρ‚ΠΈΠΈ ↑ происходит Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ – Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρ‹ бСрутся ΠΈΠ· словаря figures. Π§Ρ‚ΠΎΠ±Ρ‹ Π½Π΅ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΡ‚ΡŒ ΠΎΡˆΠΈΠ±ΠΊΡƒ IndexError: list index out of range, ΠΌΡ‹ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ ΠΊΠΎΠ½ΡΡ‚Ρ€ΡƒΠΊΡ†ΠΈΡŽ, которая обнуляСт индСкс элСмСнта, ΠΊΠΎΠ³Π΄Π° ΠΈΠ½ΠΊΡ€Π΅ΠΌΠ΅Π½Ρ‚ достигаСт максимального значСния: fallingFig['rotation'] + 1) % len(figures[fallingFig['shape']]. Если функция checkPos() сообщаСт, Ρ‡Ρ‚ΠΎ ΠΎΡ‡Π΅Ρ€Π΅Π΄Π½ΠΎΠ΅ Π²Ρ€Π°Ρ‰Π΅Π½ΠΈΠ΅ Π½Π΅Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎ ΠΈΠ·-Π·Π° Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎ Ρ„ΠΈΠ³ΡƒΡ€Π° натыкаСтся Π½Π° ΠΊΠ°ΠΊΠΎΠΉ-Ρ‚ΠΎ Π±Π»ΠΎΠΊ, Π½ΡƒΠΆΠ½ΠΎ Π²Π΅Ρ€Π½ΡƒΡ‚ΡŒΡΡ ΠΊ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰Π΅ΠΌΡƒ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρƒ ΠΈΠ· списка:

        if not checkPos(cup, fallingFig):
    fallingFig['rotation'] = (fallingFig['rotation'] - 1) % len(figures[fallingFig['shape']])
    

Для ускорСния падСния ΠΈΠ³Ρ€ΠΎΠΊ Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ ΠΈ ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ ↓:

                    	elif event.key == K_DOWN:
                	going_down = True
                	if checkPos(cup, fallingFig, adjY=1):
                    	    fallingFig['y'] += 1
  	                last_move_down = time.time()
    

Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Ρ…ΠΎΡ‡Π΅Ρ‚ ΠΌΠ³Π½ΠΎΠ²Π΅Π½Π½ΠΎ ΡΠ±Ρ€ΠΎΡΠΈΡ‚ΡŒ Ρ„ΠΈΠ³ΡƒΡ€Ρƒ Π½Π° Π΄Π½ΠΎ, ΠΎΠ½ ΠΌΠΎΠΆΠ΅Ρ‚ Π½Π°ΠΆΠ°Ρ‚ΡŒ Enter. Π¦ΠΈΠΊΠ» for здСсь опрСдСляСт максимально Π½ΠΈΠ·ΠΊΡƒΡŽ ΡΠ²ΠΎΠ±ΠΎΠ΄Π½ΡƒΡŽ ΠΏΠΎΠ·ΠΈΡ†ΠΈΡŽ Π² стаканС:

                    	elif event.key == K_RETURN:
                	going_down = False
                	going_left = False
                	going_right = False
                	for i in range(1, cup_h):
                    	    if not checkPos(cup, fallingFig, adjY=i):
                      	        break
                	fallingFig['y'] += i - 1
    

Π£Π΄Π΅Ρ€ΠΆΠ°Π½ΠΈΠ΅ клавиш

Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ, ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Π΅Ρ‚ Π»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ двиТСния, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ условия:

        if (going_left or going_right) and time.time() - last_side_move > side_freq:
    

ΠΈ

        if going_down and time.time() - last_move_down > down_freq and checkPos(cup, fallingFig, adjY=1):
    

Π’ этих условиях ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° провСряСт, Π½Π°ΠΆΠΈΠΌΠ°Π΅Ρ‚ Π»ΠΈ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ ΠΊΠ»Π°Π²ΠΈΡˆΡƒ дольшС, Ρ‡Π΅ΠΌ 0.15 ΠΈΠ»ΠΈ 0.1 сСкунды – Π² этом случаС условиС соотвСтствуСт True, ΠΈ Ρ„ΠΈΠ³ΡƒΡ€Π° ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠΈΡ‚ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π² Π·Π°Π΄Π°Π½Π½ΠΎΠΌ Π½Π°ΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠΈ. Π­Ρ‚ΠΈ условия ΠΈΠ·Π±Π°Π²Π»ΡΡŽΡ‚ ΠΈΠ³Ρ€ΠΎΠΊΠ° ΠΎΡ‚ нСобходимости ΠΌΠ½ΠΎΠ³ΠΎΠΊΡ€Π°Ρ‚Π½ΠΎ Π½Π°ΠΆΠΈΠΌΠ°Ρ‚ΡŒ клавиши пСрСдвиТСния – для продолТСния двиТСния достаточно ΠΈΡ… ΡƒΠ΄Π΅Ρ€ΠΆΠΈΠ²Π°Ρ‚ΡŒ.

Π‘Π²ΠΎΠ±ΠΎΠ΄Π½ΠΎΠ΅ ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅

Если ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒ Π½ΠΈΠΊΠ°ΠΊ Π½Π΅ Π²ΠΌΠ΅ΡˆΠΈΠ²Π°Π΅Ρ‚ΡΡ Π² ΡƒΠΏΡ€Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€ΠΎΠΉ, Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ· происходит Ρ‚Π°ΠΊ:

            	if time.time() - last_fall > fall_speed: # свободноС ΠΏΠ°Π΄Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹           
        	if not checkPos(cup, fallingFig, adjY=1): # ΠΏΡ€ΠΎΠ²Π΅Ρ€ΠΊΠ° "призСмлСния" Ρ„ΠΈΠ³ΡƒΡ€Ρ‹
            	    addToCup(cup, fallingFig) # Ρ„ΠΈΠ³ΡƒΡ€Π° ΠΏΡ€ΠΈΠ·Π΅ΠΌΠ»ΠΈΠ»Π°ΡΡŒ, добавляСм Π΅Π΅ Π² содСрТимоС стакана
            	    points += clearCompleted(cup)
            	    level, fall_speed = calcSpeed(points)
            	    fallingFig = None
        	else: # Ρ„ΠΈΠ³ΡƒΡ€Π° ΠΏΠΎΠΊΠ° Π½Π΅ ΠΏΡ€ΠΈΠ·Π΅ΠΌΠ»ΠΈΠ»Π°ΡΡŒ, ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅ΠΌ Π΄Π²ΠΈΠΆΠ΅Π½ΠΈΠ΅ Π²Π½ΠΈΠ·
                    fallingFig['y'] += 1
                    last_fall = time.time()

    

ΠžΡ‚Ρ€ΠΈΡΠΎΠ²ΠΊΠ°, ΠΎΠ±Π½ΠΎΠ²Π»Π΅Π½ΠΈΠ΅ ΠΎΠΊΠ½Π° ΠΈΠ³Ρ€Ρ‹ ΠΈ Π²Ρ‹Π²ΠΎΠ΄ надписСй

Π€ΡƒΠ½ΠΊΡ†ΠΈΡŽ runTetris() Π·Π°Π²Π΅Ρ€ΡˆΠ°Π΅Ρ‚ Π½Π°Π±ΠΎΡ€ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ, ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΡ… отрисовку ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ³ΠΎ поля, Π²Ρ‹Π²ΠΎΠ΄ названия ΠΈΠ³Ρ€Ρ‹, ΠΏΠ°Π΄Π°ΡŽΡ‰Π΅ΠΉ ΠΈ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€, Π° Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Ρ… надписСй:

            	display_surf.fill(bg_color)
    	drawTitle()
    	gamecup(cup)
    	drawInfo(points, level)
    	drawnextFig(nextFig)
    	if fallingFig != None:
        	drawFig(fallingFig)
    	pg.display.update()
    	fps_clock.tick(fps)
    

Π’ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ

Ѐункция txtObjects() ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°Π΅Ρ‚ тСкст, ΡˆΡ€ΠΈΡ„Ρ‚ ΠΈ Ρ†Π²Π΅Ρ‚, ΠΈ с ΠΏΠΎΠΌΠΎΡ‰ΡŒΡŽ ΠΌΠ΅Ρ‚ΠΎΠ΄Π° render() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ Π³ΠΎΡ‚ΠΎΠ²Ρ‹Π΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Surface (ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ) ΠΈ Rect (ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ). Π­Ρ‚ΠΈ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρ‹ Π² дальнСйшСм ΠΎΠ±Ρ€Π°Π±Π°Ρ‚Ρ‹Π²Π°ΡŽΡ‚ΡΡ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠΌ blit Π² Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΈ showText(), выводящСй ΠΈΠ½Ρ„ΠΎΡ€ΠΌΠ°Ρ†ΠΈΠΎΠ½Π½Ρ‹Π΅ надписи ΠΈ Π½Π°Π·Π²Π°Π½ΠΈΠ΅ ΠΈΠ³Ρ€Ρ‹.

Π’Ρ‹Ρ…ΠΎΠ΄ ΠΈΠ· ΠΈΠ³Ρ€Ρ‹ обСспСчиваСт функция stopGame(), Π² ΠΊΠΎΡ‚ΠΎΡ€ΠΎΠΉ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ sys.exit() ΠΈΠ· ΠΈΠΌΠΏΠΎΡ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ³ΠΎ Π² Π½Π°Ρ‡Π°Π»Π΅ ΠΊΠΎΠ΄Π° модуля sys.

Π—Π° Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€ ΠΊ содСрТимому стакана ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ addToCup():

        def addToCup(cup, fig):
	for x in range(fig_w):
            for y in range(fig_h):
        	if figures[fig['shape']][fig['rotation']][y][x] != empty:
            	    cup[x + fig['x']][y + fig['y']] = fig['color']
    

Пока Ρ„ΠΈΠ³ΡƒΡ€Π° двигаСтся, Π΅Π΅ Π±Π»ΠΎΠΊΠΈ Π½Π΅ ΠΏΡ€ΠΈΠ½Π°Π΄Π»Π΅ΠΆΠ°Ρ‚ ΠΊ содСрТимому стакана – Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ происходит послС призСмлСния. Π­Ρ‚ΠΎΡ‚ процСсс ΠΌΡ‹ рассмотрим Ρ‡ΡƒΡ‚ΡŒ Π½ΠΈΠΆΠ΅.

ГСнСрация ΠΈ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½ΠΈΠ΅ стакана

ΠŸΡƒΡΡ‚ΠΎΠΉ стакан создаСтся Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠ΅ΠΉ emptycup():

        def emptycup():
    cup = []
    for i in range(cup_w):
        cup.append([empty] * cup_h)
    return cup

    

ΠŸΡƒΡΡ‚ΠΎΠΉ стакан прСдставляСт собой Π΄Π²ΡƒΠΌΠ΅Ρ€Π½Ρ‹ΠΉ список, Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹ΠΉ символами o. ЗанятыС ячСйки Π² дальнСйшСм ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‚ значСния 0, 1, 2, 3 – Π² соотвСтствии с индСксами Ρ†Π²Π΅Ρ‚ΠΎΠ² Ρ„ΠΈΠ³ΡƒΡ€ Π² ΠΊΠΎΡ€Ρ‚Π΅ΠΆΠ΅ colors. Π’Π°ΠΊ выглядит массив cup послС призСмлСния Π½Π΅ΡΠΊΠΎΠ»ΡŒΠΊΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€:

        ['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 2, 2, 1, 1]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 3, 3, 2, 2, 1, 1]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 3, 2, 2, 'o', 'o', 'o', 1]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 3, 3, 2, 2, 0, 2, 1]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 3, 0, 2, 0, 0, 2, 'o']
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 0, 0, 0, 0, 0, 0, 1, 'o']
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 0, 0, 2, 1, 0, 1, 1]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 2, 2, 1, 1, 1, 'o']
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 1, 0, 0, 0, 0, 0]
['o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 'o', 1, 1, 1, 2, 2, 2, 0, 0]

    
ДопустимоС ΠΈ нСдопустимоС ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² стаканС
ДопустимоС ΠΈ нСдопустимоС ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² стаканС

Ѐункция checkPos() слСдит Π·Π° Ρ‚Π΅ΠΌ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ°Π΄Π°ΡŽΡ‰Π°Ρ Ρ„ΠΈΠ³ΡƒΡ€Π° ΠΎΡΡ‚Π°Π²Π°Π»Π°ΡΡŒ Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ³ΠΎ поля ΠΈ Π½Π΅ Π½Π°ΠΊΠ»Π°Π΄Ρ‹Π²Π°Π»Π°ΡΡŒ Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΠ΅. На ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ слСва Ρ„ΠΈΠ³ΡƒΡ€Π° остаСтся Π² допустимой области, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ справа – ΠΎΡˆΠΈΠ±ΠΎΡ‡Π½ΠΎ накладываСтся Π½Π° ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΡƒΡŽ. Π§Ρ‚ΠΎΠ±Ρ‹ ΠΎΠΏΡ€Π΅Π΄Π΅Π»ΠΈΡ‚ΡŒ ΠΏΠΎΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ Π² стаканС, Π½ΡƒΠΆΠ½ΠΎ ΡΡƒΠΌΠΌΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ собствСнныС ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ со «стаканными»:

БобствСнныС ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ – (2, 1), (3, 1), (2, 2), (2, 3).

Π‘Ρ‚Π°ΠΊΠ°Π½Π½Ρ‹Π΅ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ – (2, 3) Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ слСва ΠΈ (1, 11) Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ справа. Π‘ΡƒΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π΄Π°Π΅Ρ‚ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ Ρ€Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚Ρ‹:

(2+2, 1+3), (3+2, 1+3), (2+2, 2+3), (2+2, 3+3) = (4, 4), (5, 4), (4, 5), (4, 6). Π—Π½Π°Ρ‡ΠΈΡ‚, Ρ„ΠΈΠ³ΡƒΡ€Π° находится Π² ΠΏΡ€Π΅Π΄Π΅Π»Π°Ρ… стакана ΠΈ Π½Π΅ наталкиваСтся Π½ΠΈ Π½Π° ΠΎΠ΄ΠΈΠ½ элСмСнт ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€.

На ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅ слСва ситуация обратная:

(2+1, 2+11), (3+1, 2+11), (2+1, 3+11), (2+1, 4+11) = (3, 13), (4, 13), (3, 14), (3, 15) – Π΄Π²Π΅ послСдниС ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ Π² массивС cup ΡƒΠΆΠ΅ заняты Π±Π»ΠΎΠΊΠ°ΠΌΠΈ ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Ρ„ΠΈΠ³ΡƒΡ€. ИмСнно Ρ‚Π°ΠΊΠΈΠ΅ ситуации ΠΈ ΠΏΡ€Π΅Π΄ΠΎΡ‚Π²Ρ€Π°Ρ‰Π°ΡŽΡ‚ checkPos() вмСстС с incup():

                	if not incup(x + fig['x'] + adjX, y + fig['y'] + adjY):
                    return False
        	if cup[x + fig['x'] + adjX][y + fig['y'] + adjY] != empty:
            	    return False
    

Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… рядов ΠΈ сдвиг Π±Π»ΠΎΠΊΠΎΠ² Π²Π½ΠΈΠ·

Π—Π° ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ΠΈΠ΅ ΠΈ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΠ΅ Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… рядов ΠΎΡ‚Π²Π΅Ρ‡Π°Π΅Ρ‚ функция clearCompleted() вмСстС со Π²ΡΠΏΠΎΠΌΠΎΠ³Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠΉ isCompleted(). Если isCompleted() Π²ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅Ρ‚ True, ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ΅ Π½ΡƒΠΆΠ½ΠΎ ΠΏΠΎΡΠ»Π΅Π΄ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ ΠΏΠ΅Ρ€Π΅ΠΌΠ΅ΡΡ‚ΠΈΡ‚ΡŒ Π²Π½ΠΈΠ· всС ряды, Ρ€Π°ΡΠΏΠΎΠ»Π°Π³Π°ΡŽΡ‰ΠΈΠ΅ΡΡ Π½Π°Π΄ удаляСмым, послС Ρ‡Π΅Π³ΠΎ Π·Π°ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ ряд empty-значСниями ΠΎ:

        
def clearCompleted(cup):
    # Π£Π΄Π°Π»Π΅Π½ΠΈΠ΅ Π·Π°ΠΏΠΎΠ»Π΅Π½Π½Ρ‹Ρ… рядов ΠΈ сдвиг Π²Π΅Ρ€Ρ…Π½ΠΈΡ… рядов Π²Π½ΠΈΠ·
    removed_lines = 0
    y = cup_h - 1 
    while y >= 0:
        if isCompleted(cup, y):
           for pushDownY in range(y, 0, -1):
                for x in range(cup_w):
                    cup[x][pushDownY] = cup[x][pushDownY-1]
           for x in range(cup_w):
                cup[x][0] = empty
           removed_lines += 1
        else:
            y -= 1 
    return removed_lines
    
ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ ряд
ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΡƒΠ΄Π°Π»Π΅Π½Π½Ρ‹ΠΉ ряд

ΠŸΠ΅Ρ€Π΅ΠΌΠ΅Π½Π½Π°Ρ y послС удалСния ΠΎΠ΄Π½ΠΎΠ³ΠΎ ряда ΠΏΡ€ΠΎΠ΄ΠΎΠ»ΠΆΠ°Π΅Ρ‚ ΡƒΠΊΠ°Π·Ρ‹Π²Π°Ρ‚ΡŒ Π½Π° Π΅Π³ΠΎ Π½ΠΎΠΌΠ΅Ρ€ – это Π½ΡƒΠΆΠ½ΠΎ для Ρ‚ΠΎΠ³ΠΎ, Ρ‡Ρ‚ΠΎΠ±Ρ‹ ΠΏΠ΅Ρ€Π΅ΠΉΡ‚ΠΈ ΠΊ ΡƒΠ΄Π°Π»Π΅Π½ΠΈΡŽ Π΄Ρ€ΡƒΠ³ΠΈΡ… Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… рядов, Ссли ΠΎΠ½ΠΈ ΡΠΌΠ΅Ρ‰Π°ΡŽΡ‚ΡΡ Π½Π° мСсто Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‡Ρ‚ΠΎ ΡƒΠ΄Π°Π»Π΅Π½Π½ΠΎΠ³ΠΎ. Π’ случаС Ссли Π΄Ρ€ΡƒΠ³ΠΈΡ… Π·Π°ΠΏΠΎΠ»Π½Π΅Π½Π½Ρ‹Ρ… рядов ΠΏΠΎΠΊΠ° Π½Π΅Ρ‚, происходит ΡƒΠΌΠ΅Π½ΡŒΡˆΠ΅Π½ΠΈΠ΅ Ρƒ.

РисованиС Π±Π»ΠΎΠΊΠΎΠ² Ρ„ΠΈΠ³ΡƒΡ€

КаТдая Ρ„ΠΈΠ³ΡƒΡ€Π° состоит ΠΈΠ· 4 элСмСнтов – Π±Π»ΠΎΠΊΠΎΠ². Π‘Π»ΠΎΠΊΠΈ рисуСт функция drawBlock(), которая ΠΏΠΎΠ»ΡƒΡ‡Π°Π΅Ρ‚ ΠΊΠΎΠΎΡ€Π΄ΠΈΠ½Π°Ρ‚Ρ‹ ΠΈΠ· convertCoords():

        def drawBlock(block_x, block_y, color, pixelx=None, pixely=None):
    #отрисовка ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚Π½Ρ‹Ρ… Π±Π»ΠΎΠΊΠΎΠ², ΠΈΠ· ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Ρ… состоят Ρ„ΠΈΠ³ΡƒΡ€Ρ‹
    if color == empty:
        return
    if pixelx == None and pixely == None:
        pixelx, pixely = convertCoords(block_x, block_y)
    pg.draw.rect(display_surf, colors[color], (pixelx + 1, pixely + 1, block - 1, block - 1), 0, 3)
    pg.draw.rect(display_surf, lightcolors[color], (pixelx + 1, pixely + 1, block - 4, block - 4), 0, 3)
    pg.draw.circle(display_surf, colors[color], (pixelx + block / 2, pixely + block / 2), 5)
    
    

Для рисования Π±Π»ΠΎΠΊΠΎΠ² ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ ΠΏΡ€ΠΈΠΌΠΈΡ‚ΠΈΠ²Ρ‹ rect (ΠΏΡ€ΡΠΌΠΎΡƒΠ³ΠΎΠ»ΡŒΠ½ΠΈΠΊ) ΠΈ circle (ΠΊΡ€ΡƒΠ³). ΠŸΡ€ΠΈ ΠΆΠ΅Π»Π°Π½ΠΈΠΈ Π²Π΅Ρ€Ρ…Π½ΠΈΠΉ ΠΊΠ²Π°Π΄Ρ€Π°Ρ‚ ΠΌΠΎΠΆΠ½ΠΎ ΠΊΠΎΠ½Π²Π΅Ρ€Ρ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ Π² ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ (Surface), послС Ρ‡Π΅Π³ΠΎ Π½Π°Π»ΠΎΠΆΠΈΡ‚ΡŒ Π½Π° эту ΠΏΠΎΠ²Π΅Ρ€Ρ…Π½ΠΎΡΡ‚ΡŒ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅ ΠΈΠ»ΠΈ тСкстовый символ. Ѐункция drawBlock() Ρ‚Π°ΠΊΠΆΠ΅ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ Π² drawnextFig() для Π²Ρ‹Π²ΠΎΠ΄Π° ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΉ Ρ„ΠΈΠ³ΡƒΡ€Ρ‹ справа ΠΎΡ‚ ΠΈΠ³Ρ€ΠΎΠ²ΠΎΠ³ΠΎ поля.

Π—Π°ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅

НапоминаСм, Ρ‡Ρ‚ΠΎ ΠΏΠΎΠ»Π½Ρ‹ΠΉ ΠΊΠΎΠ΄ ΠΈΠ³Ρ€Ρ‹ ΠΌΠΎΠΆΠ½ΠΎ ΡΠΊΠ°Ρ‡Π°Ρ‚ΡŒ здСсь. Π­Ρ‚ΠΎ ΠΏΠΎΠ»Π½ΠΎΡΡ‚ΡŒΡŽ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΎΠ½Π°Π»ΡŒΠ½Ρ‹ΠΉ ВСтрис с простым интСрфСйсом. Pygame прСдоставляСт Π½Π΅ΠΌΠ°Π»ΠΎ Π΄ΠΎΠΏΠΎΠ»Π½ΠΈΡ‚Π΅Π»ΡŒΠ½Ρ‹Ρ… возмоТностСй для дополнСния ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΡ‹: ΠΊ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Ρƒ, Π² ΠΈΠ³Ρ€Ρƒ ΠΌΠΎΠΆΠ½ΠΎ Π΄ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ Π·Π²ΡƒΠΊΠΎΠ²Ρ‹Π΅ эффСкты, Π΄ΠΈΠ°Π»ΠΎΠ³ΠΎΠ²ΠΎΠ΅ ΠΎΠΊΠ½ΠΎ для закрытия, Ρ„ΠΎΠ½ΠΎΠ²ΠΎΠ΅ ΠΈΠ·ΠΎΠ±Ρ€Π°ΠΆΠ΅Π½ΠΈΠ΅, запись Ρ€Π΅ΠΊΠΎΡ€Π΄ΠΎΠ² Π² Ρ„Π°ΠΉΠ». Если ΠΊΠ°ΠΊΠΈΠ΅-Ρ‚ΠΎ ΠΌΠΎΠΌΠ΅Π½Ρ‚Ρ‹ ΠΎΡΡ‚Π°Π»ΠΈΡΡŒ нСясными – Π·Π°Π΄Π°Π²Π°ΠΉΡ‚Π΅ вопросы Π² коммСнтариях.

ΠœΠ°Ρ‚Π΅Ρ€ΠΈΠ°Π»Ρ‹ ΠΏΠΎ Ρ‚Π΅ΠΌΠ΅


ΠœΠ•Π ΠžΠŸΠ Π˜Π―Π’Π˜Π―

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ

Π’ΠΠšΠΠΠ‘Π˜Π˜

Π”ΠΎΠ±Π°Π²ΠΈΡ‚ΡŒ вакансию
Аналитик Π΄Π°Π½Π½Ρ‹Ρ…
Π•ΠΊΠ°Ρ‚Π΅Ρ€ΠΈΠ½Π±ΡƒΡ€Π³, ΠΏΠΎ ΠΈΡ‚ΠΎΠ³Π°ΠΌ собСсСдования

Π›Π£Π§Π¨Π˜Π• БВАВЬИ ПО Π’Π•ΠœΠ•