我怎样才能用空格键射击子弹?
- 2025-01-09 08:46:00
- admin 原创
- 12
问题描述:
这是我的代码:
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
。
解决方案 1:
发射子弹的一般方法是将子弹的位置存储在一个列表中 ( bullet_list
)。发射子弹时,将子弹的起始位置 ( [start_x, start_y]
) 添加到列表中。起始位置是发射子弹的对象(玩家或敌人)的位置。使用for
-循环遍历列表中的所有子弹。在循环中移动每颗子弹的位置。从列表中移除离开屏幕的子弹 ( bullet_list.remove(bullet_pos)
)。为此,bullet_list[:]
必须运行列表的副本 ( )(请参阅如何在迭代时从列表中移除项目?)。 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))
# [...]
另请参阅射击子弹。
请注意,类名通常应使用 CapWords 约定。(请参阅Python 代码样式指南 - 类名)
这意味着它必须是Player
andBullet
而不是player
andbullet
您有一个应用程序循环,因此请使用它。所有对象都在主应用程序循环中的每一帧中不断更新和绘制。
该类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)
使用 列表bullets
。按下 时创建一个新项目符号。在每一帧中space
移动项目符号 ( ) ,如果项目符号超出窗口,则移动一个项目符号。在每一帧中绘制剩余的项目符号:update
`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()
- 2024年20款好用的项目管理软件推荐,项目管理提效的20个工具和技巧
- 2024年开源项目管理软件有哪些?推荐5款好用的项目管理工具
- 2024年常用的项目管理软件有哪些?推荐这10款国内外好用的项目管理工具
- 项目管理软件有哪些?推荐7款超好用的项目管理工具
- 项目管理软件有哪些最好用?推荐6款好用的项目管理工具
- 项目管理软件哪个最好用?盘点推荐5款好用的项目管理工具
- 项目管理软件有哪些,盘点推荐国内外超好用的7款项目管理工具
- 项目管理软件排行榜:2024年项目经理必备5款开源项目管理软件汇总
- 2024项目管理软件排行榜(10类常用的项目管理工具全推荐)
- 项目管理必备:盘点2024年13款好用的项目管理软件