<p>该问题是由代码的该部分引起的:</p>
<blockquote>
<pre class="lang-py prettyprint-override"><code>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))
</code></pre>
</blockquote>
<p>只要项目符号在窗口的边界内,第一个条件就会计算<code>True</code>。这导致子弹只能在x方向移动</p>
<p>在类<code>projectile</code>中添加<code>direction</code>属性,而不是<code>facing</code>属性。此外,添加一个方法(<code>move</code>)来移动射弹。此方法忽略窗口的边界:</p>
<pre class="lang-py prettyprint-override"><code>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)
</code></pre>
<p>在循环结束时移动项目符号,如果项目符号在窗口的边界内,则进行求值。这可以通过使用<a href="https://www.pygame.org/docs/ref/rect.html" rel="nofollow noreferrer">^{<cd6>}</a>和<a href="https://www.pygame.org/docs/ref/rect.html#pygame.Rect.collidepoint" rel="nofollow noreferrer">^{<cd7>}</a>轻松完成:</p>
<pre class="lang-py prettyprint-override"><code>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))
</code></pre>
<p>根据油箱的移动方向设置子弹的方向:</p>
<pre class="lang-py prettyprint-override"><code>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))
</code></pre>
<hr/>
<p><a href="https://i.stack.imgur.com/l8z1u.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/l8z1u.gif" alt=""/></a></p>
<hr/>
<p>我建议在<code>pygame.KEYDOWN</code>事件中生成项目符号,而不是计算按下的键(<code>keys[pygame.K_SPACE]</code>)。当按下按钮时,事件发生一次。因此,每次按下空格时,都会生成一个项目符号(当然,这取决于您):</p>
<pre class="lang-py prettyprint-override"><code>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()
</code></pre>