Razón Artificial

La ciencia y el arte de crear videojuegos

Juego de la serpiente paso a paso. Parte 2

Escrito por adrigm el 17 de julio de 2010 en Desarrollo Videojuegos, Noticias, Programación | 10 Comentarios.

En esta parte definiremos sub-rutinas que nos servirán para controlar varios loops dentro de un juego, muy útil para mostrar menús, pausar el juego y demás.

Adaptando a subrutinas

Antes de seguir vamos a mirar al futuro, la idea es que el juego muestre al iniciar un menú donde puedas elegir nuevo juego, opciones, mejores puntuaciones y salir. Por lo que el bucle principal de nuestro juego debería ser este menú y luego según la opción llamar a una función u otra que se encargue de gestionar un sub-bucle propio.

Primero que nada vamos a crear la función que ejecuta el juego que sería la siguiente:

def nuevo_juego(screen):
	background_image = load_image('images/fondo.jpg');
	
	clock = pygame.time.Clock()
	
	while True:
		time = clock.tick(60)
		keys = pygame.key.get_pressed()
		salir(keys)
		
		mapa.dibujar(screen)
		screen.blit(background_image, (0, 0))
		pygame.display.flip()

y el bucle principal entonces nos queda así:

def main():
	screen = pygame.display.set_mode((WIDTH, HEIGHT))
	pygame.display.set_caption("Pruebas Pygame")
	
	while True:
		nuevo_juego(screen)
	return 0

Como vemos la ventana (screen) se sigue creando en el bucle principal, pero se la pasamos como parámetro a nuestra sub-rutina nuevo_juego. Por ahora lo único que hacemos dento del bucle principal es llamar a la sub-rutina nuevo_juego y que esta tome el control, por lo que por ahora trabajaremos sobre esta.

Tenemos que crear el objeto mapa dentro de nuestra función nuevo_juego, para ello añadimos la siguiente línea:

mapa = Mapa("mapa.txt")

Dibujando el mapa

Como ya hemos dicho será la clase mapa la encargada de dibujar todo, por lo que será el mapa con los valores de sus casillas los que dibujarán una cosa u otra, así que vamos con el método dibujar de la clase mapa:

def dibujar(self, screen):
	for f in range(self.fil):
		for c in range(self.col):
			if self.mapa[f]1 == 1:
				screen.blit(self.bloque, (self.rect_bloque.w*c, self.rect_bloque.h*f))
			if self.mapa[f]1 == 2 or self.mapa[f]1 == 5:
				screen.blit(self.snake, (self.rect_snake.w*c, self.rect_snake.h*f))
			if self.mapa[f]1 == 3:
				screen.blit(self.comida, (self.rect_comida.w*c, self.rect_comida.h*f))

Muy simple, recorremos el mapa usando self.fil y self.col que definimos en el primer tutorial y comprobamos el valor de la casilla y guiandonos por nuestro esquema de valores que definimos dibujamos una cosa u otra.

Por ejemplo, el 1 representaba un muro por lo que si la casilla vale 1 dibujamos en pantalla un sprite bloque. Especial atencion a que lo dibujo usando su rect (self.rect_bloque.w*c, self.rect_bloque.h*f) es decir que la estoy pasando donde debe colocar la esquina superior izquierda del sprite, en este caso le digo que la coordenada x del punto está en self.rect_bloque.w*c, es decir, el ancho del sprite por la columna en la que se encuentra y la coordenada y en el punto self.rect_bloque.h*f, la altura del sprite por la fila en la que se encuentra por lo que un muro en la fila 2 columna 4 con un sprite de 16×16 píxeles dibujaría su esquina superior izquierda en la coordenada (16×4, 16×2) o lo que es lo mismo (64, 32).

lo único que nos queda es dibujar el mapa en nuestra bucle de la función nuevo_juego, recuerda hacerlo después de dibujar el fondo, sino no verás nada (el fondo siempre es lo primero que se dibuja):

screen.blit(background_image, (0, 0))
mapa.dibujar(screen)

y si ejecutamos veremos lo siguiente:

El juego nos queda así:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

# Módulos
import sys, pygame
from pygame.locals import *

# Constantes
WIDTH = 640
HEIGHT = 480

# Clases
# ---------------------------------------------------------------------

class Mapa(pygame.sprite.Sprite):
	def __init__(self, archivo):
		pygame.sprite.Sprite.__init__(self)
		
		self.bloque = load_image("images/bloque.png")
		self.rect_bloque = self.bloque.get_rect()
		
		self.snake = load_image("images/snake.png")
		self.rect_snake = self.snake.get_rect()
		
		self.comida = load_image("images/comida.png", True)
		self.rect_comida = self.comida.get_rect()
		
		self.mapa = leerMapa(archivo)
		self.fil = len(self.mapa)
		self.col = len(self.mapa[0])
		
	def dibujar(self, screen):
		for f in range(self.fil):
			for c in range(self.col):
				if self.mapa[f]1 == 1:
					screen.blit(self.bloque, (self.rect_bloque.w*c, self.rect_bloque.h*f))
				if self.mapa[f]1 == 2 or self.mapa[f]1 == 5:
					screen.blit(self.snake, (self.rect_snake.w*c, self.rect_snake.h*f))
				if self.mapa[f]1 == 3:
					screen.blit(self.comida, (self.rect_comida.w*c, self.rect_comida.h*f))

# ---------------------------------------------------------------------

# Funciones
# ---------------------------------------------------------------------

# Quita el ultimo caracter de una lista.
def quitarUltimo(lista):
	for i in range(len(lista)):
		lista[i] = lista[i][:-1]
	return lista

# Covierte una cadena en una lista.	
def listarCadena(cadena):
	lista = []
	for i in range(len(cadena)):
		if cadena[i] == ".":
			lista.append(0)
		if cadena[i] == "#":
			lista.append(1)
		if cadena[i] == "*":
			lista.append(2)
	return lista

# Lee un archivo de texto y lo convierte en una lista.
def leerMapa(archivo):
	mapa = open(archivo, "r")
	mapa = mapa.readlines()
	mapa = quitarUltimo(mapa)
	for i in range(len(mapa)):
		mapa[i] = listarCadena(mapa[i])
	return mapa

# Carga una imagen a Pygame
def load_image(filename, transparent=False):
        try: image = pygame.image.load(filename)
        except pygame.error, message:
                raise SystemExit, message
        image = image.convert()
        if transparent:
                color = image.get_at((0,0))
                image.set_colorkey(color, RLEACCEL)
        return image
        
def salir(keys):
	for eventos in pygame.event.get():
		if eventos.type == QUIT:
			sys.exit(0)
		if keys[K_ESCAPE]:
			sys.exit(0)

def nuevo_juego(screen):
	background_image = load_image('images/fondo.jpg');
	
	clock = pygame.time.Clock()
	
	mapa = Mapa("mapa.txt")
	
	while True:
		time = clock.tick(60)
		keys = pygame.key.get_pressed()
		salir(keys)
		
		screen.blit(background_image, (0, 0))
		mapa.dibujar(screen)
		pygame.display.flip()

# ---------------------------------------------------------------------

def main():
	screen = pygame.display.set_mode((WIDTH, HEIGHT))
	pygame.display.set_caption("Serpiente")
	
	while True:
		nuevo_juego(screen)
	return 0

if __name__ == '__main__':
	pygame.init()
	main()

10 Comentarios en "Juego de la serpiente paso a paso. Parte 2"

  1. Antonio dice:

    Tengo una pequeña duda. ¿Qué hay que tener instalado para hacerlo funcionar y cómo se ejecuta el programa?

  2. adrigm dice:

    Debes tener instalado Python y Pygame. Luego debes ejecutar el fichero .py

    mas info aquí: http://razonartificial.com/2010/01/curso-python-i-interprete-y-scripts/

  3. Cristian dice:

    Hola, a mi no me funciona el codigo y no se porque me da error en la sintaxis cuando dices
    self.mapa[f]1
    me sale error en el 1, he cogido tambien tu codigo entero y lo comprobe e igual. No se si sera porque uso el python 2.7, pero no creo.
    Espero una respuesta gracias =)
    Aaa y se me olvidaba muy buenos tutoriales gracias a ellos consegui mejorar mi programacion.

    • adrigm dice:

      Ha habido un error al migrar el host de la web y el cófigo fuente pegado ha quedado mal, en realidad es:

      self.mapa[f][ c ]

      donde veas:

      self.mapa[f]1

      sustituye el 1 por [ c ]

      • Cristian dice:

        Muchas gracias, por responder tan rapido pensaba que iba a durar 4 o 5 dias en recibir la respuesta y a los segundos me respondes jeje.
        He quitado los 1 pero hay un problema enciendo el juego y solo me aparece el fondo nada mas y no se porque. No encuentro la manera de empezar el juego.
        Soy novato en python llevo 1 mes trabajando en el.
        Saludos y gracias

        • adrigm dice:

          A este tutorial le quedo una parte por publicar, te aconsejo que hagas es del pong que está totalmente completo.

          Un saludo.

          • Cristian dice:

            Ahora me he dado cuenta =) el del pong ya lo he hecho y me salio perfecto. Siento haber molestado. He cogido el codigo de tu juego de la serpiente que habias hecho y trabajo encima de el.

            Un saludo y muchas gracias por responder.

  4. Rincorpe dice:

    Muy buen artículo me funciono perfectamente.. cuando van a publicar la tercera parte?

  5. […] Juego de la serpiente paso a paso. Parte 2 […]

  6. Marco Andrade dice:

    Buenas amigo, no logro encontrar el pong, podrias pasar el link? Gracias

Deja un comentario