You are on page 1of 43

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.

org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Second Example: Pong &mdash; The Pygame SGE 0.8.0 documentation</titl e> <link rel="stylesheet" href="_static/default.css" type="text/css" /> <link rel="stylesheet" href="_static/pygments.css" type="text/css" /> <script type="text/javascript"> var DOCUMENTATION_OPTIONS = { URL_ROOT: '', VERSION: '0.8.0', COLLAPSE_INDEX: false, FILE_SUFFIX: '.html', HAS_SOURCE: true }; </script> <script type="text/javascript" src="_static/jquery.js"></script> <script type="text/javascript" src="_static/underscore.js"></script> <script type="text/javascript" src="_static/doctools.js"></script> <link rel="top" title="The Pygame SGE 0.8.0 documentation" href="index.html" /> <link rel="next" title="Global Variables and Constants" href="globalvars.htm l" /> <link rel="prev" title="First Example: Hello, world!" href="hello_world.html " /> </head> <body> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="General Index" accesskey="I">index</a></li> <li class="right" > <a href="globalvars.html" title="Global Variables and Constants" accesskey="N">next</a> |</li> <li class="right" > <a href="hello_world.html" title="First Example: Hello, world!" accesskey="P">previous</a> |</li> <li><a href="index.html">The Pygame SGE 0.8.0 documentation</a> &raquo;< /li> </ul> </div> <div class="document"> <div class="documentwrapper"> <div class="bodywrapper"> <div class="body"> <div class="section" id="second-example-pong"> <h1>Second Example: Pong<a class="headerlink" href="#second-example-pong" title=

"Permalink to this headline"></a></h1> <p>Now that you&#8217;ve seen the basics of the SGE, it&#8217;s time to create a n actual game. Although Pong might seem extremely simple, it will give you a great foundation for developing more complex games in the future.</p> <div class="section" id="setting-up-the-project"> <h2>Setting Up the Project<a class="headerlink" href="#setting-up-the-project" t itle="Permalink to this headline"></a></h2> <p>I am going to set up my project in &#8220;~/pong&#8221;, and the game script is going to be called &#8220;pong.py&#8221;.</p> <p>I am going to open pong.py and add the appropriate shebang, my copyright notice (I am choosing the CC0 license), and my imports. This is what I have so far:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr /bin/env python3</span> <span class="c"># Pong</span> <span class="c"># Written in 2013 by Julian Marchant &lt;onpon4@riseup.net&gt;</ span> <span class="c">#</span> <span class="c"># To the extent possible under law, the author(s) have dedicated all</span> <span class="c"># copyright and related and neighboring rights to this software to the</span> <span class="c"># public domain worldwide. This software is distributed without any</span> <span class="c"># warranty.</span> <span class="c">#</span> <span class="c"># You should have received a copy of the CC0 Public Domain Dedic ation</span> <span class="c"># along with this software. If not, see</span> <span class="c"># &lt;http://creativecommons.org/publicdomain/zero/1.0/&gt;.</sp an> <span class="kn">import</span> <span class="nn">sge</span> </pre></div> </div> </div> <div class="section" id="global-variables"> <h2>Global Variables<a class="headerlink" href="#global-variables" title="Permal ink to this headline"></a></h2> <p>For our implementation of Pong, we are going to store a few variables that can be accessed conveniently by everybody: in a word, &#8220;global&#8221; variables.</p> <p>Of course, one way we could do this is to actually use global variables. However, using this approach has a significant disadvantage: in Python, local variables take precedence over global variables, so to assign to a global variable within a function, you have to declare it with the <tt class="docutils literal"><span class="pre">global</span></tt> keyword. If w e forget to do this, the resulting bugs can be difficult to solve.</p> <p>So we are going to use a different approach: a container class. Put simply, this is a class that contains only class attributes that we will use as variables. Our container class looks like this:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class< /span> <span class="nc">glob</span><span class="p">:</span> <span class="c"># This class is for global variables. While not necessary, using a</span>

<span class="c"># container class like this is less potentially confusing th an using</span> <span class="c"># actual global variables.</span> <span class="n">player1</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">player2</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">ball</span> <span class="o">=</span> <span class="bp">None</ span> <span class="n">hud_sprite</span> <span class="o">=</span> <span class="bp"> None</span> <span class="n">bounce_sound</span> <span class="o">=</span> <span class="bp ">None</span> <span class="n">bounce_wall_sound</span> <span class="o">=</span> <span clas s="bp">None</span> <span class="n">score_sound</span> <span class="o">=</span> <span class="bp" >None</span> <span class="n">game_in_progress</span> <span class="o">=</span> <span class ="bp">True</span> </pre></div> </div> <p>I call the class &#8220;glob&#8221; as a shorthand for &#8220;global&#8221; ( the shorthand is necessary since <tt class="docutils literal"><span class="pre">global</span></tt > is a keyword in Python).</p> <p>The reason for having all of these variables will be explained later when we actually use them.</p> </div> <div class="section" id="the-game-class"> <h2>The Game Class<a class="headerlink" href="#the-game-class" title="Permalink to this headline"></a></h2> <p>For our <a class="reference internal" href="Game.html#sge.Game" title="sge.Ga me"><tt class="xref py py-class docutils literal"><span class="pre">sge.Game</sp an></tt></a> class, we want to of course provide a way to exit the game, and in this case, we are also going to provide a way to pause the game. Just for the heck of it, let&#8217;s also allow the player to take a screenshot by pressing F8. With those goals in mind, our Game class is defined as follows:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class< /span> <span class="nc">Game</span><span class="p">(</span><span class="n">sge</ span><span class="o">.</span><span class="n">Game</span><span class="p">):</span > <span class="k">def</span> <span class="nf">event_key_press</span><span clas s="p">(</span><span class="bp">self</span><span class="p">,</span> <span class=" n">key</span><span class="p">,</span> <span class="n">char</span><span class="p" >):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;f8&#39;</span><span class="p">:</span> <span class="n">sge</span><span class="o">.</span><span class="n">Sp rite</span><span class="o">.</span><span class="n">from_screenshot</span><span c lass="p">()</span><span class="o">.</span><span class="n">save</span><span class ="p">(</span><span class="s">&#39;screenshot.jpg&#39;</span><span class="p">)</s pan> <span class="k">elif</span> <span class="n">key</span> <span class="o">= =</span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">elif</span> <span class="n">key</span> <span class="ow">

in</span> <span class="p">(</span><span class="s">&#39;p&#39;</span><span class= "p">,</span> <span class="s">&#39;enter&#39;</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n"> pause</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_close</span><span class="p ">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">m</span> <span class="o">=</span> <span class="s">&quot; Are you sure you want to quit?&quot;</span> <span class="k">if</span> <span class="n">sge</span><span class="o">.</s pan><span class="n">show_message</span><span class="p">(</span><span class="n">m </span><span class="p">,</span> <span class="p">(</span><span class="s">&quot;No &quot;</span><span class="p">,</span> <span class="s">&quot;Yes&quot;</span><spa n class="p">)):</span> <span class="bp">self</span><span class="o">.</span><span class="n"> end</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_key_press</span><sp an class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">char</span><span cl ass="p">):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="c"># This allows the player to still exit while the gam e is</span> <span class="c"># paused, rather than having to unpause first.</span > <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> unpause</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_close</span><span c lass="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># This allows the player to still exit while the game is paused,</span> <span class="c"># rather than having to unpause first.</span> <span class="bp">self</span><span class="o">.</span><span class="n">even t_close</span><span class="p">()</span> </pre></div> </div> <p>The first event we define is the key press event. When the F8 key is pressed, we create a sprite from a screenshot using the <a class="reference internal" href="Sprite.html#sge.Sprite.from_screenshot" titl e="sge.Sprite.from_screenshot"><tt class="xref py py-meth docutils literal"><spa n class="pre">sge.Sprite.from_screenshot()</span></tt></a> class method, then sa ve that sprite as &#8220;screenshot.jpg&#8221;. When the Esc key is pressed, we close the game by calling the close event. When the &#8220;P&#8221; or Enter key is pressed, we u se <a class="reference internal" href="Game.html#sge.Game.pause" title="sge.Game.pa use"><tt class="xref py py-meth docutils literal"><span class="pre">sge.Game.pau se()</span></tt></a> to pause the game. &#8220;P&#8221; and Enter are checked together by grouping them in a tuple and then using the <tt class="docutils lite ral"><span class="pre">in</span></tt> operator, rather than checking them separately, because it&#8217;s easier to read and less verbose.</p> <p>The next event we define is the close event. Unlike our last example,

here, we first ask the player to confirm whether or not they want to close before actually closing. <a class="reference internal" href="functions.ht ml#sge.show_message" title="sge.show_message"><tt class="xref py py-func docutil s literal"><span class="pre">sge.show_message()</span></tt></a> returns a number representing what button was pressed, with <tt class="docutils literal">< span class="pre">0</span></tt> as the first number, so we are able to simplify the check of what button was pressed with a simple hack: the first button (button 0) is the &#8220;No&#8221; button, and the second button (button 1) is the &#8220;Yes&#8221; button. The numbers these buttons return correspond to <tt class="xref py py-const docutils literal"><span class="pre">False</span></tt> and <tt class="xref py py-const docutils literal" ><span class="pre">True</span></tt>, respectively.</p> <p>Next, we need to define &#8220;paused&#8221; events, because normal events ar e suspended while the game is paused. The &#8220;paused&#8221; close event just do es the same thing as the regular &#8220;close&#8221; event, to allow the game to be exited without unpausing the game first. The &#8220;paused&#8221; key event, on the other hand, unpauses the game if any key other than the Esc key (which ends the game) is pressed.</p> </div> <div class="section" id="the-player-class"> <h2>The Player Class<a class="headerlink" href="#the-player-class" title="Permal ink to this headline"></a></h2> <p>The Player class is going to be a subclass of <a class="reference internal" h ref="StellarClass.html#sge.StellarClass" title="sge.StellarClass"><tt class="xre f py py-class docutils literal"><span class="pre">sge.StellarClass</span></tt></ a>, which is the class that represents individual objects in the SGE. This class is used for players, bullets, floors, walls, and pretty much anything else you can think of.</p> <p>For the Player class, we are actually going to do something a bit unusual: we are going to extend <a class="reference internal" href="StellarClass .html#sge.StellarClass.__init__" title="sge.StellarClass.__init__"><tt class="xr ef py py-meth docutils literal"><span class="pre">sge.StellarClass.__init__()</s pan></tt></a> (the constructor method):</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class< /span> <span class="nc">Player</span><span class="p">(</span><span class="n">sge </span><span class="o">.</span><span class="n">StellarClass</span><span class="p ">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">,</span> <span class="n">play er</span><span class="o">=</span><span class="mi">1</span><span class="p">):</sp an> <span class="k">if</span> <span class="n">player</span> <span class="o"> ==</span> <span class="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;w&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;s&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3 2</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer1</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n">

hit_direction</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;up&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;down&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sg e</span><span class="o">.</span><span class="n">game</span><span class="o">.</sp an><span class="n">width</span> <span class="o">-</span> <span class="mi">32</sp an> <span class="n">glob</span><span class="o">.</span><span class="n">p layer2</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n"> hit_direction</span> <span class="o">=</span> <span class="o">-</span><span clas s="mi">1</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.< /span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">0</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;paddle&quot;</span><span class="p">) </span> </pre></div> </div> <p>As you can see, our extended <tt class="xref py py-meth docutils literal"><sp an class="pre">__init__()</span></tt> now only takes one argument indicating the player: <tt class="docutils literal"><span class="pre">1 </span></tt> for the left player, and any other value (such as <tt class="docutils literal"><span class="pre">2</span></tt>) for the right player. Everything else is then inferred from that: the controls (you will see why we are storing the controls like this in a minute), the horizontal location, and the direction the paddle hits (<tt class="docutils literal"><span class="pre">1</spa n></tt> for right, <tt class="docutils literal"><span class="pre">-1</span></tt> for left). As a bonus, we also use this information to decide what &#8220;global&#8221; variable to assign the player to: <tt class="xref py py-attr docutils literal"><span class=" pre">glob.player1</span></tt> if it is the left player, or <tt class="xref py py-attr docutils literal"><span class="pre">glob.player2</spa n></tt> if it is the right player.</p> <p>Keep in mind that you must never <em>override</em> <a class="reference internal" href="StellarClass.html#sge.StellarClass.__init__" title="sge.StellarClass.__init__"><tt class="xref py py-meth docutils literal"> <span class="pre">sge.StellarClass.__init__()</span></tt></a>; you should only e xtend it. This is why we have the last line. The <tt class="xref py py-func docutils literal"><sp an class="pre">super()</span></tt> function allows us to call the corresponding method in the parent class, making our new <tt class="xref py py-meth docutils literal"><span class="pre">__init__()</span> </tt> an extension rather than an override.</p> <p>Next up, we need to add code to allow the paddles to move. The easiest place to do this is in the step event:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_step</span><span class="p">(</span><span class="bp"> self</span><span class="p">,</span> <span class="n">time_passed</span><span clas s="p">):</span>

<span class="c"># Movement</span> <span class="n">key_motion</span> <span class="o">=</span> <span class="p">( </span><span class="n">sge</span><span class="o">.</span><span class="n">get_key _pressed</span><span class="p">(</span><span class="bp">self</span><span class=" o">.</span><span class="n">down_key</span><span class="p">)</span> <span class=" o">-</span> <span class="n">sge</span><span class="o">.</span><span class= "n">get_key_pressed</span><span class="p">(</span><span class="bp">self</span><s pan class="o">.</span><span class="n">up_key</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvelocit y</span> <span class="o">=</span> <span class="n">key_motion</span> <span class= "o">*</span> <span class="n">PADDLE_SPEED</span> <span class="c"># Keep the paddle inside the window</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class="mi">0 </span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox _top</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</s pan><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span class=" n">sge</span><span class="o">.</span><span class="n">game</span><span class="o"> .</span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox _bottom</span> <span class="o">=</span> <span class="n">sge</span><span class="o ">.</span><span class="n">game</span><span class="o">.</span><span class="n">hei ght</span> </pre></div> </div> <p>The first thing we do is check whether the paddle&#8217;s assigned down key i s pressed and whether the assigned up key is pressed. The simplest way to do this is to use an if statement, but instead, I subtracted the result for the up key from the result for the down key. Since the returned values are equivalent to <tt class="docutils literal"><span class="pre">1</span> </tt> and <tt class="docutils literal"><span class="pre">0</span></tt> in subtra ction, key_motion will become <tt class="docutils literal"><span class="pre">-1</span></tt> if only the up key is pressed, <tt class="docutils literal"><span class="pre">1</span></tt> if only the down key is pressed, and <tt class="docutils literal"><span class="pre">0</span></tt> if neither or both of the keys are pressed. This method of figuring out the desired direction not only is a lot simpler than an if statement, but also handles the condition of opposite directions being pressed at the same time properly.</p> <p>Since <tt class="docutils literal"><span class="pre">-1</span></tt> is up, <t t class="docutils literal"><span class="pre">1</span></tt> is down, and <tt clas s="docutils literal"><span class="pre">0</span></tt> is no movement, I now just need to multiply <tt class="docutils literal"><span class="pre">key_motion</span ></tt> by some constant value (the paddle speed I wish to use) to get the desired vertical velocity. The name I have chosen for this constant is <tt class="xref py py-const docutils literal"><span class="pre">PADDLE_SPEED</span></tt>. Attempting to use an undefined constant will cause an error, so let&#8217;s define it now:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">PADDLE _SPEED</span> <span class="o">=</span> <span class="mi">4</span> </pre></div> </div> <p>This should be placed in the global namespace, probably right after your

imports. I chose <tt class="docutils literal"><span class="pre">4</span></tt> t o be the value of this constant because I found it to be the best balance between precision and speed.</p> <p>As you may have figured out, <tt class="xref py py-attr docutils literal"><sp an class="pre">sge.StellarClass.yvelocity</span></tt> is a special attribute. In simple terms, the SGE automatically adds this number to the vertical position of the object every frame, creating an illusion of continuous movement.</p> <p>With just this, the players will be able to move the paddles off of the screen, and we don&#8217;t want this. To prevent it, we check the paddle&#8217; s <tt class="xref py py-attr docutils literal"><span class="pre">sge.StellarClass. bbox_top</span></tt> and <tt class="xref py py-attr docutils literal"><span class="pre">sge.StellarClass. bbox_bottom</span></tt> attributes to see if they are above or below the screen, respectively, and then set them to the respective edge of the screen if they are.</p> </div> <div class="section" id="the-ball-class"> <h2>The Ball Class<a class="headerlink" href="#the-ball-class" title="Permalink to this headline"></a></h2> <p>Once again, the Ball class is going to be a subclass of <a class="reference internal" href="StellarClass.html#sge.StellarClass" title="s ge.StellarClass"><tt class="xref py py-class docutils literal"><span class="pre" >sge.StellarClass</span></tt></a>. Once again, we are going to start by extending the constructor method:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">class< /span> <span class="nc">Ball</span><span class="p">(</span><span class="n">sge</ span><span class="o">.</span><span class="n">StellarClass</span><span class="p"> ):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">):</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">width</span> <span class="o">/</span> <span class="mi">2</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.< /span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">1</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;ball&quot;</span><span class="p">)</ span> </pre></div> </div> <p>This extension is more simple than <tt class="xref py py-class docutils liter al"><span class="pre">Player</span></tt>&#8216;s: our extension simply removes all arguments from the constructor method and hard-codes values to pass on to <a class="reference internal" href="StellarClass.html#sge.S tellarClass.__init__" title="sge.StellarClass.__init__"><tt class="xref py py-me th docutils literal"><span class="pre">sge.StellarClass.__init__()</span></tt></ a>.</p> <p>When the ball is created, we want to immediately serve it to a player. To achieve that, we are going to define the create event, which occurs whenever an object of the class is created:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_create</span><span class="p">(</span><span class="bp ">self</span><span class="p">):</span>

<span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">()</span> </pre></div> </div> <p>We are defining <tt class="xref py py-func docutils literal"><span class="pre ">Ball.serve()</span></tt> to achieve serving the ball because there are other situations when the ball needs to be served, namely whenever a player scores. This will be our serve method:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">serve</span><span class="p">(</span><span class="bp">self< /span><span class="p">,</span> <span class="n">direction</span><span class="o">= </span><span class="mi">1</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">xstart</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">ystart</span> <span class="c"># Next round</span> <span class="bp">self</span><span class="o">.</span><span class="n">xvelocit y</span> <span class="o">=</span> <span class="n">BALL_START_SPEED</span> <span class="o">*</span> <span class="n">direction</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvelocit y</span> <span class="o">=</span> <span class="mi">0</span> </pre></div> </div> <p>In a nutshell, we set the ball back to the its starting position (which is the center of the screen) and reset its movement based on an argument called <tt class="docutils literal"><span class="pre">direction</span></tt>, whi ch will be <tt class="docutils literal"><span class="pre">1</span></tt> (for rig ht) or <tt class="docutils literal"><span class="pre">-1</span></tt> (for left). We multiply this by a constant called <tt class="xref py py-const docuti ls literal"><span class="pre">BALL_START_SPEED</span></tt>; let&#8217;s define this constant now, right below our definition of <tt class="xref py py-const docutils literal"><span class="pre">PADDLE_SPEED</sp an></tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">BALL_S TART_SPEED</span> <span class="o">=</span> <span class="mi">2</span> </pre></div> </div> <p>As it is, the ball will pass through the paddles, which is not what we want; we want the ball to bounce off of the paddles. We will achieve that with a collision event:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_collision</span><span class="p">(</span><span class= "bp">self</span><span class="p">,</span> <span class="n">other</span><span class ="p">):</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p"> (</span><span class="n">other</span><span class="p">,</span> <span class="n">Pla yer</span><span class="p">):</span> <span class="k">if</span> <span class="n">other</span><span class="o">.< /span><span class="n">hit_direction</span> <span class="o">==</span> <span class ="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_left</span> <span class="o">=</span> <span class="n">other</span><span clas s="o">.</span><span class="n">bbox_right</span> <span class="o">+</span> <span c lass="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="nb">min</span><span class

="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="bp" >self</span><span class="o">.</span><span class="n">xvelocity</span><span class= "p">)</span> <span class="o">+</span> <span class="n">BALL_ACCELERATION</span><s pan class="p">,</span> <span class="n">BALL_MAX_SPEED</span><span clas s="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_right</span> <span class="o">=</span> <span class="n">other</span><span cla ss="o">.</span><span class="n">bbox_left</span> <span class="o">-</span> <span c lass="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="nb">max</span><span class ="p">(</span><span class="o">-</span><span class="nb">abs</span><span class="p"> (</span><span class="bp">self</span><span class="o">.</span><span class="n">xvel ocity</span><span class="p">)</span> <span class="o">-</span> <span class="n">BA LL_ACCELERATION</span><span class="p">,</span> <span class="o">-</span><span class="n">BALL_MA X_SPEED</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">+=</span> <span class="p">(</span><span class="bp"> self</span><span class="o">.</span><span class="n">y</span> <span class="o">-</s pan> <span class="n">other</span><span class="o">.</span><span class="n">y</span ><span class="p">)</span> <span class="o">*</span> <span class="n">PADDLE_VERTIC AL_FORCE</span> </pre></div> </div> <p>We also need to define three more constants:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">BALL_A CCELERATION</span> <span class="o">=</span> <span class="mf">0.2</span> <span class="n">BALL_MAX_SPEED</span> <span class="o">=</span> <span class="mi"> 15</span> <span class="n">PADDLE_VERTICAL_FORCE</span> <span class="o">=</span> <span clas s="mi">1</span> <span class="o">/</span> <span class="mi">12</span> </pre></div> </div> <p>The collision event occurs whenever another object touches this object. when this happens, we check if the other object is an instance of the <tt class="xref py py-class docutils literal"><span class="pre">Player</span></t t> class; if it is, we check the other object&#8217;s <tt class="xref py py-attr docutils literal"><span class="pre">hit_direction</sp an></tt>; if it&#8217;s <tt class="docutils literal"><span class="pre">1</span>< /tt>, we place the left side of the ball&#8217;s bounding box just to the right of the right side of the paddle&#821 7;s bounding box, then we make the ball&#8217;s horizontal velocity positive and add a constant, <tt class="xref py py-const docutils literal"><span class="pre"> BALL_ACCELERATION</span></tt>, to it; this will cause the ball to slowly speed up as the game progresses. If <tt class="xref py py-attr docutils literal"><span class="pre">hit_direction</sp an></tt> is something other than <tt class="docutils literal"><span class="pre"> 1</span></tt>, we assume that the paddle hits to the left; the behavior is identical to the behavior of hitting to the right, but opposite.</p> <p>Although accelerating the ball makes the gameplay more fun, we must not let the ball go too fast. Remember that movement is much like an animation. The ball changes its position from one position to another; the greater the speed, the bigger the difference. Movement perceived is only an illusion. As a result, if the ball goes too fast, it can

pass right through a paddle without a collision ever being detected. To prevent this, we limit the speed the ball can go at by a constant; in general, a good value to choose is one that is slightly less than the width (in the case of horizontal movement) or height (in the case of vertical movement) of the two objects that need to detect collisions with each other added together. This method only works reliably if one of the objects is not moving; if both of the objects are moving, what maximum speed they should be moving at is more complicated, but in this case, the paddle is horizontally stationary. We are later going to set the width of both the paddle and the ball to <tt class="docutils literal"><span class="pre">8</span></tt>, so we will set the maximum ball speed to <tt class="docutils literal"><span class="pre">15</span></ tt> (i.e. <tt class="docutils literal"><span class="pre">8</span> <span class="p re">+</span> <span class="pre">8</span> <span class="pre">-</span> <span class=" pre">1</span></tt>).</p> <p>The game would be rather dull if the players couldn&#8217;t control the direction of the ball, so we allow the players to control the ball by adding the difference between the ball and paddle&#8217;s vertical positions (which are going to be their centers) multiplied by a constant to the ball&#8217;s vertical velocity.</p> <p>There are two remaining problems with our ball class: first, if the ball passes a player, it doesn&#8217;t return. Second, if the ball reaches the edge of the screen, it will just float off and be impossible to retrieve by the receiving player. This actually would be realistic behavior, but it wouldn&#8217;t be very fun. We will fix both of these problems in the step event:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_step</span><span class="p">(</span><span class="bp"> self</span><span class="p">,</span> <span class="n">time_passed</span><span clas s="p">):</span> <span class="c"># Scoring</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">bbox_right</span> <span class="o">&lt;</span> <span class="mi" >0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">serv e</span><span class="p">(</span><span class="o">-</span><span class="mi">1</span ><span class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</s pan><span class="n">bbox_left</span> <span class="o">&gt;</span> <span class="n" >sge</span><span class="o">.</span><span class="n">game</span><span class="o">.< /span><span class="n">width</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">serv e</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span > <span class="c"># Bouncing off of the edges</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span class="n" >sge</span><span class="o">.</span><span class="n">game</span><span class="o">.< /span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox _bottom</span> <span class="o">=</span> <span class="n">sge</span><span class="o ">.</span><span class="n">game</span><span class="o">.</span><span class="n">hei ght</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="o">-</span><span class="nb">a bs</span><span class="p">(</span><span class="bp">self</span><span class="o">.</ span><span class="n">yvelocity</span><span class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</s pan><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class="mi"

>0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox _top</span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="nb">abs</span><span class="p" >(</span><span class="bp">self</span><span class="o">.</span><span class="n">yve locity</span><span class="p">)</span> </pre></div> </div> <p>Since we have our <tt class="xref py py-meth docutils literal"><span class="p re">serve()</span></tt> method, we simply need to call it when the ball passes one of the players and goes horizontally outside the screen. For bouncing off the edges, we use a similar method to the method we used to keep the paddles inside the view; the main difference is we also set the ball&#8217;s vertical velocity to move away from the edge; if it collided with the bottom, the vertical velocity is made negative, and if it collided with the top, the vertical velocity is made positive.</p> </div> <div class="section" id="the-main-function"> <h2>The main Function<a class="headerlink" href="#the-main-function" title="Perm alink to this headline"></a></h2> <p>Let&#8217;s make our Pong game playable now by defining the <tt class="xref p y py-func docutils literal"><span class="pre">main()</span></tt> function:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">main</span><span class="p">():</span> <span class="c"># Create Game object</span> <span class="n">Game</span><span class="p">(</span><span class="mi">640</spa n><span class="p">,</span> <span class="mi">480</span><span class="p">,</span> < span class="n">fps</span><span class="o">=</span><span class="mi">120</span><spa n class="p">)</span> <span class="c"># Load sprites</span> <span class="n">paddle_sprite</span> <span class="o">=</span> <span class="n ">sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p" >(</span><span class="n">ID</span><span class="o">=</span><span class="s">&quot; paddle&quot;</span><span class="p">,</span> <span class="n">width</span><span cl ass="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n ">height</span><span class="o">=</span><span class="mi">48</span><span class="p" >,</span> <span class="n">origin_x</span><span class="o">=</span><span class="mi ">4</span><span class="p">,</span> <span class="n">origin_y</span><span class="o">=< /span><span class="mi">24</span><span class="p">)</span> <span class="n">paddle_sprite</span><span class="o">.</span><span class="n"> draw_rectangle</span><span class="p">(</span><span class="mi">0</span><span clas s="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n" >paddle_sprite</span><span class="o">.</span><span class="n">width</span><span c lass="p">,</span> <span class="n">paddle_sprite</span><span class ="o">.</span><span class="n">height</span><span class="p">,</span> <span class=" n">fill</span><span class="o">=</span><span class="s">&quot;white&quot;</span><s pan class="p">)</span> <span class="n">ball_sprite</span> <span class="o">=</span> <span class="n"> sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p">( </span><span class="n">ID</span><span class="o">=</span><span class="s">&quot;ba ll&quot;</span><span class="p">,</span> <span class="n">width</span><span class= "o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">he ight</span><span class="o">=</span><span class="mi">8</span><span class="p">,</s pan> <span class="n">origin_x</span><span class="o">=</span><span class="mi">4</ span><span class="p">,</span>

<span class="n">origin_y</span><span class="o">=</s pan><span class="mi">4</span><span class="p">)</span> <span class="n">ball_sprite</span><span class="o">.</span><span class="n">dr aw_rectangle</span><span class="p">(</span><span class="mi">0</span><span class= "p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">b all_sprite</span><span class="o">.</span><span class="n">width</span><span class ="p">,</span> <span class="n">ball_sprite</span><span class="o">.</span><span cl ass="n">height</span><span class="p">,</span> <span class="n">fill</span><span class="o">=</spa n><span class="s">&quot;white&quot;</span><span class="p">)</span> <span class="c"># Load backgrounds</span> <span class="n">layers</span> <span class="o">=</span> <span class="p">(</sp an><span class="n">sge</span><span class="o">.</span><span class="n">BackgroundL ayer</span><span class="p">(</span><span class="s">&quot;ball&quot;</span><span class="p">,</span> <span class="n">sge</span><span class="o">.</span><span class ="n">game</span><span class="o">.</span><span class="n">width</span> <span class ="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi" >0</span><span class="p">,</span> <span class="o">-</span><span class="mi">10000 </span><span class="p">,</span> <span class="n">xrepeat</span><span class="o"> =</span><span class="bp">False</span><span class="p">),)</span> <span class="n">background</span> <span class="o">=</span> <span class="n">s ge</span><span class="o">.</span><span class="n">Background</span> <span class=" p">(</span><span class="n">layers</span><span class="p">,</span> <span class="s" >&quot;black&quot;</span><span class="p">)</span> <span class="c"># Create objects</span> <span class="n">Player</span><span class="p">(</span><span class="mi">1</spa n><span class="p">)</span> <span class="n">Player</span><span class="p">(</span><span class="mi">2</spa n><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">ball</spa n> <span class="o">=</span> <span class="n">Ball</span><span class="p">()</span> <span class="n">objects</span> <span class="o">=</span> <span class="p">(</s pan><span class="n">glob</span><span class="o">.</span><span class="n">player1</ span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span ><span class="n">player2</span><span class="p">,</span> <span class="n">glob</sp an><span class="o">.</span><span class="n">ball</span><span class="p">)</span> <span class="c"># Create rooms</span> <span class="n">room1</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">Room</span><span class="p">(</span>< span class="n">objects</span><span class="p">,</span> <span class="n">background </span><span class="o">=</span><span class="n">background</span><span class="p"> )</span> <span class="n">sge</span><span class="o">.</span><span class="n">game</span ><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</sp an> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">main</span><span class="p">()</span> </pre></div> </div> <p>Since the graphics of Pong are so simple, we are dynamically generating them rather than loading existing images. We are also generating a background with a line in the middle by using a <a class="reference internal" href="BackgroundLayer.html#sge.BackgroundLayer" ti

tle="sge.BackgroundLayer"><tt class="xref py py-class docutils literal"><span cl ass="pre">sge.BackgroundLayer</span></tt></a> object. Background layers basicall y tell a background how to tile a particular sprite in order to decorate the background. In our case, we take the ball sprite (since it is just a white square; no need to create an entirely new one) and tile it only vertically in the horizontal center of the screen (vertically at y=0, but this doesn&#8217;t matter because the sprite is being tiled infinitely in the vertical direction).</p> <p>We set the game to run at 120 frames per second because it&#8217;s hard to play Pong with digital controls, and a higher frame rate helps minimize this difficulty.</p> </div> <div class="section" id="pong-without-scoring-or-sound"> <h2>Pong Without Scoring or Sound<a class="headerlink" href="#pong-without-scori ng-or-sound" title="Permalink to this headline"></a></h2> <p>This is what we have so far:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr /bin/env python3</span> <span class="c"># Pong</span> <span class="c"># Written in 2013 by Julian Marchant &lt;onpon4@riseup.net&gt;</ span> <span class="c">#</span> <span class="c"># To the extent possible under law, the author(s) have dedicated all</span> <span class="c"># copyright and related and neighboring rights to this software to the</span> <span class="c"># public domain worldwide. This software is distributed without any</span> <span class="c"># warranty.</span> <span class="c">#</span> <span class="c"># You should have received a copy of the CC0 Public Domain Dedic ation</span> <span class="c"># along with this software. If not, see</span> <span class="c"># &lt;http://creativecommons.org/publicdomain/zero/1.0/&gt;.</sp an> <span class="kn">import</span> <span class="nn">sge</span> <span class="n">PADDLE_SPEED</span> <span class="o">=</span> <span class="mi">4< /span> <span class="n">PADDLE_VERTICAL_FORCE</span> <span class="o">=</span> <span clas s="mi">1</span> <span class="o">/</span> <span class="mi">12</span> <span class="n">BALL_START_SPEED</span> <span class="o">=</span> <span class="mi ">2</span> <span class="n">BALL_ACCELERATION</span> <span class="o">=</span> <span class="m f">0.2</span> <span class="n">BALL_MAX_SPEED</span> <span class="o">=</span> <span class="mi"> 15</span> <span class="k">class</span> <span class="nc">glob</span><span class="p">:</span > <span class="c"># This class is for global variables. While not necessary, using a</span> <span class="c"># container class like this is less potentially confusing th an using</span> <span class="c"># actual global variables.</span>

<span class="n">player1</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">player2</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">ball</span> <span class="o">=</span> <span class="bp">None</ span> <span class="n">hud_sprite</span> <span class="o">=</span> <span class="bp"> None</span> <span class="n">bounce_sound</span> <span class="o">=</span> <span class="bp ">None</span> <span class="n">bounce_wall_sound</span> <span class="o">=</span> <span clas s="bp">None</span> <span class="n">score_sound</span> <span class="o">=</span> <span class="bp" >None</span> <span class="n">game_in_progress</span> <span class="o">=</span> <span class ="bp">True</span> <span class="k">class</span> <span class="nc">Game</span><span class="p">(</span ><span class="n">sge</span><span class="o">.</span><span class="n">Game</span><s pan class="p">):</span> <span class="k">def</span> <span class="nf">event_key_press</span><span clas s="p">(</span><span class="bp">self</span><span class="p">,</span> <span class=" n">key</span><span class="p">,</span> <span class="n">char</span><span class="p" >):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;f8&#39;</span><span class="p">:</span> <span class="n">sge</span><span class="o">.</span><span class="n">Sp rite</span><span class="o">.</span><span class="n">from_screenshot</span><span c lass="p">()</span><span class="o">.</span><span class="n">save</span><span class ="p">(</span><span class="s">&#39;screenshot.jpg&#39;</span><span class="p">)</s pan> <span class="k">elif</span> <span class="n">key</span> <span class="o">= =</span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">elif</span> <span class="n">key</span> <span class="ow"> in</span> <span class="p">(</span><span class="s">&#39;p&#39;</span><span class= "p">,</span> <span class="s">&#39;enter&#39;</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n"> pause</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_close</span><span class="p ">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">m</span> <span class="o">=</span> <span class="s">&quot; Are you sure you want to quit?&quot;</span> <span class="k">if</span> <span class="n">sge</span><span class="o">.</s pan><span class="n">show_message</span><span class="p">(</span><span class="n">m </span><span class="p">,</span> <span class="p">(</span><span class="s">&quot;No &quot;</span><span class="p">,</span> <span class="s">&quot;Yes&quot;</span><spa n class="p">)):</span> <span class="bp">self</span><span class="o">.</span><span class="n"> end</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_key_press</span><sp an class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">char</span><span cl ass="p">):</span>

<span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="c"># This allows the player to still exit while the gam e is</span> <span class="c"># paused, rather than having to unpause first.</span > <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> unpause</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_close</span><span c lass="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># This allows the player to still exit while the game is paused,</span> <span class="c"># rather than having to unpause first.</span> <span class="bp">self</span><span class="o">.</span><span class="n">even t_close</span><span class="p">()</span> <span class="k">class</span> <span class="nc">Player</span><span class="p">(</sp an><span class="n">sge</span><span class="o">.</span><span class="n">StellarClas s</span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">,</span> <span class="n">play er</span><span class="o">=</span><span class="mi">1</span><span class="p">):</sp an> <span class="k">if</span> <span class="n">player</span> <span class="o"> ==</span> <span class="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;w&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;s&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3 2</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer1</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n"> hit_direction</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;up&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;down&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sg e</span><span class="o">.</span><span class="n">game</span><span class="o">.</sp an><span class="n">width</span> <span class="o">-</span> <span class="mi">32</sp an> <span class="n">glob</span><span class="o">.</span><span class="n">p layer2</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n"> hit_direction</span> <span class="o">=</span> <span class="o">-</span><span clas s="mi">1</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.<

/span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">0</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;paddle&quot;</span><span class="p">) </span> <span class="k">def</span> <span class="nf">event_step</span><span class="p" >(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ti me_passed</span><span class="p">):</span> <span class="c"># Movement</span> <span class="n">key_motion</span> <span class="o">=</span> <span class=" p">(</span><span class="n">sge</span><span class="o">.</span><span class="n">get _key_pressed</span><span class="p">(</span><span class="bp">self</span><span cla ss="o">.</span><span class="n">down_key</span><span class="p">)</span> <span cla ss="o">-</span> <span class="n">sge</span><span class="o">.</span><span cl ass="n">get_key_pressed</span><span class="p">(</span><span class="bp">self</spa n><span class="o">.</span><span class="n">up_key</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="n">key_motion</span> <span cl ass="o">*</span> <span class="n">PADDLE_SPEED</span> <span class="c"># Keep the paddle inside the window</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class="m i">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_top</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span cla ss="n">sge</span><span class="o">.</span><span class="n">game</span><span class= "o">.</span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_bottom</span> <span class="o">=</span> <span class="n">sge</span><span clas s="o">.</span><span class="n">game</span><span class="o">.</span><span class="n" >height</span> <span class="k">class</span> <span class="nc">Ball</span><span class="p">(</span ><span class="n">sge</span><span class="o">.</span><span class="n">StellarClass< /span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">):</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">width</span> <span class="o">/</span> <span class="mi">2</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.< /span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">1</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;ball&quot;</span><span class="p">)</ span> <span class="k">def</span> <span class="nf">event_create</span><span class=" p">(</span><span class="bp">self</span><span class="p">):</span>

<span class="bp">self</span><span class="o">.</span><span class="n">serv e</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_step</span><span class="p" >(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ti me_passed</span><span class="p">):</span> <span class="c"># Scoring</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_right</span> <span class="o">&lt;</span> <span class= "mi">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> serve</span><span class="p">(</span><span class="o">-</span><span class="mi">1</ span><span class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_left</span> <span class="o">&gt;</span> <span class ="n">sge</span><span class="o">.</span><span class="n">game</span><span class="o ">.</span><span class="n">width</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> serve</span><span class="p">(</span><span class="mi">1</span><span class="p">)</ span> <span class="c"># Bouncing off of the edges</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span class ="n">sge</span><span class="o">.</span><span class="n">game</span><span class="o ">.</span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_bottom</span> <span class="o">=</span> <span class="n">sge</span><span clas s="o">.</span><span class="n">game</span><span class="o">.</span><span class="n" >height</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="o">-</span><span class="n b">abs</span><span class="p">(</span><span class="bp">self</span><span class="o" >.</span><span class="n">yvelocity</span><span class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class= "mi">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_top</span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="nb">abs</span><span class ="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n" >yvelocity</span><span class="p">)</span> <span class="k">def</span> <span class="nf">event_collision</span><span clas s="p">(</span><span class="bp">self</span><span class="p">,</span> <span class=" n">other</span><span class="p">):</span> <span class="k">if</span> <span class="nb">isinstance</span><span class= "p">(</span><span class="n">other</span><span class="p">,</span> <span class="n" >Player</span><span class="p">):</span> <span class="k">if</span> <span class="n">other</span><span class="o ">.</span><span class="n">hit_direction</span> <span class="o">==</span> <span c lass="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class= "n">bbox_left</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">bbox_right</span> <span class="o">+</span> <sp an class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class= "n">xvelocity</span> <span class="o">=</span> <span class="nb">min</span><span c lass="p">(</span><span class="nb">abs</span><span class="p">(</span><span class=

"bp">self</span><span class="o">.</span><span class="n">xvelocity</span><span cl ass="p">)</span> <span class="o">+</span> <span class="n">BALL_ACCELERATION</spa n><span class="p">,</span> <span class="n">BALL_MAX_SPEED</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class= "n">bbox_right</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">bbox_left</span> <span class="o">-</span> <sp an class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class= "n">xvelocity</span> <span class="o">=</span> <span class="nb">max</span><span c lass="p">(</span><span class="o">-</span><span class="nb">abs</span><span class= "p">(</span><span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span><span class="p">)</span> <span class="o">-</span> <span class="n ">BALL_ACCELERATION</span><span class="p">,</span> <span class="o">-</span><span class="n">BAL L_MAX_SPEED</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">+=</span> <span class="p">(</span><span class=" bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o"> -</span> <span class="n">other</span><span class="o">.</span><span class="n">y</ span><span class="p">)</span> <span class="o">*</span> <span class="n">PADDLE_VE RTICAL_FORCE</span> <span class="k">def</span> <span class="nf">serve</span><span class="p">(</s pan><span class="bp">self</span><span class="p">,</span> <span class="n">directi on</span><span class="o">=</span><span class="mi">1</span><span class="p">):</sp an> <span class="bp">self</span><span class="o">.</span><span class="n">x</s pan> <span class="o">=</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">xstart</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</s pan> <span class="o">=</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">ystart</span> <span class="c"># Next round</span> <span class="bp">self</span><span class="o">.</span><span class="n">xvel ocity</span> <span class="o">=</span> <span class="n">BALL_START_SPEED</span> <s pan class="o">*</span> <span class="n">direction</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span > <span class="c"># Create Game object</span> <span class="n">Game</span><span class="p">(</span><span class="mi">640</spa n><span class="p">,</span> <span class="mi">480</span><span class="p">,</span> < span class="n">fps</span><span class="o">=</span><span class="mi">120</span><spa n class="p">)</span> <span class="c"># Load sprites</span> <span class="n">paddle_sprite</span> <span class="o">=</span> <span class="n ">sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p" >(</span><span class="n">ID</span><span class="o">=</span><span class="s">&quot; paddle&quot;</span><span class="p">,</span> <span class="n">width</span><span cl ass="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n ">height</span><span class="o">=</span><span class="mi">48</span><span class="p"

>,</span> <span class="n">origin_x</span><span class="o">=</span><span class="mi ">4</span><span class="p">,</span> <span class="n">origin_y</span><span class="o">=< /span><span class="mi">24</span><span class="p">)</span> <span class="n">paddle_sprite</span><span class="o">.</span><span class="n"> draw_rectangle</span><span class="p">(</span><span class="mi">0</span><span clas s="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n" >paddle_sprite</span><span class="o">.</span><span class="n">width</span><span c lass="p">,</span> <span class="n">paddle_sprite</span><span class ="o">.</span><span class="n">height</span><span class="p">,</span> <span class=" n">fill</span><span class="o">=</span><span class="s">&quot;white&quot;</span><s pan class="p">)</span> <span class="n">ball_sprite</span> <span class="o">=</span> <span class="n"> sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p">( </span><span class="n">ID</span><span class="o">=</span><span class="s">&quot;ba ll&quot;</span><span class="p">,</span> <span class="n">width</span><span class= "o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">he ight</span><span class="o">=</span><span class="mi">8</span><span class="p">,</s pan> <span class="n">origin_x</span><span class="o">=</span><span class="mi">4</ span><span class="p">,</span> <span class="n">origin_y</span><span class="o">=</s pan><span class="mi">4</span><span class="p">)</span> <span class="n">ball_sprite</span><span class="o">.</span><span class="n">dr aw_rectangle</span><span class="p">(</span><span class="mi">0</span><span class= "p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">b all_sprite</span><span class="o">.</span><span class="n">width</span><span class ="p">,</span> <span class="n">ball_sprite</span><span class="o">.</span><span cl ass="n">height</span><span class="p">,</span> <span class="n">fill</span><span class="o">=</spa n><span class="s">&quot;white&quot;</span><span class="p">)</span> <span class="c"># Load backgrounds</span> <span class="n">layers</span> <span class="o">=</span> <span class="p">(</sp an><span class="n">sge</span><span class="o">.</span><span class="n">BackgroundL ayer</span><span class="p">(</span><span class="s">&quot;ball&quot;</span><span class="p">,</span> <span class="n">sge</span><span class="o">.</span><span class ="n">game</span><span class="o">.</span><span class="n">width</span> <span class ="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi" >0</span><span class="p">,</span> <span class="o">-</span><span class="mi">10000 </span><span class="p">,</span> <span class="n">xrepeat</span><span class="o"> =</span><span class="bp">False</span><span class="p">),)</span> <span class="n">background</span> <span class="o">=</span> <span class="n">s ge</span><span class="o">.</span><span class="n">Background</span> <span class=" p">(</span><span class="n">layers</span><span class="p">,</span> <span class="s" >&quot;black&quot;</span><span class="p">)</span> <span class="c"># Create objects</span> <span class="n">Player</span><span class="p">(</span><span class="mi">1</spa n><span class="p">)</span> <span class="n">Player</span><span class="p">(</span><span class="mi">2</spa n><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">ball</spa n> <span class="o">=</span> <span class="n">Ball</span><span class="p">()</span> <span class="n">objects</span> <span class="o">=</span> <span class="p">(</s pan><span class="n">glob</span><span class="o">.</span><span class="n">player1</ span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span ><span class="n">player2</span><span class="p">,</span> <span class="n">glob</sp an><span class="o">.</span><span class="n">ball</span><span class="p">)</span>

<span class="c"># Create rooms</span> <span class="n">room1</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">Room</span><span class="p">(</span>< span class="n">objects</span><span class="p">,</span> <span class="n">background </span><span class="o">=</span><span class="n">background</span><span class="p"> )</span> <span class="n">sge</span><span class="o">.</span><span class="n">game</span ><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</sp an> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">main</span><span class="p">()</span> </pre></div> </div> <p>This is a playable Pong game; there are two paddles and a ball, and the ball returns any time it leaves the left or right side of the screen. Unfortunately, though, it is at this point less like Pong and more like the Magnavox Odyssey; there is no scoring, so you have to keep track of this manually, and there is no sound. Let&#8217;s fix those problems.</p> </div> <div class="section" id="adding-scoring"> <h2>Adding Scoring<a class="headerlink" href="#adding-scoring" title="Permalink to this headline"></a></h2> <p>It&#8217;s a little weird to have a video game that doesn&#8217;t keep score, so we will now add a proper scoring system to our Pong game. Each player will get one point whenever the ball passes by the other player, and whoever gets 10 points first will win.</p> <p>Let&#8217;s start by defining some constants:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">POINTS _TO_WIN</span> <span class="o">=</span> <span class="mi">10</span> <span class="n">TEXT_OFFSET</span> <span class="o">=</span> <span class="mi">16< /span> </pre></div> </div> <p>There are a couple of ways to display the score. The most obvious way is to project the score each frame, but we are instead going to create a custom sprite, an object to display that sprite, and re-draw to it as needed. While projection will work just fine for Pong, drawing to a sprite will be much easier than projections for more complicated HUDs, so it&#8217;s good to know how to do it.</p> <div class="section" id="hud-sprite-and-object"> <h3>HUD sprite and object<a class="headerlink" href="#hud-sprite-and-object" tit le="Permalink to this headline"></a></h3> <p>First, we need to create the HUD sprite and the HUD object. We will do this in the <tt class="xref py py-func docutils literal"><span class="pre">main( )</span></tt> function.</p> <p>Add one more sprite to the list of sprites:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">glob</ span><span class="o">.</span><span class="n">hud_sprite</span> <span class="o">= </span> <span class="n">sge</span><span class="o">.</span><span class="n">Sprite </span><span class="p">(</span><span class="n">width</span><span class="o">=</sp an><span class="mi">320</span><span class="p">,</span> <span class="n">height</s pan><span class="o">=</span><span class="mi">160</span><span class="p">,</span> <span class="n">origin_x</span><span class="o">=</span><span class="mi">160</spa n><span class="p">,</span> <span class="n">origin_y</span><span class="o">=</s

pan><span class="mi">0</span><span class="p">)</span> </pre></div> </div> <p>Create a HUD object:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">hud</s pan> <span class="o">=</span> <span class="n">sge</span><span class="o">.</span> <span class="n">StellarClass</span><span class="p">(</span><span class="n">sge</ span><span class="o">.</span><span class="n">game</span><span class="o">.</span> <span class="n">width</span> <span class="o">/</span> <span class="mi">2</span>< span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">10</span><span class="p">,</span> <span class ="n">sprite</span><span class="o">=</span><span class="n">glob</span><span class ="o">.</span><span class="n">hud_sprite</span><span class="p">,</span> <span class="n">detects_collisions</span><span class="o"> =</span><span class="bp">False</span><span class="p">)</span> </pre></div> </div> <p>And finally, add the HUD object to the list of initial objects:</p> <div class="highlight-python"><div class="highlight"><pre><span class="n">object s</span> <span class="o">=</span> <span class="p">(</span><span class="n">glob</ span><span class="o">.</span><span class="n">player1</span><span class="p">,</sp an> <span class="n">glob</span><span class="o">.</span><span class="n">player2</ span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span ><span class="n">ball</span><span class="p">,</span> <span class="n">hud</span>< span class="p">)</span> </pre></div> </div> <p>We want to put the HUD sprite in a globally-accessible variable because we are going to change the score table by changing the sprite directly. The HUD object, on the other hand, never needs to be changed; it just needs to be in the room.</p> <p>The size of the HUD sprite is arbitrary. Most of it is going to be invisible, so our only requirement for it is that it needs to be large enough to fit the rendered text.</p> </div> <div class="section" id="font"> <h3>Font<a class="headerlink" href="#font" title="Permalink to this headline"></a> </h3> <p>Next, we need to load a font. To do so, we will add this (I am putting it between the background and object creations, but you can put them anywhere in <tt class="xref py py-func docutils literal"><span class="pre">main( )</span></tt> as long as it&#8217;s before the game is started):</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Load fonts</span> <span class="n">sge</span><span class="o">.</span><span class="n">Font</span><sp an class="p">(</span><span class="s">&#39;Liberation Mono&#39;</span><span class ="p">,</span> <span class="n">ID</span><span class="o">=</span><span class="s">& quot;hud&quot;</span><span class="p">,</span> <span class="n">size</span><span c lass="o">=</span><span class="mi">48</span><span class="p">)</span> </pre></div> </div> <p>For the first argument of <a class="reference internal" href="Font.html#sge.F ont.__init__" title="sge.Font.__init__"><tt class="xref py py-meth docutils lite ral"><span class="pre">sge.Font.__init__()</span></tt></a>, we specify one of two things: either the name of a system font, or the name of a font file that we are distributing with our game in our data folder. For simplicity, we will use a system font for now. I chose Liberation Mono, but you can choose any font you like.</p> <div class="admonition note"> <p class="first admonition-title">Note</p>

<p class="last">What system fonts are available on a given system is not standar dized in any way. If you specify a system font and that system font is not available, the SGE will choose what font to use arbitrarily. For this reason, you should never use system fonts in your games except as a temporary placeholder.</p> </div> </div> <div class="section" id="score-property"> <h3>Score property<a class="headerlink" href="#score-property" title="Permalink to this headline"></a></h3> <p>Now let&#8217;s add score attributes to the players. Because we want to refresh the HUD every time the score changes, we are going to make these score attributes a property of the <tt class="xref py py-class docutils literal" ><span class="pre">Player</span></tt> class:</p> <div class="highlight-python"><div class="highlight"><pre><span class="nd">@prop erty</span> <span class="k">def</span> <span class="nf">score</span><span class="p">(</span> <span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o">.< /span><span class="n">v_score</span> <span class="nd">@score.setter</span> <span class="k">def</span> <span class="nf">score</span><span class="p">(</span> <span class="bp">self</span><span class="p">,</span> <span class="n">value</span ><span class="p">):</span> <span class="k">if</span> <span class="n">value</span> <span class="o">!=</s pan> <span class="bp">self</span><span class="o">.</span><span class="n">v_score </span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">v_sc ore</span> <span class="o">=</span> <span class="n">value</span> <span class="n">refresh_hud</span><span class="p">()</span> </pre></div> </div> <p><tt class="xref py py-func docutils literal"><span class="pre">refresh_hud()< /span></tt> will be the function we define later on to refresh the HUD.</p> <p>Next, we need to initialize <tt class="xref py py-attr docutils literal"><spa n class="pre">v_score</span></tt>. We will do this in the create event:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_create</span><span class="p">(</span><span class="bp ">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">v_score< /span> <span class="o">=</span> <span class="mi">0</span> </pre></div> </div> <p>The reason we initialize <tt class="xref py py-attr docutils literal"><span c lass="pre">v_score</span></tt> directly is because <tt class="xref py py-func docutils literal"><span class="pre">refresh_hud()</sp an></tt> is going to need both player&#8217;s scores; if we call it before both players&#8217; scores are initialized, we will get an error.</p> </div> <div class="section" id="refresh-hud-function"> <h3>Refresh HUD Function<a class="headerlink" href="#refresh-hud-function" title ="Permalink to this headline"></a></h3> <p>Now that the score property is defined, let&#8217;s add that function:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">refresh_hud</span><span class="p">():</span> <span class="c"># This fixes the HUD sprite so that it displays the correct

score.</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_clear</span><span class="p" >()</span> <span class="n">x</span> <span class="o">=</span> <span class="n">glob</span ><span class="o">.</span><span class="n">hud_sprite</span><span class="o">.</spa n><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span > <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_text</span><span class="p"> (</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span cla ss="nb">str</span><span class="p">(</span><span class="n">glob</span><span class ="o">.</span><span class="n">player1</span><span class="o">.</span><span class=" n">score</span><span class="p">),</span> <span class="n">x</span> <span class="o ">-</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class="p"> ,</span> <span class="n">color</span><span class="o">=</span><span class="s">&qu ot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">=</sp an><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_RIGHT </span><span class="p">,</span> <span class="n">valign</span><span class="o">=</ span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_TOP </span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_text</span><span class="p"> (</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span cla ss="nb">str</span><span class="p">(</span><span class="n">glob</span><span class ="o">.</span><span class="n">player2</span><span class="o">.</span><span class=" n">score</span><span class="p">),</span> <span class="n">x</span> <span class="o ">+</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class="p"> ,</span> <span class="n">color</span><span class="o">=</span><span class="s">&qu ot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">=</sp an><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_LEFT< /span><span class="p">,</span> <span class="n">valign</span><span class="o">=</s pan><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_TOP< /span><span class="p">)</span> </pre></div> </div> <p>First we clear the sprite with <a class="reference internal" href="Sprite.htm l#sge.Sprite.draw_clear" title="sge.Sprite.draw_clear"><tt class="xref py py-met h docutils literal"><span class="pre">sge.Sprite.draw_clear()</span></tt></a>, t hen we draw both player&#8217;s scores on it; player 1&#8217;s score goes on the left, and player 2&#8217;s score goes on the right. We use <tt class="xref py py-const do cutils literal"><span class="pre">TEXT_OFFSET</span></tt> to make it look nicer; if you set <tt class="xref py py-const docutils literal"><span cl ass="pre">TEXT_OFFSET</span></tt> to <tt class="docutils literal"><span class="p re">0</span></tt>, you will notice that it looks a little ugly because the text is right next to the line and right below the top of the screen.</p> <p>The way it is now, the score won&#8217;t start being displayed until someone scores, which is not what we want. To prevent this, we want to call <tt class="xref py py-func docutils literal"><span class="pre">refresh_hud()</sp an></tt> somewhere when the game starts. I am choosing the create event of <tt class="xref py py-class docutils literal"><span class="pre"> Ball</span></tt>, because the ball is created after both of the players (and so its create event will always execute after both of

the player objects&#8217;).</p> </div> <div class="section" id="adding-points"> <h3>Adding Points<a class="headerlink" href="#adding-points" title="Permalink to this headline"></a></h3> <p>We need to make the players actually get points for the scoring system to be of any use. This is what we currently have in the step event of <tt class="xref py py-class docutils literal"><span class="pre">Ball</span></ tt>:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Scor ing</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">bbox_right</span> <span class="o">&lt;</span> <span class="mi">0</ span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="o">-</span><span class="mi">1</span><sp an class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span> <span class="n">bbox_left</span> <span class="o">&gt;</span> <span class="n">sge </span><span class="o">.</span><span class="n">game</span><span class="o">.</spa n><span class="n">width</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="mi">1</span><span class="p">)</span> </pre></div> </div> <p>Let&#8217;s add some lines to increase the players&#8217; score:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Scor ing</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">bbox_right</span> <span class="o">&lt;</span> <span class="mi">0</ span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">player2</ span><span class="o">.</span><span class="n">score</span> <span class="o">+=</sp an> <span class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="o">-</span><span class="mi">1</span><sp an class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span> <span class="n">bbox_left</span> <span class="o">&gt;</span> <span class="n">sge </span><span class="o">.</span><span class="n">game</span><span class="o">.</spa n><span class="n">width</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">player1</ span><span class="o">.</span><span class="n">score</span> <span class="o">+=</sp an> <span class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="mi">1</span><span class="p">)</span> </pre></div> </div> <p>Now, every time the ball passes a player, the opposite player will get a point.</p> </div> <div class="section" id="win-condition"> <h3>Win Condition<a class="headerlink" href="#win-condition" title="Permalink to this headline"></a></h3> <p>At this point, the game will go on forever until the players decide to stop. That&#8217;s not what we want; we want the first player to get 10 points to be declared the winner. We will handle this in <tt class="xref py py-meth docutils literal"><span class="pre">Ball.serve()</spa n></tt>. This is what we have so far:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s

pan> <span class="nf">serve</span><span class="p">(</span><span class="bp">self< /span><span class="p">,</span> <span class="n">direction</span><span class="o">= </span><span class="mi">1</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">xstart</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">ystart</span> <span class="c"># Next round</span> <span class="bp">self</span><span class="o">.</span><span class="n">xvelocit y</span> <span class="o">=</span> <span class="n">BALL_START_SPEED</span> <span class="o">*</span> <span class="n">direction</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvelocit y</span> <span class="o">=</span> <span class="mi">0</span> </pre></div> </div> <p>Replace that with this:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">serve</span><span class="p">(</span><span class="bp">self< /span><span class="p">,</span> <span class="n">direction</span><span class="o">= </span><span class="mi">1</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">xstart</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">ystart</span> <span class="k">if</span> <span class="p">(</span><span class="n">glob</span ><span class="o">.</span><span class="n">player1</span><span class="o">.</span>< span class="n">score</span> <span class="o">&lt;</span> <span class="n">POINTS_T O_WIN</span> <span class="ow">and</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer2</span><span class="o">.</span><span class="n">score</span> <span class="o ">&lt;</span> <span class="n">POINTS_TO_WIN</span><span class="p">):</span> <span class="c"># Next round</span> <span class="bp">self</span><span class="o">.</span><span class="n">xvel ocity</span> <span class="o">=</span> <span class="n">BALL_START_SPEED</span> <s pan class="o">*</span> <span class="n">direction</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">else</span><span class="p">:</span> <span class="c"># Game Over!</span> <span class="bp">self</span><span class="o">.</span><span class="n">xvel ocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_s prite</span><span class="o">.</span><span class="n">draw_clear</span><span class ="p">()</span> <span class="n">x</span> <span class="o">=</span> <span class="n">glob</ span><span class="o">.</span><span class="n">hud_sprite</span><span class="o">.< /span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</ span> <span class="n">p1score</span> <span class="o">=</span> <span class="n"> glob</span><span class="o">.</span><span class="n">player1</span><span class="o" >.</span><span class="n">score</span> <span class="n">p2score</span> <span class="o">=</span> <span class="n">

glob</span><span class="o">.</span><span class="n">player2</span><span class="o" >.</span><span class="n">score</span> <span class="n">p1text</span> <span class="o">=</span> <span class="s">& quot;WIN&quot;</span> <span class="k">if</span> <span class="n">p1score</span> < span class="o">&gt;</span> <span class="n">p2score</span> <span class="k">else</ span> <span class="s">&quot;LOSE&quot;</span> <span class="n">p2text</span> <span class="o">=</span> <span class="s">& quot;WIN&quot;</span> <span class="k">if</span> <span class="n">p2score</span> < span class="o">&gt;</span> <span class="n">p1score</span> <span class="k">else</ span> <span class="s">&quot;LOSE&quot;</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_s prite</span><span class="o">.</span><span class="n">draw_text</span><span class= "p">(</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span class="n">p1text</span><span class="p">,</span> <span class="n">x</span> <span class="o">-</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class= "p">,</span> <span class="n">color</span><span class="o">=</span><span class="s" >&quot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">= </span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_R IGHT</span><span class="p">,</span> <span class="n">valign</span><span class="o">= </span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_T OP</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_s prite</span><span class="o">.</span><span class="n">draw_text</span><span class= "p">(</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span class="n">p2text</span><span class="p">,</span> <span class="n">x</span> <span class="o">+</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class= "p">,</span> <span class="n">color</span><span class="o">=</span><span class="s" >&quot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">= </span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_L EFT</span><span class="p">,</span> <span class="n">valign</span><span class="o">= </span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_T OP</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">game_ in_progress</span> <span class="o">=</span> <span class="bp">False</span> </pre></div> </div> <p>That&#8217;s a lot of extra code. First, we check if both players&#8217; sco res are less than <tt class="xref py py-const docutils literal"><span class="pre">POINTS _TO_WIN</span></tt>. If it is, that means the game is still in progress, so we start the next round as the function did previously. Otherwise, we stop the ball, and then we draw &#8220;WIN&#8221; on the winner&#8217;s side, and &#8220;LOSE&#8221; on the loser&#8217;s side. I used t wo conditional expressions to achieve this because it&#8217;s quick, and if by some freak accident (perhaps the result of a &#8220;2-balls mod&#8221; or something) both players get 10 points at the same time, it will be considered a loss for both players.</p> <p>We will also set <tt class="xref py py-attr docutils literal"><span class="pr e">glob.game_in_progress</span></tt> to False, so that it can be understood by other functions and methods that a game is not currently in progress. We will use this later to give the pause keys a secondary function of starting a new game.</p>

</div> </div> <div class="section" id="adding-sound"> <h2>Adding Sound<a class="headerlink" href="#adding-sound" title="Permalink to t his headline"></a></h2> <p>There are three sounds we want to add: one for when the ball hits a paddle, one for when the ball hits a wall, and one for when a player scores.</p> <p>There are many ways you can get these sounds. The easiest way is to find them on a website that has free/libre culture sound effects available. A good place to search for such assets is <a class="reference extern al" href="http://opengameart.org">OpenGameArt.org</a>. Another easy way if you only need simple sound effects, and the method I used, is to generate them with a free/libre program called <a class="reference external" href="http://www.drpette r.se/project_sfxr.html">sfxr</a>. Whatever method you use, once you have your three sound effects, set their file names to &#8220;bounce&#8221;, &#8220;bounce_wall&#8221;, and &#8220;score&#8221;, plus w hatever extension is appropriate. Make sure to use a format supported by the SGE implementation used; in my case, I can use WAV and Ogg Vorbis sound effects, and my sound files are all WAV format.</p> <p>Create a folder in the same location as pong.py called &#8220;data&#8221;. W ithin the &#8220;data&#8221; folder, create another folder called &#8220;sounds&#8221; .</p> <div class="admonition note"> <p class="first admonition-title">Note</p> <p class="last">Directories are not case-sensitive on all file systems; most not ably, NTFS (the file system used by Windows) would treat the directory name &#8220;data&#8221; as being identical to &#8220;Data&#8221;. However, many other file systems are case-sensitive. On those file systems, &#8220;data&#8221; is distinct from &#8220;Data&#8221;. Because of this, don&#8217;t get into the hab it of capitalizing the names of these folders; it&#8217;s &#8220;data&#8221;, not &#82 20;Data&#8221;, and it&#8217;s &#8220;sounds&#8221;, not &#8220;Sounds&#8221;.</p> </div> <p>Put your three sound effects, which in my case are now named &#8220;bounce.wav&#8221;, &#8220;bounce_wall.wav&#8221;, and &#8220;score.wav&#8 221;, into data/sounds.</p> <div class="section" id="loading-the-sounds"> <h3>Loading The Sounds<a class="headerlink" href="#loading-the-sounds" title="Pe rmalink to this headline"></a></h3> <p>To use sound effects, we first need to load them. We will do so in the <tt class="xref py py-func docutils literal"><span class="pre">main()</span></tt > function. I am putting this code after the code that loads the font and before the code that creates the objects:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Load sounds</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_sound< /span> <span class="o">=</span> <span class="n">sge</span><span class="o">.</spa n><span class="n">Sound</span><span class="p">(</span><span class="s">&#39;bounc e.wav&#39;</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_wall_s ound</span> <span class="o">=</span> <span class="n">sge</span><span class="o">. </span><span class="n">Sound</span><span class="p">(</span><span class="s">&#39; bounce_wall.wav&#39;</span><span class="p">)</span>

<span class="n">glob</span><span class="o">.</span><span class="n">score_sound</ span> <span class="o">=</span> <span class="n">sge</span><span class="o">.</span ><span class="n">Sound</span><span class="p">(</span><span class="s">&#39;score. wav&#39;</span><span class="p">)</span> </pre></div> </div> </div> <div class="section" id="playing-the-sounds"> <h3>Playing The Sounds<a class="headerlink" href="#playing-the-sounds" title="Pe rmalink to this headline"></a></h3> <p>This part is extremely simple. Just call <a class="reference internal" href= "Sound.html#sge.Sound.play" title="sge.Sound.play"><tt class="xref py py-meth do cutils literal"><span class="pre">sge.Sound.play()</span></tt></a> in the proper places.</p> <p>Here:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Scor ing</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">bbox_right</span> <span class="o">&lt;</span> <span class="mi">0</ span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">player2</ span><span class="o">.</span><span class="n">score</span> <span class="o">+=</sp an> <span class="mi">1</span> <span class="n">glob</span><span class="o">.</span><span class="n">score_sou nd</span><span class="o">.</span><span class="n">play</span><span class="p">()</ span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="o">-</span><span class="mi">1</span><sp an class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span> <span class="n">bbox_left</span> <span class="o">&gt;</span> <span class="n">sge </span><span class="o">.</span><span class="n">game</span><span class="o">.</spa n><span class="n">width</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">player1</ span><span class="o">.</span><span class="n">score</span> <span class="o">+=</sp an> <span class="mi">1</span> <span class="n">glob</span><span class="o">.</span><span class="n">score_sou nd</span><span class="o">.</span><span class="n">play</span><span class="p">()</ span> <span class="bp">self</span><span class="o">.</span><span class="n">serve</s pan><span class="p">(</span><span class="mi">1</span><span class="p">)</span> </pre></div> </div> <p>Here:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c"># Boun cing off of the edges</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><s pan class="n">bbox_bottom</span> <span class="o">&gt;</span> <span class="n">sge </span><span class="o">.</span><span class="n">game</span><span class="o">.</spa n><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox_bot tom</span> <span class="o">=</span> <span class="n">sge</span><span class="o">.< /span><span class="n">game</span><span class="o">.</span><span class="n">height< /span> <span class="bp">self</span><span class="o">.</span><span class="n">yvelocit y</span> <span class="o">=</span> <span class="o">-</span><span class="nb">abs</ span><span class="p">(</span><span class="bp">self</span><span class="o">.</span ><span class="n">yvelocity</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_wa ll_sound</span><span class="o">.</span><span class="n">play</span><span class="p

">()</span> <span class="k">elif</span> <span class="bp">self</span><span class="o">.</span> <span class="n">bbox_top</span> <span class="o">&lt;</span> <span class="mi">0</ span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n">bbox_top </span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvelocit y</span> <span class="o">=</span> <span class="nb">abs</span><span class="p">(</ span><span class="bp">self</span><span class="o">.</span><span class="n">yveloci ty</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_wa ll_sound</span><span class="o">.</span><span class="n">play</span><span class="p ">()</span> </pre></div> </div> <p>And here:</p> <div class="highlight-python"><div class="highlight"><pre><span class="k">def</s pan> <span class="nf">event_collision</span><span class="p">(</span><span class= "bp">self</span><span class="p">,</span> <span class="n">other</span><span class ="p">):</span> <span class="k">if</span> <span class="nb">isinstance</span><span class="p"> (</span><span class="n">other</span><span class="p">,</span> <span class="n">Pla yer</span><span class="p">):</span> <span class="k">if</span> <span class="n">other</span><span class="o">.< /span><span class="n">hit_direction</span> <span class="o">==</span> <span class ="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_left</span> <span class="o">=</span> <span class="n">other</span><span clas s="o">.</span><span class="n">bbox_right</span> <span class="o">+</span> <span c lass="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="nb">min</span><span class ="p">(</span><span class="nb">abs</span><span class="p">(</span><span class="bp" >self</span><span class="o">.</span><span class="n">xvelocity</span><span class= "p">)</span> <span class="o">+</span> <span class="n">BALL_ACCELERATION</span><s pan class="p">,</span> <span class="n">BALL_MAX_SPEED</span><span clas s="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_right</span> <span class="o">=</span> <span class="n">other</span><span cla ss="o">.</span><span class="n">bbox_left</span> <span class="o">-</span> <span c lass="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="nb">max</span><span class ="p">(</span><span class="o">-</span><span class="nb">abs</span><span class="p"> (</span><span class="bp">self</span><span class="o">.</span><span class="n">xvel ocity</span><span class="p">)</span> <span class="o">-</span> <span class="n">BA LL_ACCELERATION</span><span class="p">,</span> <span class="o">-</span><span class="n">BALL_MA X_SPEED</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">+=</span> <span class="p">(</span><span class="bp"> self</span><span class="o">.</span><span class="n">y</span> <span class="o">-</s pan> <span class="n">other</span><span class="o">.</span><span class="n">y</span ><span class="p">)</span> <span class="o">*</span> <span class="n">PADDLE_VERTIC AL_FORCE</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounc e_sound</span><span class="o">.</span><span class="n">play</span><span class="p"

>()</span> </pre></div> </div> </div> </div> <div class="section" id="restarting-the-game"> <h2>Restarting The Game<a class="headerlink" href="#restarting-the-game" title=" Permalink to this headline"></a></h2> <p>One last touch: we&#8217;re going to allow the game to be restarted. We do this by modifying the key press event for <a class="reference internal" href="Ga me.html#sge.Game" title="sge.Game"><tt class="xref py py-class docutils literal" ><span class="pre">sge.Game</span></tt></a>, specifically the keys that normally pause the game:</p> <div class="highlight-python"><pre>elif key in (&#x27;p&#x27;, &#x27;enter&#x27; ): if glob.game_in_progress: self.pause() else: glob.game_in_progress = True self.current_room.start()</pre> </div> <p>If the game is in progress, we pause the game, as before. Otherwise, we set <tt class="xref py py-attr docutils literal"><span class="pre">glob.game_in_ progres</span></tt> to <tt class="xref py py-const docutils literal"><span class ="pre">True</span></tt> and call the current room&#8217;s <tt class="xref py py-meth docutils literal"><span class="pre">star t()</span></tt> method, which resets and starts the room.</p> </div> <div class="section" id="the-final-result"> <h2>The Final Result<a class="headerlink" href="#the-final-result" title="Permal ink to this headline"></a></h2> <p>Congratulations! You have completed your first real game. This is the final result:</p> <div class="highlight-python"><div class="highlight"><pre><span class="c">#!/usr /bin/env python3</span> <span class="c"># Pong</span> <span class="c"># Written in 2013 by Julian Marchant &lt;onpon4@riseup.net&gt;</ span> <span class="c">#</span> <span class="c"># To the extent possible under law, the author(s) have dedicated all</span> <span class="c"># copyright and related and neighboring rights to this software to the</span> <span class="c"># public domain worldwide. This software is distributed without any</span> <span class="c"># warranty.</span> <span class="c">#</span> <span class="c"># You should have received a copy of the CC0 Public Domain Dedic ation</span> <span class="c"># along with this software. If not, see</span> <span class="c"># &lt;http://creativecommons.org/publicdomain/zero/1.0/&gt;.</sp an> <span class="kn">import</span> <span class="nn">sge</span> <span class="n">PADDLE_SPEED</span> <span class="o">=</span> <span class="mi">4< /span> <span class="n">PADDLE_VERTICAL_FORCE</span> <span class="o">=</span> <span clas s="mi">1</span> <span class="o">/</span> <span class="mi">12</span>

<span class="n">BALL_START_SPEED</span> <span class="o">=</span> <span class="mi ">2</span> <span class="n">BALL_ACCELERATION</span> <span class="o">=</span> <span class="m f">0.2</span> <span class="n">BALL_MAX_SPEED</span> <span class="o">=</span> <span class="mi"> 15</span> <span class="n">POINTS_TO_WIN</span> <span class="o">=</span> <span class="mi">1 0</span> <span class="n">TEXT_OFFSET</span> <span class="o">=</span> <span class="mi">16< /span> <span class="k">class</span> <span class="nc">glob</span><span class="p">:</span > <span class="c"># This class is for global variables. While not necessary, using a</span> <span class="c"># container class like this is less potentially confusing th an using</span> <span class="c"># actual global variables.</span> <span class="n">player1</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">player2</span> <span class="o">=</span> <span class="bp">Non e</span> <span class="n">ball</span> <span class="o">=</span> <span class="bp">None</ span> <span class="n">hud_sprite</span> <span class="o">=</span> <span class="bp"> None</span> <span class="n">bounce_sound</span> <span class="o">=</span> <span class="bp ">None</span> <span class="n">bounce_wall_sound</span> <span class="o">=</span> <span clas s="bp">None</span> <span class="n">score_sound</span> <span class="o">=</span> <span class="bp" >None</span> <span class="n">game_in_progress</span> <span class="o">=</span> <span class ="bp">True</span> <span class="k">class</span> <span class="nc">Game</span><span class="p">(</span ><span class="n">sge</span><span class="o">.</span><span class="n">Game</span><s pan class="p">):</span> <span class="k">def</span> <span class="nf">event_key_press</span><span clas s="p">(</span><span class="bp">self</span><span class="p">,</span> <span class=" n">key</span><span class="p">,</span> <span class="n">char</span><span class="p" >):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;f8&#39;</span><span class="p">:</span> <span class="n">sge</span><span class="o">.</span><span class="n">Sp rite</span><span class="o">.</span><span class="n">from_screenshot</span><span c lass="p">()</span><span class="o">.</span><span class="n">save</span><span class ="p">(</span><span class="s">&#39;screenshot.jpg&#39;</span><span class="p">)</s pan> <span class="k">elif</span> <span class="n">key</span> <span class="o">= =</span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">elif</span> <span class="n">key</span> <span class="ow"> in</span> <span class="p">(</span><span class="s">&#39;p&#39;</span><span class=

"p">,</span> <span class="s">&#39;enter&#39;</span><span class="p">):</span> <span class="k">if</span> <span class="n">glob</span><span class="o" >.</span><span class="n">game_in_progress</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class= "n">pause</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class=" n">game_in_progress</span> <span class="o">=</span> <span class="bp">True</span> <span class="bp">self</span><span class="o">.</span><span class= "n">current_room</span><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_close</span><span class="p ">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">m</span> <span class="o">=</span> <span class="s">&quot; Are you sure you want to quit?&quot;</span> <span class="k">if</span> <span class="n">sge</span><span class="o">.</s pan><span class="n">show_message</span><span class="p">(</span><span class="n">m </span><span class="p">,</span> <span class="p">(</span><span class="s">&quot;No &quot;</span><span class="p">,</span> <span class="s">&quot;Yes&quot;</span><spa n class="p">)):</span> <span class="bp">self</span><span class="o">.</span><span class="n"> end</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_key_press</span><sp an class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">key</span><span class="p">,</span> <span class="n">char</span><span cl ass="p">):</span> <span class="k">if</span> <span class="n">key</span> <span class="o">==< /span> <span class="s">&#39;escape&#39;</span><span class="p">:</span> <span class="c"># This allows the player to still exit while the gam e is</span> <span class="c"># paused, rather than having to unpause first.</span > <span class="bp">self</span><span class="o">.</span><span class="n"> event_close</span><span class="p">()</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> unpause</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_paused_close</span><span c lass="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="c"># This allows the player to still exit while the game is paused,</span> <span class="c"># rather than having to unpause first.</span> <span class="bp">self</span><span class="o">.</span><span class="n">even t_close</span><span class="p">()</span> <span class="k">class</span> <span class="nc">Player</span><span class="p">(</sp an><span class="n">sge</span><span class="o">.</span><span class="n">StellarClas s</span><span class="p">):</span> <span class="nd">@property</span> <span class="k">def</span> <span class="nf">score</span><span class="p">(</s pan><span class="bp">self</span><span class="p">):</span> <span class="k">return</span> <span class="bp">self</span><span class="o ">.</span><span class="n">v_score</span> <span class="nd">@score.setter</span>

<span class="k">def</span> <span class="nf">score</span><span class="p">(</s pan><span class="bp">self</span><span class="p">,</span> <span class="n">value</ span><span class="p">):</span> <span class="k">if</span> <span class="n">value</span> <span class="o">! =</span> <span class="bp">self</span><span class="o">.</span><span class="n">v_s core</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> v_score</span> <span class="o">=</span> <span class="n">value</span> <span class="n">refresh_hud</span><span class="p">()</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">,</span> <span class="n">play er</span><span class="o">=</span><span class="mi">1</span><span class="p">):</sp an> <span class="k">if</span> <span class="n">player</span> <span class="o"> ==</span> <span class="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;w&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;s&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">3 2</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer1</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n"> hit_direction</span> <span class="o">=</span> <span class="mi">1</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> up_key</span> <span class="o">=</span> <span class="s">&quot;up&quot;</span> <span class="bp">self</span><span class="o">.</span><span class="n"> down_key</span> <span class="o">=</span> <span class="s">&quot;down&quot;</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sg e</span><span class="o">.</span><span class="n">game</span><span class="o">.</sp an><span class="n">width</span> <span class="o">-</span> <span class="mi">32</sp an> <span class="n">glob</span><span class="o">.</span><span class="n">p layer2</span> <span class="o">=</span> <span class="bp">self</span> <span class="bp">self</span><span class="o">.</span><span class="n"> hit_direction</span> <span class="o">=</span> <span class="o">-</span><span clas s="mi">1</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.< /span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">0</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;paddle&quot;</span><span class="p">) </span> <span class="k">def</span> <span class="nf">event_create</span><span class=" p">(</span><span class="bp">self</span><span class="p">):</span> <span class="bp">self</span><span class="o">.</span><span class="n">v_sc ore</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">def</span> <span class="nf">event_step</span><span class="p" >(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ti me_passed</span><span class="p">):</span> <span class="c"># Movement</span>

<span class="n">key_motion</span> <span class="o">=</span> <span class=" p">(</span><span class="n">sge</span><span class="o">.</span><span class="n">get _key_pressed</span><span class="p">(</span><span class="bp">self</span><span cla ss="o">.</span><span class="n">down_key</span><span class="p">)</span> <span cla ss="o">-</span> <span class="n">sge</span><span class="o">.</span><span cl ass="n">get_key_pressed</span><span class="p">(</span><span class="bp">self</spa n><span class="o">.</span><span class="n">up_key</span><span class="p">))</span> <span class="bp">self</span><span class="o">.</span><span class="n">yvel ocity</span> <span class="o">=</span> <span class="n">key_motion</span> <span cl ass="o">*</span> <span class="n">PADDLE_SPEED</span> <span class="c"># Keep the paddle inside the window</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class="m i">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_top</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span cla ss="n">sge</span><span class="o">.</span><span class="n">game</span><span class= "o">.</span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_bottom</span> <span class="o">=</span> <span class="n">sge</span><span clas s="o">.</span><span class="n">game</span><span class="o">.</span><span class="n" >height</span> <span class="k">class</span> <span class="nc">Ball</span><span class="p">(</span ><span class="n">sge</span><span class="o">.</span><span class="n">StellarClass< /span><span class="p">):</span> <span class="k">def</span> <span class="nf">__init__</span><span class="p">( </span><span class="bp">self</span><span class="p">):</span> <span class="n">x</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">width</span> <span class="o">/</span> <span class="mi">2</span> <span class="n">y</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">game</span><span class="o">.</span>< span class="n">height</span> <span class="o">/</span> <span class="mi">2</span> <span class="nb">super</span><span class="p">()</span><span class="o">.< /span><span class="n">__init__</span><span class="p">(</span><span class="n">x</ span><span class="p">,</span> <span class="n">y</span><span class="p">,</span> < span class="mi">1</span><span class="p">,</span> <span class="n">sprite</span><s pan class="o">=</span><span class="s">&quot;ball&quot;</span><span class="p">)</ span> <span class="k">def</span> <span class="nf">event_create</span><span class=" p">(</span><span class="bp">self</span><span class="p">):</span> <span class="n">refresh_hud</span><span class="p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n">serv e</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_step</span><span class="p" >(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ti me_passed</span><span class="p">):</span> <span class="c"># Scoring</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_right</span> <span class="o">&lt;</span> <span class=

"mi">0</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer2</span><span class="o">.</span><span class="n">score</span> <span class="o ">+=</span> <span class="mi">1</span> <span class="n">glob</span><span class="o">.</span><span class="n">s core_sound</span><span class="o">.</span><span class="n">play</span><span class= "p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n"> serve</span><span class="p">(</span><span class="o">-</span><span class="mi">1</ span><span class="p">)</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_left</span> <span class="o">&gt;</span> <span class ="n">sge</span><span class="o">.</span><span class="n">game</span><span class="o ">.</span><span class="n">width</span><span class="p">:</span> <span class="n">glob</span><span class="o">.</span><span class="n">p layer1</span><span class="o">.</span><span class="n">score</span> <span class="o ">+=</span> <span class="mi">1</span> <span class="n">glob</span><span class="o">.</span><span class="n">s core_sound</span><span class="o">.</span><span class="n">play</span><span class= "p">()</span> <span class="bp">self</span><span class="o">.</span><span class="n"> serve</span><span class="p">(</span><span class="mi">1</span><span class="p">)</ span> <span class="c"># Bouncing off of the edges</span> <span class="k">if</span> <span class="bp">self</span><span class="o">.< /span><span class="n">bbox_bottom</span> <span class="o">&gt;</span> <span class ="n">sge</span><span class="o">.</span><span class="n">game</span><span class="o ">.</span><span class="n">height</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_bottom</span> <span class="o">=</span> <span class="n">sge</span><span clas s="o">.</span><span class="n">game</span><span class="o">.</span><span class="n" >height</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="o">-</span><span class="n b">abs</span><span class="p">(</span><span class="bp">self</span><span class="o" >.</span><span class="n">yvelocity</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">b ounce_wall_sound</span><span class="o">.</span><span class="n">play</span><span class="p">()</span> <span class="k">elif</span> <span class="bp">self</span><span class="o"> .</span><span class="n">bbox_top</span> <span class="o">&lt;</span> <span class= "mi">0</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class="n"> bbox_top</span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="nb">abs</span><span class ="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n" >yvelocity</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">b ounce_wall_sound</span><span class="o">.</span><span class="n">play</span><span class="p">()</span> <span class="k">def</span> <span class="nf">event_collision</span><span clas s="p">(</span><span class="bp">self</span><span class="p">,</span> <span class=" n">other</span><span class="p">):</span> <span class="k">if</span> <span class="nb">isinstance</span><span class= "p">(</span><span class="n">other</span><span class="p">,</span> <span class="n" >Player</span><span class="p">):</span> <span class="k">if</span> <span class="n">other</span><span class="o

">.</span><span class="n">hit_direction</span> <span class="o">==</span> <span c lass="mi">1</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class= "n">bbox_left</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">bbox_right</span> <span class="o">+</span> <sp an class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class= "n">xvelocity</span> <span class="o">=</span> <span class="nb">min</span><span c lass="p">(</span><span class="nb">abs</span><span class="p">(</span><span class= "bp">self</span><span class="o">.</span><span class="n">xvelocity</span><span cl ass="p">)</span> <span class="o">+</span> <span class="n">BALL_ACCELERATION</spa n><span class="p">,</span> <span class="n">BALL_MAX_SPEED</span><span class="p">)</span> <span class="k">else</span><span class="p">:</span> <span class="bp">self</span><span class="o">.</span><span class= "n">bbox_right</span> <span class="o">=</span> <span class="n">other</span><span class="o">.</span><span class="n">bbox_left</span> <span class="o">-</span> <sp an class="mi">1</span> <span class="bp">self</span><span class="o">.</span><span class= "n">xvelocity</span> <span class="o">=</span> <span class="nb">max</span><span c lass="p">(</span><span class="o">-</span><span class="nb">abs</span><span class= "p">(</span><span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span><span class="p">)</span> <span class="o">-</span> <span class="n ">BALL_ACCELERATION</span><span class="p">,</span> <span class="o">-</span><span class="n">BAL L_MAX_SPEED</span><span class="p">)</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">+=</span> <span class="p">(</span><span class=" bp">self</span><span class="o">.</span><span class="n">y</span> <span class="o"> -</span> <span class="n">other</span><span class="o">.</span><span class="n">y</ span><span class="p">)</span> <span class="o">*</span> <span class="n">PADDLE_VE RTICAL_FORCE</span> <span class="n">glob</span><span class="o">.</span><span class="n">b ounce_sound</span><span class="o">.</span><span class="n">play</span><span class ="p">()</span> <span class="k">def</span> <span class="nf">serve</span><span class="p">(</s pan><span class="bp">self</span><span class="p">,</span> <span class="n">directi on</span><span class="o">=</span><span class="mi">1</span><span class="p">):</sp an> <span class="bp">self</span><span class="o">.</span><span class="n">x</s pan> <span class="o">=</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">xstart</span> <span class="bp">self</span><span class="o">.</span><span class="n">y</s pan> <span class="o">=</span> <span class="bp">self</span><span class="o">.</spa n><span class="n">ystart</span> <span class="k">if</span> <span class="p">(</span><span class="n">glob</ span><span class="o">.</span><span class="n">player1</span><span class="o">.</sp an><span class="n">score</span> <span class="o">&lt;</span> <span class="n">POIN TS_TO_WIN</span> <span class="ow">and</span> <span class="n">glob</span><span class="o">.</span><span class=" n">player2</span><span class="o">.</span><span class="n">score</span> <span clas s="o">&lt;</span> <span class="n">POINTS_TO_WIN</span><span class="p">):</span> <span class="c"># Next round</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="n">BALL_START_SPEED</span > <span class="o">*</span> <span class="n">direction</span>

<span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="k">else</span><span class="p">:</span> <span class="c"># Game Over!</span> <span class="bp">self</span><span class="o">.</span><span class="n"> xvelocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="bp">self</span><span class="o">.</span><span class="n"> yvelocity</span> <span class="o">=</span> <span class="mi">0</span> <span class="n">glob</span><span class="o">.</span><span class="n">h ud_sprite</span><span class="o">.</span><span class="n">draw_clear</span><span c lass="p">()</span> <span class="n">x</span> <span class="o">=</span> <span class="n">gl ob</span><span class="o">.</span><span class="n">hud_sprite</span><span class="o ">.</span><span class="n">width</span> <span class="o">/</span> <span class="mi" >2</span> <span class="n">p1score</span> <span class="o">=</span> <span class= "n">glob</span><span class="o">.</span><span class="n">player1</span><span class ="o">.</span><span class="n">score</span> <span class="n">p2score</span> <span class="o">=</span> <span class= "n">glob</span><span class="o">.</span><span class="n">player2</span><span class ="o">.</span><span class="n">score</span> <span class="n">p1text</span> <span class="o">=</span> <span class=" s">&quot;WIN&quot;</span> <span class="k">if</span> <span class="n">p1score</spa n> <span class="o">&gt;</span> <span class="n">p2score</span> <span class="k">el se</span> <span class="s">&quot;LOSE&quot;</span> <span class="n">p2text</span> <span class="o">=</span> <span class=" s">&quot;WIN&quot;</span> <span class="k">if</span> <span class="n">p2score</spa n> <span class="o">&gt;</span> <span class="n">p1score</span> <span class="k">el se</span> <span class="s">&quot;LOSE&quot;</span> <span class="n">glob</span><span class="o">.</span><span class="n">h ud_sprite</span><span class="o">.</span><span class="n">draw_text</span><span cl ass="p">(</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> < span class="n">p1text</span><span class="p">,</span> <span class="n">x</span> <s pan class="o">-</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span > <span class="n">TEXT_OFFSET</span><span cl ass="p">,</span> <span class="n">color</span><span class="o">=</span><span class ="s">&quot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class=" o">=</span><span class="n">sge</span><span class="o">.</span><span class="n">ALI GN_RIGHT</span><span class="p">,</span> <span class="n">valign</span><span class=" o">=</span><span class="n">sge</span><span class="o">.</span><span class="n">ALI GN_TOP</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">h ud_sprite</span><span class="o">.</span><span class="n">draw_text</span><span cl ass="p">(</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> < span class="n">p2text</span><span class="p">,</span> <span class="n">x</span> <s pan class="o">+</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span > <span class="n">TEXT_OFFSET</span><span cl ass="p">,</span> <span class="n">color</span><span class="o">=</span><span class ="s">&quot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class=" o">=</span><span class="n">sge</span><span class="o">.</span><span class="n">ALI GN_LEFT</span><span class="p">,</span> <span class="n">valign</span><span class=" o">=</span><span class="n">sge</span><span class="o">.</span><span class="n">ALI GN_TOP</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">g

ame_in_progress</span> <span class="o">=</span> <span class="bp">False</span> <span class="k">def</span> <span class="nf">refresh_hud</span><span class="p">() :</span> <span class="c"># This fixes the HUD sprite so that it displays the correct score.</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_clear</span><span class="p" >()</span> <span class="n">x</span> <span class="o">=</span> <span class="n">glob</span ><span class="o">.</span><span class="n">hud_sprite</span><span class="o">.</spa n><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span > <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_text</span><span class="p"> (</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span cla ss="nb">str</span><span class="p">(</span><span class="n">glob</span><span class ="o">.</span><span class="n">player1</span><span class="o">.</span><span class=" n">score</span><span class="p">),</span> <span class="n">x</span> <span class="o ">-</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class="p"> ,</span> <span class="n">color</span><span class="o">=</span><span class="s">&qu ot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">=</sp an><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_RIGHT </span><span class="p">,</span> <span class="n">valign</span><span class="o">=</ span><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_TOP </span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span><span class="o">.</span><span class="n">draw_text</span><span class="p"> (</span><span class="s">&quot;hud&quot;</span><span class="p">,</span> <span cla ss="nb">str</span><span class="p">(</span><span class="n">glob</span><span class ="o">.</span><span class="n">player2</span><span class="o">.</span><span class=" n">score</span><span class="p">),</span> <span class="n">x</span> <span class="o ">+</span> <span class="n">TEXT_OFFSET</span><span class="p">,</span> <span class="n">TEXT_OFFSET</span><span class="p"> ,</span> <span class="n">color</span><span class="o">=</span><span class="s">&qu ot;white&quot;</span><span class="p">,</span> <span class="n">halign</span><span class="o">=</sp an><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_LEFT< /span><span class="p">,</span> <span class="n">valign</span><span class="o">=</s pan><span class="n">sge</span><span class="o">.</span><span class="n">ALIGN_TOP< /span><span class="p">)</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span > <span class="c"># Create Game object</span> <span class="n">Game</span><span class="p">(</span><span class="mi">640</spa n><span class="p">,</span> <span class="mi">480</span><span class="p">,</span> < span class="n">fps</span><span class="o">=</span><span class="mi">120</span><spa n class="p">)</span> <span class="c"># Load sprites</span> <span class="n">paddle_sprite</span> <span class="o">=</span> <span class="n ">sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p" >(</span><span class="n">ID</span><span class="o">=</span><span class="s">&quot; paddle&quot;</span><span class="p">,</span> <span class="n">width</span><span cl ass="o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n

">height</span><span class="o">=</span><span class="mi">48</span><span class="p" >,</span> <span class="n">origin_x</span><span class="o">=</span><span class="mi ">4</span><span class="p">,</span> <span class="n">origin_y</span><span class="o">=< /span><span class="mi">24</span><span class="p">)</span> <span class="n">paddle_sprite</span><span class="o">.</span><span class="n"> draw_rectangle</span><span class="p">(</span><span class="mi">0</span><span clas s="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n" >paddle_sprite</span><span class="o">.</span><span class="n">width</span><span c lass="p">,</span> <span class="n">paddle_sprite</span><span class ="o">.</span><span class="n">height</span><span class="p">,</span> <span class=" n">fill</span><span class="o">=</span><span class="s">&quot;white&quot;</span><s pan class="p">)</span> <span class="n">ball_sprite</span> <span class="o">=</span> <span class="n"> sge</span><span class="o">.</span><span class="n">Sprite</span><span class="p">( </span><span class="n">ID</span><span class="o">=</span><span class="s">&quot;ba ll&quot;</span><span class="p">,</span> <span class="n">width</span><span class= "o">=</span><span class="mi">8</span><span class="p">,</span> <span class="n">he ight</span><span class="o">=</span><span class="mi">8</span><span class="p">,</s pan> <span class="n">origin_x</span><span class="o">=</span><span class="mi">4</ span><span class="p">,</span> <span class="n">origin_y</span><span class="o">=</s pan><span class="mi">4</span><span class="p">)</span> <span class="n">ball_sprite</span><span class="o">.</span><span class="n">dr aw_rectangle</span><span class="p">(</span><span class="mi">0</span><span class= "p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">b all_sprite</span><span class="o">.</span><span class="n">width</span><span class ="p">,</span> <span class="n">ball_sprite</span><span class="o">.</span><span cl ass="n">height</span><span class="p">,</span> <span class="n">fill</span><span class="o">=</spa n><span class="s">&quot;white&quot;</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">hud_sprit e</span> <span class="o">=</span> <span class="n">sge</span><span class="o">.</s pan><span class="n">Sprite</span><span class="p">(</span><span class="n">width</ span><span class="o">=</span><span class="mi">320</span><span class="p">,</span> <span class="n">height</span><span class="o">=</span><span class="mi">160</span ><span class="p">,</span> <span class="n">origin_x</span><span class="o">=</span ><span class="mi">160</span><span class="p">,</span> <span class="n">origin_y</span><span class="o"> =</span><span class="mi">0</span><span class="p">)</span> <span class="c"># Load backgrounds</span> <span class="n">layers</span> <span class="o">=</span> <span class="p">(</sp an><span class="n">sge</span><span class="o">.</span><span class="n">BackgroundL ayer</span><span class="p">(</span><span class="s">&quot;ball&quot;</span><span class="p">,</span> <span class="n">sge</span><span class="o">.</span><span class ="n">game</span><span class="o">.</span><span class="n">width</span> <span class ="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi" >0</span><span class="p">,</span> <span class="o">-</span><span class="mi">10000 </span><span class="p">,</span> <span class="n">xrepeat</span><span class="o"> =</span><span class="bp">False</span><span class="p">),)</span> <span class="n">background</span> <span class="o">=</span> <span class="n">s ge</span><span class="o">.</span><span class="n">Background</span> <span class=" p">(</span><span class="n">layers</span><span class="p">,</span> <span class="s" >&quot;black&quot;</span><span class="p">)</span> <span class="c"># Load fonts</span> <span class="n">sge</span><span class="o">.</span><span class="n">Font</span

><span class="p">(</span><span class="s">&#39;Liberation Mono&#39;</span><span c lass="p">,</span> <span class="n">ID</span><span class="o">=</span><span class=" s">&quot;hud&quot;</span><span class="p">,</span> <span class="n">size</span><sp an class="o">=</span><span class="mi">48</span><span class="p">)</span> <span class="c"># Load sounds</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_so und</span> <span class="o">=</span> <span class="n">sge</span><span class="o">.< /span><span class="n">Sound</span><span class="p">(</span><span class="s">&#39;b ounce.wav&#39;</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">bounce_wa ll_sound</span> <span class="o">=</span> <span class="n">sge</span><span class=" o">.</span><span class="n">Sound</span><span class="p">(</span><span class="s">& #39;bounce_wall.wav&#39;</span><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">score_sou nd</span> <span class="o">=</span> <span class="n">sge</span><span class="o">.</ span><span class="n">Sound</span><span class="p">(</span><span class="s">&#39;sc ore.wav&#39;</span><span class="p">)</span> <span class="c"># Create objects</span> <span class="n">Player</span><span class="p">(</span><span class="mi">1</spa n><span class="p">)</span> <span class="n">Player</span><span class="p">(</span><span class="mi">2</spa n><span class="p">)</span> <span class="n">glob</span><span class="o">.</span><span class="n">ball</spa n> <span class="o">=</span> <span class="n">Ball</span><span class="p">()</span> <span class="n">hud</span> <span class="o">=</span> <span class="n">sge</spa n><span class="o">.</span><span class="n">StellarClass</span><span class="p">(</ span><span class="n">sge</span><span class="o">.</span><span class="n">game</spa n><span class="o">.</span><span class="n">width</span> <span class="o">/</span> <span class="mi">2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="o">-</span><span class="mi">10</span><span clas s="p">,</span> <span class="n">sprite</span><span class="o">=</span><span class= "n">glob</span><span class="o">.</span><span class="n">hud_sprite</span><span cl ass="p">,</span> <span class="n">detects_collisions</span><span class= "o">=</span><span class="bp">False</span><span class="p">)</span> <span class="n">objects</span> <span class="o">=</span> <span class="p">(</s pan><span class="n">glob</span><span class="o">.</span><span class="n">player1</ span><span class="p">,</span> <span class="n">glob</span><span class="o">.</span ><span class="n">player2</span><span class="p">,</span> <span class="n">glob</sp an><span class="o">.</span><span class="n">ball</span><span class="p">,</span> < span class="n">hud</span><span class="p">)</span> <span class="c"># Create rooms</span> <span class="n">room1</span> <span class="o">=</span> <span class="n">sge</s pan><span class="o">.</span><span class="n">Room</span><span class="p">(</span>< span class="n">objects</span><span class="p">,</span> <span class="n">background </span><span class="o">=</span><span class="n">background</span><span class="p"> )</span> <span class="n">sge</span><span class="o">.</span><span class="n">game</span ><span class="o">.</span><span class="n">start</span><span class="p">()</span> <span class="k">if</span> <span class="n">__name__</span> <span class="o">==</sp an> <span class="s">&#39;__main__&#39;</span><span class="p">:</span> <span class="n">main</span><span class="p">()</span> </pre></div> </div>

</div> </div> </div> </div> </div> <div class="sphinxsidebar"> <div class="sphinxsidebarwrapper"> <p class="logo"><a href="index.html"> <img class="logo" src="_static/sge_logo_alpha_black.png" alt="Logo "/> </a></p> <h3><a href="index.html">Table Of Contents</a></h3> <ul> <li><a class="reference internal" href="#">Second Example: Pong</a><ul> <li><a class="reference internal" href="#setting-up-the-project">Setting Up the Project</a></li> <li><a class="reference internal" href="#global-variables">Global Variables</a>< /li> <li><a class="reference internal" href="#the-game-class">The Game Class</a></li> <li><a class="reference internal" href="#the-player-class">The Player Class</a>< /li> <li><a class="reference internal" href="#the-ball-class">The Ball Class</a></li> <li><a class="reference internal" href="#the-main-function">The main Function</a ></li> <li><a class="reference internal" href="#pong-without-scoring-or-sound">Pong Wit hout Scoring or Sound</a></li> <li><a class="reference internal" href="#adding-scoring">Adding Scoring</a><ul> <li><a class="reference internal" href="#hud-sprite-and-object">HUD sprite and o bject</a></li> <li><a class="reference internal" href="#font">Font</a></li> <li><a class="reference internal" href="#score-property">Score property</a></li> <li><a class="reference internal" href="#refresh-hud-function">Refresh HUD Funct ion</a></li> <li><a class="reference internal" href="#adding-points">Adding Points</a></li> <li><a class="reference internal" href="#win-condition">Win Condition</a></li> </ul> </li> <li><a class="reference internal" href="#adding-sound">Adding Sound</a><ul> <li><a class="reference internal" href="#loading-the-sounds">Loading The Sounds< /a></li> <li><a class="reference internal" href="#playing-the-sounds">Playing The Sounds< /a></li> </ul> </li> <li><a class="reference internal" href="#restarting-the-game">Restarting The Gam e</a></li> <li><a class="reference internal" href="#the-final-result">The Final Result</a>< /li> </ul> </li> </ul> <h4>Previous topic</h4> <p class="topless"><a href="hello_world.html" title="previous chapter">First Example: Hello, world!</a ></p> <h4>Next topic</h4> <p class="topless"><a href="globalvars.html"

title="next chapter">Global Variables and Constants</a>< /p> <h3>This Page</h3> <ul class="this-page-menu"> <li><a href="_sources/pong.txt" rel="nofollow">Show Source</a></li> </ul> <div id="searchbox" style="display: none"> <h3>Quick search</h3> <form class="search" action="search.html" method="get"> <input type="text" name="q" /> <input type="submit" value="Go" /> <input type="hidden" name="check_keywords" value="yes" /> <input type="hidden" name="area" value="default" /> </form> <p class="searchtip" style="font-size: 90%"> Enter search terms or a module, class or function name. </p> </div> <script type="text/javascript">$('#searchbox').show(0);</script> </div> </div> <div class="clearer"></div> </div> <div class="related"> <h3>Navigation</h3> <ul> <li class="right" style="margin-right: 10px"> <a href="genindex.html" title="General Index" >index</a></li> <li class="right" > <a href="globalvars.html" title="Global Variables and Constants" >next</a> |</li> <li class="right" > <a href="hello_world.html" title="First Example: Hello, world!" >previous</a> |</li> <li><a href="index.html">The Pygame SGE 0.8.0 documentation</a> &raquo;< /li> </ul> </div> <div class="footer"> Created using <a href="http://sphinx.pocoo.org/">Sphinx</a> 1.1.3. </div> </body> </html>

You might also like