Как очистить экран от ВСЕХ объектов в PyGame + Pymunk?
Делаю программу, где у пользователя есть возможность рисовать поверхности для взаимодействия с этими поверхностями мячиков, которые пользователь тоже может пускать где и когда захочет.
Периодически — экран переполняется, да и производительность падает ввиду того, что объектов для обработки слишком много.
Ну так вот. Как очистить пространство от всех созданных объектов?
Имён объектов я не знаю, так как создаю их при помощи функции(пробовал применять классы, но он выдавал ошибку почему-то, видимо я что-то не то делал).
- Вопрос задан более двух лет назад
- 657 просмотров
Комментировать
Решения вопроса 1
michadimin @michadimin Автор вопроса
Сам нашёл ответ.
Для тех, кто будет мучится с таким же вопросом в будущем и увидит эту тему тут — объясню решение:
Нужно объявить массивы(списки) для объектов, которые создаются в функциях, после чего добавлять в эти массивы каждый новый элемент.
При необходимости удаления — нужно создать цикл(думаю все уже поняли какой, так что объяснять не буду), где вы будете удалять каждый объект обращаясь по его индексу в массиве через метод remove() для вашего пространства в Pymunk.
Ответ написан более двух лет назад
Комментировать
Нравится Комментировать
Ответы на вопрос 0
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
- +1 ещё
Как создать зависящие от времени функции не останаливая работу программы на pygame?
- 1 подписчик
- 01 янв.
- 50 просмотров
Очистка консоли после каждого принта
А предыдущий текст затирался, и на его месте появлялся новый, то есть должна быть одна строка которая плавно заполнится от одного # до #########. Возможно ли это и как правильно реализовать?
Отслеживать
139 11 11 бронзовых знаков
задан 7 сен 2017 в 13:29
Игорь Игоряныч Игорь Игоряныч
1,903 4 4 золотых знака 15 15 серебряных знаков 27 27 бронзовых знаков
Вам нужно кроссплатформенно или решение, работающее только в юникс-терминалах, тоже сойдёт?
7 сен 2017 в 13:31
@andreymal лучше конечно кросс
7 сен 2017 в 13:34
А вам не прогрессбар ли нужен? Просто есть готовые решения.
7 сен 2017 в 13:39
@mkkik да, я его уже почти написал, вот столкнулся с тем что не знаю как поток вывода чистить, не когда не было данной потребности, а вот появилась.
7 сен 2017 в 13:41
связанный вопрос Нужна ли многопоточность, чтобы показывать прогресс долговыполняющейся функции
8 сен 2017 в 15:50
6 ответов 6
Сортировка: Сброс на вариант по умолчанию
Для управления консолью обычно используют ANSI, но Windows-консоль его не поддерживает, поэтому предварительно придётся воткнуть какой-нибудь костыль для его поддержки. Обычно устанавливают и используют модуль colorama:
import colorama colorama.init()
Его установка и дружба с pycharm данного вопроса не касается, поэтому не буду это описывать.
Можно передвинуть курсор на один символ назад с помощью ASCII-символа BS (escape-последовательность \b ). После этого можно напечатать новый текст поверх старого:
print('abc\b\bXY')
Можно передвинуть курсор в начало строки с помощью возврата каретки ( \r ) и тоже напечатать что-нибудь поверх:
print('abcde\r123')
Можно стереть все символы от курсора до конца строки с помощью ANSI-последовательности \033[K (для Windows нужна вышеупомянутая colorama). В примере ниже переносим курсор на четыре символа влево и тем самым стираем последнее слово:
print('foo bar baz\b\b\b\b\033[K!')
Выведет: foo bar! (от baz не будет и следа)
Если переместить курсор в начало строки, то можно стереть всю строку:
print('###############\r\033[KDone!')
Выведет: Done! (без всяких решёточек)
Можно передвинуть курсор на одну строку вверх и в её начало с помощью \033[F :
print('foo') print('\033[F!')
Комбинируя всё вышеперечисленное, можно модифицировать ваш пример таким образом:
import time aggr = '#' for n in range(10): if n > 0: # Если мы выводили решёточки в предыдущей итерации, # то поднимаемся на строку назад и стираем их print('\033[F\033[K', end='') print(aggr * n) time.sleep(0.3)
Но, возможно, для вашего частного случая намного лучше подойдёт вариант от mkkik 🙂
Отслеживать
ответ дан 7 сен 2017 в 14:17
13k 10 10 золотых знаков 41 41 серебряный знак 78 78 бронзовых знаков
в моём окружении: print(«\033c») работает, чтобы очистить экран в терминале. Python — Clearing the terminal screen more elegantly. На Windows 10 поддерживаются напрямую (если включить) последовательности, основанные на VT100: так называемые Console Virtual Terminal Sequences
30 мая 2018 в 6:13
Для «затирания» текста можно использовать символ возврата каретки \r без перевода строки:
import time for i in range(10): print('*' * (i + 1), end='\r') time.sleep(.3) print()
Но можно и не затирать, а выводить по одному символу, принудительно «выпихивая» буфер на каждой итерации цикла:
import time for i in range(10): print('#', end='', flush=True) time.sleep(.3) print()
Отслеживать
ответ дан 7 сен 2017 в 13:59
user207200 user207200
5,210 8 8 золотых знаков 23 23 серебряных знака 41 41 бронзовый знак
можно print(‘*’ * (i+1), end=’\r’)
7 сен 2017 в 17:17
Чтобы не изобретать велосипед, можно использовать tqdm модуль (читается как «такадум» — означает «прогресс»):
Отслеживать
ответ дан 8 сен 2017 в 16:06
52.3k 11 11 золотых знаков 108 108 серебряных знаков 312 312 бронзовых знаков
иногда под индивидуальные задачи все же приходиться изобретать велосипед
8 сен 2017 в 16:45
Дело такого рода, что вопрос вообще не про прогрессбар был, а про то как поток вывода почистить, а про бар то уже в процессе переговоров в комментариях всплыло )
8 сен 2017 в 18:20
ну если на то пошло, вопрос стоял как очищать консоль после каждого принта, а пример с ### был приведен ниже, для более понятного описания чего хочу, и в моем случае не подойдет print(‘#’, end=», flush=True), в моем случае подойдет именно то о чем я просил, а именно очистка консоли после каждого вывода, а ответ от mkkik, действительно хорошо вписывается в ответ на мой вопрос.
8 сен 2017 в 20:16
для ясности суть вопроса указана в вопросе, а в комментариях уже если человек задает вопрос то поему бы ему не ответить, суть изначально заданого вопроса это не меняет ни как. Так что если я даже ответил в комментах что для прогрессбара, это изначально заданный вопрос не трансформировало и не как не изменило.
8 сен 2017 в 23:24
О каких телепатах вы говорите ? Суть вопроса была четко указана, что бы прочитать вопрос и ответить на него телепатом быть не нужно, а где я буду применять тот участок кода в програссабе или любой другой программе это уже не играет роли, и суть вопроса не как не меняет, и все все прекрасно поняли и дали нужные ответы, одному вам телепат понадобился. Не забудьте отминусть вопрос со всех аккаунтов, а то одного минуса мало.
Модули pygame.image и pygame.transform
Функция load() модуля pygame.image загружает изображение и создает экземпляр Surface , на котором отображено это изображение. В load() передается имя файла. «Родным» форматом является BMP, однако если функция pygame.image.get_extended() возвращает истину, то можно загружать ряд других форматов: PNG, GIF, JPG и др.
import pygame as pg import sys W = 400 H = 300 sc = pg.display.set_mode((W, H)) sc.fill((100, 150, 200)) dog_surf = pg.image.load('dog.bmp') dog_rect = dog_surf.get_rect(bottomright=(W, H)) sc.blit(dog_surf, dog_rect) pg.display.update() while 1: for i in pg.event.get(): if i.type == pg.QUIT: sys.exit() pg.time.delay(20)

Если у изображения нет прозрачного слоя, но он необходим, то следует воспользоваться методом set_colorkey() класса Surface :
dog_surf = pg.image.load('dog.bmp') dog_surf.set_colorkey((255, 255, 255))
Все пиксели, цвет которых совпадает с переданным в set_colorkey() значением, станут прозрачными.

У формата PNG с альфа-каналом (когда для точек можно настраивать степень прозрачности; обычно устанавливается полностью прозрачный фон) таких проблем нет:
sun_surf = pg.image.load('sun.png') sun_rect = sun_surf.get_rect() sc.blit(sun_surf, sun_rect)

Ко всем экземплярам Surface рекомендуется применять метод convert() , который, если не передавать аргументы, переводит формат кодирования пикселей поверхности в формат кодирования пикселей главной поверхности. При выполнении игры это ускоряет отрисовку поверхностей.
Если поверхность была создана на базе изображения с альфа-каналом, то вместо convert() надо использовать метод convert_alpha() , так как первый удаляет прозрачные пиксели (вместо них будет черный цвет). Таким образом, код загрузки и обработки изображений разных форматов должен выглядеть примерно так:
dog_surf = pg.image.load('dog.bmp').convert() sun_surf = pg.image.load('sun.png').convert_alpha()
Что по смыслу равносильно:
. dog_surf = pg.image.load('dog.bmp') dog_surf = dog_surf.convert() .
Метод convert() возвращает новую, конвертированную, поверхность. Он не изменяет ту, к которой применяется.
В модуле pygame.image есть функция save() , которая позволяет сохранять переданную ей поверхность (не обязательно главную) в формат BMP, TGA, PNG, JPEG. Пример:
while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() elif i.type == pygame.KEYUP \ and i.key == pygame.K_s: pygame.image.save(sc, 'day.png') pygame.time.delay(20)
Изменение поверхностей
Модуль pygame.transform содержит функции для изменения поверхностей. Некоторые трансформации (например, изменение размера) приводят к ухудшению изображения из-за потери части пикселей. В таких случаях надо сохранять исходную поверхность и выполнять трансформации от нее.
Функции модуля transform , которые изменяют поверхности, возвращают новые. Первым аргументом им передается исходный Surface . Ниже приведены примеры использования наиболее востребованных функций.
Функция flip() переворачивает Surface по горизонтали и вертикали, к потери качества не приводит. Указывается поверхность и булевыми значениями оси переворота.
import pygame import sys sc = pygame.display.set_mode((400, 300)) sc.fill((100, 150, 200)) dog_surf = pygame.image.load('dog.bmp').convert() dog_surf.set_colorkey((255, 255, 255)) dog_rect = dog_surf.get_rect(center=(200, 150)) sc.blit(dog_surf, dog_rect) pygame.display.update() while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() # При отжатии (нажать и отпустить) клавиши f elif i.type == pygame.KEYUP and i.key == pygame.K_f: # собака перевернется слева направо flip = pygame.transform.flip(dog_surf, True, False) sc.fill((100, 150, 200)) sc.blit(flip, dog_rect) pygame.display.update(dog_rect) pygame.time.delay(20)
Поворот и изменение размера:
import pygame import sys sc = pygame.display.set_mode((400, 300)) sc.fill((100, 150, 200)) dog_surf = pygame.image.load('dog.bmp').convert() dog_surf.set_colorkey((255, 255, 255)) dog_rect = dog_surf.get_rect(center=(200, 150)) sc.blit(dog_surf, dog_rect) pygame.display.update() # ждем 1 секунду перед изменением pygame.time.wait(1000) sc.fill((100, 150, 200)) # уменьшаем в два раза scale = pygame.transform.scale( dog_surf, (dog_surf.get_width() // 2, dog_surf.get_height() // 2)) scale_rect = scale.get_rect(center=(200, 150)) sc.blit(scale, scale_rect) pygame.display.update(dog_rect) pygame.time.wait(1000) sc.fill((100, 150, 200)) # поворачиваем на 45 градусов rot = pygame.transform.rotate(dog_surf, 45) rot_rect = rot.get_rect(center=(200, 150)) sc.blit(rot, rot_rect) pygame.display.update() while 1: for i in pygame.event.get(): if i.type == pygame.QUIT: sys.exit() pygame.time.delay(20)
Практическая работа
Допустим, у вас есть такое изображение вида сверху машины:
Напишите программу управления ее движением с помощью стрелок клавиатуры (вверх, вниз, влево, вправо) так, чтобы объект всегда двигался головой вперед.
Курс с примерами решений практических работ:
pdf-версия
X Скрыть Наверх
Pygame. Введение в разработку игр на Python
Программирование аркадных игр
и обучение информатике
Copyright © 2017
English version by Paul Vincent Craven
Spanish version by Antonio Rodríguez Verdugo
Russian version by Vladimir Slav
Turkish version by Güray Yildirim
Portuguese version by Armando Marques Sobrinho and Tati Carvalho
Dutch version by Frank Waegeman
Hungarian version by Nagy Attila
Finnish version by Jouko Järvenpää
French version by Franco Rossi
Korean version by Kim Zeung-Il
Chinese version by Kai Lin