Por ejemplo:
- Menú Principal
- Opciones del Juego
- Créditos
- Pantalla del juego
- etc ...
- Captura de eventos (teclado, ratón, etc..)
- Dibujar (mostrar las opciones del menú, mostrar la pantalla del juego ...)
- Actualizar estados (cambiar la opcion del menu seleccionada, actualizar la posicion del jugador ...)
- Y otros como pueden ser, ¿que pasa cuando se inicializa el estado?, ¿que pasa cuando se finaliza?, ¿que pasa si se hace un pause?
Tendremos una clase llamada GameManager que controlará el paso de un estado a otro y sus eventos, y una clase abstracta llamada GameState, de la que heredarán todos los estados por los que pueda pasar nuestro juego.
Para que veais como funciona todo esto, vamos a hacer un pequeño ejemplo que luego nos servirá para nuestro juego.
Necesitamos crear inicialmente un fichero llamada juego.py y dos carpetas una llamada gamemanager y otra dentro de esta llamada states.
Dentro de la carpeta "states" crearemos un archivo llamado gamestate.py con el siguiente codigo:
class GameState(object): def __init__(self,parent): pass def start(self): pass def cleanUp(self): pass def pause(self): pass def resume(self): pass def handleEvents(self, events, parent): pass def update(self): pass def draw(self): pass
Ahora dentro de la carpeta "gamemanager" creamos 2 archivos, el primero con el nombre singleton.py con el siguiente codigo:
class Singleton(type): def __init__(cls,name,bases,dic): super(Singleton,cls).__init__(name,bases,dic) cls.instance=None def __call__(cls,*args,**kw): if cls.instance is None: cls.instance=super(Singleton,cls).__call__(*args,**kw) return cls.instance
y el otro con el nombre gamemanager.py y con el siguiente codigo:
import os import sys import pygame from pygame.locals import * from singleton import * class GameManager(object): __metaclass__ = Singleton def __init__(self, titulo, size=(320, 200), fullscreen=False): print "Inicilizado el GameManager" self.states = [] self.running = True os.environ['SDL_VIDEO_CENTERED'] = '1' pygame.init(); self.screen = pygame.display.set_mode(size) pygame.display.set_caption(titulo) pygame.mouse.set_visible(0) def cleanUp (self): while len(self.states) > 0: state = self.states.pop() state.cleanUp() sys.exit(0) def changeState (self, gameState): print "Cambio de Estado" if len(self.states) > 0: state = self.states.pop() state.cleanUp() self.states.append(gameState) self.states[-1].start() def pushState(self, gameState): if len(self.states) > 0: self.states[-1].pause() self.states.append(gameState) self.states[-1].start() def popState(self): if len(self.states) > 0: state = self.states.pop() state.cleanUp() if len(self.states) > 0: self.states[-1].resume() def handleEvents(self, events): self.states[-1].handleEvents(events) def update(self): self.states[-1].update() def draw(self): self.states[-1].draw() pygame.display.flip() def quit(self): print "Quit" self.running = False
Con estos archivos ya tenemos toda la base para crear nuestro juego.
Ahora solo nos quedará crear un estado inicial para nuestro juego, por ejemplo el menú, y proceder a arrancarlo.
Para ello hacemos lo siguiente, creamos un archivo llamado menustate.py en la carpeta "states" y le añadimos el siguiente código:
import pygame from pygame.locals import * from gamemanager.states import gamestate class MenuState(gamestate.GameState): def __init__(self, parent): self.parent = parent self.background = pygame.Surface(self.parent.screen.get_size()) self.background = self.background.convert() self.background.fill((255, 0, 0)) def start(self): print "GameState Menu Started" def cleanUp(self): print "GameState Menu Cleaned" pass def pause(self): print "GameState Menu Paused" pass def resume(self): print "GameState Menu Resumed" pass def handleEvents(self, events): for event in events: if event.type == pygame.KEYDOWN : if event.key == pygame.K_ESCAPE : self.parent.quit() def update(self): pass def draw(self): self.parent.screen.blit(self.background, (0,0))
Y por ultimo añadimos al archivo principal juego.py el siguiente codigo:
import pygame from pygame.locals import * from gamemanager.gamemanager import GameManager from gamemanager.states import menustate if __name__ == "__main__": game = GameManager('Juego Python',(320,200),False) game.changeState(menustate.MenuState(game)) while game.running: game.handleEvents(pygame.event.get()) game.update() game.draw() game.cleanUp()
Nota: Por cuestiones del lenguaje de Python debemos crear un archivo llamado __init__.py dentro de cada una de las carpetas que hemos creado (gamemanager, states).
Por ahora podemos dejar en blanco dicho archivo.
Ya podremos ejecutar el programa y veremos como se inicia el estado de Menu.
python juego.py
Al pulsar la tecla ESC saldremos del programa.
Ahora puedes intentar crear un estado nuevo, por ejemplo Opciones, e intentar llamarlo desde el Menu.
Para ello os explicaré un par de cosas.
Podemos pasar de un estado a otro conservando en memoria el estado actual o cambiando por completo el estado.
Para cambiar de un estado a otro, sin mantener el estado actual, se hace de la siguiente forma:
self.parent.changeState(opcionesstate.OpcionesState(self.parent)
y para cambiar de un estado a otro conservando el estado actual:
self.parent.pushState(opcionesstate.OpcionesState(self.parent)
Si cambiamos el estado de esta ultima forma, para recuperar el estado anterior, deberemos ejecutar esto en el estado en el que nos encontramos ahora.
self.parent.popState()
Si no os queda claro, os pongo el codigo necesario para hacer esto que os comento.
El archivo opcionesstate.py tendrá que crearse en la carpeta "states" con el siguiente codigo:
import pygame from pygame.locals import * from gamemanager.states import gamestate class OpcionesState(gamestate.GameState): def __init__(self, parent): self.parent = parent self.background = pygame.Surface(self.parent.screen.get_size()) self.background = self.background.convert() self.background.fill((0, 255, 0)) def start(self): print "GameState Opciones Started" def cleanUp(self): print "GameState Opciones Cleaned" pass def pause(self): print "GameState Opciones Paused" pass def resume(self): print "GameState Opciones Resumed" pass def handleEvents(self, events): for event in events: if event.type == pygame.KEYDOWN : if event.key == pygame.K_ESCAPE : self.parent.popState() def update(self): pass def draw(self): self.parent.screen.blit(self.background, (0,0))
Y el archivo menustate.py quedará de la siguiente forma:
import pygame from pygame.locals import * from gamemanager.states import gamestate import opcionesstate class MenuState(gamestate.GameState): def __init__(self, parent): self.parent = parent self.background = pygame.Surface(self.parent.screen.get_size()) self.background = self.background.convert() self.background.fill((255, 0, 0)) def start(self): print "GameState Menu Started" def cleanUp(self): print "GameState Menu Cleaned" pass def pause(self): print "GameState Menu Paused" pass def resume(self): print "GameState Menu Resumed" pass def handleEvents(self, events): for event in events: if event.type == pygame.KEYDOWN : if event.key == pygame.K_ESCAPE : self.parent.quit() elif event.key == pygame.K_o: self.parent.pushState(opcionesstate.OpcionesState(self.parent)) def update(self): pass def draw(self): self.parent.screen.blit(self.background, (0,0))
Ya podeis probar y jugar con los distintos estados hasta la siguiente entrega.
¿Seguirás con el blog? Es que me estoy iniciando en PyGame y me está siendo muy útil. ¿Podrías subir al menos (algunas partes) del código de tu juego?
ResponderEliminarGracias.
Gispsan
Si claro, seguiré con el Blog.
ResponderEliminarA ver si esta seman publico algo más ;)
¿Has probado todo?
¿Te funciona correctamente?
Muchas gracias por compartir esto pive, estoy siguiendo este curso y voy por esta parte de blog, aunque estoy realizando un juego plataforma ya yo adapatare todo lo que expongas a mi juego ya que creo que basicamente es lo mismo.
ResponderEliminarTodo funciona perfecto! por lo menos lo que pones en esta parte de la pagina.
aunque en el primer code que pusistes se te colo esta etiqueta en la linea 22.
una pregunta ¿que tecnologia usastes para pegar el codigo con este estylo en el blog?
Genial!!!, si necesitas ayuda dilo.
ResponderEliminarPara que el codigo salga aí utilizo al etiqueta
pre class="brush: python"