Какой код надо дописать для этой игры?
Как сделать таймер(Изначальное время 5 секунд, когда он дойдёт до нуля счёт сбрасывается, кроме рекорда, а при нажатии на правильную кнопку время восстанавливается), рандом чисел(При нажатии на правильную кнопку время восстанавливается и добавляет 1 очко к счету а также к рекорду, если он побит. А при неправильной счёт сбрасывается) рекорд для игры(Когда счет больше рекорда то он(рекорд) перезаписывается и сохраняется после выхода из игры) ссылка на сайт(в углу будет значок, если на него нажать то откроется сайт) и как сделать эту игру доступным для android(.apk) на питон? Сам код игры:
from tkinter import * import random as rn root = Tk() root.title('Мой первый графический интерфейс') root.geometry('720x1280') clicks = 0 def click_button(): global clicks clicks += 1 labelClick['text'] = str(clicks) labelClick.pack() count = rn.randrange(1,10,1) print(count) count = str(count) if count == '1': bgcolor='blue' if count == '2': bgcolor='green' if count == '3': bgcolor='red' if count == '4': bgcolor='yellow' if count == '5': bgcolor='orange' if count == '6': bgcolor='brown' if count == '7': bgcolor='violet' if count == '8': bgcolor='grey' if count == '9': bgcolor='pink' #bgcolor='blue' but_0 = Button(text=count, width=3, height=1, bg= bgcolor, font='Hack 30', command=click_button) print(bgcolor) but_0.place(x=310, y=140) labelClick = Label(root, text=clicks) labelClick.pack() but_1 = Button(text='1', width=3, height=1, bg='blue', font='Hack 30', command=click_button) but_2 = Button(text='2', width=3, height=1, bg='green', font='Hack 30', command=click_button) but_3 = Button(text='3', width=3, height=1, bg='red', font='Hack 30', command=click_button) but_4 = Button(text='4', width=3, height=1, bg='yellow', font='Hack 30', command=click_button) but_5 = Button(text='5', width=3, height=1, bg='orange', font='Hack 30', command=click_button) but_6 = Button(text='6', width=3, height=1, bg='brown', font='Hack 30', command=click_button) but_7 = Button(text='7', width=3, height=1, bg='violet', font='Hack 30', command=click_button) but_8 = Button(text='8', width=3, height=1, bg='grey', font='Hack 30', command=click_button) but_9 = Button(text='9', width=3, height=1, bg='pink', font='Hack 30', command=click_button) but_1.place(x=210, y=240) but_2.place(x=310, y=240) but_3.place(x=410, y=240) but_4.place(x=210, y=340) but_5.place(x=310, y=340) but_6.place(x=410, y=340) but_7.place(x=210, y=440) but_8.place(x=310, y=440) but_9.place(x=410, y=440) root.mainloop()
Пин-понг на Python
Продолжая наш цикл аркадных игр на Python, напишем свою реализацю игры Пин-Понг на Python с использованием библиотеки tkinter.
- Создание игрового поля.
- Движение мячика.
- Управление ракетками.
- Реализация отскоков.
- Подсчет отчков и респаун мячика.
Создание игрового поля.
Начнем с установки игрового поля. Зададим родительское окно, область для отрисовки анимации и основные элементы игрового поля.
Обратите внимание на создание глобальных переменных в начале скрипта. Они нам пригодятся для того, чтобы нам было легче настраивать нашу игру. Если у нас ширина 900 пикселей, то проще создать переменную WIDTH, присвоить ей значение 900 и использовать ее имя в тексте программы, чем вручную каждый раз переписывать 900. Вы ощутите пользу от этого, когда захотите изменить ширину окна, и сможете сделать это просто изменив значение этой переменной:
from tkinter import * # глобальные переменные # настройки окна WIDTH = 900 HEIGHT = 300 # настройки ракеток # ширина ракетки PAD_W = 10 # высота ракетки PAD_H = 100 # настройки мяча # радиус мяча BALL_RADIUS = 30 # устанавливаем окно root = Tk() root.title("PythonicWay Pong") # область анимации c = Canvas(root, width=WIDTH, height=HEIGHT, background="#003300") c.pack() # элементы игрового поля # левая линия c.create_line(PAD_W, 0, PAD_W, HEIGHT, fill="white") # правая линия c.create_line(WIDTH-PAD_W, 0, WIDTH-PAD_W, HEIGHT, fill="white") # центральная линия c.create_line(WIDTH/2, 0, WIDTH/2, HEIGHT, fill="white") # установка игровых объектов # создаем мяч BALL = c.create_oval(WIDTH/2-BALL_RADIUS/2, HEIGHT/2-BALL_RADIUS/2, WIDTH/2+BALL_RADIUS/2, HEIGHT/2+BALL_RADIUS/2, fill="white") # левая ракетка LEFT_PAD = c.create_line(PAD_W/2, 0, PAD_W/2, PAD_H, width=PAD_W, fill="yellow") # правая ракетка RIGHT_PAD = c.create_line(WIDTH-PAD_W/2, 0, WIDTH-PAD_W/2, PAD_H, width=PAD_W, fill="yellow") # запускаем работу окна root.mainloop()
Должно получиться примерно следующее:
Заставляем мячик двигаться.
Создадим функцию move_ball в которой пропишем код движения мяча. После этого создадим функцию main в которой будем вызывать move_ball и рекурсивно саму себя через root.after
# добавим глобальные переменные для скорости движения мяча # по горизонтали BALL_X_CHANGE = 20 # по вертикали BALL_Y_CHANGE = 0 def move_ball(): c.move(BALL, BALL_X_CHANGE, BALL_Y_CHANGE) def main(): move_ball() # вызываем саму себя каждые 30 миллисекунд root.after(30, main) # запускаем движение main()
Если вы все правильно добавили, то при запуске скрипта мяч летит в правую сторону. Вы можете изменить скорость и направление движения по горизонтали, изменяя значение BALL_X_CHANGE.
Задаем управление движением ракеток.
Логика движения ракеток будет следующая. Задается скорость ракетки — изначально она равна нулю, то есть ракетка стоит на месте. Как только пользователь нажимает клавишу — скорость изменяется, и ракетка едет вверх либо вниз. Когда игрок отпускает клавишу скорость ракетки опять становится равна нулю.
# зададим глобальные переменные скорости движения ракеток # скорось с которой будут ездить ракетки PAD_SPEED = 20 # скорость левой платформы LEFT_PAD_SPEED = 0 # скорость правой ракетки RIGHT_PAD_SPEED = 0 # функция движения обеих ракеток def move_pads(): # для удобства создадим словарь, где ракетке соответствует ее скорость PADS = # перебираем ракетки for pad in PADS: # двигаем ракетку с заданной скоростью c.move(pad, 0, PADS[pad]) # если ракетка вылезает за игровое поле возвращаем ее на место if c.coords(pad)[1] < 0: c.move(pad, 0, -c.coords(pad)[1]) elif c.coords(pad)[3] >HEIGHT: c.move(pad, 0, HEIGHT - c.coords(pad)[3]) # Вставляем созданную функцию в main def main(): move_ball() move_pads() root.after(30, main) # Установим фокус на Canvas чтобы он реагировал на нажатия клавиш c.focus_set() # Напишем функцию обработки нажатия клавиш def movement_handler(event): global LEFT_PAD_SPEED, RIGHT_PAD_SPEED if event.keysym == "w": LEFT_PAD_SPEED = -PAD_SPEED elif event.keysym == "s": LEFT_PAD_SPEED = PAD_SPEED elif event.keysym == "Up": RIGHT_PAD_SPEED = -PAD_SPEED elif event.keysym == "Down": RIGHT_PAD_SPEED = PAD_SPEED # Привяжем к Canvas эту функцию c.bind("", movement_handler) # Создадим функцию реагирования на отпускание клавиши def stop_pad(event): global LEFT_PAD_SPEED, RIGHT_PAD_SPEED if event.keysym in "ws": LEFT_PAD_SPEED = 0 elif event.keysym in ("Up", "Down"): RIGHT_PAD_SPEED = 0 # Привяжем к Canvas эту функцию c.bind("", stop_pad)
Теперь мы можем управлять обеими ракетками.
Отскок мячика от стенок и «ракеток».
Отскок реализуется достаточно просто: при соприкосновении со стенкой или «ракеткой» мы будем изменять значение переменных движения мяча на противоположные. Ради интереса при ударе о ракетку будет увеличиваться горизонтальная скорость мячика и случайным образом изменяться вертикальная.
# импортируем библиотеку random import random # Добавляем глобальные переменные # Насколько будет увеличиваться скорость мяча с каждым ударом BALL_SPEED_UP = 1.05 # Максимальная скорость мяча BALL_MAX_SPEED = 40 # Начальная скорость по горизонтали BALL_X_SPEED = 20 # Начальная скорость по вертикали BALL_Y_SPEED = 20 # Добавим глобальную переменную отвечающую за расстояние # до правого края игрового поля right_line_distance = WIDTH - PAD_W # функция отскока мяча def bounce(action): global BALL_X_SPEED, BALL_Y_SPEED # ударили ракеткой if action == "strike": BALL_Y_SPEED = random.randrange(-10, 10) if abs(BALL_X_SPEED) < BALL_MAX_SPEED: BALL_X_SPEED *= -BALL_SPEED_UP else: BALL_X_SPEED = -BALL_X_SPEED else: BALL_Y_SPEED = -BALL_Y_SPEED # Переписываем функцию движения мяча с учетом наших изменений def move_ball(): # определяем координаты сторон мяча и его центра ball_left, ball_top, ball_right, ball_bot = c.coords(BALL) ball_center = (ball_top + ball_bot) / 2 # вертикальный отскок # Если мы далеко от вертикальных линий - просто двигаем мяч if ball_right + BALL_X_SPEED < right_line_distance and \ ball_left + BALL_X_SPEED >PAD_W: c.move(BALL, BALL_X_SPEED, BALL_Y_SPEED) # Если мяч касается своей правой или левой стороной границы поля elif ball_right == right_line_distance or ball_left == PAD_W: # Проверяем правой или левой стороны мы касаемся if ball_right > WIDTH / 2: # Если правой, то сравниваем позицию центра мяча # с позицией правой ракетки. # И если мяч в пределах ракетки делаем отскок if c.coords(RIGHT_PAD)[1] < ball_center < c.coords(RIGHT_PAD)[3]: bounce("strike") else: # Иначе игрок пропустил - тут оставим пока pass, его мы заменим на подсчет очков и респаун мячика pass else: # То же самое для левого игрока if c.coords(LEFT_PAD)[1] < ball_center < c.coords(LEFT_PAD)[3]: bounce("strike") else: pass # Проверка ситуации, в которой мячик может вылететь за границы игрового поля. # В таком случае просто двигаем его к границе поля. else: if ball_right >WIDTH / 2: c.move(BALL, right_line_distance-ball_right, BALL_Y_SPEED) else: c.move(BALL, -ball_left+PAD_W, BALL_Y_SPEED) # горизонтальный отскок if ball_top + BALL_Y_SPEED < 0 or ball_bot + BALL_Y_SPEED >HEIGHT: bounce("ricochet")
Теперь наш мячек отскакивает от стенок и ракеток и зависает если попадает в вертикальную границу поля, но не попадает в ракетку.
Подсчет очков и респаун мячика.
Создадим глобальные переменные очков для каждого игрока и обнулим их.
PLAYER_1_SCORE = 0 PLAYER_2_SCORE = 0
Теперь добавим текстовые объекты в которых будем отображать счет.
p_1_text = c.create_text(WIDTH-WIDTH/6, PAD_H/4, text=PLAYER_1_SCORE, font="Arial 20", fill="white") p_2_text = c.create_text(WIDTH/6, PAD_H/4, text=PLAYER_2_SCORE, font="Arial 20", fill="white")
Создадим функции изменения счета и респауна мяча
# Добавьте глобальную переменную INITIAL_SPEED INITIAL_SPEED = 20 def update_score(player): global PLAYER_1_SCORE, PLAYER_2_SCORE if player == "right": PLAYER_1_SCORE += 1 c.itemconfig(p_1_text, text=PLAYER_1_SCORE) else: PLAYER_2_SCORE += 1 c.itemconfig(p_2_text, text=PLAYER_2_SCORE) def spawn_ball(): global BALL_X_SPEED # Выставляем мяч по центру c.coords(BALL, WIDTH/2-BALL_RADIUS/2, HEIGHT/2-BALL_RADIUS/2, WIDTH/2+BALL_RADIUS/2, HEIGHT/2+BALL_RADIUS/2) # Задаем мячу направление в сторону проигравшего игрока, # но снижаем скорость до изначальной BALL_X_SPEED = -(BALL_X_SPEED * -INITIAL_SPEED) / abs(BALL_X_SPEED)
Осталось вставить вызов этих функций вместо pass в функцию move_ball. Замените
. if c.coords(RIGHT_PAD)[1] < ball_center < c.coords(RIGHT_PAD)[3]: bounce("strike") else: # Иначе игрок пропустил - тут оставим пока pass, его мы заменим на подсчет очков и респаун мячика pass else: # То же самое для левого игрока if c.coords(LEFT_PAD)[1] < ball_center < c.coords(LEFT_PAD)[3]: bounce("strike") else: pass .
if c.coords(RIGHT_PAD)[1] < ball_center < c.coords(RIGHT_PAD)[3]: bounce("strike") else: update_score("left") spawn_ball() else: if c.coords(LEFT_PAD)[1] < ball_center < c.coords(LEFT_PAD)[3]: bounce("strike") else: update_score("right") spawn_ball()
Теперь наш пин-понг можно считать завершенным.
Полный код игры пин-понг на Python на GitHub.
Обучение детей программированию на Python в Minecraft
Игра — лучший способ быстро усвоить новый, сложный материал. Наши преподаватели используют популярнейшую игру Minecraft, чтобы познакомить школьников с основами программирования и показать на практике возможности Python.
Вы уже пытались обучить своего ребенка программированию? Тогда вы знаете, как быстро детям надоедают однообразные строчки кода и сложные операции, которые приводят к непонятным результатам. Когда в глазах пропадает огонек интереса, новые знания в голову не попадают.
В ProgKids мы поддерживаем этот огонек живым, предлагая юным ученикам интерактивную среду для самых разных экспериментов. В этих условиях обучение программированию идет естественным образом, а возможность сделать фантазию реальностью помогает быстро разобраться в командах и рабочих инструментах.
Что такое Minecraft?
Фактически это виртуальный мир, созданный из Lego. В этой игре нет сюжета и врагов, которых нужно победить. Вместо этого игроки добывают ресурсы, чтобы создавать собственные проекты: создавать полезные, возводить замки, строить механические конструкции. Minecraft стала абсолютным хитом, обогнав по популярности все существующие компьютерные игры — к 2019 году количество проданных копий приблизилось к 200 миллионам, а ежемесячное число активных игроков превышает 112 миллионов.
Как Minecraft помогает учить программированию?
Как и в жизни, компьютерные программы в Minecraft избавляют игрока от рутинных операций, помогая ускорить работу над масштабными проектами. Ребенок видит, что несколько строчек кода дают ему столько ресурсов, сколько руками пришлось бы добывать несколько часов. А другой код позволяет построить из этих ресурсов огромные движущиеся объекты, которые вовсе невозможно создать без специальных средств. У него разгорается фантазия, появляется желание экспериментировать и создавать. Наши преподаватели помогают разобраться, как добиться поставленных целей.
Почему в Minecraft так удобно учить детей программированию?
- Знакомая среда. Даже если вы впервые слышите про эту игру, ваши дети наверняка ее знают. Им не придется знакомиться с новым интерфейсом, да возможности, на которых построено обучение, им по большей части уже известны. Многие ученики даже знают про командную строку, через которую в Minecraft можно менять внутриигровые условия.
Почему Python?
Python — один из самых популярных современных языков. Профессионалы единогласно называют его лучшим языком программирования для новичков. Его простой синтаксис позволяет писать программы, как книгу, выстраивая команды согласно простой человеческой логике.
Поэтому если вы хотите обучить программированию детей от 10 лет и старше, Python и Minecraft обеспечивают идеальные условия.
Остались вопросы? Напишите нам, и мы расскажем о содержании курса и прочих интересующих вас деталях.
Я пишу текстовую игру на Python: доработанный прототип
В прошлый раз мы довели текстовую игру LAM-40 до первого рабочего прототипа, который, правда, ещё далёк от финальной версии. В конце материала я обозначил главные недостатки этого прототипа, и сегодня мы справимся с некоторыми из них. Во-первых, сейчас весь код содержится в одном файле. Это непорядок: реплики бюрократов лучше хранить в другом месте, как и основную логику игры. Во-вторых, нынешний прототип плохо выглядит: ориентироваться в тексте, который выводит игра, неудобно. Сегодня мы не будем кардинально менять функционал, а просто доведём до ума то, что делали в предыдущий раз.
ПРИМЕЧАНИЕ: весь код приводится для Python версии 3.0 и старше, а потому может не работать на более старых версиях.
Для начала давайте посмотрим, какой код остался с прошлого раза.
Я сделал упор на реструктуризацию кода и внешний вид игры: первое ни в коем случае нельзя откладывать на потом, когда кода станет больше, а за вторым лучше начать следить как можно раньше. В итоге вместо одного файла стало три файла. В одном из них, text.py, сейчас хранится текстовая информация: в частности, реплики бюрократов. Разбирать там особо нечего: это просто набор списков, который не изменился с предыдущего раза, но если хотите на него посмотреть, то вот он. А мы же пока перейдём в другой новый файл, game.py, где содержится класс Game — основная логика игры.
Строка 1: в начале файла я добавил комментарий между тройными кавычками, также известный как docstring. Это очень полезная практика, которой всегда нужно следовать: она не только облегчает чтение кода другим людям, но и помогает тестировать программу с помощью doctest (этим мы займёмся на последних стадиях разработки, хотя многие советуют прописывать тесты с самого начала). Кроме того, когда вы пользуетесь функцией help(), выводящей описание того, как работает тот или иной объект языка, она берёт описание как раз из docstring.
Строки 3–9: новые модули! Во-первых, модуль os, который даёт доступ к возможностям операционной системы. Мы воспользуемся им для написания функции очистки экрана. Во-вторых, с помощью конструкции from — import мы импортируем в текущий файл один класс из другого модуля или файла. В нашем случае это класс Bureaucrat из файла bureaucrat.py и класс Terminal из модуля blessings, предназначенного для форматирования текста. Мы создаём образец класса Terminal и присваиваем его переменной с коротким названием t — её будет удобно вставлять в код.
Строки 12–15: инициализация класса — это основная логика игры, которая в предыдущей версии находилась внизу файла bureaucrat.py. В неё добавилась функция clear_screen(), очищающая экран (не забываем о ключевом слове self внутри класса). Определение функции находится на строках 25–29. Функция смотрит на то, в какой операционной системе находится пользователь. Если в Windows, обозначенной как 'nt', то выполняется специфичная для неё команда 'cls', которая становится атрибутом функции os.system(). Ветка else и команда 'clear' предназначены для Mac и Linux.
Строка 16: выводим в начале игры её название и версию. Для того чтобы название было подчёркнутым, пользуемся функцией underline(), которая входит в класс Terminal модуля blessings. Её атрибутом становится string, внутри которого есть символ новой строки \n, принятый во многих языках программирования. Он даёт интерпретатору знать, что следующие за \n символы нужно выводить с новой строки.
Строки 31–38: функции act() и react() переехали из bureaucrat.py в game.py, потому что не относятся напрямую к действиям бюрократа. Внутрь неё я поместил все доступные на сегодня действия, включая проигнорированные в предыдущей версии ожидание и выход.
Далее мы используем цикл for — in, о котором я до этого, если я правильно помню, не рассказывал. Цикл for — in проходит столько итераций, сколько элементов находится в объекте, который размещается после ключевого слова in. В нашем случае это список действий actions. Функция enumerate() используется для того, чтобы на каждом этапе цикла в памяти компьютера был не только элемент списка (я назвал временную переменную с ним action, но вообще имя можно задавать более-менее свободным образом), но и его порядковый номер (number). Иначе говоря, цикл for — in означает следующее: «для каждого элемента element в объекте elements выполни блок кода, находящийся после двоеточия».
Мы используем цикл с функцией enumerate для того, чтобы вывести перечисление всех доступных действий, которые находятся в переменной actions, ставшей со времён предыдущей версии не одним string'ом, а списком string'ов.
В программировании отсчёт начинается с нуля (то есть порядковый номер '[A]sk' — 0, '[B]ribe' — 1 и так далее), а потому, чтобы первым порядковым номером не был 0, с самого начала отсчёта к number нужно прибавлять единицу. Также number нужно превратить из типа данных integer в тип данных string с помощью функции str(). Мы уверены на 100%, что каждая переменная number будет сначала принадлежать типу integer, а потому никаких дополнительных проверок не делаем. Наконец, мы выводим каждый элемент списка actions как пункт меню, используя функцию print(). Внутри неё мы соединяем переменные типа string с помощью символа +. Именно для этого мы и переводили на каждой итерации цикла переменную number в тип данных string.
Строки 39–79: мы используем на символе, который вводит игрок, функцию lower(), чтобы строчные буквы становились прописными, — так вводить команды проще. Соответственно, во всём остальном файле я поменял в условиях строчные буквы на прописные, везде проставил одинарные кавычки, чтобы соблюдать единство стиля, а также добавил возможность ввода не только первых букв слов-действий, но и номеров, под которыми они стоят в меню. Внутри ветки выхода из игры я использую функцию clear_screen(), чтобы на выводимом после игры экране было только сообщение с благодарностью — без всякого мусора. Завершает файл создание образца класса Game, благодаря чему игра начнётся сразу после того, как мы запустим интерпретатор.
Файл bureaucrat.py стал значительно меньше после того, как я разнёс его составляющие по другим двум файлам, но без изменений не обошлось.
Строки 1–8: помимо модуля blessings, уже описанного в комментариях к файлу game.py, я также импортировал содержимое файла text.py — иначе бюрократы не будут знать, что им говорить.
Строки 13–23: в инициализацию класса Bureaucrat я добавил атрибут gender. Для выбора атрибута используется функция random() из модуля random, случайным образом дающая число типа float (то есть со множеством знаков после запятой) от 0 до 1. Из условной конструкции выходит, что с вероятностью 49,5% бюрократ окажется женщиной, с вероятностью 49,5% — мужчиной, а в каждом сотом случае бюрократ будет входить в число людей, объединённых под термином intersex. Ранги и действия я поместил прямо как аргументы функции random.choice(), чтобы код был лаконичнее.
Строки 25–43: наконец, я сделал с помощью соединения стрингов, функций из модуля blessings и специальных символов так, чтобы основные действия бюрократа отображались красивее. Важные характеристики ранга и настроения выделяются жирным, а где надо, используется символ новой строки \n.
К сожалению, курсив и некоторые другие виды форматирования текста из blessings не заработали в «Терминале» Mac OS X. Ну а ещё в этих строках вы можете найти отсылки к угадайте какой игре!
Вот как выглядит наша игра в окне терминала сейчас. Намного лучше того скопища нагромождённого текста, что был там раньше.
Хотя мы решили лишь малую часть стоящих перед нами проблем, на текущей стадии этот прототип уже годится для уровня proof of concept. А значит, в следующий раз я не только продолжу решать задачи, обозначенные в предыдущем выпуске, но и напишу ёмкий дизайн-документ, по которому можно будет ориентироваться на предстоящих этапах разработки. Если вам что-то непонятно, пишите комментарии под материалом и в социальных сетях — буду рад и любым другим отзывам. Если вы более опытный в программировании человек, чем я, то с удовольствием выслушаю содержательную критику. Спасибо и до следующего раза!
Документация модуля Blessings
Полные курсы Python на Codeacademy и Treehouse*
* — платные курсы, но есть пробный период
Развитие программистского мышления на Udacity
Учебники по Python на LearnPython.org и Python Course