Adicionando tela de fundo.
Autor: João Paulo Farias | Publicado: 2009-06-19T17:36:00-03:00

 Olá! Continuando nosso pequeno joguinho, esta semana vamos fazer a tela de fundo um pouco mais interessante que apenas um fundo preto e opaco... Vamos adicionar estrelas, com movimento!    Abaixo está o código da classe "Background", que devemos salvar no arquivo "background.py".   
# coding: utf8
# background.py

import pygame
import random

class Background(object):
    
    def __init__(self, max_stars=100):
        self.max_speed = 6
        screen = pygame.display.get_surface()
        size = screen.get_size()
        back = pygame.Surface(size).convert()
        back.fill( (0,0,0) )
        self.image = back
        self.stars = []
        for _ in range(max_stars):
            rand = random.randint
            self.stars.append( [rand(0, size[0]), rand(0, size[1]), rand(1, self.max_speed)])
    
    def update(self):
        size = pygame.display.get_surface().get_size()
        for star in self.stars:
            star[1] += star[2]
            if star[1] >= size[1]:
                star[1] = 0
                star[0] = random.randint(0, size[0])
                star[2] = random.randint(1, self.max_speed)
    
    def draw(self, screen):
        image = self.image
        image.fill( (0, 0, 0) )
        for star in self.stars:
            image.set_at(star[:2], (255, 255, 255))
        
        screen.blit(self.image, (0, 0))
   Como vocês podem ver, a classe é bem simples. Inicializamos a o objeto background com um número máximo padrão de 100 estrelas, cada estrela irá se mover de cima para baixo na tela, dando a impressão que estamos percorrendo o espaço. Atribuímos também a velocidade máxima com que cada estrela poderá se movimentar.    Preenchemos a tela com o tradicional fundo preto, criamos uma "Surface" que será onde iremos desenhar nossas estrelas e salvamos essa "Surface" na variável "self.image".    Agora a parte interessante. A criação das estrelas. Para nosso exemplo, faremos da forma mais simples possível: uma array com 3 números, representando a posição da estrela e sua velocidade (x, y, velocidade).    O método "update(self)" é onde ocorre a atualização do estado do nosso background. O que faremos aqui é simplesmente adicionar a velocidade (star[2]) à coordenada y da posição (star[1]). Caso após adicionarmos a velocidade a estrela suma, ou seja, sua cordenada y passe a ser maior que o tamanho da nossa tela na vertical, reposicionamos esta estrela, colocando-a no topo da tela, com novos valores para a coordenada x e para a velocidade. Note que para a velocidade sempre iremos desejar um valor >= 1, pois caso contrário teríamos uma estrela estática.    O método "draw(self)" é mais simples ainda. Preenchemos a nossa imagem com preto e então percorremos a lista de estrelas, adicionando um ponto branco para cada uma delas em sua posição atual. Após isso chamamos "blit" na variável "screen". O que está função faz é copiar o conteúdo de uma "Surface" para outra. Assim, ao copiarmos o fundo para a "Surface" screen, estaremos substituindo a imagem que será mostrada na tela na próxima atualização.    O que resta agora é apenas alterar a classe "Game" para utilizar o nosso background animado. Abaixo está o código da classe com as devidas alterações:   
# coding: utf8
# game.py

import pygame
import random

from pygame.locals import *
import background

class Game(object):
    
    def __init__(self, size):
        pygame.init()
        flags = DOUBLEBUF
        self.screen = pygame.display.set_mode(size, flags)
        self.screen_size = self.screen.get_size()
        
        pygame.mouse.set_visible(False)
        pygame.display.set_caption('Meu Primeiro Jogo em Python')
        
        self.run = True
        self.list = {
            'player': pygame.sprite.RenderPlain(),
            'enemy': pygame.sprite.RenderPlain(),
            'fire': pygame.sprite.RenderPlain(),
            'enemy_fire': pygame.sprite.RenderPlain(),
        }
        self.player = None
        self.background = background.Background()
    
    def update_actors(self):
        if self.background is not None:
            self.background.update()
        
        for actor in self.list.values():
            actor.update()
    
    def draw_actors(self):
        if self.background is not None:
            self.background.draw(self.screen)
        else:
            self.screen.fill(0)
        
        for actor in self.list.values():
            actor.draw(self.screen)
    
    def act_actors(self):
        pass
    
    def manage(self):
        pass
    
    def handle_events(self):
        player = self.player
        for event in pygame.event.get():
            t = event.type
            
            if t in (KEYDOWN, KEYUP):
                k = event.key
            
            if t == QUIT:
                self.run = False
            elif t == KEYDOWN and k == K_ESCAPE:
                self.run = False
            elif t == KEYUP:
                pass
    
    def loop(self):
        clock = pygame.time.Clock()
        
        while self.run:
            clock.tick(1000)
            
            self.handle_events()
            self.manage()
            
            self.act_actors()
            self.update_actors()
            self.draw_actors()
            
            pygame.display.flip()

if __name__ == '__main__':
    game = Game( (640, 480) )
    game.loop()

   Como você pode observar, com poucas linhas de código criamos um fundo de tela animado bem legal. No próximo post vou adicionar algumas naves. Até!