python - 用户需要移动鼠标来发射子弹

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

当用户点击 q 发射子弹时, Action 不流畅。他们需要在屏幕上移动鼠标才能让子弹移动。

我尝试浏览 StackOverflow、youtube,重新组织代码。

def tank(x,y,turretpos):
        x = int(x)
        y = int(y)
        possibleturrets = [(x-25, y-2), (x-25, y-4), (x-25, y-6), (x-25, y-8), (x-24, y-10),
                  (x-24, y-12), (x-23, y-14), (x-20, y-16), (x-18, y-18), (x-16, y-20)]

        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),possibleturrets[turretpos], turretwidth)
        pygame.draw.line(screen,black,(x,y),possibleturrets[turretpos], turretwidth)

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

        return possibleturrets

def fire(gun,tankx,tanky,turretpos):
    fire = True
    startingshellx = gun[0][0]
    startingshelly = gun[0][1]
    while fire: 
        for event in pygame.event.get():
            startingshellx -= (12-turretpos)*2
            startingshelly += int((((startingshellx - (gun[0][0]))*0.015)**2) - (turretpos+turretpos/(12-turretpos)))
            pygame.draw.circle(screen,red,(startingshellx, startingshelly-turretpos),5)
            if startingshelly > height-100:
                fire = False
            pygame.display.update()

我希望用户点击 q 并且子弹应该以抛物线形状顺利发射。

最佳答案

您必须在主循环而不是事件循环中更新位置。请注意,事件循环仅在事件发生时执行。这意味着按下按钮时执行一次,释放按钮时执行第二次。鼠标的移动也是一个事件,并导致事件循环被执行。

以下方法可能有效。内部事件处理由 pygame.event.pump() 完成,而不是事件循环。 :

def fire(gun,tankx,tanky,turretpos):
    firebullet = True
    startingshellx = gun[0][0]
    startingshelly = gun[0][1]
    while firebullet: 

        pygame.event.pump()

        startingshellx -= (12-turretpos)*2
        startingshelly += int((((startingshellx - (gun[0][0]))*0.015)**2) - (turretpos+turretpos/(12-turretpos)))
        pygame.draw.circle(screen,red,(startingshellx, startingshelly-turretpos),5)
        if startingshelly > height-100:
            firebullet = False
        pygame.display.update()

但我建议更改设计。避免函数和变量同名。不要在主循环内进行额外的循环以显示更新:

def fire(shellpos, tankx, tanky, turretpos):
    shellpos[0] -= (12-turretpos)*2
    shellpos[1] += (((shellpos[0] - (gun[0][0]))*0.015)**2) - (turretpos+turretpos/(12-turretpos))
    pygame.draw.circle(screen,red,(round(shellpos[0]), round(shellpos[1]-turretpos)),5)
    return (shellpos[1] <= height-100), shellpos

run = True
firebullet = False
while run:

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_q:
                firebullet, shellpos = True, gun[0]

    # [...]

    if firebullet:
        firebullet, shellpos = fire(shellpos, tankx, tanky, turretpos)

    # [...]    

    pygame.display.update()

<小时/>

如果你想产生平滑的运动,那么你必须使用浮点值进行计算:

startingshellx -= (12-turretpos)*2
startingshelly += (((startingshellx - (gun[0][0]))*0.015)**2) - (turretpos+turretpos/(12-turretpos))

Actor ( int() ) 或 round当绘制对象(圆)时,坐标为整数值:

pygame.draw.circle(screen,red,(round(startingshellx), round(startingshelly-turretpos)),5)

请注意,如果该值在相加之前被截断为整数值,则小数位会丢失:

>>> int(0.3) + int(0.4) + int(0.5) + int(0.6)
0

如果稍后完成转换操作,则结果中仅丢失小数位:

>>> int(0.3 + 0.4 + 0.5 + 0.6)
1

round()如果小数位数 >= 0.5,则给出下一个更大的积分值:

>>> round(0.3 + 0.4 + 0.5 + 0.6)
2

关于python - 用户需要移动鼠标来发射子弹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56447321/

相关文章:

python - 每当我尝试在 PyCharm 上配置 Python 解释器时都会收到错误

python - Alien 类没有 rect 属性

python - 如何从 pandas 数据框中找到调和平均速度

python-3.x - 如何用鼠标画图并保存为1和0

python - 重绘图像不起作用?

python - 从 Python 中的一行中提取时间

python 3 : CSV utf-8 encoding

python - 没有名为 'pydruid' 的模块

python - 如何在 pyglet 中制作 3D?

python - 如何解决 pygame 中的内存泄漏问题?