Как удалить объект в pygame
Перейти к содержимому

Как удалить объект в pygame

  • автор:

Как удалить объект спрайта Pygame?

Мне нужно удалять спрайт из массива, когда он выходит за границу.
Вот код:

import pygame pygame.init() win = pygame.display.set_mode((700, 400)) pygame.display.set_caption("Защита") pygame.display.set_icon(pygame.image.load("images/sheald.png")) fon = pygame.image.load("images/fon.png") class Bullet(pygame.sprite.Sprite): def __init__(self, y, speed, image): pygame.sprite.Sprite.__init__(self) self.image = pygame.image.load(image).convert_alpha() self.rect = self.image.get_rect(center=(70, y + 20)) self.speed = speed def update(self): self.rect.x += self.speed win.blit(self.image, self.rect) playerY = 70 playerX = 20 bull = [] bulletsNumber = 10 FPS = 60 def shoot(): global bulletsNumber if bulletsNumber > 0: bulletsNumber -= 1 bullet = Bullet(playerY, 2, 'images/bullet.png') bull.append(bullet) def window(): win.blit(fon, (0, 0)) pygame.draw.rect(win, (236, 218, 103), (playerX, playerY, 40, 40)) for bul in bull: bul.update() if bul.rect.x >= 700: **тут нужно удалить объект** 

window — это обновление экрана shoot — создание объекта Как это сделать?

Отслеживать

12.5k 7 7 золотых знаков 19 19 серебряных знаков 48 48 бронзовых знаков

задан 26 мар 2021 в 16:25

Tikhon_ Yaremchuk Tikhon_ Yaremchuk

Pygame: анимация удаления спрайта

Author24 — интернет-сервис помощи студентам

Всем добрый день! Возник один вопрос в ходе написания игры. Надо сделать анимацию удаления спрайта. Суть в том, что этот спрайт должен «сползти» с окна. Я просто увеличивал его координаты по оси y, пока он не выйдет за пределы экрана. Однако в ходе этого, он замазывает все остальные изображения на экране, находящиеся на его пути вниз. Как можно реализовать эту вешь?

94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:

Перемещение спрайта в pygame
Доброго времени суток. Начал писать несложный шутер с помощью pygame, есть небольшая проблема с.

Анимация в pygame
Как в pygame создать анимацию объекта?

Анимация закрашивает спрайт | pygame + pyganim
Здравствуйте. Столкнулся с проблемой: захотел добавить фон в игру. . Вот тако вот получилось.

При импорте pygame пишет что нет модуля pygame.base
Устанавливаю для kivy.Всё есть (sython,gsstreamer,kivy,pyscripter,python) , а вот фраем. pygame не.

Ошибка в pygame AttributeError: ‘pygame.Rect’ object has no attribute ‘blit’
Создаю игру, крестики нолики Почему возникает ошибка и как ее исправить? AttributeError.

1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073
Надо перерисовывать все что есть на экране
Регистрация: 02.12.2018
Сообщений: 2

А есть какая-либо функция, чтобы сделать ‘скриншот’ экрана и вместо того, чтобы перерисовывать все изображения, просто рисовать уже сделанный скриншот

1291 / 908 / 479
Регистрация: 05.12.2013
Сообщений: 3,073

Не надо придумывать не пойми чего, вся отрисовка происходит внутри главного цикла, на каждом шаге экран заливается и затем отрисовываются все объекты

87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
Помогаю со студенческими работами здесь

pygame.error: cannot convert without pygame.display initialized
Только начал изучать спрайты Выдаёт ошибку: Traceback (most recent call last): File.

Pygame ошибка module ‘pygame’ has no ‘init’ member
Всем здравствуйте. Недавно начал работать с VS code и выдает такая ошибка. Прикрепляю полностью.

Python, Pygame, артефакты при движения спрайта по экрану
Здравствуйте, не так давно начал изучать питон, вместе с ним и pygame. Несколько дней назад.

Анимация спрайта
Есть такая проблема, только начал изучать ООП и C# делаю свою игру на Unity, написал .

анимация спрайта
Доброго времени суток. Нужно анимировать спрайт, в нем 6 кадров всего, но не знаю как это.

Анимация спрайта
Помогите чем могете?(Хочу реализовать анимированное движение персонажа, т.е при нажатии например.

Или воспользуйтесь поиском по форуму:

Как удалить объект при выходе за экран?

Пишу игру по примеру, есть задание удалить пулю при выходе за правую часть экрана.
Ври выходе пули за экран она не удаляется, что соответственно не дает выпустить новую, хотя в коде вроде все прописал(смотри внизу)

from bullet import Bullet

def check_keydown_events(event, ai_settings, screen, ship, bullets):
#»»»Реагирует на нажатие клавиш.»»»
if event.key == pygame.K_UP:
ship.moving_up = True
elif event.key == pygame.K_DOWN:
ship.moving_down = True
elif event.key == pygame.K_SPACE:
fire_bullet(ai_settings, screen, ship, bullets)

def fire_bullet(ai_settings, screen, ship, bullets):
#»»»Выпускает пулю, если максимум еще не достигнут.»»»
# Создание новой пули и включение ее в группу bullets.
if len(bullets) < ai_settings.bullets_allowed:
new_bullet = Bullet(ai_settings, screen, ship)
bullets.add(new_bullet)
# Создание новой пули и включение ее в группу bullets.

def check_keyup_events(event, ship):
#»»»Реагирует на отпускание клавиш.»»»
if event.key == pygame.K_UP:
ship.moving_up = False
elif event.key == pygame.K_DOWN:
ship.moving_down = False

def check_events(ai_settings, screen, ship, bullets):
«»»Обрабатывает нажатия клавиш и события мыши.»»»
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event, ai_settings, screen, ship, bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event, ship)

def update_screen(ai_settings, screen, ship, bullets):
#»»»Обновляет изображения на экране и отображает новый экран.»»»
# При каждом проходе цикла перерисовывается экран.
screen.fill(ai_settings.bg_color)
# Все пули выводятся позади изображений корабля и пришельцев.
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
# Отображение последнего прорисованного экрана.
pygame.display.flip()

def update_bullets(bullets):
bullets.update()
# Удаление пуль, вышедших за край экрана.
for bullet in bullets.copy():
if bullet.rect.right bullets.remove(bullet)

  • Вопрос задан более года назад
  • 157 просмотров

Удаление объекта Pygame

Мне нужна помощь в удалении объекта, и я имею в виду удаление, а не перерисовку или другие вещи. Мой код пока что:

def detect_collision(player_pos, enemy_pos): p_x = player_pos[0] p_y = player_pos[1] e_x = enemy_pos[0] e_y = enemy_pos[1] if (e_x >= p_x and e_x < (p_x + player_size)) or (p_x >= e_x and p_x < (e_x+enemy_size)): if (e_y >= p_y and e_y < (p_y + player_size)) or (p_y >= e_y and p_y < (e_y+enemy_size)): return True return False def bullets(): b_x = player_pos[0] b_y = player_pos[1] keep_going = True pygame.draw.rect(screen, TEAL, (b_x, b_y, 15, 50)) while keep_going: b_y += 75 if detect_collision(player_pos, enemy_pos): # deleting part here 

Вот что делает моего игрока и врага:

enemy_size = 50 enemy_pos = [random.randint(0,WIDTH-enemy_size), 0] enemy_list = [enemy_pos] def drop_enemies(enemy_list): delay = random.random() if len(enemy_list) < 10 and delay < 0.1: x_pos = random.randint(0,WIDTH-enemy_size) y_pos = 0 enemy_list.append([x_pos, y_pos]) def draw_enemies(enemy_list): for enemy_pos in enemy_list: pygame.draw.rect(screen, RED, (enemy_pos[0], enemy_pos[1], enemy_size, enemy_size)) def update_enemy_positions(enemy_list, score): for idx, enemy_pos in enumerate(enemy_list): if enemy_pos[1] >= 0 and enemy_pos[1] < HEIGHT: enemy_pos[1] += SPEED else: enemy_list.pop(idx) score += 1 return score 
player_size = 50 player_pos = [WIDTH/2, HEIGHT-2*player_size] pygame.draw.rect(screen, TEAL, (player_pos[0], player_pos[1], player_size, player_size)) 

Поделиться Источник 30 июля 2020 в 01:47

4 ответа

Лучший способ решить вашу проблему - научиться использовать объекты Sprite в pygame . Вместе с объектами Group , они уже могут делать то, что вы хотите, прямо из коробки.

Вкратце, ваш "враг" должен быть экземпляром какого-то подкласса Sprite , и вы добавите его в экземпляр Group (вместо создания собственного enemy_list ). Когда вы хотите, чтобы враг умер, вы можете вызвать метод kill() на нем, который удалит его из Group . Это служит для удаления его из игры, так как вы должны использовать методы на объекте Group для обновления и отрисовки всех спрайтов, которые он содержит (но не тех, которые были убиты).

Поделиться 30 июля 2020 в 02:46

Я предполагаю, что на экране есть только один пуля за раз, так как вы не упоминали список пуль. Вы, вероятно, создаете пулю, нажав на пробел или что-то, что я оставлю здесь. Одно, что нужно учесть в вашей функции bullets() , это перемещение, отрисовка и проверка столкновения в той же функции. Обратите внимание, что всегда хорошая идея сделать функцию только одним.

def draw_bullet(): move_bullet() pygame.draw.rect(screen, TEAL, (b_x, b_y, 15, 50)) def move_bullet(): if b_y < HEIGHT: b_y += 75 else: create_bullet = False # explained below 

Таким образом, чтобы создать пулю, у вас должна быть логическая переменная create_bullet . Таким образом:

# mainloop if user hits spacebar (or the key used to create bullet) : create_bullet = true b_x = player_pos[0] # initialise bullet b_y = player_pos[1] if create_bullet: draw_bullet() if detect_collision((b_x, b_y), enemy_pos): # assuming b_x, b_y are global variable or something, so that they are actually defined and equal to bullet's x and y pos # if bullet and enemy collide, remove them both enemy_list.remove(enemy) create_bullet = False if detect_collision(player_pos, enemy_pos): # reset player pos, or whatever you want to do 

Вы говорите, что хотите удалить его, а не просто нарисовать поверх него. Однако способ, которым pygame генерирует экран'moving/video-like' это путем непрерывного рисования поверх. Например: игрок рисуется в (10, 10) и затем рисуется в (20, 10) так, что выглядит так, будто игрок переместился. Однако это делается очень быстро, чтобы вы не увидели, что он 'исчезает' и 'повторится'. Вот что делает вышеуказанный код.

При попадании в пробел, он 'создает' пулю, установив ее значение x и y в текущую позицию игрока и установив create_bullet = true. Затем, на каждой итерации основного цикла, если create_bullet является истинным, он перемещается, а затем рисует пулю. Если пуля перемещается за пределы экрана или столкнётся с врагом, create_bullet = False, то он перестанет рисовать ее, и на следующей итерации основного цикла, пуля будет нарисована поверх фона и 'исчезнет'.

Поделиться 30 июля 2020 в 05:54

Было бы полезно изучить Sprites и SpriteGroups для отслеживания сущностей в вашей игре. У них есть множество встроенных функциональных возможностей, которые упростят работу.

Вот демонстрация, которую я имею, чтобы сгруппировать спрайты, удаляя те, которые столкнутся с указателем мыши:

import random import pygame screen_width, screen_height = 640, 480 def get_random_position(): """return a random (x,y) position in the screen""" return ( random.randint(0, screen_width - 1), # randint includes both endpoints. random.randint(0, screen_height - 1), ) color_list = ["red", "orange", "yellow", "green", "cyan", "blue", "blueviolet"] colors = [pygame.color.Color(c) for c in color_list] class PowerUp(pygame.sprite.Sprite): def __init__(self): pygame.sprite.Sprite.__init__(self) width, height = 64, 32 self.color = random.choice(colors) self.image = pygame.Surface([width, height]) self.image.fill(self.color) # Fetch the rectangle object that has the dimensions of the image self.rect = self.image.get_rect() # then move to a random position self.update() def update(self): # move to a random position self.rect.center = get_random_position() if __name__ == "__main__": pygame.init() screen = pygame.display.set_mode((screen_width, screen_height)) pygame.display.set_caption("Sprite Group Collision Demo") clock = pygame.time.Clock() # for limiting FPS FPS = 60 exit_demo = False # create a sprite group to track the power ups. power_ups = pygame.sprite.Group() for _ in range(10): power_ups.add(PowerUp()) # create a new power up and add it to the group. # main loop while not exit_demo: for event in pygame.event.get(): if event.type == pygame.QUIT: exit_demo = True elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: exit_demo = True elif event.key == pygame.K_SPACE: power_ups.update() elif event.type == pygame.MOUSEBUTTONUP: for _ in range(10): power_ups.add(PowerUp()) # Update State: check for collisions for p in power_ups: if p.rect.collidepoint(pygame.mouse.get_pos()): power_ups.remove(p) # draw background screen.fill(pygame.Color("black")) # use black background # draw sprites power_ups.draw(screen) # update screen pygame.display.update() clock.tick(FPS) pygame.quit() quit() 

Нажатие кнопки мыши создает больше спрайтов, и нажатие пробельной строки рандомизирует их положение.

Метод update() спрайта пули будет регулировать положение спрайта по его скорости, например, self.rect.x += SPEED , и вам нужно будет вызывать метод группы спрайтов .update() в каждом игровом цикле.

Поделиться 30 июля 2020 в 02:52

Правильно, поэтому у вас есть список позиций противника в enemy_list . Это хороший старт. Я не вижу bullet_list , поэтому я предполагаю, что за раз будет только одна пуля, позиционированная на b_x , b_y .

Таким образом, основной цикл для этой программы может выглядеть примерно так:

### Main Loop while not game_over: # handle user input # move the player # move the bullet (if any) # move the enemies # if there's a bullet, did it hit an enemy? # remove enemy hit from enemy_list # Did an enemy in enemy_list, hit the player? # do game-over # clear the screen # paint the player # paint the bullet (if any) # paint every enemy in enemy_list 

Где столкновение противника и удаление списка могут выглядеть примерно так: (Я попытался максимально соответствовать виду вашего кода.)

# if a bullet is on-screen (non 0,0), see if it hits an enemy if ( b_x != 0 and b_y != 0 ): hit_enemy_idx = None for idx, enemy_pos in enumerate( enemy_list ): # check for collision if detect_collision( ( b_x, b_y ), enemy_pos ): hit_enemy = idx # note the enemy index b_x, b_y = 0, 0 # erase the bullet break # exit the loop when hit found # If the bullet hit an enemy, remove from list if hit_enemy_idx != None: del( enemy_list[ hit_enemy_idx ] ) # delete hit enemy from list 

Мы выполняем итерацию по списку противника, проверяя наличие столкновения. Как только обнаруживается удар, он сохраняет индекс, по которому был удален противник, и останавливает цикл.

Следующий шаг - удаление противника из списка. Я написал это в отдельном блоке, а не помещаю его перед break в цикл. Это связано с тем, что неожиданные результаты могут возникнуть при изменении списка при итерации по нему.В данном конкретном случае это было бы хорошо, но это что-то, о чем нужно быть осторожным, как начинающий.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *