问题
Heres my code
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()
This is what i could come up with after a few Trial and errors but it is really uneffective. Firstly the player disappers when i press space bar. I guess this is obvious as i have a different loops for shooting and player but i dont know how to get around it and implement both shooting and player in the same loop.
The second probllem i am having is breaking the while self.shooting: loop. I tried breaking it when y reaches a certain point by doing this
if y <= 0:
self.shooting = False
but this dosent break. Instead, it restarts the loop all over again.
Another weird problem i am having is that everytime i move mouse(slightly fast) or press a bunch of buttons at once, it breaks the while self.shooting loop.
回答1:
Please note, that class names should normally use the CapWords convention.
(See Style Guide for Python Code - Class names)
That means it has to be Player and Bullet rather than player and bullet
You have an application loop, so use it. All the objects are continuously updated and drawn in the main application loop, in each frame.
The class Bullet do not need any loop. The constructor has to have parameters for the position (x, y). Further it needs on method which changes the position and one which draws the bullet:
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)
Use a list of bullets. Create a new bullet when space is pressed. Move the bullets (update) in every frame an remove a bullet if it is out of the window. Draw the remaining bullets in every frame:
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()
Furthermore use pygame.key.get_pressed() use to get the state of the keys in every frame and to update the position of the player:
while run:
# [...]
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
p.move_left()
if keys[pygame.K_RIGHT]:
p.move_right()
Complete example:
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()
来源:https://stackoverflow.com/questions/59687250/how-can-i-shoot-a-bullet-with-space-bar