Задать вопрос
@LarkovAA

Спрайт снаряд после выстрела поворачивается по направлению другого спрайта(танка). Не знаю почему так происходит?

Добрый день. Создаю игру есть объект танка который производит выстрел. Проблема в том что когда снаряд летит и я поворачиваю танк направление снаряда то же поворачивается в данную сторону. Не понимаю почему так происходит. Помогите плиз !!
import pygame
import creating_map
import copy

pygame.init()
# Константы
screen_dimensions = (1000, 1000)
exit = True
playing_field = 25
grass = pygame.image.load('images/grass.png')
see = pygame.image.load('images/see.png')
FPS = 60
clock = pygame.time.Clock()
WHITE = (255,255,255)
there_turn = False

if __name__ == "__main__":

    # Создаем класс танка
    class Panzer:
        def __init__(self):
            self.panze_img = pygame.image.load('images/gamers_panzer.png')
            self.panze_movement = pygame.math.Vector2(2, 0)
            self.panzer_weigth = 100
            self.panzer_heigth = 100
            self.panzer_vector = pygame.math.Vector2((self.panzer_weigth, self.panzer_heigth))
            self.new_panzer_position = None


        # Рисуем новые границы танка
        def draw_the_new_coordinates_of_the_tank(self):
            panze_corner = self.panze_movement.angle_to((1,0))
            self.new_panzer_position = pygame.transform.rotate(self.panze_img, panze_corner)
            self.new_panzer_position.set_colorkey(WHITE)
            self.position_panzer = self.new_panzer_position.get_rect(center=(round(self.panzer_vector.x), (round(self.panzer_vector.y))))
            return self.new_panzer_position, self.position_panzer


    class Projectile(pygame.sprite.Sprite):
        def __init__(self, weigth, heigth, corner):
            pygame.sprite.Sprite.__init__(self)
            self.projectile_img = pygame.image.load('images/projectile.png')
            self.projectile = pygame.math.Vector2((weigth, heigth))
            self.projectile_corner = corner
            self.new_position_projectile = None
            self.new_position_projectile = pygame.transform.rotate(self.projectile_img, self.projectile_corner)
            self.new_position_projectile.set_colorkey(WHITE)

        def update(self):
            self.projectile += projectile_speed
            self.position_projectile = self.new_position_projectile.get_rect(center=(round(self.projectile.x), (round(self.projectile.y)))).copy()
            display.blit(self.new_position_projectile, self.position_projectile)



    # Настройка дисплея
    display = pygame.display.set_mode(screen_dimensions)

    # Создаем переменную в которую будем хранить класс panzer
    panzer = Panzer()
    # Создаем список где будем хранить созданные объекты снаряда
    projectiles = pygame.sprite.Group()
    projectile_speed = pygame.math.Vector2((4, 0))
    list_projectiles = []
    while exit:
        # Выгружаем из другого файла редактор карты
        creating_map.creating_map()

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                pygame.quit()
                exit = False

        continuous_movement = pygame.key.get_pressed()
        if continuous_movement[pygame.K_UP]:
            panzer.panzer_vector += panzer.panze_movement
        if continuous_movement[pygame.K_DOWN]:
            panzer.panzer_vector -= panzer.panze_movement
        if continuous_movement[pygame.K_LEFT]:
            panzer.panze_movement.rotate_ip(-1)
            projectile_speed.rotate_ip(-1)
        if continuous_movement[pygame.K_RIGHT]:
            panzer.panze_movement.rotate_ip(1)
            projectile_speed.rotate_ip(1)


        if continuous_movement[pygame.K_SPACE]:

            projectile_corner_object = projectile_speed.angle_to((1,0)) #copy.copy()
            projectile_position = panzer.position_panzer.center
            projectile = Projectile(projectile_position[0], projectile_position[1], projectile_corner_object)
            projectiles.add(projectile)

        for pro in projectiles:
            pro.update()

        panzer.draw_the_new_coordinates_of_the_tank()

        display.blit(panzer.new_panzer_position, panzer.position_panzer)
        print(list_projectiles)

        pygame.display.update()
        clock.tick(FPS)


creating_map.py
import pygame
import game
display = pygame.display.set_mode(game.screen_dimensions)
def creating_map():
    for place_y in range(0, game.screen_dimensions[0], game.playing_field):
        for place_x in range(0, game.screen_dimensions[0], game.playing_field):
            if place_y == 0 or place_x == 0 or place_y == game.screen_dimensions[0] - game.playing_field or place_x == \
                    game.screen_dimensions[0] - game.playing_field:
                display.blit(game.see, (place_y, place_x))
            else:
                display.blit(game.grass, (place_y, place_x))
  • Вопрос задан
  • 217 просмотров
Подписаться 1 Средний 4 комментария
Решения вопроса 1
@o5a
Как уже заметили в комментариях, проблема в том, что для прироста положения снаряда (вектора скорости) используется одна и та же глобальная переменная. Поэтому при обновлении все снаряды изменяют вектор на одинаковый. Нужно было использовать локальный аттрибут каждого снаряда для хранения скорости (фиксированный на момент создания, как я понимаю скорость и направление уже не должна меняться).
Навскидку вижу можно просто сделать так:
...
    class Projectile(pygame.sprite.Sprite):
        def __init__(self, weigth, heigth, corner):
            ...
            # добавляем каждому снаряду свою скорость. вычисляем поворотом на передаваемый угол
            self.projectile_speed = pygame.math.Vector2((4, 0)).rotate(-corner)

        def update(self):
            # и тут соответственно используем вектор скорости собственный для каждого снаряда
            self.projectile += self.projectile_speed

spoiler
Еще заметил, что английские названия ошибочны
heigth => height (высота)
weigth => weight (вес)
видимо имелось в виду width (ширина)
corner - в английском тоже значит "угол" но это не тот угол (как угол поворота), а как угол квадрата, угол комнаты.
для угла как направления используется angle
see = "видеть", наверное имелось в виду sea = "море".
Не критично конечно, но лучше привыкать к правильным названиям, чтобы у других изучающих код потом не возникло недопонимания.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы