Skip to content

Instantly share code, notes, and snippets.

@iminurnamez
Last active December 16, 2015 22:52
Show Gist options
  • Save iminurnamez/5f661612c6ed752e18fc to your computer and use it in GitHub Desktop.
Save iminurnamez/5f661612c6ed752e18fc to your computer and use it in GitHub Desktop.
import sys
from random import choice, randint
import pygame as pg
COLORS = ["springgreen", "goldenrod"]
class Square(pg.sprite.DirtySprite):
"""
A colored square that move very slowly around the screen. Their slow speed
means that most of the time they aren't actually moving on the screen so they
don't really need to be redrawn.
"""
def __init__(self, center, color, size, *groups):
super(Square, self).__init__(*groups)
self.image = pg.Surface((size, size))
self.image.fill(color)
self.pos = center
self.rect = self.image.get_rect(center=self.pos)
self.speed = .1
self.velocity = (randint(-1, 1), randint(-1, 1))
#DirtySprites have a self.dirty attribute that tells the LayeredDirty
#group whether the sprite is dirty or not. Possible values are 0, 1 and 2.
#0 means the sprite isn't dirty and doesn't need to be drawn, 1 means the sprite
#is dirty and that after being drawn the sprite should no longer be dirty (i.e., dirty
#automatically gets set to 0), 2 means the sprite is dirty and should stay that way.
#
#Here we're setting dirty to 1 so that the sprite gets drawn on the very first frame
#otherwise it wouldn't show up on the screen.
self.dirty = 1
def update(self):
#Note where the sprite is now
last_pos = self.rect.center
#Move the sprite
self.pos = (self.pos[0] + (self.velocity[0] * self.speed),
self.pos[1] + (self.velocity[1] * self.speed))
self.rect.center = self.pos
#Check if the sprite's screen position is different from
#the last frame. If it is, the sprite needs to be redrawn so
#self.dirty gets set to 1. After the sprite gets drawn
#dirty will automatically be changed to 0.
#You would also set dirty to 1 if the sprite's image
#changed in some way.
if last_pos != self.rect.center:
self.dirty = 1
class Game(object):
def __init__(self):
#basic setup stuff
self.screen = pg.display.set_mode((1280, 720))
self.screen_rect = self.screen.get_rect()
self.clock = pg.time.Clock()
self.fps = 60
self.done = False
#DirtySprite stuff
#Make a background for the scene - the background gets subsurfaced to
#cover up sprites that are dirty.
self.background = self.make_background()
#subclass of sprite.Group that handles dirty rendering
self.all_sprites = pg.sprite.LayeredDirty()
#Add some sprites
self.add_squares()
#Set the background that the LayeredDirty group will use.
#You only need to do this once unless you switch to a
#different background.
self.all_sprites.clear(self.screen, self.background)
def make_background(self):
"""A little more interesting than filling with a color."""
background = pg.Surface(self.screen.get_size())
r, g, b = 5, 5, 10
for y in range(0, 721, 10):
rect = pg.Rect(0, y, 1280, 10)
background.fill((r, g, b), rect)
r += 1
g += 1
b += 2
return background
def add_squares(self):
for _ in range(200):
pos = (randint(20, self.screen_rect.w - 20),
randint(20, self.screen_rect.h - 20))
color = pg.Color(choice(COLORS))
size = randint(10, 30)
Square(pos, color, size, self.all_sprites)
def update(self):
self.all_sprites.update()
#the Layered part of LayeredDirty, sprites are drawn in
#order sorted by their layer number
for sprite in self.all_sprites:
self.all_sprites.change_layer(sprite, sprite.rect.bottom)
def event_loop(self):
for event in pg.event.get():
if event.type == pg.QUIT:
self.done = True
def draw(self):
dirty_rects = self.all_sprites.draw(self.screen)
return dirty_rects
def run(self):
while not self.done:
self.event_loop()
self.update()
dirty_rects = self.draw()
pg.display.update(dirty_rects)
self.clock.tick(self.fps)
if __name__ == "__main__":
game = Game()
game.run()
pg.quit()
sys.exit()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment