Skip to main content
Engineering LibreTexts

9.16: Moving the Enemy Squirrels

  • Page ID

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

    \( \newcommand{\id}{\mathrm{id}}\) \( \newcommand{\Span}{\mathrm{span}}\)

    ( \newcommand{\kernel}{\mathrm{null}\,}\) \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\) \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\) \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\id}{\mathrm{id}}\)

    \( \newcommand{\Span}{\mathrm{span}}\)

    \( \newcommand{\kernel}{\mathrm{null}\,}\)

    \( \newcommand{\range}{\mathrm{range}\,}\)

    \( \newcommand{\RealPart}{\mathrm{Re}}\)

    \( \newcommand{\ImaginaryPart}{\mathrm{Im}}\)

    \( \newcommand{\Argument}{\mathrm{Arg}}\)

    \( \newcommand{\norm}[1]{\| #1 \|}\)

    \( \newcommand{\inner}[2]{\langle #1, #2 \rangle}\)

    \( \newcommand{\Span}{\mathrm{span}}\) \( \newcommand{\AA}{\unicode[.8,0]{x212B}}\)

    \( \newcommand{\vectorA}[1]{\vec{#1}}      % arrow\)

    \( \newcommand{\vectorAt}[1]{\vec{\text{#1}}}      % arrow\)

    \( \newcommand{\vectorB}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vectorC}[1]{\textbf{#1}} \)

    \( \newcommand{\vectorD}[1]{\overrightarrow{#1}} \)

    \( \newcommand{\vectorDt}[1]{\overrightarrow{\text{#1}}} \)

    \( \newcommand{\vectE}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash{\mathbf {#1}}}} \)

    \( \newcommand{\vecs}[1]{\overset { \scriptstyle \rightharpoonup} {\mathbf{#1}} } \)

    \( \newcommand{\vecd}[1]{\overset{-\!-\!\rightharpoonup}{\vphantom{a}\smash {#1}}} \)

            # move all the squirrels
            for sObj in squirrelObjs:
                # move the squirrel, and adjust for their bounce
                sObj['x'] += sObj['movex']
                sObj['y'] += sObj['movey']
                sObj['bounce'] += 1
                if sObj['bounce'] > sObj['bouncerate']:
                    sObj['bounce'] = 0 # reset bounce amount
                # random chance they change direction
                if random.randint(0, 99) < DIRCHANGEFREQ:
                    sObj['movex'] = getRandomVelocity()
                    sObj['movey'] = getRandomVelocity()
                    if sObj['movex'] > 0: # faces right
                        sObj['surface'] = pygame.transform.scale(R_SQUIR_IMG, (sObj['width'], sObj['height']))
                    else: # faces left
                        sObj['surface'] = pygame.transform.scale(L_SQUIR_IMG, (sObj['width'], sObj['height']))

    The enemy squirrels all move according to the values in their 'movex' and 'movey' keys. If these values are positive, the squirrels move right or down. If these values are negative, they move left or up. The larger the value, the farther they move on each iteration through the game loop (which means they move faster).

    The for loop on line 2 [137] will apply this moving code to each of the enemy squirrel objects in the squirrelObjs list. First, line 4 [139] and 5 [140] will adjust their 'x' and 'y' keys’ values.

    The value in sObj['bounce'] is incremented on each iteration of the game loop for each squirrel. When this value is 0, the squirrel is at the very beginning of its bounce. When this value is equal to the value in sObj['bouncerate'] the value is at its end. (This is why a smaller sObj['bouncerate'] value makes for a faster bounce. If sObj['bouncerate'] is 3, then it only takes three iterations through the game loop for the squirrel to do a full bounce. If sObj['bouncerate'] were 10, then it would take ten iterations.)

    When sObj['bounce'] gets larger than sObj['bouncerate'], then it needs to be reset to 0. This is what lines 7 [142] and 8 [143] do.

    There is a 2% chance on each iteration through the game loop that the squirrel will randomly change speed and direction. On line 11 [146] the random.randint(0, 99) call randomly selects an integer out of 100 possible integers. If this number is less than DIRCHANGEFREQ (which we set to 2 on line 33) then a new value will be set for sObj['movex'] and sObj['movey'].

    Because this means the squirrel might have changed direction, the Surface object in sObj['surface'] should be replaced by a new one that is properly facing left or right and scaled to the squirrel’s size. This is what lines 14 [149] to 17 [152] determine. Note that line 15 [150] gets a Surface object scaled from R_SQUIR_IMG and line 17 [152] gets one scaled from L_SQUIR_IMG.

    This page titled 9.16: Moving the Enemy Squirrels is shared under a CC BY-NC-SA 3.0 license and was authored, remixed, and/or curated by Al Sweigart via source content that was edited to the style and standards of the LibreTexts platform; a detailed edit history is available upon request.