1
votes

I am a beginner for pygame and I am imitating the game code "alien invasion" in the book "Python Crash Course" to program a game named "Alphabet zoo". In this game, different letters fall down from the top of the screen after a time interval and the letter will vanish while you strike the corresponding key on the keyboard. The x position of each letter is random and the falling speed will accelerate as the game progress. Game will end under a certain condition(e.g. screen height is occupied by letters). This seems a great chanllenge for me. During the first stage, my codes are simplified for same letters 'A' rather than varied letters. They are as the following:

A.png

  1. alphabet_zoo.py
import sys
import pygame
from pygame.locals import *
from settings import Settings
from letter import Letter
import game_functions as gf
from pygame.sprite import Group

def run_game():
    pygame.init()
    az_settings =Settings()
    screen = pygame.display.set_mode((0,0), RESIZABLE)   
    pygame.display.set_caption("Alphabet Zoo")
    letter = Letter(az_settings, screen)
    letters = Group()


    while True:
        gf.check_events(az_settings, screen, letters)
        letters.update()
        gf.update_screen(az_settings, screen, letters)


run_game()

  1. settings.py
class Settings():
    def __init__(self):
        self.bg_color = (0, 0, 0)
        self.letter_speed_factor = 10.5
  1. game_functions.py
import sys
import pygame
from letter import Letter

def letter_generator(az_settings, screen, letters, lag_time):
    new_letter = Letter(az_settings, screen)
    letters.add(new_letter)

def check_events(az_settings, screen, letters):
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_a:   
                print('a')    


def update_screen(az_settings, screen, letters):
    screen.fill(az_settings.bg_color)
    letters.blitme()
    letters.update()
    pygame.display.flip()
  1. letter.py
import pygame
import random
from pygame.sprite import Sprite


class Letter(Sprite):

    def __init__(self, az_settings, screen):
        super().__init__()
        self.screen = screen
        self.az_settings = az_settings
        self.image = pygame.image.load('images/A.png')
        self.rect = self.image.get_rect()
        self.screen_rect = screen.get_rect()

        self.rect.centerx = random.randint(0, self.screen_rect.right)
        self.rect.top = self.screen_rect.top
        self.center = float(self.rect.centerx)
    def blitme(self):
        self.screen.blit(self.image, self.rect)

    def update(self):
        if self.rect.bottom < self.screen_rect.bottom:
            self.rect.centery += self.az_settings.letter_speed_factor

I think I should use sprite in the codes. Unfortunately, the program hints " AttributeError: 'Group' object has no attribute 'blitme'" after running. I would appreciate a lot if you help me with the problem.

1

1 Answers

1
votes

The method blitme doesn't exist in pygame.sprite.Group. You cannot invoke a method on a pygame.sprite.Group object, that doesn't exist. But you don't need blitme at all. All you have to do is to invoke pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect for the position.

For instance:

letters.draw()

pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.

The former delegates the to the update mehtod of the contained pygame.sprite.Sprites - you have to implement the method. See pygame.sprite.Group.update():

Calls the update() method on all Sprites in the Group [...]

The later uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects - you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. [...]