问题
I'm making a simple game in pygame, in which you're supposed to dodge or shoot the targets that descend through the screen. So far, I've created the ship movement, the bullet movement, and the first enemy appearance. However, I have absolutely no clue on how to generate new enemies every 3 seconds on the screen. I made a timer, but I still don't know how to generate an enemy after triggering the timer. When the timer hits 3 seconds, it restarts and sets the "has_passed" variable to True, which allows me to draw the clone enemy. But obviously, this doesn't work because the variable is instantly set to False afterwards. I really don't know how to proceed, especially because I'm a beginner, so this type of problem is out of my scope, regarding python and pygame knowledge. Any help would be very much appreciated.
import pygame, sys
import random
import time
pygame.init()
clock = pygame.time.Clock()
time0 = time.time()
has_passed = False
screen_width = 600
screen_height = 800
enemyWidth = 30
enemyHeight = 10
bg_color = (94, 50, 50)
enemy_color = (0, 0, 0)
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Space Race Game")
class ROCKET:
def __init__(self):
self.rocketImg = pygame.image.load("spaceship.png")
self.rocket_x = screen_width/2 - 32
self.rocket_y = screen_height/2 + 150
def draw_rocket(self):
screen.blit(self.rocketImg, (self.rocket_x, self.rocket_y))
def move_rocket(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and self.rocket_x + 15 > 0:
self.rocket_x -= 5
if key[pygame.K_RIGHT] and self.rocket_x < screen_width - 40:
self.rocket_x += 5
class BULLET(ROCKET):
def __init__(self):
super().__init__()
self.bullet_width = 10
self.bullet_height = 20
self.bullet_x = self.rocket_x + 25
self.bullet_y = self.rocket_y
self.move = [0, 0]
self.bullet_speed = 7
self.bullet_rect = pygame.Rect(self.bullet_x, self.bullet_y, self.bullet_width, self.bullet_height)
def draw_bullet(self, rocket, bullet):
key = pygame.key.get_pressed()
if key[pygame.K_SPACE] and self.move[1] == 0:
self.bullet_x = rocket.rocket_x + 25
self.move[1] = -1
self.bullet_y += self.move[1] * self.bullet_speed
self.bullet_rect.topleft = (self.bullet_x, self.bullet_y)
if self.bullet_y < self.rocket_y - 10:
pygame.draw.rect(screen, (0, 0, 0), self.bullet_rect)
if self.bullet_y < - 20:
self.bullet_y = self.rocket_y
self.move[1] = 0
class ENEMY(ROCKET):
def __init__(self):
super().__init__()
self.enemy_width = enemyWidth
self.enemy_height = enemyHeight
self.enemy_x = random.randint(self.enemy_width, screen_width - self.enemy_width)
self.enemy_y = 0
self.enemy_speed = 1
self.enemy_rect = pygame.Rect(self.enemy_x, self.enemy_y, self.enemy_width, self.enemy_height)
def draw_enemy(self, rocket, bullet, time, random):
clone_x = random
clone_y = 0
clone_rect = pygame.Rect(clone_x, clone_y, self.enemy_width, self.enemy_height)
pygame.draw.rect(screen, enemy_color, self.enemy_rect)
self.enemy_y += self.enemy_speed
self.enemy_rect.topleft = (self.enemy_x, self.enemy_y)
# Time Management and clone drawing
if has_passed == True:
pygame.draw.rect(screen, enemy_color, clone_rect)
rocket = ROCKET()
bullet = BULLET()
enemy = ENEMY()
randomNum = random.randint(enemyWidth, screen_width - enemyWidth)
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
# Time Management
time1 = time.time()
elapse = time1 - time0
if elapse > 3:
time0 = time1
has_passed = True
else:
has_passed = False
screen.fill(bg_color)
rocket.draw_rocket()
rocket.move_rocket()
bullet.draw_bullet(rocket, bullet)
enemy.draw_enemy(rocket, bullet, has_passed, randomNum)
pygame.display.flip()
clock.tick(60)
回答1:
Don't use time.time(). Use pygame.time.get_ticks() to return the number of milliseconds since pygame.init() was called. Define the time when the next enemy must appear. Create a new enemy when the current time exceeds the calculated time and increase the time by the time interval during which new enemies are continuously created:
next_enemy_time = 0
while True:
# [...]
current_time = pygame.time.get_ticks()
if current_time > next_enemy_time:
next_enemy_time = current_time + 3000 # 3000 milliseconds == 3 seconds
# [...] create new enemy
You don't need an enemy clone at all. Use a list to mange multiple enemies:
class ENEMY(ROCKET):
# [...]
def draw_enemy(self, rocket, bullet):
pygame.draw.rect(screen, enemy_color, self.enemy_rect)
self.enemy_y += self.enemy_speed
self.enemy_rect.topleft = (self.enemy_x, self.enemy_y)
enemies = []
while True:
# [...]
if current_time > next_enemy_time:
next_enemy_time = current_time + 3000
enemies.insert(0, ENEMY())
# [...]
Draw the enemies in a loop and remove the enemies from the list if the y-coordinate is greater than the height of the screen:
while True:
# [...]
for enemy in enemies:
enemy.draw_enemy(rocket, bullet)
for i, enemy in enumerate(enemies):
if enemy.enemy_y > screen_height:
del enemies[i:]
break
# [...]
Complete example:
import pygame, sys
import random
import time
pygame.init()
clock = pygame.time.Clock()
time0 = time.time()
has_passed = False
screen_width = 600
screen_height = 800
enemyWidth = 30
enemyHeight = 10
bg_color = (94, 50, 50)
enemy_color = (0, 0, 0)
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Space Race Game")
class ROCKET:
def __init__(self):
self.rocketImg = pygame.image.load("spaceship.png")
self.rocket_x = screen_width/2 - 32
self.rocket_y = screen_height/2 + 150
def draw_rocket(self):
screen.blit(self.rocketImg, (self.rocket_x, self.rocket_y))
def move_rocket(self):
key = pygame.key.get_pressed()
if key[pygame.K_LEFT] and self.rocket_x + 15 > 0:
self.rocket_x -= 5
if key[pygame.K_RIGHT] and self.rocket_x < screen_width - 40:
self.rocket_x += 5
class BULLET(ROCKET):
def __init__(self):
super().__init__()
self.bullet_width = 10
self.bullet_height = 20
self.bullet_x = self.rocket_x + 25
self.bullet_y = self.rocket_y
self.move = [0, 0]
self.bullet_speed = 7
self.bullet_rect = pygame.Rect(self.bullet_x, self.bullet_y, self.bullet_width, self.bullet_height)
def draw_bullet(self, rocket, bullet):
key = pygame.key.get_pressed()
if key[pygame.K_SPACE] and self.move[1] == 0:
self.bullet_x = rocket.rocket_x + 25
self.move[1] = -1
self.bullet_y += self.move[1] * self.bullet_speed
self.bullet_rect.topleft = (self.bullet_x, self.bullet_y)
if self.bullet_y < self.rocket_y - 10:
pygame.draw.rect(screen, (0, 0, 0), self.bullet_rect)
if self.bullet_y < - 20:
self.bullet_y = self.rocket_y
self.move[1] = 0
class ENEMY(ROCKET):
def __init__(self):
super().__init__()
self.enemy_width = enemyWidth
self.enemy_height = enemyHeight
self.enemy_x = random.randint(self.enemy_width, screen_width - self.enemy_width)
self.enemy_y = 0
self.enemy_speed = 1
self.enemy_rect = pygame.Rect(self.enemy_x, self.enemy_y, self.enemy_width, self.enemy_height)
def draw_enemy(self, rocket, bullet):
pygame.draw.rect(screen, enemy_color, self.enemy_rect)
self.enemy_y += self.enemy_speed
self.enemy_rect.topleft = (self.enemy_x, self.enemy_y)
rocket = ROCKET()
bullet = BULLET()
randomNum = random.randint(enemyWidth, screen_width - enemyWidth)
next_enemy_time = 0
enemies = []
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
current_time = pygame.time.get_ticks()
if current_time > next_enemy_time:
next_enemy_time = current_time + 3000
enemies.insert(0, ENEMY())
screen.fill(bg_color)
rocket.draw_rocket()
rocket.move_rocket()
bullet.draw_bullet(rocket, bullet)
for enemy in enemies:
enemy.draw_enemy(rocket, bullet)
for i, enemy in enumerate(enemies):
if enemy.enemy_y > screen_height:
del enemies[i:]
break
pygame.display.flip()
clock.tick(60)
来源:https://stackoverflow.com/questions/65400457/making-clone-enemies