I can't blit the same object multiple times

2019-08-31 07:56发布

问题:

I am currently making a Guitar Hero like game in python and I am trying to blit a note multiple times, but I can't seem to get it to work (the note is called Red)!

#Sprite Class
class Sprite(pygame.sprite.Sprite):
    # What has to be passed when you create a sprite.
    #   image_file: The filename of the image.
    #   lacation: The initial location of where to draw the image.
    def __init__(self, image_file, location):                       
    pygame.sprite.Sprite.__init__(self) # Call Sprite initializer       
    self.image = pygame.image.load(image_file)                         
    self.rect = self.image.get_rect()                                  
    self.rect.left, self.rect.top = location
    self.xSpeed = 15 # The default xSpeed
    self.ySpeed = 15 # The default ySpeed
    self.name = "Not Assigned"
    self.speed = 10
    self.direction = 0

    def setSpeed(self, speed):
        self.speed = speed
        self.calcXYSpeeds()

    def setDirection(self, direction):
        self.direction = direction
        self.calcXYSpeeds()

    def calcXYSpeeds(self):
        angleRadians = math.radians(self.direction) # Convert the direction to radians.
        self.xSpeed= self.speed*math.cos(angleRadians)
        self.ySpeed = self.speed*math.sin(angleRadians)

    def move(self):
        self.rect = self.rect.move(self.xSpeed,self.ySpeed)

    def setDirectionTowards(self, (x,y)):
        self.direction = math.degrees(math.atan2((self.rect.x - x), (self.rect.y - y)))
        self.direction = 270 - self.direction
        self.calcXYSpeeds()

#Object Variables
Red = Sprite("Red.png", (100,25))
note1 = Sprite("note1.jpg", (50,650))
#add sprite to group
notes = pygame.sprite.Group()
notes.add(Red)
# Create an clock to keep track time
clock = pygame.time.Clock()
#Scoring Variables
font=pygame.font.Font(None,50)
score=0
score_text=font.render(str(score),1,(225,225,225))
#other Variables
Red1=0
ySpeed = 10
running = 1
while (running==1):
    # Sets the frame rate to 30 frames/second.
    clock.tick(30)

    # Gets any events like keyboard or mouse.
    event = pygame.event.poll()
    key=pygame.key.get_pressed()
    #object random spawn
    time = pygame.time.get_ticks()
    if (time==30*(random.randint(0,1000))):
        screen.blit(Red.image, Red.rect)
        pygame.display.update()

    #Object Movement
    Red.rect.y = Red.rect.y + ySpeed

    #Keys to complete notes
    if key[pygame.K_a]and Red1==0 and pygame.sprite.collide_rect(Red, note1) == True:
        font=pygame.font.Font(None,50)
        score = score+1
        score_text=font.render(str(score),1,(225,225,225))
        Red1=1
        #where i currently working to fix the problem
        notes.Group.clear(screen, background)
        notes.Group.update()
        notes.draw(screen)

    # Sets the exit flag if the X was clicked on the run window.
    if event.type == pygame.QUIT:
        running = 0

    # Color the whole screen with a solid color.
    screen.fill((0, 255, 255))
    #prints objects
    screen.blit(note1.image, note1.rect)
    screen.blit(Red.image, Red.rect)
    screen.blit(score_text,(500,50))

    # Update the window.
    pygame.display.update()

回答1:

You are cleaning and updating the screen multiple times in the same cycle.

Clean the screen in every cycle is a correct approach, but you need to clean only once otherwise you are erasing everything you blitted before.

Also, for notes to persist between cycles you need to keep them in a collection, like notes, that way you blit every note in every cycle.

Keep in mind this order in your main loop:

  1. Control FPS (clock.tick())
  2. Check events
  3. Update state (ie: add/remove notes collection, etc)
  4. Clear screen
  5. Draw current state (notes, static elements, etc)
  6. Update display

Another important thing, don't use the same Sprite() nor the same Rectangle in different locations. If you want to draw another copy of the same image in a new location make a copy of the rectangle, then create a new Sprite() object.