Задать вопрос
@Joynear
Начинающий программист 15 лет

Как сделать так, чтобы пули на платформе pygame стреляли по вертикали?

Я только начал учится программировать, и пули стреляют нормально влево и вправо, а вверх и вниз отказываются напрочь.
Вот весь код:
import pygame

pygame.init()

screen = pygame.display.set_mode((1920, 1080))

pygame.display.set_caption('My game')

left = False
right = False
up = False
down = False

x = 5
y = 540

wide = 300
tall = 300
speed = 5

person1right = pygame.image.load('1.png')
person1up = pygame.image.load('1.1.png')
person1left = pygame.image.load('1.2.png')
person1down = pygame.image.load('1.3.png')
back = pygame.image.load('back.png')

class Bullet():

    def __init__(self, x, y, radius, color, facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing
        self.speed = facing * 15

    def draw(self, screen):
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.radius)
lastmove = 1
run = True
clock = pygame.time.Clock()

def draw():
    screen.blit(back, (0, 0))

    if right:
        screen.blit(person1right, (x, y))
    if left:
        screen.blit(person1left, (x, y))
    if up:
        screen.blit(person1up, (x, y))
    if down:
        screen.blit(person1down, (x, y))
    for bullet in bullets:
        bullet.draw(screen)

    pygame.display.update()
bullets = []
run = True
while run == True:
    clock.tick(60)
    pygame.time.delay(5)

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

    keys = pygame.key.get_pressed()
    if keys[pygame.K_s] and y<1920 - tall -5:
        y += speed
        left = False
        right = False
        up = False
        down = True
    if keys[pygame.K_w] and y>5:
        y -= speed
        left = False
        right = False
        up = True
        down = False
    if keys[pygame.K_a] and x>5:
        x -= speed
        left = True
        right = False
        up = False
        down = False
    if keys[pygame.K_d] and x<1920 - wide -5:
        x += speed
        left = False
        right = True
        up = False
        down = False

    if right == True:
        lastmove == 1
    elif left== True:
        lastmove == 2
    elif up == True:
        lastmove == 3
    elif down == True:
        lastmove == 4
    if keys[pygame.K_f]:
        if len(bullets) <= 100:
            bullets.append(Bullet(round(x + wide // 2), round(y + tall // 2 ), 5, (255, 0, 0), facing ))
    if right:
        facing = 1
    if down:
        facing = 1
    if left:
        facing = -1
    if up:
        facing = -1

    for bullet in bullets:
        if bullet.x > 0 and bullet.x < 1920:
            if lastmove == 1 or lastmove == 2:
                bullet.x += bullet.speed
        if lastmove == 3 or lastmove == 4:
                bullet.y += bullet.speed
        if bullet.x < 0 or bullet.x >1920:
            bullets.pop(bullets.index(bullet))
    keys = pygame.key.get_pressed()
    draw()
pygame.quit()
Часть с пулями:
class Bullet():

    def __init__(self, x, y, radius, color, facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing
        self.speed = facing * 15

if keys[pygame.K_d] and x<1920 - wide -5:
        x += speed
        left = False
        right = True
        up = False
        down = False


    if right == True:
        lastmove == 1
    elif left== True:
        lastmove == 2
    elif up == True:
        lastmove == 3
    elif down == True:
        lastmove == 4
    if keys[pygame.K_f]:
        if len(bullets) <= 100:
            bullets.append(Bullet(round(x + wide // 2), round(y + tall // 2 ), 5, (255, 0, 0), facing ))
    if right:
        facing = 1
    if down:
        facing = 1
    if left:
        facing = -1
    if up:
        facing = -1

    for bullet in bullets:
        if bullet.x > 0 and bullet.x < 1920:
            if lastmove == 1 or lastmove == 2:
                bullet.x += bullet.speed
        if lastmove == 3 or lastmove == 4:
                bullet.y += bullet.speed
        if bullet.x < 0 or bullet.x >1920:
            bullets.pop(bullets.index(bullet))


Не могу разобраться уже кучу времени.
  • Вопрос задан
  • 727 просмотров
Подписаться 1 Средний 1 комментарий
Решения вопроса 2
dollar
@dollar
Делай добро и бросай его в воду.
Процесс поиска ошибок называется "отладка". Как программист, вы первым делом должны овладеть этим навыком. И не важно, начинающий вы или нет.

В программировании вообще, в частности в языке Python, и уж тем более в игровом движке Pygame, удобно использовать консоль для вывода отладочной информации, а именно функцию print().

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

Пример того, как можно было бы сделать отладку через консоль в вашем случае:
for bullet in bullets:
        print("lastmove:", lastmove)
        if bullet.x > 0 and bullet.x < 1920:
            if lastmove == 1 or lastmove == 2:
                bullet.x += bullet.speed
        if lastmove == 3 or lastmove == 4:
                bullet.y += bullet.speed
        if bullet.x < 0 or bullet.x >1920:
            print("bullets.pop!!!")
            bullets.pop(bullets.index(bullet))


Но где, что и как вы будете проверять - вам решать.
Ответ написан
Комментировать
tsarevfs
@tsarevfs
C++ developer
Попробуйте добавить print(lastmove) перед движением пуль.
Добавлю пару непрошенных советов:
if right == True: #заменить на if right:
if по определению срабатывает если условие равно True. Сравнение избыточно.
if keys[pygame.K_a] and x>5:
        x -= speed
        left = True
        right = False
        up = False
       down = False

Очень много кода, и как следствие легко допустить ошибку. Используйте векторное представление направления. x и y будут иметь значения -1, 0 или 1.
https://www.pygame.org/docs/ref/math.html вам поможет удобно работать с такими векторами.
direction = Vector2(0, 0)
    if keys[pygame.K_s] and y<1920 - tall -5:
        direction.y = 1
    if keys[pygame.K_w] and y>5:
        direction.y = -1
    if keys[pygame.K_a] and x>5:
        direction.x = -1
    if keys[pygame.K_d] and x<1920 - wide -5:
        direction.x = 1

    if direction.length() != 0:
        last_direction = direction
    pos += direction * speed;
    if keys[pygame.K_f]:
        if len(bullets) <= 100:
            bullets.append(Bullet(pos + gun_offset, (255, 0, 0), last_direction ))
    for bullet in bullets:
        bullet.pos += bullet.speed
        window_rect = pygame.Rect(0, 0, 1920, 1080) #можно определить глобально 1 раз
        if not window_rect.collidepoint(bullet.pos):
            bullets.pop(bullets.index(bullet))

if keys[pygame.K_s] and y<1920 - tall -5:
Может быть чуть удобнее не смешивать регистрацию нажатий и контроля позиции. используйте window_rect.contains для этого непосредственно перед тем как изменить позицию игрока.

P.S.
Раньше pygame хотел обязательно int координаты при рисовании, поэтому Vector2 приходилось преобразовывать в пару int:
def vec_to_int(vec):
    return (int(vec.x), int(vec.y))
pygame.draw.circle(screen, self.color, vec_to_int(self.pos), self.radius)


Но вроде как они это поправили, так что может это и не понадобится.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

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

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