Revision: 6783
          http://matplotlib.svn.sourceforge.net/matplotlib/?rev=6783&view=rev
Author:   jdh2358
Date:     2009-01-14 17:54:36 +0000 (Wed, 14 Jan 2009)

Log Message:
-----------
added Paul Ivanov's gui independent pong example

Added Paths:
-----------
    trunk/matplotlib/examples/event_handling/pipong.py
    trunk/matplotlib/examples/event_handling/pong_gtk.py
    trunk/matplotlib/examples/event_handling/pong_qt.py

Added: trunk/matplotlib/examples/event_handling/pipong.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pipong.py                          
(rev 0)
+++ trunk/matplotlib/examples/event_handling/pipong.py  2009-01-14 17:54:36 UTC 
(rev 6783)
@@ -0,0 +1,257 @@
+#!/usr/bin/env python
+# A matplotlib based game of Pong illustrating one way to write interactive
+# animation which are easily ported to multiply backends
+# pipong.py was written by Paul Ivanov <http://pirsquared.org>
+
+import numpy as np
+import matplotlib.pyplot as plt
+from numpy.random import randn, randint
+
+instructions = """
+Player A:       Player B:
+  'e'      up     'i'
+  'd'     down    'k'
+
+press 't' -- close these instructions 
+            (animation will be much faster)
+press 'a' -- add a puck                
+press 'A' -- remove a puck             
+press '1' -- slow down all pucks       
+press '2' -- speed up all pucks        
+press '3' -- slow down distractors     
+press '4' -- speed up distractors      
+press ' ' -- reset the first puck
+press 'n' -- toggle distractors on/off    
+press 'g' -- toggle the game on/off    
+
+  """
+
+class Pad(object):
+    def __init__(self, disp,x,y,type='l'):
+        self.disp = disp
+        self.x = x
+        self.y = y
+        self.w = .3
+        self.score = 0
+        self.xoffset = 0.3
+        self.yoffset = 0.1
+        if type=='r':
+            self.xoffset *= -1.0
+
+        if type=='l' or type=='r':
+            self.signx = -1.0
+            self.signy = 1.0
+        else:
+            self.signx = 1.0
+            self.signy = -1.0
+    def contains(self, loc):
+        return self.disp.get_bbox().contains(loc.x,loc.y)
+
+class Puck(object):
+    def __init__(self, disp, pad, field):
+        self.vmax= .2
+        self.disp = disp
+        self.field = field
+        self._reset(pad)
+    def _reset(self,pad):
+        self.x = pad.x + pad.xoffset
+        if pad.y < 0:
+            self.y = pad.y +  pad.yoffset 
+        else:
+            self.y = pad.y - pad.yoffset
+        self.vx = pad.x - self.x
+        self.vy = pad.y + pad.w/2 - self.y
+        self._speedlimit()
+        self._slower()
+        self._slower()
+    def update(self,pads):
+        self.x += self.vx
+        self.y += self.vy
+        for pad in pads:
+            if pad.contains(self):
+                self.vx *= 1.2 *pad.signx
+                self.vy *= 1.2 *pad.signy
+        fudge = .001
+        #probably cleaner with something like...if not 
self.field.contains(self.x, self.y):
+        if self.x < 0+fudge:
+            #print "player A loses"
+            pads[1].score += 1;
+            self._reset(pads[0])
+            return True
+        if self.x > 7-fudge:
+            #print "player B loses"
+            pads[0].score += 1;
+            self._reset(pads[1])
+            return True
+        if self.y < -1+fudge or self.y > 1-fudge:
+            self.vy *= -1.0 
+            # add some randomness, just to make it interesting
+            self.vy -= (randn()/300.0 + 1/300.0) * np.sign(self.vy)
+        self._speedlimit()
+        return False
+    def _slower(self):
+        self.vx /= 5.0
+        self.vy /= 5.0
+    def _faster(self):
+        self.vx *= 5.0
+        self.vy *= 5.0
+    def _speedlimit(self):
+        if self.vx > self.vmax:
+            self.vx = self.vmax
+        if self.vx < -self.vmax:
+            self.vx = -self.vmax
+
+        if self.vy > self.vmax:
+            self.vy = self.vmax
+        if self.vy < -self.vmax:
+            self.vy = -self.vmax
+
+class Game(object):        
+
+    def __init__(self, ax):
+        # create the initial line
+        self.ax = ax
+        padAx = padBx= .50
+        padAy = padBy= .30
+        padBx+=6.3
+        pA, = self.ax.barh(padAy,.2, height=.3,color='k', alpha=.5, 
edgecolor='b',lw=2,label="Player B", animated=True)
+        pB, = self.ax.barh(padBy,.2, height=.3, left=padBx, 
color='k',alpha=.5, edgecolor='r',lw=2,label="Player A",animated=True)
+
+        # distractors
+        self.x = np.arange(0,2.22*np.pi,0.01)
+        self.line, = self.ax.plot(self.x, np.sin(self.x),"r", animated=True, 
lw=4)
+        self.line2, = self.ax.plot(self.x, np.cos(self.x),"g", animated=True, 
lw=4)
+        self.line3, = self.ax.plot(self.x, np.cos(self.x),"g", animated=True, 
lw=4)
+        self.line4, = self.ax.plot(self.x, np.cos(self.x),"r", animated=True, 
lw=4)
+        self.centerline,= self.ax.plot([3.5,3.5], [1,-1],'k',alpha=.5, 
animated=True,  lw=8)
+        self.puckdisp = self.ax.scatter([1],[1],label='_nolegend_', 
s=200,c='g',alpha=.9,animated=True)
+
+        self.canvas = self.ax.figure.canvas
+        self.background = None
+        self.cnt = 0
+        self.distract = True
+        self.res = 100.0
+        self.on = False
+        self.inst = True    # show instructions from the beginning
+        self.background = None
+        self.pads = []
+        self.pads.append( Pad(pA,0,padAy))
+        self.pads.append( Pad(pB,padBx,padBy,'r'))
+        self.pucks =[] 
+        self.i = self.ax.annotate(instructions,(.5,0.5),
+                     name='monospace',
+                     verticalalignment='center',
+                     horizontalalignment='center',
+                     multialignment='left',
+                     textcoords='axes fraction',animated=True )
+        self.canvas.mpl_connect('key_press_event', self.key_press)
+
+    def draw(self, evt):
+        draw_artist = self.ax.draw_artist
+        if self.background is None:
+            self.background = self.canvas.copy_from_bbox(self.ax.bbox)
+
+        # restore the clean slate background
+        self.canvas.restore_region(self.background)
+
+        # show the distractors
+        if self.distract:
+            self.line.set_ydata(np.sin(self.x+self.cnt/self.res))
+            self.line2.set_ydata(np.cos(self.x-self.cnt/self.res))
+            self.line3.set_ydata(np.tan(self.x+self.cnt/self.res))
+            self.line4.set_ydata(np.tan(self.x-self.cnt/self.res))
+            draw_artist(self.line)
+            draw_artist(self.line2)
+            draw_artist(self.line3)
+            draw_artist(self.line4)
+
+        # show the instructions - this is very slow
+        if self.inst:
+            self.ax.draw_artist(self.i)
+
+        # pucks and pads
+        if self.on:
+            self.ax.draw_artist(self.centerline)
+            for pad in self.pads:
+                pad.disp.set_y(pad.y)
+                pad.disp.set_x(pad.x)
+                self.ax.draw_artist(pad.disp)
+
+            for puck in self.pucks:
+                if puck.update(self.pads):
+                    # we only get here if someone scored
+                    self.pads[0].disp.set_label("   "+ 
str(self.pads[0].score)) 
+                    self.pads[1].disp.set_label("   "+ 
str(self.pads[1].score)) 
+                    self.ax.legend(loc='center')
+                    self.leg = self.ax.get_legend()
+                    #self.leg.draw_frame(False) #don't draw the legend border
+                    self.leg.get_frame().set_alpha(.2)
+                    
plt.setp(self.leg.get_texts(),fontweight='bold',fontsize='xx-large')
+                    self.leg.get_frame().set_facecolor('0.2')
+                    self.background = None
+                    self.ax.draw()
+                    return True
+                puck.disp.set_offsets([puck.x,puck.y])
+                self.ax.draw_artist(puck.disp)
+
+
+        # just redraw the axes rectangle
+        self.canvas.blit(self.ax.bbox)
+
+        if self.cnt==50000:
+            # just so we don't get carried away
+            print "...and you've been playing for too long!!!"
+            plt.close()
+
+        self.cnt += 1
+        return True
+
+    def key_press(self,event):
+        if event.key == '3':
+            self.res *= 5.0
+        if event.key == '4':
+            self.res /= 5.0
+
+        if event.key == 'e':
+            self.pads[0].y += .1
+            if self.pads[0].y > 1 - .3:
+                self.pads[0].y = 1-.3
+        if event.key == 'd':
+            self.pads[0].y -= .1
+            if self.pads[0].y < -1:
+                self.pads[0].y = -1
+
+        if event.key == 'i':
+            self.pads[1].y += .1
+            if self.pads[1].y > 1 - .3:
+                self.pads[1].y = 1-.3
+        if event.key == 'k':
+            self.pads[1].y -= .1
+            if self.pads[1].y < -1:
+                self.pads[1].y = -1
+        
+        if event.key == 'a':
+            
self.pucks.append(Puck(self.puckdisp,self.pads[randint(2)],self.ax.bbox))
+        if event.key == 'A' and len(self.pucks):
+            self.pucks.pop()
+        if event.key == ' ' and len(self.pucks):
+            self.pucks[0]._reset(self.pads[randint(2)])
+        if event.key == '1':
+            for p in self.pucks:
+                p._slower()
+        if event.key == '2':
+            for p in self.pucks:
+                p._faster()
+        
+        if event.key == 'n':
+            self.distract = not self.distract
+
+        if event.key == 'g':
+            #self.ax.clear()
+            #self.ax.grid() # seems to be necessary for qt backend
+            self.on = not self.on
+        if event.key == 't':
+            self.inst = not self.inst
+            self.i.set_visible(self.i.get_visible())
+        if event.key == 'q':
+            plt.close() 

Added: trunk/matplotlib/examples/event_handling/pong_gtk.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pong_gtk.py                        
        (rev 0)
+++ trunk/matplotlib/examples/event_handling/pong_gtk.py        2009-01-14 
17:54:36 UTC (rev 6783)
@@ -0,0 +1,35 @@
+#!/usr/bin/env python
+
+# For detailed comments on animation and the techniques used here, see
+# the wiki entry
+# http://www.scipy.org/wikis/topical_software/MatplotlibAnimation
+import time
+
+import gtk, gobject
+
+import matplotlib
+matplotlib.use('GTKAgg')
+
+import numpy as np
+import matplotlib.pyplot as plt
+import pipong 
+from numpy.random import randn, randint
+
+
+fig = plt.figure()
+ax = fig.add_subplot(111)
+canvas = ax.figure.canvas
+
+
+def start_anim(event):
+    gobject.idle_add(animation.draw,animation)
+    canvas.mpl_disconnect(start_anim.cid)
+
+animation = pipong.Game(ax)
+start_anim.cid = canvas.mpl_connect('draw_event', start_anim)
+
+
+tstart = time.time()
+plt.grid() # to ensure proper background restore
+plt.show()
+print 'FPS:' , animation.cnt/(time.time()-tstart)

Added: trunk/matplotlib/examples/event_handling/pong_qt.py
===================================================================
--- trunk/matplotlib/examples/event_handling/pong_qt.py                         
(rev 0)
+++ trunk/matplotlib/examples/event_handling/pong_qt.py 2009-01-14 17:54:36 UTC 
(rev 6783)
@@ -0,0 +1,42 @@
+# For detailed comments on animation and the techniqes used here, see
+# the wiki entry http://www.scipy.org/Cookbook/Matplotlib/Animations
+
+import os, sys
+import matplotlib
+matplotlib.use('QtAgg') # qt3 example
+
+from qt import *
+# Note: color-intensive applications may require a different color allocation
+# strategy.
+QApplication.setColorSpec(QApplication.NormalColor)
+
+TRUE  = 1
+FALSE = 0
+ITERS = 1000
+
+import pylab as p
+import matplotlib.pyplot as plt
+import numpy as np
+import time
+import pipong 
+from numpy.random import randn, randint
+
+class BlitQT(QObject):
+    def __init__(self):
+        QObject.__init__(self, None, "app")
+
+        self.ax = plt.subplot(111)
+        self.animation = pipong.Game(self.ax)
+
+    def timerEvent(self, evt):
+       self.animation.draw(evt)
+
+plt.grid() # to ensure proper background restore
+
+app = BlitQT()
+# for profiling
+app.tstart = time.time()
+app.startTimer(0)
+
+plt.show()
+print 'FPS:' , app.animation.cnt/(time.time()-app.tstart)


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
This SF.net email is sponsored by:
SourcForge Community
SourceForge wants to tell your story.
http://p.sf.net/sfu/sf-spreadtheword
_______________________________________________
Matplotlib-checkins mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/matplotlib-checkins

Reply via email to