Python-сообщество
- Начало
- » Python для новичков
- » удаление спрайта Pygame
#1 Июнь 14, 2022 07:20:45
Rad.89 Зарегистрирован: 2022-06-07 Сообщения: 15 Репутация: 0 Профиль Отправить e-mail
удаление спрайта Pygame
Всем доброго времени суток! В Pygame через def сделана отрисовка спрайтов при событии:
def player_upd(): if v_c_rand1 == 100: player=Player() #переменная из класса для спрайта all_sprites.add(player) player_group.add(player) global all_spr all_spr += 1 #счетчик
Не могу допетрить, как сделать удаление спрайта при щелчке мышкой. ЕСЛИ мышь нажата, то: player.kill() не решает. Пишет: нет такого имени “player”
Отредактировано Rad.89 (Июнь 14, 2022 07:28:50)
#2 Июнь 14, 2022 09:46:59
ZerG Зарегистрирован: 2012-04-05 Сообщения: 2330 Репутация: 63 Профиль Отправить e-mail
удаление спрайта Pygame
Ну наверное покажите больше кода — не гадат же нам как и откудова вы получаете ошибку
Влодение рускай арфаграфией — это как владение кунг-фу: настаящие мастира не преминяют ево бес ниабхадимости
#3 Июнь 14, 2022 12:35:02
Rad.89 Зарегистрирован: 2022-06-07 Сообщения: 15 Репутация: 0 Профиль Отправить e-mail
удаление спрайта Pygame
сократил, как оно идет по программе по порядку и все связанное с данным img:
#грузим картинку player = pygame.image.load(os.path.join(img_folder, 'player.png')) # даем класс: class Plyer (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = player self.image = pygame.transform.scale(player,(25,25)) self.rect = self.image.get_rect() self.rect.center=((pl_pos), (pl_x+15)) player = pygame.sprite.Group() # далее в программе вызываем функцию def player_upd(): player = (pl_pos), (pl_x+15) #получаем координаты, где появится новый клон спрайта if v_c_rand1 == 100: player=Player() all_sprites.add(player) player_group.add(player) global all_pl all_pl += 1 # клоны спрайтов создаются исправно. Теперь нужна функция, убирающая # спрайт, если на нем нажать. # попытка сделать это через отловку событий event: if event.type == pygame.MOUSEBUTTONDOWN: m_pos_x,m_pos_y = pygame.mouse.get_pos() m_position=(m_pos_x,m_pos_y) if event.button == 1: if player.rect.collidepoint(m_position): print ('----')#индикатор, что команда сработала # как только происходит нажатие вылетает ошибка: # ~ Traceback (most recent call last): # ~ File "тут путь до файла", line 231, in # ~ if player.rect.collidepoint(m_position): # ~ NameError: name 'player' is not defined
Отредактировано Rad.89 (Июнь 14, 2022 12:36:19)
#4 Июнь 14, 2022 13:18:42
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
удаление спрайта Pygame
self.image = player self.image = pygame.transform.scale(player,(25,25))
это оригинальный приём!
давайте без сокращений лучше, а то тут трудно понять, это автор по пояс деревянный или просто сократил неудачно
#5 Июнь 14, 2022 13:32:28
Rad.89 Зарегистрирован: 2022-06-07 Сообщения: 15 Репутация: 0 Профиль Отправить e-mail
удаление спрайта Pygame
Приношу извинения, если код нафарширован визуальными ошибками. Пока только изучаю принцип работы. Если файлы нужны: могу скинуть.
import pygame import time import random import os import sys # ~ инициализация фона pygame.font.init() pygame.font.SysFont('arial', 15) # ~ инициализация звука pygame.mixer.init() # ~ инициализация дисплея pygame.display.init() # ~ окно: screen=pygame.display.set_mode((600,600)) # ~ фуллскрин: # ~ screen=pygame.display.set_mode((0, 0), pygame.FULLSCREEN) # ~ получение размеров дисплея sW, sH = screen.get_size() # ~ функция сохранения пути файлов для формовки ехе def resource_path(relative_path): try: base_path = sys._MEIPASS except Exception: base_path = os.path.abspath(".") return os.path.join(base_path, relative_path) game_folder = os.path.dirname(__file__) ######################################################################## # ~ загрузка звука kluv_sound = pygame.mixer.Sound("sound/1kick.mp3") s_back = pygame.mixer.Sound("sound/back_sound.mp3") chikin_voice = pygame.mixer.Sound("sound/chikin_voice.mp3") # ~ загрузка файлов изображений img_folder = os.path.join(game_folder, 'sprites') player_img1 = pygame.image.load(resource_path('sprites/chikin.png')) player_img2 = pygame.image.load(resource_path('sprites/chikin_3.png')) player_img3 = pygame.image.load(resource_path('sprites/chikin_2.png')) player_img_dead = pygame.image.load(resource_path('sprites/chikin_dead.png')) btn_food = pygame.image.load(resource_path('sprites/btn_food.png')) btn_energy = pygame.image.load(resource_path('sprites/btn_energy.png')) bg = pygame.image.load(resource_path('sprites/background.png')) player_poo_img = pygame.image.load(resource_path('sprites/poo.png')) # ~ вариант загрузки файла без дампирования для компиляции health_img = pygame.image.load(os.path.join(img_folder, 'hart1.png')) energy_img = pygame.image.load(os.path.join(img_folder, 'energy1.png')) food_img = pygame.image.load(os.path.join(img_folder, 'food.png')) # ~ Переменные: FPS=29 BLACK=(0,0,0) WHITE=(255,255,255) GRAY=(192,192,192) YELLOW=(255,255,0) Health_point=100 Energy_point=100 Food_point=100 hourse=0 years=0 seconds=0 pl_pos=dm=sW/2 pl_x=(sH/4)*3 speed=2 dm_time=dm_time_rand=0 t=0 n=0 scale=(80,80) s=1 v_c_rand1=0 v_c_rand2=200 all_player_poo = 0 f1 = pygame.font.Font((os.path.join(img_folder, 'vcrosdmonorusbyd.ttf')), 15) class Player (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = player_img1 self.image = pygame.transform.scale(self.image,(scale)) self.rect = self.image.get_rect() self.rect.center=((int(pl_pos)), (pl_x)) class Health (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = health_img self.image = pygame.transform.scale(health_img,(20,20)) self.rect = self.image.get_rect() self.rect.center=(10, 85) class Energy (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = energy_img self.image = pygame.transform.scale(energy_img,(20,20)) self.rect = self.image.get_rect() self.rect.center=(10, 55) class Food (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = food_img self.image = pygame.transform.scale(food_img,(20,20)) self.rect = self.image.get_rect() self.rect.center=(10, 25) class Btn_Food (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = btn_food self.image = pygame.transform.scale(btn_food,(50,50)) self.rect = self.image.get_rect() self.rect.center=(sW-50, sH/4) class Btn_Energy (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = btn_energy self.image = pygame.transform.scale(btn_energy,(50,50)) self.rect = self.image.get_rect() self.rect.center=(sW-50, sH/4+70) class Player_poo (pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) self.image = player_poo_img self.image = pygame.transform.scale(player_poo_img,(25,25)) self.rect = self.image.get_rect() self.rect.center=((pl_pos), (pl_x+15)) # ~ функция смены изображения во время передвижения def Anim_step(): if t > 2: player.image = player_img1 if n == 1: player.image = pygame.transform.flip(player_img1,False,False) else: player.image = pygame.transform.flip(player_img1,True,False) player.image = pygame.transform.scale(player.image,(scale)) else: player.image = player_img2 if n == 1: player.image = pygame.transform.flip(player_img2,False,False) else: player.image = pygame.transform.flip(player_img2,True,False) player.image = pygame.transform.scale(player.image,(scale)) # ~ функция клевания def Klyvanie(): if t > 2: player.image = player_img1 if n == 1: player.image = pygame.transform.flip(player_img1,False,False) else: player.image = pygame.transform.flip(player_img1,True,False) player.image = pygame.transform.scale(player.image,(scale)) else: player.image = player_img3 if n == 1: player.image = pygame.transform.flip(player_img3,False,False) else: player.image = pygame.transform.flip(player_img3,True,False) player.image = pygame.transform.scale(player.image,(scale)) # ~ функция смерти def Dead (): player.image = player_img_dead player.image = pygame.transform.scale(player.image,(scale)) # ~ функция появления какашек и их учет player_poo_group = pygame.sprite.Group() def player_poo_upd(): player_poo_pos = (pl_pos), (pl_x+15) player_poo=Player_poo() if v_c_rand1 == 100: all_sprites.add(player_poo) player_poo_group.add(player_poo) global all_player_poo all_player_poo += 1 ######################################################################## #инициализация и запуск программы pygame.init() s_back.play(-1) s_back.set_volume(0.008) chikin_voice.set_volume(0.05) clock=pygame.time.Clock() all_sprites = pygame.sprite.Group() player = Player() health = Health () energy = Energy () food = Food () btn_food = Btn_Food() btn_energy = Btn_Energy() all_sprites.add(player, health, energy, food, btn_food, btn_energy) running = True while running: clock.tick(FPS) # ~ выход из игры for event in pygame.event.get(): if event.type == pygame.QUIT: running = False # ~ #управление с клавиатуры if event.type == pygame.KEYDOWN: # ~ if event.key == pygame.K_UP: # ~ if Health_point >0: # ~ Food_point=100 # ~ if event.key == pygame.K_DOWN: # ~ if Health_point >0: # ~ Energy_point=100 if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() # ~ управление с мыши: if event.type == pygame.MOUSEBUTTONDOWN: m_pos_x,m_pos_y = pygame.mouse.get_pos() m_position=(m_pos_x,m_pos_y) print (m_position) if event.button == 1: if btn_energy.rect.collidepoint(m_position): if Health_point >0: Energy_point=100 if btn_food.rect.collidepoint(m_position): if Health_point >0: Food_point=100 if player_poo.rect.collidepoint(m_position): print ('-----') # ~ #движение птички и разворот в направлении if pl_pos > dm+1: pl_pos -=speed pl_pos=int(pl_pos) Anim_step() player.rect.center=(pl_pos,pl_x) t+=1 if t >= 7: t = 0 n=1 # ~ модуль голоса курочки v_c_rand1=random.randint(0,v_c_rand2) if v_c_rand1 == 100: chikin_voice.play() v_c_rand2=200 if pl_pos dm-1: pl_pos +=speed pl_pos=int(pl_pos) Anim_step() player.rect.center=(pl_pos,pl_x) t+=1 if t >= 7: t = 0 n=0 # ~ модуль голоса курочки v_c_rand1=random.randint(0,v_c_rand2) if v_c_rand1 == 200: chikin_voice.play() v_c_rand2=100 # Дефикация курочки player_poo_upd() # ~ #задержка на позиции if pl_pos == dm+1 or pl_pos == dm-1 or pl_pos == dm: dm_time+=1 t+=1 if t >= 10: t = 0 Klyvanie() #звук клевка if t == 9: kluv_sound.play() if dm_time >= dm_time_rand: dm = int(random.randint(20, sW)) dm_time_rand = int(random.randint(10, 70)) dm_time=1 # ~ #зависимость здоровья от еды и энергии # ~ снижение еды и энергии if Food_point>0: Food_point-=0.01 if Energy_point0: Energy_point=0 Food_point-=0.03 if Energy_point>0: Energy_point -=0.03 if Food_point 0: Food_point=0 Energy_point -=0.05 # ~ Снижение здоровья if Food_point 1 and Energy_point 1: Health_point -=1 speed=1 elif Food_point 1 or Energy_point 1 or all_player_poo > 20: Health_point -=0.02 speed=1 # ~ #восстанавливаем здоровье if Food_point >90 and Energy_point >90 and Health_point 99: Health_point +=1 speed=2 # ~ #Птичка сдохла if Health_point 1: Health_point=0 dm=pl_pos Dead() screen.blit(text5, (300, 20)) # ~ Счетчик прожитого времени if Health_point > 0: hourse=pygame.time.get_ticks()/10000 else: hourse = hourse if hourse > 365: years +=1 all_sprites.update() # отрисовка фона bg = pygame.transform.scale(bg,(sW,sH)) screen.blit(bg,(0,0)) # отрисовка текста на экране text1 = f1.render(("Жрачка: " + str(round(Food_point))), True,(180, 0, 0)) text2 = f1.render(("Энергия: " + str(round(Energy_point))), True,(YELLOW)) text3 = f1.render(("Здоровье: " + str(round(Health_point))), True,(180, 0, 0)) text4 = f1.render(("прожито :" + str(round(years)) + " лет и " + str(round(hourse)) + " дней "), True,(180, 0, 0)) text5 = f1.render("СДОХ =(" , True,(180, 0, 0)) if Health_point 1: screen.blit(text5, (sW/2, sH/2)) screen.blit(text4, (300, 20)) else: screen.blit(text1, (25, 20)) screen.blit(text2, (25, 50)) screen.blit(text3, (25, 80)) screen.blit(text4, (sW/2, sH/30)) all_sprites.draw(screen) pygame.display.flip() pygame.quit()
#6 Июнь 14, 2022 13:36:40
Rad.89 Зарегистрирован: 2022-06-07 Сообщения: 15 Репутация: 0 Профиль Отправить e-mail
удаление спрайта Pygame
и вот тут, когда нужно вызвать print (‘—–’) по щелчку мыши, вылезает ошибка:
# ~ управление с мыши: if event.type == pygame.MOUSEBUTTONDOWN: m_pos_x,m_pos_y = pygame.mouse.get_pos() m_position=(m_pos_x,m_pos_y) print (m_position) if event.button == 1: if btn_energy.rect.collidepoint(m_position): if Health_point >0: Energy_point=100 if btn_food.rect.collidepoint(m_position): if Health_point >0: Food_point=100 if player_poo.rect.collidepoint(m_position): ###Здесь пишет, что нет 'player_poo' print ('-----')
#7 Июнь 14, 2022 13:54:42
FishHook От: Зарегистрирован: 2011-01-08 Сообщения: 8312 Репутация: 568 Профиль Отправить e-mail
удаление спрайта Pygame
Rad.89
совершенно справедливо пишет
я тоже не нашел в какой строке кода определена переменная player_poo, её просто нет в вашем коде
Как удалить один спрайт из группы? pygame.sprite.Group()
В all_sprites добавлено кучу Surface’ов. Как мне удалить какой-то определенный, используя all_sprites.remove()?
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
Pygame sprite.Group()
У меня есть группа спрайтов, делаю платформер. 1) Как в этой группе мне убрать какой-то.
Как при объявлении переменной типа Sprite сразу задать нужный спрайт
using System.Collections; using System.Collections.Generic; using UnityEngine; public class.
Сломался спрайт после Sprite Editor
(сразу говорю — не спрашивайте, насчет того, почему я взял такой убогий спрайт) Проблема в том.
Pygame Sprite
Как сделать что бы спрайт перемещался слева направо и отталкивался от стенок, дошёл до левой стенки.
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
Сообщение от stympel
используя all_sprites.remove()?
А точно нужно использовать remove()? У каждого спрайта есть метод kill(), после вызова спрайт сам удалится из всех групп
Регистрация: 17.05.2017
Сообщений: 97
Хм, так как у меня группа из спрайтов, то я не знаю какой-то определенный. Или я ошибаюсь?
1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
Сообщение от stympel
так как у меня группа из спрайтов, то я не знаю какой-то определенный
Но он же чем то отличается от других спрайтов, количество жизней, цвет скорость, проверяй в цикле и вызывай kill()
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь
Ошибка pygame.sprite.spritecollide
Здравствуйте! Такая проблема: ошибка в pygame.sprite.spritecollide(). Строчка кода hits =.
Не могу найти спрайт (Sprite | Tile | Tileset) Эмоций (Смайлов)
Давным давно, я видел где то спрайт(тайлсет) с прикольными красивыми смайликами в облачке. Всё.
Создание экземпляров класса Sprite в Pygame
Здравствуйте. Только относительно недавно начал изучать ООП да и в целом Python. Предпочитаю.
Анимация закрашивает спрайт | pygame + pyganim
Здравствуйте. Столкнулся с проблемой: захотел добавить фон в игру. . Вот тако вот получилось.
Можно ли программно менять «Sprite» в спрайт рендерере?
Можно ли программно менять "Sprite" в спрайт рендерере? Задача такова: масив текстур. из него.
Как переместить один спрайт в направлении другого?
Есть два квадрата. Как прибавлять x и y так, чтобы первый квадрат двигался ко второму (по нажатию.
[pygame][python] Спрятать объект
Только недавно начал работать с Pygame и есть ряд вопросов. Мне надо убрать объект с экрана. Скажем когда перемещаю его по экрану. Когда фон одноцветный, я на предыдущем место, где находился спрайт рисую объект, схожий по цвету с фоном, и равный по размеру со спрайтом, который перемещаем.
А как поступить в том случае, когда фон не одноцветный, а скажем какая-нибудь картинка?
Chubakur ★★
11.02.11 19:24:58 MSK
Порядок отрисовки: в буфер рисуется сначала слой с фоном, потом слои со спрайтами, затем этот буфер показывается. При перемещении повторить. Но это довольно медленно, хоть и работает.
drakmail ★★★★
( 11.02.11 20:15:37 MSK )
Ответ на: комментарий от drakmail 11.02.11 20:15:37 MSK
Спасибо, не догадался что-то. Попробую.
Chubakur ★★
( 11.02.11 20:17:19 MSK ) автор топика
как вариант — копировать перед отрисовкой объекта область фона под ним, рисовать объект. При перемещении помещать скопированную область поверх объекта, копировать область фона под местом отрисовки объекта, рисовать объект.
drakmail ★★★★
( 11.02.11 20:21:13 MSK )
Ответ на: комментарий от drakmail 11.02.11 20:21:13 MSK
Ну это вроде слишком круто 🙂 Попробовал с предварительной прорисовкой фона, это работает ) Спасибо!
Chubakur ★★
( 11.02.11 20:22:13 MSK ) автор топика
Ответ на: комментарий от drakmail 11.02.11 20:15:37 MSK
> Но это довольно медленно, хоть и работает.
А есть какие-то другие варианты? о_о
pevzi ★★★★★
( 11.02.11 23:11:04 MSK )
Ответ на: комментарий от pevzi 11.02.11 23:11:04 MSK
А фиг знает, я этим лет 5 назад интересовался, думал, что есть способы быстрее ) Допустим, не рисовать фон в буфере каждый раз полностью, а перерисовывать только изменившуюся часть.
PyGame — шпаргалка для использования
Pygame использует объекты Rect для хранения и манипулирования прямоугольными областями. Rect может быть создан из комбинации значений слева, сверху, ширины и высоты. Rect также могут быть созданы из объектов python, которые уже являются Rect или имеют атрибут с именем «rect».
Rect(left, top, wiph, height) -> Rect Rect((left, top), (wiph, height)) -> Rect Rect(object) -> Rect
Методы работы с Rect
pygame.Rect.copy | Возвращает новый прямоугольник, имеющий ту же позицию и размер, что и оригинал. |
pygame.Rect.move | Возвращает новый прямоугольник, перемещаемый данным смещением. Аргументы x и y могут быть любым целочисленным значением, положительным или отрицательным. |
pygame.Rect.move_ip | То же, что и метод Rect.move (), но работает на месте. |
pygame.Rect.inflate | увеличивать или уменьшать размер прямоугольника, на месте |
pygame.Rect.inflate_ip | увеличивать или уменьшать размер прямоугольника, на месте |
pygame.Rect.clamp | перемещает прямоугольник внутри другого |
pygame.Rect.clamp_ip | перемещает прямоугольник внутри другого, на месте |
pygame.Rect.clip | обрезает прямоугольник внутри другого |
pygame.Rect.union | соединяет два прямоугольника в один |
pygame.Rect.union_ip | соединяет два прямоугольника в один, на месте |
pygame.Rect.unionall | объединение многих прямоугольников |
pygame.Rect.unionall_ip | объединение многих прямоугольников, на месте |
pygame.Rect.fit | изменить размер и переместить прямоугольник учмиывая соотношение сторон |
pygame.Rect.normalize | корректировать отрицательные размеры |
pygame.Rect.contains | проверить, находится ли один прямоугольник внутри другого |
pygame.Rect.collidepoint | проверить, находится ли точка внутри прямоугольника |
pygame.Rect.colliderect | тест, пересекаются ли два прямоугольника |
pygame.Rect.collidelist | проверить, пересекается ли хоть один прямоугольник в списке |
pygame.Rect.collidelistall | пересекаются ли все прямоугольники в списке |
pygame.Rect.collidedict | проверить, если один прямоугольник в словаре пересекается |
pygame.Rect.collidedictall | пересекаются ли все прямоугольники в словаре |
Обработка событий
Событие — это то, как Pygame сообщает о том, что что-то случилось за пределами кода программы. События создаются, например, при нажатии клавиш клавиатуры, мыши и размещаются в очереди, дожидаясь обработки.
Функция get в модуле pygame.event возвращает последнее событие, ожидающее в очереди и удаляет его из очереди.
Объект event
Модуль pygame.event для обработки очереди событий
pygame.event.pump | Если вы не используете другие функции событий в своей игре, вы должны вызвать pygame.event.pump (), чтобы позволить pygame обрабатывать внутренние действия |
pygame.event.get | получает события из очереди |
pygame.event.poll | получить одно событие из очереди |
pygame.event.wait | ждёт одиночного события из очереди |
pygame.event.peek | проверить, ждут ли очереди события определённого типа |
pygame.event.clear | удалить все события из очереди |
pygame.event.event_name | возвращает имя для типа события. Строка находится в стиле WordCap |
pygame.event.set_blocked | проверяет, какие события не разрешены в очереди |
pygame.event.set_allowed | проверяет, какие события разрешены в очереди |
pygame.event.get_blocked | проверить, заблокирован ли тип события из очереди |
pygame.event.set_grab | проверяет совместное использование устройств ввода с другими приложениями |
pygame.event.get_grab | проверить, работает ли программа на устройствах ввода данных |
pygame.event.post | поместить новое событие в очередь |
pygame.event.Event | создать новый объект события |
pygame.event.EventType | Объект Python, представляющий событие SDL. Экземпляры пользовательских событий создаются с вызовом функции Event. Тип EventType не может быть напрямую вызван. Экземпляры EventType поддерживают назначение и удаление атрибутов. |
Pygame отслеживает все сообщения о событиях через очередь событий. Процедуры в этом модуле помогают управлять этой очередью событий. Входная очередь сильно зависит от модуля отображения (display) pygame. Если дисплей не был инициализирован и видеорежим не установлен, очередь событий не будет работать.
Существует множество способов доступа к очереди событий. Просто проверять существование событий, захватывать их непосредственно из стека.
Мышь
Модуль pygame.mouse для работы с мышью
pygame.mouse.get_pressed | получить состояние кнопок мыши |
pygame.mouse.get_pos | получить позицию курсора мыши |
pygame.mouse.get_rel | получить количество движений мыши |
pygame.mouse.set_pos | установить позицию курсора мыши |
pygame.mouse.set_visible | скрыть или показать курсор мыши |
pygame.mouse.get_focused | проверяет, принимает ли дисплей ввод мыши |
pygame.mouse.set_cursor | установить изображение для курсора мыши |
pygame.mouse.get_cursor | получить изображение для курсора мыши |
Функции мыши можно использовать для получения текущего состояния устройства мышь. Эти функции также могут изменять курсор мыши.
Когда режим отображения (display) установлен, очередь событий начнет принимать события мыши. Кнопки мыши генерируют события pygame.MOUSEBUTTONDOWN и pygame.MOUSEBUTTONUP , когда они нажимаются и отпускаются. Эти события содержат атрибут кнопки, указывающий, какая кнопка была нажата. Колесо мыши будет генерировать pygame.MOUSEBUTTONDOWN и pygame.MOUSEBUTTONUP события при прокрутке.
Когда колесо повернуто вверх, кнопка будет установлена на 4, вниз -5. Всякий раз, когда мышь перемещается, генерируется событие pygame.MOUSEMOTION . Движение мыши разбито на небольшие и точные события движения. По мере перемещения мыши многие события движения будут помещены в очередь. События движения мыши, которые неправильно очищены от очереди событий, являются основной причиной того, что очередь событий заполняется.
Пример. Нарисовать курсор под текущей позицией мыши.
x, y = pygame.mouse.get_pos() x -= mouse_cursor.get_width()/2 y -= mouse_cursor.get_height()/2 screen.blit(mouse_cursor, (x, y))
Определить какая кнопка была нажата на мышке можно используя значение event.button:
1 - left click 2 - middle click 3 - right click 4 - scroll up 5 - scroll down
Координаты курсора при нажатии кнопки мыши находятся в event.pos .
Пример. Перемещать картинку курсором мыши.
import pygame, sys, time from pygame.locals import * pygame.init() FPS=30 fpsClock=pygame.time.Clock() width=500 height=500 mainSurface=pygame.display.set_mode((width,height),0,32) pygame.display.set_caption('Keyb moves') background=pygame.image.load('images//bg1.jpg') sprite=pygame.image.load('images//pict2.gif') # Place image to the center of mainSurface image_pos = ((mainSurface.get_width() - sprite.get_width())/2, (mainSurface.get_height() - sprite.get_height())/2) doMove = False # game loop while True: fpsClock.tick(FPS) # frame rate mainSurface.blit(background,(0,0)) # get all events from the queue for event in pygame.event.get(): # loop events queue if event.type == QUIT: # window close X pressed pygame.quit() sys.exit() if event.type == KEYDOWN and event.key == K_ESCAPE: # ESC key pressed pygame.quit() sys.exit() if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: # левая кнопка мыши doMove = True if event.button == 3: # правая кнопка мыши image_pos = ((mainSurface.get_width() - sprite.get_width())/2, (mainSurface.get_height() - sprite.get_height())/2) doMove = False if event.type == pygame.MOUSEBUTTONUP: doMove = False if event.type == MOUSEMOTION and doMove: image_pos = event.pos mainSurface.blit(sprite,image_pos) pygame.display.update()
Клавиатура
Модуль pygame.key
Этот модуль содержит функции для работы с клавиатурой.Очередь событий получает события pygame.KEYDOWN и pygame.KEYUP при нажатии и отпускании клавиш клавиатуры.
Оба события имеют ключевой атрибут, который представляет собой целочисленный идентификатор, представляющий каждую клавишу на клавиатуре.Событие pygame.KEYDOWN имеет дополнительные атрибуты: unicode и scancode. unicode представляет собой одну символьную строку, которая соответствует введённому символу. Scancode представляет собой код для конкретной платформы.
Получить код клавиши:
pressed_keys = pygame.key.get_pressed() if pressed_keys[K_SPACE]: # Space key has been pressed fire()
Существует много клавиатурных констант, они используются для представления клавиш на клавиатуре. Ниже приведен список всех клавиатурных констант:
KeyASCII | ASCII | CommonName |
---|---|---|
K_BACKSPACE | \b | backspace |
K_TAB | \t | tab |
K_CLEAR | clear | |
K_RETURN | \r | return |
K_PAUSE | pause | |
K_ESCAPE | ^[ | escape |
K_SPACE | space | |
K_EXCLAIM | ! | exclaim |
K_QUOTEDBL | « | quotedbl |
K_HASH | # | hash |
K_DOLLAR | $ | dollar |
K_AMPERSAND | & | ampersand |
K_QUOTE | quote | |
K_LEFTPAREN | ( | leftparenthesis |
K_RIGHTPAREN | ) | rightparenthesis |
K_ASTERISK | * | asterisk |
K_PLUS | + | plussign |
K_COMMA | , | comma |
K_MINUS | — | minussign |
K_PERIOD | . | period |
K_SLASH | / | forwardslash |
K_0 | 0 | 0 |
K_1 | 1 | 1 |
K_2 | 2 | 2 |
K_3 | 3 | 3 |
K_4 | 4 | 4 |
K_5 | 5 | 5 |
K_6 | 6 | 6 |
K_7 | 7 | 7 |
K_8 | 8 | 8 |
K_9 | 9 | 9 |
K_COLON | : | colon |
K_SEMICOLON | ; | semicolon |
K_LESS | less-thansign | |
K_EQUALS | = | equalssign |
K_GREATER | > | greater-thansign |
K_QUESTION | ? | questionmark |
K_AT | @ | at |
K_LEFTBRACKET | [ | leftbracket |
K_BACKSLASH | \ | backslash |
K_RIGHTBRACKET | ] | rightbracket |
K_CARET | ^ | caret |
K_UNDERSCORE | _ | underscore |
K_BACKQUOTE | ` | grave |
K_a | a | a |
K_b | b | b |
K_c | c | c |
K_d | d | d |
K_e | e | e |
K_f | f | f |
K_g | g | g |
K_h | h | h |
K_i | i | i |
K_j | j | j |
K_k | k | k |
K_l | l | l |
K_m | m | m |
K_n | n | n |
K_o | o | o |
K_p | p | p |
K_q | q | q |
K_r | r | r |
K_s | s | s |
K_t | t | t |
K_u | u | u |
K_v | v | v |
K_w | w | w |
K_x | x | x |
K_y | y | y |
K_z | z | z |
K_DELETE | delete | |
K_KP0 | keypad0 | |
K_KP1 | keypad1 | |
K_KP2 | keypad2 | |
K_KP3 | keypad3 | |
K_KP4 | keypad4 | |
K_KP5 | keypad5 | |
K_KP6 | keypad6 | |
K_KP7 | keypad7 | |
K_KP8 | keypad8 | |
K_KP9 | keypad9 | |
K_KP_PERIOD | . | keypadperiod |
K_KP_DIVIDE | / | keypaddivide |
K_KP_MULTIPLY | * | keypadmultiply |
K_KP_MINUS | — | keypadminus |
K_KP_PLUS | + | keypadplus |
K_KP_ENTER | \r | keypadenter |
K_KP_EQUALS | = | keypadequals |
K_UP | uparrow | |
K_DOWN | downarrow | |
K_RIGHT | rightarrow | |
K_LEFT | leftarrow | |
K_INSERT | insert | |
K_HOME | home | |
K_END | end | |
K_PAGEUP | pageup | |
K_PAGEDOWN | pagedown | |
K_F1 | F1 | |
K_F2 | F2 | |
K_F3 | F3 | |
K_F4 | F4 | |
K_F5 | F5 | |
K_F6 | F6 | |
K_F7 | F7 | |
K_F8 | F8 | |
K_F9 | F9 | |
K_F10 | F10 | |
K_F11 | F11 | |
K_F12 | F12 | |
K_F13 | F13 | |
K_F14 | F14 | |
K_F15 | F15 | |
K_NUMLOCK | numlock | |
K_CAPSLOCK | capslock | |
K_SCROLLOCK | scrollock | |
K_RSHIFT | rightshift | |
K_LSHIFT | leftshift | |
K_RCTRL | rightcontrol | |
K_LCTRL | leftcontrol | |
K_RALT | rightalt | |
K_LALT | leftalt | |
K_RMETA | rightmeta | |
K_LMETA | leftmeta | |
K_LSUPER | leftWindowskey | |
K_RSUPER | rightWindowskey | |
K_MODE | modeshift | |
K_HELP | help | |
K_PRINT | printscreen | |
K_SYSREQ | sysrq | |
K_BREAK | break | |
K_MENU | menu | |
K_POWER | power | |
K_EURO | Euro |
Направленное движение с помощью клавиш
Можно перемещать изображение на экране с клавиатуры, назначая клавиши для перемещений: вверх, вниз, влево, вправо.
Создать картинку, например:
Проверить очередь событий:
Проверить, является ли полученное событие нажатием на клавиши со стрелками:
Если — да, то получмить код нажатой клавиши и сформировать новые координаты для картинки:
И нарисовать картинку в новом месте:
import pygame, sys, time from pygame.locals import * pygame.init() FPS=30 fpsClock=pygame.time.Clock() width=500 height=500 mainSurface=pygame.display.set_mode((width,height),0,32) pygame.display.set_caption('Keyb moves') background=pygame.image.load('images//bg1.jpg') sprite=pygame.image.load('images//pict2.gif') # Create moving image # Place image to the center of mainSurface spritex=(mainSurface.get_width() - sprite.get_width())/2 spritey=(mainSurface.get_height() - sprite.get_height())/2 direction=False # ---> def move(direction, spritex, spritey): # This function moves recalculates new image coordinates if direction: if direction == K_UP: spritey-=5 elif direction == K_DOWN: spritey+=5 if direction == K_LEFT: spritex-=5 elif direction == K_RIGHT: spritex+=5 return spritex, spritey # ---> # game loop while True: fpsClock.tick(FPS) # define frame rate mainSurface.blit(background,(0,0)) mainSurface.blit(sprite,(spritex,spritey)) # get all events from the queue for event in pygame.event.get(): # loop events queue, remember in 'direction' pressed key code if event.type==QUIT: # window close X pressed pygame.quit() sys.exit() if event.type==KEYDOWN and event.key == K_ESCAPE: # ESC key pressed pygame.quit() sys.exit() if event.type == KEYDOWN: direction = event.key # Other key pressed if event.type == KEYUP: direction = False # Key released # calculate new image position spritex, spritey = move(direction, spritex, spritey) pygame.display.update()
Объект Surface
pygame.Surface — объект pygame для представления изображений
Surface((width, height), flags=0, depth=0, masks=None) -> Surface Surface((width, height), flags=0, Surface) -> Surface
Наложение поверхностей, прозрачность.
#-*-coding: utf-8-*- import pygame pygame.init() # Create base surface screen = pygame.display.set_mode((500,500)) # Create new surface surface1 = pygame.Surface((150,150)) surface1.fill((255,0,0)) surface1.set_alpha(150) # surface2 = pygame.Surface((100,100)) surface2.fill((255,255,0)) surface2.set_alpha(100) # Create image bgImg = pygame.image.load("images//bg3.jpg") bgImg = pygame.transform.scale(bgImg,(500,500)) # pict1 = pygame.image.load("images//pict1.jpg") pict1 = pygame.transform.scale(pict1,(130,130)) pict1.set_alpha(100) # pict2 = pygame.image.load("images//pict2.gif") pict2 = pygame.transform.scale(pict2,(50,50)) clock = pygame.time.Clock() running = 1 dX = dY = 1 x = y = 0 while running: clock.tick(50) event = pygame.event.poll() if event.type == pygame.QUIT: running = 0 x += 8 * dX y += 6 * dY if (y= (screen.get_height() - pict2.get_height())) : dY *= -1 if (x= (screen.get_width() - pict2.get_width())) : dX *= -1 screen.blit(bgImg,(0,0)) surface1.blit(pict1,(0,0)) screen.blit(surface1,(20,50)) screen.blit(surface2,(150,150)) screen.blit(pict2,(x,y)) pygame.display.flip() pygame.quit()
Управление временем
Модуль pygame.time содержит объект Clock, который можно использовать для отслеживания
времени. Чтобы создать объект типа: время, вызывается конструктор pygame.time.Clock:
clock = pygame.time.Clock()
Когда создан объект clock, можно вызвать его функцию tick один раз за кадр,
которая возвращает время, прошедшее со времени предыдущего вызова в миллисекундах:
time_passed = clock.tick ()
Функция tick может использовать необязательный параметр для установления максимальной частоты кадров. Этот параметр нужен, если игра запущена на рабочем компьютере и необходимо контролировать, чтобы она не использовала всю его вычислительная мощность на 100%:
# Игра будет работать со скоростью не более 30 кадров в секунду
time_passed = clock.tick (30)
Звуки
Для управления звуком используется модуль pygame.mixer . Он отвечает за любые действия со звуками.
Загружаем звуковой файл в формате *.wav
sound = pygame.mixer.Sound(«sound.wav»)
(загружаем до игрового цикла, т.к. это очень долгая операция)
Столкновения (collisions)
При написании игр часто возникает необходимость проверять взаимное расположение объектов на экране, отслеживать моменты их столкновений, пересечений.
Эта задача может быть реализована разными способами.
Например, используя объект Rect
#-*-coding:utf-8-*- import pygame, sys, time from pygame.locals import * pygame.init() FPS = 30 fpsClock = pygame.time.Clock() winWidth = 500 winHeight = 500 mainSurface = pygame.display.set_mode((winWidth,winHeight),0,32) pygame.display.set_caption('Collisions test') background = pygame.image.load('images//bg1.jpg') # Рисуем неподвижные компоненты на поверхности background # Места расположения границ border1Rect = pygame.Rect(0,0,100,500) border2Rect = pygame.Rect(0,150,300,50) # границы border1 = pygame.draw.rect(background, (0,0,0), border1Rect, 0) border2 = pygame.draw.rect(background, (0,0,0), border2Rect, 0) # Записываем их в массив borders = [] borders.append((border1,border1Rect)) borders.append((border2,border2Rect)) # Подвижный блок blockWidth = 50 blockHeight = 50 blockStep = 1 blockColor = (255,0,0) # Начальные координаты подвижного блока - по центру blockX = (mainSurface.get_width() - blockWidth)/2 blockY = (mainSurface.get_height() - blockHeight)/2 blockPosition = (blockX, blockY) direction = False # описание функции ---> def newPosition(dirFlag, pos): (x,y) = pos # Функция пересчитывает координаты для подвижного объекта if dirFlag: if dirFlag == K_UP: y -= blockStep elif dirFlag == K_DOWN: y += blockStep if dirFlag == K_LEFT: x -= blockStep elif dirFlag == K_RIGHT: x += blockStep return (x, y) # ---> while True: # Игра - начало # Частота обновления экрана fpsClock.tick(FPS) # Рисуем неподвижные компоненты mainSurface.blit(background,(0,0)) # Рисуем подвижный компонент blockRect = pygame.Rect(blockPosition, (blockWidth, blockHeight)) block = pygame.draw.rect(mainSurface, blockColor, blockRect, 1) # просматриваем очередь событий for event in pygame.event.get(): # loop events queue, remember in 'direction' pressed key code if event.type == QUIT: # window close X pressed pygame.quit() sys.exit() if event.type == KEYDOWN and event.key == K_ESCAPE: # ESC key pressed pygame.quit() sys.exit() if event.type == KEYDOWN: direction = event.key # Other key pressed if event.type == KEYUP: direction = False # Key released # Cохраняем старые координаты подвижного блока savedPosition = blockPosition # Рассчитываем новые координаты подвижного блока blockPosition = newPosition(direction, blockPosition) # Проверяем их корректность for border in borders: testRect = pygame.Rect(blockPosition, (blockWidth, blockHeight)) if testRect.colliderect(border[1]): print ("Столкновение !") # Возвращаем старые координату blockPosition = savedPosition else: print ("ok") pygame.display.update() # Игра - конец
Или используя поверхности — surface
#-*-coding:utf-8-*- import pygame, sys, time from pygame.locals import * # Блоки-ограничители рисуются как отдельные поверхности # Между ними курсором перемещаем мячик FPS = 30 # кадров в сек # Размеры окна игры width = 500 height = 500 # Заголовок окна игры title = "Collisions detection test" # Сообщение в консоль игры info = "Нет столкновений \n" # Переменная - индикатор движения direction = False # Шаг движения myStep = 2 pygame.mixer.init() pygame.mixer.music.load("voice-prompts-reaction-reaction-1-child-3-yrs-oops-human-voice-kid-speak-talk.mp3") pygame.init() fpsClock = pygame.time.Clock() mainSurface=pygame.display.set_mode((width,height),0,32) pygame.display.set_caption(title) background=pygame.image.load('images//bg1.jpg') # Фон sprite = pygame.image.load('images//pict2.gif') # Подвижная картинка # Начальные координаты подвижной картинки # Важно, чтобы в начале работы она не перекрывала ни один блок spriteX=mainSurface.get_width() - sprite.get_width() spriteY=mainSurface.get_height() - sprite.get_height() # Неподвижные блоки - все сохраняем в одном списке # Структура списка blocks: # каждый элемент - пара значений: (поверхность, область её размещения) # blocks[0] - первый элемент списка, blocks[0][0] - surface первого элемента,blocks[0][1] - Rect первого элемента blocks = [] block1 = pygame.Surface((200,200)) block1.set_alpha(80) block1.fill((255,0,0)) block1Rect = pygame.Rect(0,0,block1.get_width(), block1.get_height()) blocks.append((block1,block1Rect)) # block2 = pygame.Surface((100,200)) block2.fill((0,255,0)) block2Rect = pygame.Rect(400,0,block2.get_width(), block2.get_height()) blocks.append((block2,block2Rect)) # block3 = pygame.Surface((300,100)) block3.fill((0,0,255)) block3Rect = pygame.Rect(0,350,block3.get_width(), block3.get_height()) blocks.append((block3,block3Rect)) # закончили с описанием 3-х блоков # *********> def newPosition (direction, spriteX, spriteY): # Функция пересчитывает координаты новой позиции подвижного объекта # Проверяем столкновений со всеми блоками-границаи global myStep if direction: if direction == K_UP: spriteY -= myStep elif direction == K_DOWN: spriteY += myStep elif direction == K_LEFT: spriteX -= myStep elif direction == K_RIGHT: spriteX += myStep return spriteX, spriteY # *********> # *********> def collisionDetected(): global blocks global spriteRectNew colFlag = False # Проверка столкновений со всеми блоками в массиве блоков for block in blocks: if spriteRectNew.colliderect(block[1]): collisionDir = direction colFlag = True return colFlag # *********> # Цикл игры while True: fpsClock.tick(FPS) # Частота обновления экрана # Обрабатываем очередь событий - начало for event in pygame.event.get(): # В цикле берём из очереди очередное событие, запоминаем в переменной event # Проверяем тип события и выполняем соответствующие лействия if event.type == QUIT: # Тип проверяемого события НАЖАТ Х В ОКНЕ ИГРЫ pygame.quit() sys.exit() if event.type == KEYDOWN and event.key == K_ESCAPE: # ESC key pressed pygame.quit() sys.exit() # Следующая строка получает управление только тогда, когда не отработали предыдущие проверки кода события # то есть произошло событие, отличное от перечисленных выше if event.type == KEYDOWN: direction = event.key if event.type == KEYUP: direction = False # Кнопка отпущена # Обрабатываем очередь событий - конец # Текущее место расположения подвижной картинки spriteRect = pygame.Rect(spriteX,spriteY,sprite.get_width(), sprite.get_height()) # Сохраняем старые координаты oldPos = (spriteX, spriteY) # Вычмсляем новые координаты, анализируя нажатые кнопки spriteX, spriteY = newPosition(direction, spriteX, spriteY) # Вычисляем новое место расположения картинки spriteRectNew = pygame.Rect(spriteX,spriteY,sprite.get_width(), sprite.get_height()) # Проверяем, не пересекает ли новое место блоки. Если пересекает, то вовращпни картинке старые координаты if collisionDetected(): (spriteX, spriteY) = oldPos # Play OOPS! pygame.mixer.music.play() # Рисуем всё на экране # Фон mainSurface.blit(background,(0,0)) # Блоки for block in blocks: mainSurface.blit(block[0],(block[1].x,block[1].y)) # Картинку mainSurface.blit(sprite,(spriteRect.x,spriteRect.y)) # Обновляем экран pygame.display.update()