2009-12-25
Recently, I've been getting a lot of hits from people searching for "pyclutter examples". Unfortunately, the code that most people find is my hello world example that was written for Clutter 0.6 and since the API for Clutter has change quite a bit since I wrote that code, the code doesn't work with the latest stable release of Clutter.
I've considered updating the code to work with the more modern Clutter, but that wouldn't really be fun would it? Besides, someone has already updated the code. Thanks Ryan. Why don't I write another example? Don't mind if I do.
There is nothing new Clutter-wise in this example to differentiate it from the hello world example except that this code will run with the latest Clutter.
What we have here, is John Conway's Game of Life where each cell is a Clutter Rectangle.
When running the code: press "q" to quit, press "r" to reset.
One issue I have with this code is that when creating the rectangles for the cells, creation slows down significantly after creating about 3000 rectangles. The app runs fine when all of the cells are created, but the slow down during creation really irks me. Perhaps I need more RAM or I should write the code in Vala using SDL?
Now stop reading, and go play with colored rectangles.
I've considered updating the code to work with the more modern Clutter, but that wouldn't really be fun would it? Besides, someone has already updated the code. Thanks Ryan. Why don't I write another example? Don't mind if I do.
There is nothing new Clutter-wise in this example to differentiate it from the hello world example except that this code will run with the latest Clutter.
What we have here, is John Conway's Game of Life where each cell is a Clutter Rectangle.
#!/usr/bin/env python # copyright 2009 jezra lickter #this software is licensed under the GPLv3 http://www.gnu.org/licenses/gpl.txt import clutter import random class Game: def __init__(self,cell_size): self.cells = [] #create a clutter stage self.stage = clutter.Stage() #set the stage size in x,y pixels self.stage.set_size(500,500) self.stage.set_title("The Game of Life") self.stage_width, self.stage_height = self.stage.get_size() #define some clutter colors in rgbo (red,green,blue,opacity) self.color_black =clutter.Color(0,0,0,255) self.color_green =clutter.Color(0,255,0,255) self.color_blue =clutter.Color(0,0,255,255) #set the clutter stages bg color to our black self.stage.set_color(self.color_black) #we will need to check on the key presses from the user self.stage.connect('key-press-event', self.parseKeyPress) self.stage.connect("destroy", self.quit) '''fill the screen with rectangles''' num_cols = int(self.stage_width/cell_size) num_rows = int(self.stage_height/cell_size) cells_to_create = num_cols*num_rows y = 0 for row in range(num_rows): x = 0 self.cells.append( [] ) print "%i cells to create" % (cells_to_create) for column in range(num_cols): #set the column index to a rect that is cell_size by cell_size self.cells[row].append( clutter.Rectangle() ) self.cells[row][column].set_size(cell_size,cell_size) self.cells[row][column].set_position(x,y) #add this cell to the stage self.stage.add(self.cells[row][column]) self.cells[row][column].set_color(self.color_green) self.cells[row][column].set_opacity(0) x+=cell_size cells_to_create-=num_cols y+=cell_size print "cells created" #get some data about the rows self.row_count = len(self.cells) self.col_count = len(self.cells[0]) self.cell_count = self.row_count*self.col_count #make a timer to do stuff for us self.timeline = clutter.Timeline(duration=500) #when the timer finishes running, we want to determine the life self.timeline.connect("completed",self.compute_life) #increase linearly alpha = clutter.Alpha(self.timeline, clutter.LINEAR) #make some opacity behaviours that we will apply to the cells self.dieBehaviour = clutter.BehaviourOpacity(255,0,alpha) self.aliveBehaviour = clutter.BehaviourOpacity(0,255,alpha) def parseKeyPress(self,actor,event): if event.keyval == clutter.keysyms.q: self.quit() elif event.keyval == clutter.keysyms.c: self.compute_life() elif event.keyval == clutter.keysyms.r: self.reseed() def quit(self,widget=None): clutter.main_quit() def run(self): self.stage.show_all() self.seed_life() self.compute_life() clutter.main() def reseed(self): for r in range(self.row_count): for c in range(self.col_count): if self.cells[r][c].get_opacity()>0: self.cells[r][c].set_opacity(0) self.seed_life() def seed_life(self): print "adding random life" #loop through the rows for r in range(self.row_count): #loop through the columns for c in range(self.col_count): #generate a number i = random.randint(0,4) if i==0: # x,y is alive self.cells[r][c].set_opacity(255) def compute_life(self,asset=None): #detach all objects from the behaviors self.dieBehaviour.remove_all() self.aliveBehaviour.remove_all() for r in range(self.row_count): for c in range(self.col_count): if self.cells[r][c].get_opacity()>0: alive=True else: alive=False ln = self.living_neighbors(r,c) if alive and ( ln<2 or ln>3 ): #this cell will die; boohoo self.dieBehaviour.apply(self.cells[r][c] ) elif not alive and ln==3: #this cell is now alive; damn zombies self.aliveBehaviour.apply(self.cells[r][c] ) #start the timeline again self.timeline.start() def living_neighbors(self,r,c): alive = 0 r_min = r-1 r_max = r+1 c_min = c-1 c_max = c+1 if r==0 : r_min=r elif r == self.row_count-1: r_max=r if c==0 : c_min=c elif c == self.col_count-1: c_max=c tr = r_min tc = c_min cells_computed=0 while not tr > r_max: tc = c_min while not tc > c_max: if ( tr!=r or tc!=c ): cells_computed+=1 if self.cells[tr][tc].get_opacity()>0: alive+=1 tc+=1 tr+=1 return alive if __name__=="__main__": game = Game(5) game.run()
When running the code: press "q" to quit, press "r" to reset.
One issue I have with this code is that when creating the rectangles for the cells, creation slows down significantly after creating about 3000 rectangles. The app runs fine when all of the cells are created, but the slow down during creation really irks me. Perhaps I need more RAM or I should write the code in Vala using SDL?
Now stop reading, and go play with colored rectangles.
Comments