Skip to main content
Engineering LibreTexts

10.17: Drawing the Map

  • Page ID
    14678

    \( \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}}} \)

    \(\newcommand{\avec}{\mathbf a}\) \(\newcommand{\bvec}{\mathbf b}\) \(\newcommand{\cvec}{\mathbf c}\) \(\newcommand{\dvec}{\mathbf d}\) \(\newcommand{\dtil}{\widetilde{\mathbf d}}\) \(\newcommand{\evec}{\mathbf e}\) \(\newcommand{\fvec}{\mathbf f}\) \(\newcommand{\nvec}{\mathbf n}\) \(\newcommand{\pvec}{\mathbf p}\) \(\newcommand{\qvec}{\mathbf q}\) \(\newcommand{\svec}{\mathbf s}\) \(\newcommand{\tvec}{\mathbf t}\) \(\newcommand{\uvec}{\mathbf u}\) \(\newcommand{\vvec}{\mathbf v}\) \(\newcommand{\wvec}{\mathbf w}\) \(\newcommand{\xvec}{\mathbf x}\) \(\newcommand{\yvec}{\mathbf y}\) \(\newcommand{\zvec}{\mathbf z}\) \(\newcommand{\rvec}{\mathbf r}\) \(\newcommand{\mvec}{\mathbf m}\) \(\newcommand{\zerovec}{\mathbf 0}\) \(\newcommand{\onevec}{\mathbf 1}\) \(\newcommand{\real}{\mathbb R}\) \(\newcommand{\twovec}[2]{\left[\begin{array}{r}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\ctwovec}[2]{\left[\begin{array}{c}#1 \\ #2 \end{array}\right]}\) \(\newcommand{\threevec}[3]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\cthreevec}[3]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \end{array}\right]}\) \(\newcommand{\fourvec}[4]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\cfourvec}[4]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \end{array}\right]}\) \(\newcommand{\fivevec}[5]{\left[\begin{array}{r}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\cfivevec}[5]{\left[\begin{array}{c}#1 \\ #2 \\ #3 \\ #4 \\ #5 \\ \end{array}\right]}\) \(\newcommand{\mattwo}[4]{\left[\begin{array}{rr}#1 \amp #2 \\ #3 \amp #4 \\ \end{array}\right]}\) \(\newcommand{\laspan}[1]{\text{Span}\{#1\}}\) \(\newcommand{\bcal}{\cal B}\) \(\newcommand{\ccal}{\cal C}\) \(\newcommand{\scal}{\cal S}\) \(\newcommand{\wcal}{\cal W}\) \(\newcommand{\ecal}{\cal E}\) \(\newcommand{\coords}[2]{\left\{#1\right\}_{#2}}\) \(\newcommand{\gray}[1]{\color{gray}{#1}}\) \(\newcommand{\lgray}[1]{\color{lightgray}{#1}}\) \(\newcommand{\rank}{\operatorname{rank}}\) \(\newcommand{\row}{\text{Row}}\) \(\newcommand{\col}{\text{Col}}\) \(\renewcommand{\row}{\text{Row}}\) \(\newcommand{\nul}{\text{Nul}}\) \(\newcommand{\var}{\text{Var}}\) \(\newcommand{\corr}{\text{corr}}\) \(\newcommand{\len}[1]{\left|#1\right|}\) \(\newcommand{\bbar}{\overline{\bvec}}\) \(\newcommand{\bhat}{\widehat{\bvec}}\) \(\newcommand{\bperp}{\bvec^\perp}\) \(\newcommand{\xhat}{\widehat{\xvec}}\) \(\newcommand{\vhat}{\widehat{\vvec}}\) \(\newcommand{\uhat}{\widehat{\uvec}}\) \(\newcommand{\what}{\widehat{\wvec}}\) \(\newcommand{\Sighat}{\widehat{\Sigma}}\) \(\newcommand{\lt}{<}\) \(\newcommand{\gt}{>}\) \(\newcommand{\amp}{&}\) \(\definecolor{fillinmathshade}{gray}{0.9}\)
    def drawMap(mapObj, gameStateObj, goals):
        """Draws the map to a Surface object, including the player and
        stars. This function does not call pygame.display.update(), nor
        does it draw the "Level" and "Steps" text in the corner."""
    
        # mapSurf will be the single Surface object that the tiles are drawn
        # on, so that it is easy to position the entire map on the DISPLAYSURF
        # Surface object. First, the width and height must be calculated.
        mapSurfWidth = len(mapObj) * TILEWIDTH
        mapSurfHeight = (len(mapObj[0]) - 1) * TILEFLOORHEIGHT + TILEHEIGHT
        mapSurf = pygame.Surface((mapSurfWidth, mapSurfHeight))
        mapSurf.fill(BGCOLOR) # start with a blank color on the surface.
    
        # Draw the tile sprites onto this surface.
        for x in range(len(mapObj)):
            for y in range(len(mapObj[x])):
                spaceRect = pygame.Rect((x * TILEWIDTH, y * TILEFLOORHEIGHT, TILEWIDTH, TILEHEIGHT))
                if mapObj[x][y] in TILEMAPPING:
                    baseTile = TILEMAPPING[mapObj[x][y]]
                elif mapObj[x][y] in OUTSIDEDECOMAPPING:
                    baseTile = TILEMAPPING[' ']
    
                # First draw the base ground/wall tile.
                mapSurf.blit(baseTile, spaceRect)
    
                if mapObj[x][y] in OUTSIDEDECOMAPPING:
                    # Draw any tree/rock decorations that are on this tile.
                    mapSurf.blit(OUTSIDEDECOMAPPING[mapObj[x][y]], spaceRect)
                elif (x, y) in gameStateObj['stars']:
                    if (x, y) in goals:
                        # A goal AND star are on this space, draw goal first.
                        mapSurf.blit(IMAGESDICT['covered goal'], spaceRect)
                    # Then draw the star sprite.
                    mapSurf.blit(IMAGESDICT['star'], spaceRect)
                elif (x, y) in goals:
                    # Draw a goal without a star on it.
                    mapSurf.blit(IMAGESDICT['uncovered goal'], spaceRect)
    
                # Last draw the player on the board.
                if (x, y) == gameStateObj['player']:
                    # Note: The value "currentImage" refers
                    # to a key in "PLAYERIMAGES" which has the
                    # specific player image we want to show.
                    mapSurf.blit(PLAYERIMAGES[currentImage], spaceRect)
    
        return mapSurf
    

    The drawMap() function will return a Surface object with the entire map (and the player and stars) drawn on it. The width and height needed for this Surface have to be calculated from mapObj (which is done on line 9 [543] and 10 [544]). The Surface object that everything will be drawn on is created on line 11 [545]. To begin with, the entire Surface object is painted to the background color on line 12 [546].

    The set of nested for loops on line 15 [549] and 16 [550] will go through every possible XY coordinate on the map and draw the appropriate tile image at that location.

    The baseTile variable is set to the Surface object of the tile image to be drawn at the iteration’s current XY coordinate. If the single-character string is in the OUTSIDEDECOMAPPING dictionary, then TILEMAPPING[' '] (the single-character string for the basic outdoor floor tile) will be used.

    Additionally, if the tile was listed in the OUTSIDEDECOMAPPING dictionary, the corresponding tree or rock image should be drawn on top of the tile that was just drawn at that XY coordinate.

    If there is a star located at this XY coordinate on the map (which can be found out by checking for (x, y) in the list at gameStateObj['stars']), then a star should be drawn at this XY coordinate (which is done on line 34 [568]). Before the star is drawn, the code should first check if there is also a goal at this location, in which case, the "covered goal" tile should be drawn first.

    If there is a goal at this XY coordinate on the map, then the "uncovered goal" should be drawn on top of the tile. The uncovered goal is drawn because if execution has reached the elif statement on line 35 [569], we know that the elif statement’s condition on line 29 [563] was False and there is no star that is also at this XY coordinate.

    Finally, the drawMap() function checks if the player is located at this XY coordinate, and if so, the player’s image is drawn over the tile. Line 46 [580] is outside of the nested for loops that began on line 15 [549] and 16 [550], so by the time the Surface object is returned, the entire map has been drawn on it.


    This page titled 10.17: Drawing the Map 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.