L
L
LarkovAA2021-09-14 16:42:14
pygame
LarkovAA, 2021-09-14 16:42:14

Sprite projectile after the shot turns in the direction of another sprite (tank). I don't know why this is happening?

Good afternoon. I create a game, there is a tank object that fires a shot. The problem is that when the projectile flies and I turn the tank, the direction of the projectile also turns in this direction. I don't understand why this is happening. Help plz!!

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))

Answer the question

In order to leave comments, you need to log in

1 answer(s)
O
o5a, 2021-09-15
@LarkovAA

As already noted in the comments, the problem is that the same global variable is used to increase the position of the projectile (velocity vector). Therefore, when updating, all projectiles change the vector to the same one. It was necessary to use the local attribute of each projectile to store the speed (fixed at the time of creation, as I understand it, the speed and direction should no longer change).
Offhand I see you can simply do this:

...
    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 = "море".
Не критично конечно, но лучше привыкать к правильным названиям, чтобы у других изучающих код потом не возникло недопонимания.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question