Skip to content

Instantly share code, notes, and snippets.

@mr-linch
Created March 23, 2014 22:24
Show Gist options
  • Save mr-linch/9730779 to your computer and use it in GitHub Desktop.
Save mr-linch/9730779 to your computer and use it in GitHub Desktop.
Class simplifies work with the application for PyGame
# -*- 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