python - 为什么当我按下 "a"和 "d"时我的坦克不动?

标签 python python-3.x pygame user-controls

目前,我一直在尝试在用户按下“a”和“d”时让我的坦克移动。涉及按下一个键来移动坦克的线路似乎是正确的,我相信应该有效。这也是我第一次使用其中一个论坛。请提供反馈,以便我改进。感谢您的帮助。

我求助过我的老师和 friend ,但他们都奇怪为什么坦克不动。我还通过互联网和 youtube 搜索了答案。奇怪的是,我和我的 friend 直接复制了一个关于用户移动的 youtube 视频,用户可以在其中移动一个矩形。我的 friend 可以按住“w”、“a”、“s”或“d”来移动矩形,但我不能按住“w”、“a”、“s”或“d”来移动它但需要向按钮发送垃圾邮件。奇怪的是,当你移动鼠标时,我可以按住“w”、“a”、“s”或“d”。

import pygame
from pygame.locals import *
import math
import random

width = 640 
height = 480
screen = pygame.display.set_mode((width, height))
pygame.display.set_caption("2 Player Tanks")


def gameloop(): 
    pygame.init()
    time = pygame.time.get_ticks()

    screen.fill(white)

    tankx = 100
    tanky = 100
    tankwidth = 40
    tankheight = 20
    turretwidth = 5 
    wheelwidth = 5
    tankmove = 5

    def tank(x,y):
        x = int(x)
        y = int(y)
        pygame.draw.circle(screen,black,(x,y),10)
        pygame.draw.rect(screen,black,(x-tankheight,y,tankwidth,tankheight))
        pygame.draw.line(screen,black,(x,y),(x-20,y-20), turretwidth)

        startx = 15
        for i in range(7):
            pygame.draw.circle(screen,black,(x-startx,y+20),wheelwidth)
            startx -= 5

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

        keys= pygame.key.get_pressed()

        if keys[pygame.K_a]:
            tankx -= tankmove
        if keys[pygame.K_d]:
            tankx += tankmove
        if keys[pygame.K_w]:
            tanky -= tankmove
        if keys[pygame.K_s]:
            tanky += tankmove         

         tank(tankx,tanky)
         pygame.display.update()

gameloop()

我希望玩家能够使用“a”和“d”来水平移动坦克。

最佳答案

事件循环仅在事件发生时执行。这意味着它会在按下一个键或释放一个键时执行——但是,当按下一个键时,不会发生任何事件,也不会执行事件循环。

您必须在主循环(在 gameloop 的范围内)而不是在事件循环中评估按键:

例如

def gameloop(): 

    # [...]

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

    # <--
    keys= pygame.key.get_pressed()

    if keys[pygame.K_a]:
        tankx -= tankmove
    if keys[pygame.K_d]:
        tankx += tankmove
    if keys[pygame.K_w]:
        tanky -= tankmove
    if keys[pygame.K_s]:
        tanky += tankmove         

    tank(tankx,tanky)
    pygame.display.update()

备注:pygame.key.get_pressed()返回键的当前状态,并在 pygame.event.get() 时评估和更新状态被称为。


坦克的位置在帧开始时重置,因为变量 tankxtanky 是在 gameloop 开始时设置的>:

 def gameloop(): 
      #[...]

      tankx = 100
      tanky = 100

在全局范围内定义变量,并使用global statement访问它们。
降低坦克的速度,因为它会移动得非常快 (tankmove = 1)。

pygame.init()应仅在应用程序开始时调用一次。

例如

def gameloop(): 
    global tankx, tanky, tankmove

    tankwidth = 40
    tankheight = 20
    turretwidth = 5 
    wheelwidth = 5

    time = pygame.time.get_ticks()

    screen.fill(white)

    # [...]

pygame.init()

tankx = 100
tanky = 100
tankmove = 1
run = True
while run:
    gameloop()

I can move the tank with a randomized background, but the program keeps on drawing a new tank. To fix this, I added a screen.fill(white). That fixes the drawing problem, but now I have no background.

不要将随机 背景绘制到窗口。创建 pygame.Surface并将随机背景绘制到表面。
.blit每一帧中屏幕的背景表面:

background_surface = pygame.Surface((widht, height))
# draw background to "background_surface" rather then "screen"
# [...]
def gameloop():

    # [...]

    # blit background instead of screen.fill(white)
    screen.blit(background_surface, (0, 0))

    # [...]

关于python - 为什么当我按下 "a"和 "d"时我的坦克不动?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56367412/

相关文章:

python双列表理解对scala等效

python - 为什么要使用 marshal 转储和 pickle 加载?

python - Ansible - 对输出应用过滤器,然后注册为变量

python - 给定 n 个数字和 k 个槽。这样对于每个槽,它可以是 0,也可以是小于前一个数字的数字,组合学

python - 在方法内访问方法内的变量

python - Pygame不会抛出任何错误,但是不会播放任何音频

python - 在 pandas 中使用正则表达式验证字符串

python - 替换文件中的一行将另一行移动到上一级

python - 如何使用 pygame.USEREVENT 让敌人定期开火

python - Pygame: Sprite 侧面的碰撞