Загрузить файлы в «micropython»
This commit is contained in:
parent
df2485dc51
commit
0a2c4044d6
102
micropython/game_01.py
Normal file
102
micropython/game_01.py
Normal file
@ -0,0 +1,102 @@
|
||||
# Импортировать стандартные модули, используемые в этой игре
|
||||
# Модуль экрана не импортируется, потому что он передается как объект в вызываемую функцию
|
||||
from time import sleep
|
||||
from random import randint
|
||||
from machine import Pin
|
||||
|
||||
# Функция, которая возвращает название вашей игры
|
||||
def get_game_name():
|
||||
game_name = "2P Pong"
|
||||
return game_name
|
||||
|
||||
# Основная функция игры, которая вызывается в главном меню тетриса
|
||||
def game_loop(oled, led_user_1, led_user_2):
|
||||
|
||||
# Определить пины кнопок, которые будут использоваться в этой игре и обрабатываться на втором ядра
|
||||
up = Pin(15, Pin.IN, Pin.PULL_UP)
|
||||
down = Pin(27, Pin.IN, Pin.PULL_UP)
|
||||
action_a = Pin(5, Pin.IN, Pin.PULL_UP)
|
||||
action_b = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
|
||||
# Игровой цикл, который выполняется бесконечно, пока не будет вызвано условие сброса
|
||||
while (True):
|
||||
|
||||
# Хардкодированные значения начальных позиций ракетки
|
||||
paddle_1_coord = 27
|
||||
paddle_2_coord = 27
|
||||
|
||||
# Хардкодированные значения начальной позиции и скорости "мяча"
|
||||
x_coord = 62
|
||||
y_coord = 30
|
||||
x_speed = 2
|
||||
y_speed = 1
|
||||
|
||||
# Случайным образом назначить направление мяча в начале игры
|
||||
if (randint(0, 1) == 0):
|
||||
x_speed = x_speed * -1
|
||||
if (randint(0, 1) == 0):
|
||||
y_speed = y_speed * -1
|
||||
|
||||
# Установить в false, когда мяч покидает игровое поле
|
||||
game_continue_condition = True
|
||||
|
||||
# Хранит номер игрока, который победил
|
||||
winner = 0
|
||||
|
||||
# Продолжать игру, пока мяч находится на игровом поле
|
||||
while (game_continue_condition):
|
||||
|
||||
# Нарисовать ракетки и мяч в соответствии с их координатами
|
||||
oled.fill(0)
|
||||
oled.fill_rect(x_coord, y_coord, 4, 4, 1)
|
||||
oled.fill_rect(0, paddle_1_coord, 4, 10, 1)
|
||||
oled.fill_rect(124, paddle_2_coord, 4, 10, 1)
|
||||
oled.show()
|
||||
|
||||
# Изменить координаты мяча на значение скорости
|
||||
x_coord = x_coord + x_speed
|
||||
y_coord = y_coord + y_speed
|
||||
|
||||
# Инвертировать значение скорости мяча при столкновении с ракеткой, чтобы он отразился
|
||||
if ((x_coord > 120) and (y_coord + 2 >= paddle_2_coord) and (y_coord + 2 <= paddle_2_coord + 10)):
|
||||
x_speed = x_speed * -1
|
||||
if ((x_coord < 8) and (y_coord + 2 >= paddle_1_coord) and (y_coord + 2 <= paddle_1_coord + 10)):
|
||||
x_speed = x_speed * -1
|
||||
|
||||
# Инвертировать значение скорости мяча при столкновении с потолком и полом, чтобы он отразился
|
||||
if (y_coord > 58):
|
||||
y_speed = y_speed * -1
|
||||
if (y_coord < 1):
|
||||
y_speed = y_speed * -1
|
||||
|
||||
# Если мяч проходит мимо ракетки, завершить игру и назначить соответствующего победителя
|
||||
if (x_coord > 130):
|
||||
game_continue_condition = False
|
||||
winner = 1
|
||||
if (x_coord < -6):
|
||||
game_continue_condition = False
|
||||
winner = 2
|
||||
|
||||
# Изменить координаты ракеток, пока кнопки удерживаются
|
||||
if (up.value() == 0):
|
||||
if (paddle_2_coord >= 1):
|
||||
paddle_2_coord = paddle_2_coord - 2
|
||||
if (down.value() == 0):
|
||||
if (paddle_2_coord <= 53):
|
||||
paddle_2_coord = paddle_2_coord + 2
|
||||
if (action_a.value() == 0):
|
||||
if (paddle_1_coord >= 1):
|
||||
paddle_1_coord = paddle_1_coord - 2
|
||||
if (action_b.value() == 0):
|
||||
if (paddle_1_coord <= 53):
|
||||
paddle_1_coord = paddle_1_coord + 2
|
||||
|
||||
# Очистить экран и нарисовать таблички с плашки победителей, пока не вернемся к началу игры и не перезапустится код игры
|
||||
oled.fill(0)
|
||||
if (winner == 1):
|
||||
oled.text("PLAYER 1", 32, 24, 1)
|
||||
if (winner == 2):
|
||||
oled.text("PLAYER 2", 32, 24, 1)
|
||||
oled.text("WON", 52, 33, 1)
|
||||
oled.show()
|
||||
sleep(1)
|
||||
69
micropython/game_02.py
Normal file
69
micropython/game_02.py
Normal file
@ -0,0 +1,69 @@
|
||||
# Импортировать стандартные модули, используемые в этой игре
|
||||
# Модуль экрана не импортируется, потому что он передается как объект в вызываемую функцию
|
||||
from time import sleep
|
||||
from random import randrange
|
||||
from machine import Pin
|
||||
|
||||
# Функция, которая возвращает название вашей игры
|
||||
def get_game_name():
|
||||
game_name = "Button Cowboys"
|
||||
return game_name
|
||||
|
||||
# Основная функция игры, которая вызывается в главном меню тетриса
|
||||
def game_loop(oled, led_user_1, led_user_2):
|
||||
|
||||
# Определить пины кнопок, которые будут использоваться в этой игре и обрабатываться на первом ядре
|
||||
down = Pin(27, Pin.IN, Pin.PULL_UP)
|
||||
action_b = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
|
||||
# Игровой цикл, который выполняется бесконечно, пока не будет вызвано условие сброса из второго ядра
|
||||
while(True):
|
||||
|
||||
# Очистить экран и установить переменную для цикла while
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
go_on = True
|
||||
|
||||
# Нарисовать инструкции для игры и подождать 3 секунды
|
||||
oled.text("PL1 - B", 0, 0, 1)
|
||||
oled.text("PL2 - DOWN", 0, 10, 1)
|
||||
oled.line(0, 19, 127, 19, 1)
|
||||
oled.text("first one to", 0, 21, 1)
|
||||
oled.text("press button", 0, 30, 1)
|
||||
oled.text("after 'GO' wins", 0, 39, 1)
|
||||
oled.show()
|
||||
sleep(3)
|
||||
|
||||
# Очистить экран и подождать случайное время перед противостоянием
|
||||
oled.fill(0)
|
||||
oled.text("get ready...", 16, 29, 1)
|
||||
oled.show()
|
||||
sleep(randrange(3, 15, 1))
|
||||
|
||||
# "Высокий полдень" и запомнить состояние кнопки, чтобы человек, удерживающий кнопку, не выигрывал автоматически
|
||||
oled.fill(1)
|
||||
oled.text("GO", 56, 29, 0)
|
||||
previous_down_state = down.value()
|
||||
previous_b_state = action_b.value()
|
||||
oled.show()
|
||||
|
||||
# Проверить изменение состояния кнопки, выйти из цикла while и назначить победителя соответствующим образом
|
||||
while (go_on):
|
||||
if (previous_b_state != action_b.value()):
|
||||
led_user_2.value(1)
|
||||
oled.fill(0)
|
||||
oled.text("PLAYER 1 WINS", 12, 29, 1)
|
||||
go_on = False
|
||||
if (previous_down_state != down.value()):
|
||||
led_user_1.value(1)
|
||||
oled.fill(0)
|
||||
oled.text("PLAYER 2 WINS", 12, 29, 1)
|
||||
go_on = False
|
||||
|
||||
# Показать имя победившего игрока и выключить светодиоды перед перезапуском игры
|
||||
oled.show()
|
||||
sleep(3)
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
led_user_1.value(0)
|
||||
led_user_2.value(0)
|
||||
14
micropython/game_03.py
Normal file
14
micropython/game_03.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Функция, которая возвращает название вашей игры
|
||||
def get_game_name():
|
||||
game_name = "Flashlight"
|
||||
return game_name
|
||||
|
||||
# Основная функция игры, которая вызывается в главном меню тетриса
|
||||
def game_loop(oled, rgb):
|
||||
|
||||
# Очистить экран и бесконечно отправлять команду для включения белого цвета на RGB-светодиоде
|
||||
while(True):
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
rgb[0] = (255, 255, 255)
|
||||
rgb.write()
|
||||
13
micropython/game_04.py
Normal file
13
micropython/game_04.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Функция, которая возвращает название вашей игры
|
||||
def get_game_name():
|
||||
game_name = "Your Game"
|
||||
return game_name
|
||||
|
||||
# Основная функция игры, которая вызывается в главном меню тетриса
|
||||
def game_loop(oled):
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
|
||||
# Бесконечный цикл, внутри этого цикла нужно написать свою игру
|
||||
while (True):
|
||||
pass
|
||||
335
micropython/main.py
Normal file
335
micropython/main.py
Normal file
@ -0,0 +1,335 @@
|
||||
# Импорт стандартных библиотек
|
||||
from machine import Pin
|
||||
from machine import PWM
|
||||
from machine import I2C
|
||||
from time import sleep
|
||||
from time import ticks_ms
|
||||
from neopixel import NeoPixel
|
||||
from random import randrange
|
||||
import _thread
|
||||
|
||||
# Импорт библиотеки для "OLED" дисплея
|
||||
from ssd1306 import SSD1306_I2C
|
||||
|
||||
# Импорт пользовательских игровых файлов
|
||||
import game_01
|
||||
import game_02
|
||||
import game_03
|
||||
import game_04
|
||||
|
||||
# Блокировки памяти должны использоваться, когда используются два ядра и они работают с одной и той же памятью
|
||||
# Однако далее я не буду их использовать
|
||||
lock = _thread.allocate_lock()
|
||||
|
||||
# Определения объектов кнопок (input)
|
||||
# Плюс глобальные переменные, которые хранят инверсированные значения состояний кнопок
|
||||
# Эти переменные избыточны, просто более удобный способ чтения состояний кнопок
|
||||
up = Pin(15, Pin.IN, Pin.PULL_UP)
|
||||
is_up = False
|
||||
down = Pin(27, Pin.IN, Pin.PULL_UP)
|
||||
is_down = False
|
||||
right = Pin(28, Pin.IN, Pin.PULL_UP)
|
||||
is_right = False
|
||||
left = Pin(26, Pin.IN, Pin.PULL_UP)
|
||||
is_left = False
|
||||
action_a = Pin(5, Pin.IN, Pin.PULL_UP)
|
||||
is_a = False
|
||||
action_b = Pin(4, Pin.IN, Pin.PULL_UP)
|
||||
is_b = False
|
||||
mute = Pin(1, Pin.IN, Pin.PULL_UP)
|
||||
is_mute = False
|
||||
main_menu = Pin(7, Pin.IN, Pin.PULL_UP)
|
||||
is_menu = False
|
||||
|
||||
# Определения объектов светодиодов (output)
|
||||
led_mute = Pin(0, Pin.OUT)
|
||||
led_user_1 = Pin(14, Pin.OUT)
|
||||
led_user_2 = Pin(6, Pin.OUT)
|
||||
|
||||
# Определения объекта АЦП
|
||||
# Считывание фактического напряжения батареи не работает должным образом с текущей схемой
|
||||
# Во время разряда батареи напряжение, считываемое АЦП, сначала падает, а затем начинает расти, вызывая проблемы
|
||||
batt_voltage = machine.ADC(29)
|
||||
read_voltage = 0
|
||||
|
||||
# Определения объектов I2C и дисплея
|
||||
i2c = I2C(1, sda = Pin(2), scl = Pin(3), freq = 400000)
|
||||
oled = SSD1306_I2C(128, 64, i2c)
|
||||
|
||||
# Определения объектов пищалки (PWM)
|
||||
buzzer = PWM(8, freq = 440, duty_u16 = 0)
|
||||
buzzer_is_on = True
|
||||
|
||||
# Определения объектов NeoPixel
|
||||
rgb_led = Pin(16, Pin.OUT)
|
||||
rgb = NeoPixel(rgb_led, 1)
|
||||
color_components = [0, 0, 0]
|
||||
|
||||
# Последовательность звуков для экрана загрузки
|
||||
# Выполняется на втором ядре, поэтому используются "sleep"
|
||||
def loading_screen_tune():
|
||||
#C4 нота
|
||||
buzzer.freq(262)
|
||||
buzzer.duty_u16(32768)
|
||||
sleep(0.2)
|
||||
buzzer.duty_u16(0)
|
||||
sleep(0.1)
|
||||
#D4 нота
|
||||
buzzer.freq(294)
|
||||
buzzer.duty_u16(32768)
|
||||
sleep(0.2)
|
||||
buzzer.duty_u16(0)
|
||||
sleep(0.1)
|
||||
#E4 нота
|
||||
buzzer.freq(330)
|
||||
buzzer.duty_u16(32768)
|
||||
sleep(0.2)
|
||||
buzzer.duty_u16(0)
|
||||
sleep(0.1)
|
||||
|
||||
|
||||
# АБСОЛЮТНО (не)ОБХОДИМЫЙ ЭКРАН ЗАГРУЗКИ
|
||||
def loading_screen(oled, rgb, led_user_1, led_user_2, buzzer):
|
||||
|
||||
# Очистить экран и выключить светодиоды и зуммер на всякий случай
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
rgb[0] = (0, 0, 0)
|
||||
rgb.write()
|
||||
led_user_1.value(0)
|
||||
led_user_2.value(0)
|
||||
buzzer.duty_u16(0)
|
||||
|
||||
# Эта функция запускает код на втором ядре
|
||||
# В этом случае этот код просто воспроизводит короткую мелодию из трёх нот
|
||||
_thread.start_new_thread(loading_screen_tune, ())
|
||||
|
||||
# Этот массив содержит слова, которые будут отображаться по порядку в процессе загрузки
|
||||
words_to_show = ["TETRIS", "by", "SHKLJ"]
|
||||
|
||||
# Итерация по ранее упомянутому массиву и отображение содержимого в центре экрана, каждое на новой строке
|
||||
# Именно здесь я отказываюсь от парадигмы обобщённого программирования и просто грубой силой рисую пиксели на экране
|
||||
for i in range(len(words_to_show)):
|
||||
oled.text(words_to_show[i], 64 - (len(words_to_show[i]) * 4), (i * 9) + 1, 1)
|
||||
oled.show()
|
||||
sleep(0.3)
|
||||
|
||||
# Нарисовать ограничивающий прямоугольник для индикатора прогресса
|
||||
oled.line(10, 55, 117, 55, 1)
|
||||
oled.line(10, 60, 117, 60, 1)
|
||||
oled.line(10, 55, 10, 60, 1)
|
||||
oled.line(117, 55, 117, 60, 1)
|
||||
oled.show()
|
||||
|
||||
# Заполнение шкалы загрузки
|
||||
for i in range(12, 116):
|
||||
oled.fill_rect(i, 57, 1, 2, 1)
|
||||
oled.show()
|
||||
|
||||
# Закрасить экран белым
|
||||
oled.fill(1)
|
||||
oled.show()
|
||||
sleep(0.2)
|
||||
oled.fill(0)
|
||||
oled.show()
|
||||
|
||||
# Вызов и выполнение абсолютно (не)обходимого экрана загрузки
|
||||
# Если вы хотите отключить "экран загрузки", просто закомментируйте эту строку
|
||||
loading_screen(oled, rgb, led_user_1, led_user_2, buzzer)
|
||||
|
||||
# Код второго ядра
|
||||
# Этот код не является строго необходимым, но отвечает за поведение кнопки отключения звука и кнопки сброса
|
||||
# На самом RP2040-Zero уже есть кнопка сброса, фактически нет необходимости во второй кнопке, её можно перепрофилировать, как и кнопку отключения звука
|
||||
# Ещё одна причина отказаться от второго ядра и использовать его для других задач — это то, что при каждой итерации оно отключает зуммер, если кнопка не нажата
|
||||
# Это делает невозможным воспроизведение звуков на другом ядре
|
||||
# Но если удалить этот код, то кнопки на главном меню перестанут работать
|
||||
def second_core(up, right, left, down, action_a, action_b, mute, main_menu, buzzer):
|
||||
|
||||
# Определение глобальных переменных, которые будут использоваться в главном меню
|
||||
# Глобальные переменные в целом плохая идея в программировании
|
||||
# Особенно в многозадачных системах, таких как эта, из-за проблем с доступом к памяти
|
||||
global is_up
|
||||
global is_down
|
||||
global is_left
|
||||
global is_right
|
||||
global is_a
|
||||
global is_b
|
||||
global is_mute
|
||||
global is_menu
|
||||
global buzzer_is_on
|
||||
|
||||
# Эта переменная необходима для обнаружения возрастующего фронта нажатия кнопки, чтобы срабатывать один раз, а не всё время
|
||||
previous_mute_state = 0
|
||||
|
||||
while(True):
|
||||
|
||||
# Глупая часть кода, которая просто инвертирует состояние переменной кнопки и сохраняет в другую переменную
|
||||
# Снова, если удалить, нарушится работа главного меню, кнопки отключения звука и пользовательской кнопки сброса
|
||||
# Инвертирование могло бы быть выполнено на уровне железа, подтягивая входные пины и подключив кнопки к 3.3V
|
||||
if (up.value() == False):
|
||||
is_up = 1
|
||||
else:
|
||||
is_up = 0
|
||||
if (down.value() == False):
|
||||
is_down = 1
|
||||
else:
|
||||
is_down = 0
|
||||
if (right.value() == False):
|
||||
is_right = 1
|
||||
else:
|
||||
is_right = 0
|
||||
if (left.value() == False):
|
||||
is_left = 1
|
||||
else:
|
||||
is_left = 0
|
||||
if (action_a.value() == False):
|
||||
is_a = 1
|
||||
else:
|
||||
is_a = 0
|
||||
if (action_b.value() == False):
|
||||
is_b = 1
|
||||
else:
|
||||
is_b = 0
|
||||
if (mute.value() == False):
|
||||
is_mute = 1
|
||||
else:
|
||||
is_mute = 0
|
||||
if (main_menu.value() == False):
|
||||
is_menu = 1
|
||||
else:
|
||||
is_menu = 0
|
||||
|
||||
# Поведение кнопки отключения звука для возрастающего фронта сиграла с нажатия кнопки
|
||||
if (previous_mute_state != is_mute):
|
||||
if (is_mute == True):
|
||||
if (led_mute.value() == 0):
|
||||
led_mute.value(1)
|
||||
buzzer_is_on = False
|
||||
else:
|
||||
led_mute.value(0)
|
||||
buzzer_is_on = True
|
||||
previous_mute_state = is_mute
|
||||
|
||||
# Этот код отвечает за воспроизведение звуков при нажатии кнопок
|
||||
# Он также отключает все звуки, когда кнопки не нажаты
|
||||
# Это делает невозможным воспроизведение звуков на других ядрах, когда этот код активен
|
||||
if (buzzer_is_on == False):
|
||||
buzzer.duty_u16(0)
|
||||
else:
|
||||
if (is_up):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(330)
|
||||
elif (is_left):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(349)
|
||||
elif (is_right):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(440)
|
||||
elif (is_down):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(494)
|
||||
elif (is_a):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(523)
|
||||
elif (is_b):
|
||||
buzzer.duty_u16(32768)
|
||||
buzzer.freq(659)
|
||||
else:
|
||||
buzzer.duty_u16(0)
|
||||
|
||||
# Этот код перезагружает МК, когда нажата кнопка "main menu"
|
||||
# Поскольку к кнопкам не подключены параллельные конденсаторы, иногда игра зависает из-за дребезга контактов
|
||||
# Как уже упоминалось, эту кнопку лучше перепрофилировать для другой функции
|
||||
# В качестве альтернативы можно реализовать программный таймер для сброса тетриса после длительного нажатия вместо конденсаторов
|
||||
if (is_menu):
|
||||
machine.reset()
|
||||
|
||||
# Запустить код "second_core" на втором ядре
|
||||
# Второе ядро не может выполнять два потока одновременно, но к этому времени "loading_screen_tune" уже завершён
|
||||
# Будьте осторожны при изменении временных интервалов последовательности экрана загрузки, так как это может привести к зависанию игры
|
||||
_thread.start_new_thread(second_core, (up, right, left, down, action_a, action_b, mute, main_menu, buzzer))
|
||||
|
||||
# Считывает напряжение батареи один раз при запуске игры и сохраняет в переменную
|
||||
read_voltage = batt_voltage.read_u16()
|
||||
|
||||
# Переменные, необходимые для срабатывания на возрастающий фронт нажатия кнопки в главном меню
|
||||
previous_up_state = 0
|
||||
previous_right_state = 0
|
||||
previous_left_state = 0
|
||||
previous_down_state = 0
|
||||
previous_a_state = 0
|
||||
previous_b_state = 0
|
||||
|
||||
# Начать главное меню с первым выделенным элементом
|
||||
list_hightlight = 1
|
||||
|
||||
while (True):
|
||||
|
||||
# Нарисовать "main menu" и уровень батареи в верхней и нижней части экрана
|
||||
oled.show()
|
||||
oled.fill(0)
|
||||
oled.text("Main Menu", 28, 0, 1)
|
||||
oled.line(0, 8, 127, 8, 1)
|
||||
oled.line(0, 54, 127, 54 ,1)
|
||||
oled.text("Battery:", 0, 56, 1)
|
||||
if (read_voltage > 59000):
|
||||
oled.text("FULL", 64, 56, 1)
|
||||
elif (read_voltage > 10000 and read_voltage <= 59000):
|
||||
oled.text("NOFULL", 64, 56, 1)
|
||||
elif (read_voltage <= 10000):
|
||||
oled.text("NO", 64, 56, 1)
|
||||
|
||||
# Обрабатывать нажатия кнопок для перемещения выделения вверх и вниз с помощью кнопок направления
|
||||
if (previous_up_state != is_up):
|
||||
if (is_up == True):
|
||||
if (list_hightlight == 1):
|
||||
list_hightlight = 4
|
||||
else:
|
||||
list_hightlight = list_hightlight - 1
|
||||
previous_up_state = is_up
|
||||
if (previous_right_state != is_right):
|
||||
if (is_right == True):
|
||||
if (list_hightlight == 4):
|
||||
list_hightlight = 1
|
||||
else:
|
||||
list_hightlight = list_hightlight + 1
|
||||
previous_right_state = is_right
|
||||
if (previous_left_state != is_left):
|
||||
if (is_left == True):
|
||||
if (list_hightlight == 1):
|
||||
list_hightlight = 4
|
||||
else:
|
||||
list_hightlight = list_hightlight - 1
|
||||
previous_left_state = is_left
|
||||
if (previous_down_state != is_down):
|
||||
if (is_down == True):
|
||||
if (list_hightlight == 4):
|
||||
list_hightlight = 1
|
||||
else:
|
||||
list_hightlight = list_hightlight + 1
|
||||
previous_down_state = is_down
|
||||
|
||||
# Запустить функцию игры после нажатия кнопки действия в зависимости от того, какой элемент был выделен
|
||||
if ((previous_a_state != is_a) or (previous_b_state != is_b)):
|
||||
if ((is_a == True) or (is_b == True)):
|
||||
if (list_hightlight == 1):
|
||||
game_01.game_loop(oled, led_user_1, led_user_2)
|
||||
elif (list_hightlight == 2):
|
||||
game_02.game_loop(oled, led_user_1, led_user_2)
|
||||
elif (list_hightlight == 3):
|
||||
game_03.game_loop(oled, rgb)
|
||||
elif (list_hightlight == 4):
|
||||
game_04.game_loop(oled)
|
||||
previous_a_state = is_a
|
||||
previous_b_state = is_b
|
||||
|
||||
# Нарисовать белый прямоугольник в позиции, соответствующей выделенной игре
|
||||
oled.fill_rect(0, list_hightlight * 11 - 1, 127, 10, 1)
|
||||
|
||||
# Нарисовать названия игр белым цветом, за исключением выделенной игры
|
||||
# Всё ещё не уверен, как это работает, но это работает
|
||||
oled.text(game_01.get_game_name(), 0, 11, list_hightlight - 1)
|
||||
oled.text(game_02.get_game_name(), 0, 22, list_hightlight - 2)
|
||||
oled.text(game_03.get_game_name(), 0, 33, list_hightlight - 3)
|
||||
oled.text(game_04.get_game_name(), 0, 44, list_hightlight - 4)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user