Created
March 23, 2014 22:24
-
-
Save mr-linch/9730779 to your computer and use it in GitHub Desktop.
Class simplifies work with the application for PyGame
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# -*- coding: utf-8 -*- | |
import sys | |
import pygame | |
__author__ = "Alexander Savchuk" | |
class Singleton(type): | |
"""Implementation of the Singleton pattern""" | |
_instances = {} | |
def __call__(cls, *args, **kwargs): | |
if cls not in cls._instances: | |
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs) | |
return cls._instances[cls] | |
class GameLoop(object): | |
"""docstring for GameLoop""" | |
def __init__(self): | |
super(GameLoop, self).__init__() | |
self.application = Application() | |
def startup(self): | |
print 'The gameloop started!' | |
def shutdown(self): | |
print 'The gameloop stopped!' | |
def update(self, deltatime): | |
pass | |
def draw(self): | |
pass | |
def event(self, event): | |
if event.type == pygame.QUIT: | |
self.application.stop() | |
class Application(object): | |
''' | |
Class simplifies work with the application for PyGame | |
Example: | |
>>> from application import Application, GameLoop | |
>>> application = Application() | |
>>> application.title = "Simple Example" | |
>>> application.resolution = 640, 480 | |
>>> application.fps = 30 | |
''' | |
__metaclass__ = Singleton | |
DEFAULT_CONFIG = { | |
'title': 'PyGame Application', # Title of window | |
'icon' : None, # Icon of window | |
'resolution': (800, 600), # Resolution of window | |
'resizable': False, # True, if user can change window size | |
'fullscreen': False, # True, if full screen mode enable | |
'fps': 23, # Frame per second | |
'clearcolor': (255, 102, 0), # Color of display fill | |
'depth': 0, # Depth of color | |
'autoreinit' : False # If true after change special value | |
# (resolution, icon, resizable, fullscreen, depth) application | |
# automatically initialized | |
} | |
def __init__(self, **kwargs): | |
'''See Application.config''' | |
super(Application, self).__init__() | |
self._config = dict(self.DEFAULT_CONFIG) | |
self._config.update(kwargs) | |
self._was_init = False | |
self.__screen = None | |
self.__running = False | |
self.__clock = pygame.time.Clock() | |
self.__runtime = 0.0 | |
self.__ticks = 0 | |
self.__tmp_window_resolution = (0, 0) | |
def config(self, **kwargs): | |
''' | |
Configuring the application | |
Arguments: | |
tittle -- tittle of window (string) | |
icon -- icon of window (Surface) | |
resolution -- resolution of window | |
resizable -- True, if user can change size of window | |
fullscreen -- True, if fullscreen mode active | |
fps -- max value of frame per second | |
clearcolor -- the color using for screen fill | |
depth -- depth of the color | |
autoreinit -- True, if after change special value (resolution, icon, resizable, fullscreen, depth) application automatically reinitialized | |
''' | |
self._config.update(kwargs) | |
def init(self): | |
"""Initialize of application""" | |
# Initialize PyGame display module | |
if not pygame.display.get_init(): | |
pygame.display.init() | |
# Set title of window | |
pygame.display.set_caption(self._config['title']) | |
# Set icon of window | |
if 'icon' in self._config and self._config['icon']: | |
pygame.display.set_icon(self._config['icon']) | |
# Set display mode of window | |
flags = pygame.HWSURFACE | |
flags |= pygame.RESIZABLE if self._config['resizable'] else 0 | |
flags |= pygame.FULLSCREEN if self._config['fullscreen'] else 0 | |
self.__screen = pygame.display.set_mode(self._config['resolution'], flags, self._config['depth']) | |
self._was_init = True | |
def reinit(self): | |
"""Synonym for Application.init""" | |
self.init() | |
def run(self, gameloop): | |
''' | |
Run game loop | |
Game most implement: | |
- startup() | |
- update(deltatime) | |
- draw() | |
- shutdown() | |
- event(event) | |
''' | |
if gameloop is None: | |
gameloop = sys.modules['__main__'] | |
gameloop.startup() | |
self.__running = True | |
while self.__running: | |
deltatime = self.__clock.tick(self._config['fps']) | |
self.__runtime += deltatime / 1000.0 | |
self.__ticks += 1 | |
for event in pygame.event.get(): | |
if event.type == pygame.VIDEORESIZE: | |
if event.size != self._config['resolution']: | |
flags = pygame.HWSURFACE | |
flags |= pygame.RESIZABLE if self._config['resizable'] else 0 | |
flags |= pygame.FULLSCREEN if self._config['fullscreen'] else 0 | |
self.__screen = pygame.display.set_mode(self._config['resolution'], flags, self._config['depth']) | |
self._config['resolution'] = event.size | |
gameloop.event(event) | |
gameloop.update(deltatime) | |
gameloop.draw() | |
pygame.display.update() | |
self.__screen.fill(self._config['clearcolor']) | |
gameloop.shutdown() | |
pygame.display.quit() | |
def stop(self): | |
"""Stop of the game""" | |
self.__running = False | |
def toggle_fullscreen(self): | |
"""Toggle current mode""" | |
fullscreen = self._config['fullscreen'] = not self._config['fullscreen'] | |
if fullscreen: | |
self.__tmp_window_resolution = self._config['resolution'] | |
self._config['resolution'] = pygame.display.list_modes()[0] | |
else: | |
self._config['resolution'] = self.__tmp_window_resolution | |
self.reinit() | |
@property | |
def title(self): | |
"""Title of window""" | |
return self._config['title'] | |
@title.setter | |
def title(self, value): | |
if isinstance(value, basestring): | |
if self._config['title'] != value: | |
self._config['title'] = value | |
pygame.display.set_caption(self._config['title']) | |
else: | |
raise TypeError('title must be a string') | |
@property | |
def icon(self): | |
"""Icon of window""" | |
return self._config['icon'] | |
@icon.setter | |
def icon(self, value): | |
if isinstance(value, pygame.Surface): | |
if self._config['icon'] != value: | |
self._config['icon'] = value | |
if self._config['autoreinit'] and self._was_init: | |
self.reinit() | |
else: | |
raise TypeError('icon must be a pygame.Surface') | |
@property | |
def resolution(self): | |
"""Size of window""" | |
return self._config['resolution'] | |
@resolution.setter | |
def resolution(self, value): | |
if isinstance(value, (list, tuple)) and len(value) == 2: | |
if self._config['resolution'] != value: | |
self._config['resolution'] = value | |
if self._config['autoreinit'] and self._was_init: | |
self.reinit() | |
else: | |
raise TypeError('resolution must be list or tuple, with 2 int element') | |
@property | |
def resizable(self): | |
"""If True, user can change window size (call before create of window)""" | |
return self._config['resizable'] | |
@resizable.setter | |
def resizable(self, value): | |
if isinstance(value, bool): | |
if self._config['resizable'] != value: | |
self._config['resizable'] = value | |
else: | |
raise ValueError('resizable must be bool') | |
@property | |
def maxfps(self): | |
"""Maximum frame per second""" | |
return self._config['fps'] | |
@maxfps.setter | |
def maxfps(self, value): | |
self._config['fps'] = value | |
@property | |
def fps(self): | |
"""Current frame per second value""" | |
return self.__clock.get_fps() | |
@property | |
def running(self): | |
"""State of application""" | |
return self.__running | |
@property | |
def runtime(self): | |
"""Time passed after start""" | |
return self.__runtime | |
@property | |
def ticks(self): | |
"""Ticks passed after start""" | |
return self.__ticks | |
@property | |
def screen(self): | |
"""Screen surface""" | |
return self.__screen | |
@property | |
def clearcolor(self): | |
"""Color for screen fill""" | |
return self._config['clearcolor'] | |
@clearcolor.setter | |
def clearcolor(self, value): | |
if isinstance(value, (list, tuple)) and len(value) == 3: | |
self._config['clearcolor'] = value | |
else: | |
raise TypeError('clear color must be tuple or list, and contain 3 elements') | |
@property | |
def fullscreen(self): | |
"""Full screen mode""" | |
return self._config['fullscreen'] | |
@fullscreen.setter | |
def fullscreen(self, value): | |
if isinstance(value, bool): | |
if self._config['fullscreen'] != value: | |
self._config['fullscreen'] = value | |
if self._config['autoreinit'] and self._was_init: | |
self.reinit() | |
else: | |
raise ValueError('resizable must be bool') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment