Pygam中向上射弹的故障排除

2024-06-26 13:40:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在写一个双人坦克游戏,类似于一个叫做“坦克麻烦”的游戏。当然,我现在还只是处于初级阶段,有点被一个特别的小虫子缠住了。目前,下面的代码使我能够显示我的精灵,能够在所有方向上移动,也能够发射炮弹。然而,唯一的问题是它只能向左或向右发射炮弹。有没有人对如何改变这一点有什么建议,使坦克可以向上射击,当面向上和向下,当面向下?它只能左右射击,即使它面对上或下,这有点奇怪。我很难进入y轴,让弹丸沿着它移动

如果有人能找到如何做到这一点,并告诉我新的代码是什么,在哪里放置它,这将帮助吨。这是我的密码:

import pygame
pygame.init()

screen = pygame.display.set_mode((500,500))

pygame.display.set_caption("Game")
tankImg = pygame.image.load("tank1.png")
downTank = tankImg 
leftTank = pygame.image.load("left1.png")
rightTank = pygame.image.load("right1.png")
upTank = pygame.image.load("up1.png")
bg = pygame.image.load("background.png")


screenWidth = 500
screenHeight = 500

clock = pygame.time.Clock()

class player(object):
    def __init__(self, x, y, width, height):
        self.x = x
        self.y = y
        self.width = width
        self.height = height
        self.vel = 5
        self.left = False
        self.right = False
        self.up = False
        self.down = False

    def draw(self,screen):
        screen.blit(tankImg,(self.x,self.y))        

class projectile(object):
    def __init__(self,x, y, radius, color, facing):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.facing = facing
        self.vel = 8 * facing 

    def draw(self,screen):
        pygame.draw.circle(screen, self.color, (self.x,self.y), self.radius)

def redraw():
    screen.blit(bg, (0,0))
    tank.draw(screen)

    for bullet in bullets:
        bullet.draw(screen)

    pygame.display.update()

run = True
tank = player(300, 410, 16, 16)
bullets = []
while run:

    clock.tick(30)

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

    for bullet in bullets:
        if bullet.x < screenWidth and bullet.x > 0:
            bullet.x += bullet.vel
        elif bullet.y > screenHeight and bullet.y > 0:
            bullet.y += bullet.vel 
        else:
            bullets.pop(bullets.index(bullet))



    keys = pygame.key.get_pressed()

    if keys[pygame.K_LEFT] and tank.x > tank.vel:
        tank.left = True
        tankImg = leftTank
        tank.x -= tank.vel
        facing = -1
    if keys[pygame.K_RIGHT] and tank.x < 500 - tank.width:
        tank.right = True
        tankImg = rightTank
        tank.x += tank.vel
        facing = 1
    if keys[pygame.K_UP] and tank.y > tank.vel:
        tank.up = True
        tankImg = upTank
        tank.y -= tank.vel
        facing = 1
    if keys[pygame.K_DOWN] and tank.y < 500 - tank.height:
        down = True
        tankImg = downTank
        tank.y += tank.vel
        facing = -1
    if keys[pygame.K_SPACE]:
        if len(bullets) < 1:
            bullets.append(projectile(round(tank.x + tank.width // 2), round(tank.y + tank.height // 2), 4, (0,0,0),facing))

    redraw()

pygame.quit()

Tags: andimageselfifpngloadkeysscreen
2条回答

该问题是由代码的该部分引起的:

if bullet.x < screenWidth and bullet.x > 0:
   bullet.x += bullet.vel
elif bullet.y > screenHeight and bullet.y > 0:
   bullet.y += bullet.vel 
else:
   bullets.pop(bullets.index(bullet))

只要项目符号在窗口的边界内,第一个条件就会计算True。这导致子弹只能在x方向移动

在类projectile中添加direction属性,而不是facing属性。此外,添加一个方法(move)来移动射弹。此方法忽略窗口的边界:

class projectile(object):
    def __init__(self,x, y, radius, color, direction):
        self.x = x
        self.y = y
        self.radius = radius
        self.color = color
        self.direction = direction
        self.vel = 8

    def move(self):
        self.x += self.direction[0] * self.vel
        self.y += self.direction[1] * self.vel

    def draw(self,screen):
        pygame.draw.circle(screen, self.color, (self.x,self.y), self.radius)

在循环结束时移动项目符号,如果项目符号在窗口的边界内,则进行求值。这可以通过使用^{}^{}轻松完成:

while run:
    # [...]

    for bullet in bullets[:]:
        bullet.move()
        window_rect = pygame.Rect(0, 0, screenWidth, screenHeight)
        if not window_rect.collidepoint((bullet.x, bullet.y)):
            bullets.pop(bullets.index(bullet))

根据油箱的移动方向设置子弹的方向:

direction = (-1, 0)
while run:
    # [...]

    if keys[pygame.K_LEFT] and tank.x > tank.vel:
        tank.left = True
        tankImg = leftTank
        tank.x -= tank.vel
        direction = (-1, 0)
    if keys[pygame.K_RIGHT] and tank.x < 500 - tank.width:
        tank.right = True
        tankImg = rightTank
        tank.x += tank.vel
        direction = (1, 0)
    if keys[pygame.K_UP] and tank.y > tank.vel:
        tank.up = True
        tankImg = upTank
        tank.y -= tank.vel
        direction = (0, -1)
    if keys[pygame.K_DOWN] and tank.y < 500 - tank.height:
        down = True
        tankImg = downTank
        tank.y += tank.vel
        direction = (0, 1)
    if keys[pygame.K_SPACE]:
        if len(bullets) < 1:
            px, py = round(tank.x + tank.width // 2), round(tank.y + tank.height // 2)
            bullets.append(projectile(px, py, 4, (0,0,0), direction))


我建议在pygame.KEYDOWN事件中生成项目符号,而不是计算按下的键(keys[pygame.K_SPACE])。当按下按钮时,事件发生一次。因此,每次按下空格时,都会生成一个项目符号(当然,这取决于您):

direction = (-1, 0)
while run:
    clock.tick(30)

    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        if event.type == pygame.KEYDOWN:            
            if event. key == pygame.K_SPACE:
                px, py = round(tank.x + tank.width // 2), round(tank.y + tank.height // 2)
                bullets.append(projectile(px, py, 4, (0,0,0), direction))

    for bullet in bullets[:]:
        bullet.move()
        window_rect = pygame.Rect(0, 0, screenWidth, screenHeight)
        if not window_rect.collidepoint((bullet.x, bullet.y)):
            bullets.pop(bullets.index(bullet))

    keys = pygame.key.get_pressed()
    if keys[pygame.K_LEFT] and tank.x > tank.vel:
        tank.left = True
        tankImg = leftTank
        tank.x -= tank.vel
        direction = (-1, 0)
    if keys[pygame.K_RIGHT] and tank.x < 500 - tank.width:
        tank.right = True
        tankImg = rightTank
        tank.x += tank.vel
        direction = (1, 0)
    if keys[pygame.K_UP] and tank.y > tank.vel:
        tank.up = True
        tankImg = upTank
        tank.y -= tank.vel
        direction = (0, -1)
    if keys[pygame.K_DOWN] and tank.y < 500 - tank.height:
        down = True
        tankImg = downTank
        tank.y += tank.vel
        direction = (0, 1)

    redraw()

当前,如果bullet.x在0和屏幕宽度之间,则满足第一个条件,而不检查第二个条件

for bullet in bullets:
    if bullet.x < screenWidth and bullet.x > 0:
        # When this is True then the "elif" is not run
        bullet.x += bullet.vel
    elif bullet.y > screenHeight and bullet.y > 0:
        bullet.y += bullet.vel 
    else:
        bullets.pop(bullets.index(bullet))

您应该有一个条件来确保项目符号同时处于x和y边界,以便更新x和y

for bullet in bullets:
    if 0 < bullet.x < screenWidth and 0 < bullet.y < screenHeight:
        bullet.x += bullet.vel
        bullet.y += bullet.vel 
    else:
        bullets.pop(bullets.index(bullet))

您可以组合这样的条件来检查一个值是否在两个值之间,如somin < value < max

相关问题 更多 >