pygame - событие KEYDOWN - строка, не обновляющая позицию

Я делаю игру с двумя игроками, которая должна выглядеть так:
Образ игры
В игре стрелялки (зеленые и синие, контролируемые игроками) могут стрелять в пули друг на друга.
Если пуля 1. сталкивается со стеной (серый), он разрушается.
2. попадает в стрелок, он теряет здоровье (стрелок).
Игра (предположительно) пошаговая и заканчивается, когда игрок достигает состояния 0 .

My Problem(s)
1. The barrel of my shooters is not updating/rotating.
2. Is there a better way to detect if a(ny) key is pressed.
* Shooter,Bullet,Wall are classes

My code
(comment if any function that would be useful in answering is not mentioned)

import math,random,pygame
def event_handle(event,turn):
    if turn == 1:
        c_s = p1
    elif turn == 2:
        c_s = p2
    else:
        return None
    if event.type == pygame.KEYDOWN:
        key = pygame.key.get_pressed()
        # next_pos
        if key[pygame.K_q]:
            c_s.next_x -= 1
        if key[pygame.K_e]:
            c_s.next_x += 1
        # angle
        if key[pygame.K_w]:
            c_s.angle += radians(1)
        if key[pygame.K_s]:
            c_s.angle -= radians(1)
        # power (speed)
        if key[pygame.K_d]:
            c_s.speed += 0.1
        if key[pygame.K_a]:
            c_s.speed -= 0.1

def draw_all(bullist,shooters,wall,surface):
    # draw shooters
    for shooter in shooters:
        shooter.move()
        shooter.draw(surface)
    # draw bullets
    for bullet in bullist:
        bullet.gravity()
        bullet.move()
        bullet.collides(shooters,wall,bullist)
        bullet.out(surface,bullist)
        bullet.draw(surface)
    # wall
    wall.update()
    wall.draw(surface)
    pygame.draw.aaline(surface,(255,255,255),(0,400),(640,400))

def angle(A,B,BC,theta):

    C = [0,0]
    alpha = math.atan2(A[1]-B[1] , A[0] -B[0] ) - theta
    C[0] = int(round(B[0]  + BC * math.cos(alpha),0))
    C[1] = int(round(B[1]  + BC * math.sin(alpha),0))
    return C

class Shooter:
    def __init__(self,pos,size,color,xmax,xmin):
        self.pos = pos
        self.size = size
        self.rect = pygame.Rect(pos,size)
        self.health = 100
        self.color = color
        self.angle = 0
        self.speed = 0
        self.max = xmax
        self.min = xmin
        self.next_x = pos[0]

        self.color2 = []
        for i in color:
            i = i - 100
            if i < 0:
                i = 0
            self.color2.append(i)

    def draw(self,surface):
        global C
        pygame.draw.rect(surface,self.color,self.rect)

        c = angle(self.rect.midleft,self.rect.center,
                  20,radians(self.angle))
        if c != C and c != [95,392]:
            print c
            C = c
        pygame.draw.line(surface,self.color2,self.rect.center,c,3)


## the other funcs or classes not needed

# globals
turn = 1
C = []
# pygame
(width, height) = (640, 480)
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption('Shooter')
clock = pygame.time.Clock()
# game actors
shooters = []
bullets = []
p1 = Shooter((400,400),(30,-15),(255,0,0),0,0)
p2 = Shooter((100,400),(30,-15),(0,255,0),0,0)
shooters.extend([p1, p2])
wall = Wall(100)

running = True
while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            pygame.quit()
            break
        else: event_handle(event,turn)
    if not running:
        break
    screen.fill((0,0,0))
    # Game draw logic + Game logic

    draw_all(bullets,shooters,wall,screen)
    pygame.display.flip()
    clock.tick(40)

Что я делаю не так?

1
@DominicKexel shooter.move изменяет только значение shooter.rect.x по одному за раз
добавлено автор pradyunsg, источник
@DominicKexel shooter.move изменяет только значение shooter.rect.x по одному за раз
добавлено автор pradyunsg, источник
@DominicKexel shooter.move изменяет только значение shooter.rect.x по одному за раз
добавлено автор pradyunsg, источник
@DominicKexel Хорошо ... Я отредактирую код .. Изменил :)
добавлено автор pradyunsg, источник
@DominicKexel Хорошо ... Я отредактирую код .. Изменил :)
добавлено автор pradyunsg, источник
@DominicKexel Хорошо ... Я отредактирую код .. Изменил :)
добавлено автор pradyunsg, источник
Было бы здорово, если бы вы просто разместили свой полный код, в идеале, как единый блок кода, чтобы можно просто скопировать, вставить и запустить его. В противном случае очень сложно отслеживать, что происходит.
добавлено автор sloth, источник
Отсутствует метод Shoter.move (также некоторые импорт и класс Wall , но они не являются that ).
добавлено автор sloth, источник
Отсутствует метод Shoter.move (также некоторые импорт и класс Wall , но они не являются that ).
добавлено автор sloth, источник
Отсутствует метод Shoter.move (также некоторые импорт и класс Wall , но они не являются that ).
добавлено автор sloth, источник
Было бы здорово, если бы вы просто разместили свой полный код, в идеале, как единый блок кода, чтобы можно просто скопировать, вставить и запустить его. В противном случае очень сложно отслеживать, что происходит.
добавлено автор sloth, источник

5 ответы

Ваш код действительно работает, но есть некоторые проблемы. Бочки фактически вращаются, но только очень небольшое количество при каждом нажатии клавиши.

Попробуйте изменить функцию event_handle :

def event_handle(turn):
    if turn == 1:
        c_s = p1
    elif turn == 2:
        c_s = p2
    else:
        return None
    key = pygame.key.get_pressed()
    # next_pos
    if key[pygame.K_q]:
        c_s.next_x -= 1
    if key[pygame.K_e]:
        c_s.next_x += 1
    # angle
    if key[pygame.K_w]:
        c_s.angle += radians(10)
    if key[pygame.K_s]:
        c_s.angle -= radians(10)
    # power (speed)
    if key[pygame.K_d]:
        c_s.speed += 0.1
    if key[pygame.K_a]:
        c_s.speed -= 0.1

Поскольку в данный момент вы все равно не ощущаете тип события, я удалил параметр event и проверку if event.type == pygame.KEYDOWN: . Таким образом, вы можете держать свои клавиши нажатыми, а не нажимать на клавиши несколько раз, чтобы повернуть бочки.

Я также увеличил значение, которое бочки вращаются от radians (1) до radians (10) . В противном случае изменение слишком мало, чтобы быть видимым (в разумные сроки).

Кроме того, вам необходимо настроить основной цикл на

...
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
        pygame.quit()
        break
if not running:
    break
event_handle(turn)
...

поэтому event_handle вызывается каждая итерация основного цикла.

1
добавлено
break только разбивает цикл for (цикл событий), а не цикл while, и THX !!!!
добавлено автор pradyunsg, источник
Уже сделано!! :) еще раз THX !!!!
добавлено автор pradyunsg, источник
Pls проверит этот вопрос вне
добавлено автор pradyunsg, источник
@paddila Да, вы должны положить event_handle (turn) под проверку if not running .
добавлено автор sloth, источник

Ваш код действительно работает, но есть некоторые проблемы. Бочки фактически вращаются, но только очень небольшое количество при каждом нажатии клавиши.

Попробуйте изменить функцию event_handle :

def event_handle(turn):
    if turn == 1:
        c_s = p1
    elif turn == 2:
        c_s = p2
    else:
        return None
    key = pygame.key.get_pressed()
    # next_pos
    if key[pygame.K_q]:
        c_s.next_x -= 1
    if key[pygame.K_e]:
        c_s.next_x += 1
    # angle
    if key[pygame.K_w]:
        c_s.angle += radians(10)
    if key[pygame.K_s]:
        c_s.angle -= radians(10)
    # power (speed)
    if key[pygame.K_d]:
        c_s.speed += 0.1
    if key[pygame.K_a]:
        c_s.speed -= 0.1

Поскольку в данный момент вы все равно не ощущаете тип события, я удалил параметр event и проверку if event.type == pygame.KEYDOWN: . Таким образом, вы можете держать свои клавиши нажатыми, а не нажимать на клавиши несколько раз, чтобы повернуть бочки.

Я также увеличил значение, которое бочки вращаются от radians (1) до radians (10) . В противном случае изменение слишком мало, чтобы быть видимым (в разумные сроки).

Кроме того, вам необходимо настроить основной цикл на

...
for event in pygame.event.get():
    if event.type == pygame.QUIT:
        running = False
        pygame.quit()
        break
if not running:
    break
event_handle(turn)
...

поэтому event_handle вызывается каждая итерация основного цикла.

1
добавлено
Pls проверит этот вопрос вне
добавлено автор pradyunsg, источник
break только разбивает цикл for (цикл событий), а не цикл while, и THX !!!!
добавлено автор pradyunsg, источник
Уже сделано!! :) еще раз THX !!!!
добавлено автор pradyunsg, источник
@paddila Да, вы должны положить event_handle (turn) под проверку if not running .
добавлено автор sloth, источник

Если вы используете key.get_pressed, вам не нужно вообще обнаруживать событие key_down. Просто удалите инструкцию if event.type == pygame.KEYDOWN: и перейдите к проверке, есть ли у вас ключи от pygame.key.get_pressed .

Алос, вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Поместите его внутри цикла while.

(И подсказка, не связанная с вашей проблемой: переместите этот основной цикл внутри функции - просто отвратительно, чтобы он висел в теле программы, как это)

0
добавлено
pygame.event.pump просто вызывает SDL_PumpEvents , который также выполняет pygame.event.get (а также pygame.event.peek и pygame.event.clear )) , Поэтому, когда вы вызываете pygame.event.get в свой основной цикл, нет необходимости в pygame.event.pump . Это было бы излишним. Даже pygame документация говорит, что это необязательно: < i> Эта функция не нужна, если ваша программа последовательно обрабатывает события в очереди через другие функции pygame.event.
добавлено автор sloth, источник
вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Почему? Это не нужно делать.
добавлено автор sloth, источник
@DominicKexel: спасибо за claryfing. Я думаю, что у меня были проблемы с скриптами, где я только проверял pygame.key.get_pressed и не смотрел на события через какие-либо другие вызовы.
добавлено автор jsbueno, источник
@DominicKexel: да, есть, и вы должны сделать это и в своем коде: просто случается, что хотя pygame отлично работает в определенных средах (в основном в зависимости от операционной системы) без pygame.event.pump, он не работает в других - так без этого вызова вы рискуете, что код yoru не работает на всех платформах, поддерживаемых Pygame.
добавлено автор jsbueno, источник

Если вы используете key.get_pressed, вам не нужно вообще обнаруживать событие key_down. Просто удалите инструкцию if event.type == pygame.KEYDOWN: и перейдите к проверке, есть ли у вас ключи от pygame.key.get_pressed .

Алос, вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Поместите его внутри цикла while.

(И подсказка, не связанная с вашей проблемой: переместите этот основной цикл внутри функции - просто отвратительно, чтобы он висел в теле программы, как это)

0
добавлено
pygame.event.pump просто вызывает SDL_PumpEvents , который также выполняет pygame.event.get (а также pygame.event.peek и pygame.event.clear )) , Поэтому, когда вы вызываете pygame.event.get в свой основной цикл, нет необходимости в pygame.event.pump . Это было бы излишним. Даже pygame документация говорит, что это необязательно: < i> Эта функция не нужна, если ваша программа последовательно обрабатывает события в очереди через другие функции pygame.event.
добавлено автор sloth, источник
вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Почему? Это не нужно делать.
добавлено автор sloth, источник
@DominicKexel: да, есть, и вы должны сделать это и в своем коде: просто случается, что хотя pygame отлично работает в определенных средах (в основном в зависимости от операционной системы) без pygame.event.pump, он не работает в других - так без этого вызова вы рискуете, что код yoru не работает на всех платформах, поддерживаемых Pygame.
добавлено автор jsbueno, источник
@DominicKexel: спасибо за claryfing. Я думаю, что у меня были проблемы с скриптами, где я только проверял pygame.key.get_pressed и не смотрел на события через какие-либо другие вызовы.
добавлено автор jsbueno, источник

Если вы используете key.get_pressed, вам не нужно вообще обнаруживать событие key_down. Просто удалите инструкцию if event.type == pygame.KEYDOWN: и перейдите к проверке, есть ли у вас ключи от pygame.key.get_pressed .

Алос, вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Поместите его внутри цикла while.

(И подсказка, не связанная с вашей проблемой: переместите этот основной цикл внутри функции - просто отвратительно, чтобы он висел в теле программы, как это)

0
добавлено
pygame.event.pump просто вызывает SDL_PumpEvents , который также выполняет pygame.event.get (а также pygame.event.peek и pygame.event.clear )) , Поэтому, когда вы вызываете pygame.event.get в свой основной цикл, нет необходимости в pygame.event.pump . Это было бы излишним. Даже pygame документация говорит, что это необязательно: < i> Эта функция не нужна, если ваша программа последовательно обрабатывает события в очереди через другие функции pygame.event.
добавлено автор sloth, источник
вы должны вызывать pygame.event.pump где-то в вашем коде, при каждом запуске цикла. Почему? Это не нужно делать.
добавлено автор sloth, источник
@DominicKexel: да, есть, и вы должны сделать это и в своем коде: просто случается, что хотя pygame отлично работает в определенных средах (в основном в зависимости от операционной системы) без pygame.event.pump, он не работает в других - так без этого вызова вы рискуете, что код yoru не работает на всех платформах, поддерживаемых Pygame.
добавлено автор jsbueno, источник
@DominicKexel: спасибо за claryfing. Я думаю, что у меня были проблемы с скриптами, где я только проверял pygame.key.get_pressed и не смотрел на события через какие-либо другие вызовы.
добавлено автор jsbueno, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community