这是我的代码:
import pygame, os
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()
win = pygame.display
d = win.set_mode((1200, 600))
class player:
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.speed = 2
def draw(self):
pygame.draw.rect(d, (0, 0, 0), (self.x, self.y, self.width, self.height))
def move_left(self):
self.x -= self.speed
def move_right(self):
self.x += self.speed
class bullet:
def __init__(self):
self.radius = 10
self.speed = 20
def shoot(self):
x = p.x
y = p.y
self.shooting = True
while self.shooting:
d.fill((98, 98, 98))
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
quit()
y -= self.speed
pygame.draw.circle(d, (255, 0, 0), (x, y), self.radius)
pygame.time.Clock().tick(100)
win.update()
if y <= 0:
self.shooting = False
b = bullet()
p = player(600, 500, 50, 30)
while True:
d.fill((98, 98, 98))
p.draw()
for event in pygame.event.get():
pass
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
b.shoot()
if event.key == pygame.K_LEFT:
p.move_left()
if event.key == pygame.K_RIGHT:
p.move_right()
win.update()
这是我经过几次尝试和错误后想出来的,但确实没有效果。首先,当我按空格键时,播放器消失。我想这很明显,因为我有不同的射击和玩家循环,但我不知道如何绕过它并在同一个循环中实现射击和玩家。
我遇到的第二个问题是破坏 while self.shooting:
循环。当 y 达到某个点时,我尝试通过这样做来打破它:
if y <= 0:
self.shooting = False
但这并没有破坏。相反,它会重新开始循环。
我遇到的另一个奇怪的问题是,每次我移动鼠标(稍快)或同时按下一堆按钮时,它都会破坏 while self.shooting
循环。
最佳答案
发射子弹的一般方法是将子弹的位置存储在列表(bullet_list
)中。当子弹发射时,将子弹的起始位置 ([start_x, start_y]
) 添加到列表中。起始位置是发射子弹的物体(玩家或敌人)的位置。使用 for
循环遍历列表中的所有项目符号。移动循环中每个项目符号的位置。从离开屏幕的列表中删除项目符号 (bullet_list.remove(bullet_pos)
)。因此,必须运行列表的副本 (bullet_list[:]
)(请参阅 How to remove items from a list while iterating? )。使用另一个 for
循环来 blit
屏幕上剩余的项目符号:
bullet_list = []
while run == True:
# [...]
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullet_list.append([start_x, start_y])
for bullet_pos in bullet_list[:]:
bullet_pos[0] += move_bullet_x
bullet_pos[1] += move_bullet_y
if not screen.get_rect().colliderect(bullet_image.get_rect(center = bullet_pos))
bullet_list.remove(bullet_pos)
# [...]
for bullet_pos in bullet_list[:]
screen.blit(bullet_image, bullet_image.get_rect(center = bullet_pos))
# [...]
另请参阅Shoot bullet .
<小时/>请注意,类名通常应使用 CapWords 约定。
(参见Style Guide for Python Code - Class names)
这意味着它必须是 Player
和 Bullet
而不是 player
和 bullet
您有一个应用程序循环,因此请使用它。所有对象都在每个帧的主应用程序循环中不断更新和绘制。
类Bullet
不需要任何循环。构造函数必须具有位置参数(x
、y
)。此外,它还需要一种改变位置的方法和一种绘制子弹的方法:
class Bullet:
def __init__(self, x, y):
self.radius = 10
self.speed = 10
self.x = x
self.y = y
def update(self):
self.y -= self.speed#
def draw(self):
pygame.draw.circle(d, (255, 0, 0), (self.x, self.y), self.radius)
使用项目符号列表
。按下 空格 时创建一个新项目符号。在每帧中移动项目符号(更新
)remove
如果子弹射出窗外,则为子弹。在每一帧中绘制剩余的子弹:
bullets = []
# [...]
while run:
for event in pygame.event.get():
# [...]
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullets.append(Bullet(p.x+p.width//2, p.y))
# [...]
for b in bullets:
b.update()
if b.y < 0:
bullets.remove(b)
# [...]
for b in bullets:
b.draw()
进一步使用pygame.key.get_pressed()
用于获取每一帧中关键点的状态并更新玩家的位置:
while run:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
p.move_left()
if keys[pygame.K_RIGHT]:
p.move_right()
完整示例:
import pygame, os
os.environ["SDL_VIDEO_CENTERED"] = "1"
pygame.init()
win = pygame.display
d = win.set_mode((1200, 600))
clock = pygame.time.Clock()
class Player:
def __init__(self, x, y, height, width):
self.x = x
self.y = y
self.height = height
self.width = width
self.speed = 2
def draw(self):
pygame.draw.rect(d, (0, 0, 0), (self.x, self.y, self.width, self.height))
def move_left(self):
self.x -= self.speed
def move_right(self):
self.x += self.speed
class Bullet:
def __init__(self, x, y):
self.radius = 10
self.speed = 10
self.x = x
self.y = y
def update(self):
self.y -= self.speed#
def draw(self):
pygame.draw.circle(d, (255, 0, 0), (self.x, self.y), self.radius)
bullets = []
p = Player(600, 500, 50, 30)
run = True
while run:
clock.tick(100)
# handel events
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_SPACE:
bullets.append(Bullet(p.x+p.width//2, p.y))
# update objects
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
p.move_left()
if keys[pygame.K_RIGHT]:
p.move_right()
for b in bullets:
b.update()
if b.y < 0:
bullets.remove(b)
# clear display
d.fill((98, 98, 98))
# draw scene
for b in bullets:
b.draw()
p.draw()
# update display
win.update()
关于python - 如何用空格键射击子弹?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59687250/