Olá Nicolas, peço desculpas pela demora no retorno.
Sobre essa questão de relatividade que você mencionou faz sentido sim, fazer o mapa ser gerado a partir do (0, 0)
e "puxar" esse ponto na direção contrária do movimento desejado. De forma mais detalhada seria pegar a coordenada do centro da visão a cada movimento e calcular quais as coordenadas dentro de um quadrado ao redor dessa coordenada, que seria a parte visível no momento.
Para receber eventos de movimento do mouse você pode usar o tipo de evento pygame.MOUSEMOTION
e então testar se o botão do mouse está pressionado ou não, a partir daí é possível pegar a coordenada do mouse e utilizar para mover o mapa. Segue um exemplo bem básico feito em cima do código da aula:
import pygame
pygame.init()
screen = pygame.display.set_mode((800, 800), 0)
font = pygame.font.SysFont("arial", 20, True, False)
AMARELO = (255, 255, 0)
PRETO = (0, 0, 0)
AZUL = (0, 0, 255)
VELOCIDADE = 1
class Cenario:
def __init__(self, tamanho):
self.tamanho = tamanho
self.matriz = [
# Matriz mapa mostrada em aula ...
]
def pintar_linha(self, tela, numero_linha, linha):
for numero_coluna, coluna in enumerate(linha):
x = numero_coluna * self.tamanho
y = numero_linha * self.tamanho
half = self.tamanho // 2
cor = PRETO
if coluna == 2:
cor = AZUL
pygame.draw.rect(tela, cor, (x, y, self.tamanho, self.tamanho), 0)
if coluna == 1:
pygame.draw.circle(tela, AMARELO, (x + half, y + half),
self.tamanho // 10, 0)
def pintar(self, posicao, tela):
# Área a ser mostrada ao redor da câmera
distancia_renderizada = 10
top = posicao[1] + distancia_renderizada
right = posicao[0] + distancia_renderizada
bottom = posicao[1] - distancia_renderizada
left = posicao[0] - distancia_renderizada
# Selecionando apenas a região da matriz que deve ser mostrada
lines = self.matriz[max([bottom, 0]):min([top, 29])]
visible_matrix = [line[max([left, 0]):min([right, 28])] for line in lines]
for numero_linha, linha in enumerate(visible_matrix):
self.pintar_linha(tela, numero_linha, linha)
def processar_eventos(self, posicao, eventos):
for e in eventos:
if e.type == pygame.MOUSEMOTION:
if pygame.mouse.get_pressed()[0]:
# Pega a coordenada do mouse
mouse_x, mouse_y = e.pos
# Converte a coordenada recebida em pixels (800, 800) para
# a escala da no matriz do mapa (29, 28)
posicao[0] = int(mouse_x / 29)
posicao[1] = int(mouse_y / 28)
return posicao
if __name__ == "__main__":
size = 600 // 30
cenario = Cenario(size)
posicao = [0, 0]
while True:
# Pintar a tela
screen.fill(PRETO)
cenario.pintar(posicao, screen)
pygame.display.update()
pygame.time.delay(100)
# Captura os eventos
eventos = pygame.event.get()
for e in eventos:
if e.type == pygame.QUIT:
exit()
posicao = cenario.processar_eventos(posicao, eventos)
Código acima em execução:
Ainda tem várias limitações nesse código mas já é um bom ponto de partida. Os pontos importantes são a leitura da coordenada do mouse na função processar_eventos
e a seleção da área do mapa a ser mostrada em pintar
Você pode ver mais sobre movimento de câmera (sem o mouse) no capítulo 8 do livro Making games with Python & Pygame e sobre mover elementos com o mouse na página PyGame: Drag object on screen using mouse
Exemplo do jogo feito no capítulo 8 do livro "Making games with Python & Pygame":
Espero que isso ajude, qualquer dúvida é só falar!