pygame窗口碰撞错误

pygame window collison bug

我用箭头键制作了一个可移动的白色坦克。我做了一些碰撞检测,这样“坦克”就不会离开屏幕。碰撞不起作用的唯一地方是当“坦克”位于角落附近时,当相对于顶部和底部向上或向下按下时,它会掉出窗外。任何 IDEas 如何解决这个问题?碰撞代码在 def drawtank() 中。

import pygame, sys
from pygame.locals import *

FPS = 30
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
TANK_SIZE = 20

BLACK = (0  ,0  ,0  )
WHITE = (255,255,255)

def drawArena():
    DISPLAYSURF.fill(BLACK)

def drawTank(tank):
    if tank.bottom > WINDOW_HEIGHT:
        tank.bottom = WINDOW_HEIGHT
    elif tank.top < 0:
        tank.top = 0
    elif tank.right > WINDOW_WIDTH:
        tank.right = WINDOW_WIDTH
    elif tank.left < 0:
        tank.left = 0
    pygame.draw.rect(DISPLAYSURF, WHITE, tank)

def main():
    pygame.init()
    global DISPLAYSURF
    FPSCLOCK = pygame.time.Clock()
    DISPLAYSURF = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
    pygame.display.set_caption('Tanks')

    tankX = 200
    tankY = 200
    tankX_change = 0

    tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)

    drawArena()
    drawTank(tank)

    while True:
        for event in pygame.event.get():
            if event.type == QUIT:
                pygame.quit()
                sys.exit()

        keys_pressed = pygame.key.get_pressed()

        if keys_pressed[K_LEFT]:
            tankX -= 20

        if keys_pressed[K_RIGHT]:
            tankX += 20

        if keys_pressed[K_UP]:
            tankY -=20

        if keys_pressed[K_DOWN]:
            tankY += 20


        tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)

        drawArena()
        drawTank(tank)

        pygame.display.update()
        FPSCLOCK.tick(FPS)

if __name__ == '__main__':
    main()

我不熟悉 pygame。但是,在调用 drawTank 之前是否可以按下多个箭头键?如果是这样,事情发生在角落附近的事实向我暗示,也许坦克被移动到盒子左侧和盒子下方的位置(例如)。那么您调用的 if ... elif 只会更正其中一个错误。

如果是这样,只需将 drawtank 中的每个 elif 变为 if:

def drawTank(tank):
    if tank.bottom > WINDOW_HEIGHT:
        tank.bottom = WINDOW_HEIGHT
    if tank.top < 0:
        tank.top = 0
    if tank.right > WINDOW_WIDTH:
        tank.right = WINDOW_WIDTH
    if tank.left < 0:
        tank.left = 0
    pygame.draw.rect(DISPLAYSURF, WHITE, tank)

每种可能性都需要 if/elif'selif tank.right > WINDOW_WIDTH 仅评估前一个 if 和 elif 为 False,因此当坦克在角落时您会错过:

def drawTank(tank):
    if tank.bottom > WINDOW_HEIGHT:
        tank.bottom = WINDOW_HEIGHT
    elif tank.top < 0:
        tank.top = 0
    if tank.right > WINDOW_WIDTH: # need an if here
        tank.right = WINDOW_WIDTH
    elif tank.left < 0:
        tank.left = 0
    pygame.draw.rect(DISPLAYSURF, WHITE, tank)

如果坦克不能同时出现在屏幕的顶部和底部,则不需要额外的那个。

还有一个更简单的方法:

screen = pygame.display.set_mode((800, 600)) # add this 
screen_rect = screen.get_rect() # this 

现在您的代码是:

import pygame, sys
from pygame.locals import *

FPS = 30
TANK_SIZE = 20
BLACK = (0  ,0  ,0  )
WHITE = (255,255,255)
screen=pygame.display.set_mode((800, 600))
screen_rect=screen.get_rect()
def drawArena():
    screen.fill(BLACK)

def drawTank(tank):
    tank.clamp_ip(screen_rect)
    pygame.draw.rect(screen, WHITE, tank)

def main():
    pygame.init()
    FPSCLOCK = pygame.time.Clock()
    pygame.display.set_caption('Tanks')
    tankX = 200
    tankY = 200
    tankX_change = 0

    tank = pygame.Rect(tankX, tankY, TANK_SIZE, TANK_SIZE)

    drawArena()
    drawTank(tank)
    ......