Creating a maze in Python/Pygame but not sure how to make walls
Question: 
    import pygame, sys
    from pygame.locals import *
    
    pygame.init()
    
    windowwidth = 600
    windowheight = 800
    WALLWIDTH = 30
    WALLHEIGHT = 30
    PLAYERWIDTH = 20
    PLAYERHEIGHT = 20
    
    
    BLACK = (0, 0, 0)
    WHITE = (255, 255, 255)
    RED = (255, 0, 0)
    LIMEGREEN = (50, 205, 50)
    
    running = True
    while running == True:
        for event in pygame.event.get():
            if event.type == QUIT:
                running = False
            if event.type == KEYDOWN:
                if (event.key == K_UP or event.key == K_w):
                elif (event.key == K_DOWN or event.key == K_s):
                elif (event.key == K_LEFT or event.key == K_a):
                elif (event.key == K_RIGHT or event.key == K_d):
    
    thescreen = pygame.display.set_mode((windowwidth, windowheight))
    pygame.display.set_caption('Maze Game')
    mainclock = pygame.time.Clock()
    
    player1 = pygame.draw.rect(thescreen, LIMEGREEN, (50, 50, PLAYERWIDTH, PLAYERHEIGHT))
    

I am trying to create a maze game (not generator) for a project in school
using Python/Pygame. I have looked all over for a way to create walls and make
a player (just a green rect) collide with these walls, and how to make several
levels for this. How would I make levels, how would I create walls, and how
would I detect collision between player and walls?


Answer: Here are the two easiest ways I know of making walls. Both ways work with
graph structures and graph search algorithms so you can implement "path-
finding" in the future if you wish. This is all off the top of my head so I
apologize if any of it is unclear, but I have also provided links to relevant
pieces of documentation that you can check out if you are confused.

# Method 1: Tile-Based Maze

This is probably the easiest method to generate maps in because it can by done
simply by making an array of ASCII characters and processing them in Python to
make square "wall" objects.

Take this grid for example:

    
    
    ###########
    #         #
    #  ###### #
    #S #F     #
    ###########
    

'S' denotes the starting point and 'F' denotes the finish point. Yes this is
probably the easiest "maze" to solve in the world but it's just an example.
Imagine that each character in my horrible ASCII array represents a square
tile of size N x N. The spaces represent the characters the tile can walk on
and the hash characters represent walls '#'.

In this type of game, walls are game entities themselves. Specifically in the
context of Pygame, they inherit from the [Sprite
class](http://www.pygame.org/docs/ref/sprite.html). Sprite classes are special
classes which represent entities, or basically existing objects in your game.
They are very special because they can represent obstacles, walls, floors,
ceilings, players, enemies, you name it. Basically every object in your game
can inherit from the Sprite class.

So what makes Sprite classes so special? Well for one, you mentioned that you
were having conceptual difficulty understanding wall-collision. Each sprite in
Pygame has its own [Rect attribute](http://www.pygame.org/docs/ref/rect.html).
A rect attribute is basically just an invisible rectangle that is used to
determine things like collision detection, and drawing sprites. By definition,
in a pure tile-based map, a "collision" between entities is defined as
follows: Two entities are colliding if their rectangles overlap each other.
Then there is a method of the Sprite class called
[`pygame.sprite.groupcollide()`](http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.collide_rect).
Each wall in the ASCII map above has a width, height, and location determined
by their position in the array. Thus each hashtag character directly
represents a rectangle that is also a square and has a square "surface" image.

Have your player inherit from the sprite class and place him in one sprite
group, the "player group". Have your wall entities inherit from the sprite
class and place them in another sprite group, call this the "obstacle group"
or something similar. All you have to do then is call
[`pygame.sprite.groupcollide()`](http://www.pygame.org/docs/ref/sprite.html#pygame.sprite.collide_rect)
in every frame of your game loop and use the dictionary it returns to tell if
the player is colliding with any sprites. I've provided links to the
documentation if any of this is unclear. Reading the Pygame documentation will
probably help you understand this better than my answer can.

So anyways what you end up with in the end of all this is a _dictionary_. I'll
make a direct quote from the documentation to explain my point:

    
    
    groupcollide(group1, group2, dokill1, dokill2, collided = None) -> Sprite_dict
    This will find collisions between all the Sprites in two groups. Collision is
    determined by comparing the Sprite.rect attribute of each Sprite or by using the 
    collided function if it is not None.
    
    Every Sprite inside group1 is added to the return dictionary. The value 
    for each item is the list of Sprites in group2 that intersect.
    

You would call this function directly in every iteration of your game loop
_after_ you update the player's movement and _before_ you draw all your
entities using the player's group as the `group1` argument, and the obstacles
group as your `group2` argument. Then you end up with a dictionary of the
following form:

    
    
    {player_in_group1: [<list of obstacles from group2 that collide with player>] }
    

So what do you do with that list? Well its recommended that you define your
own local function (you can also make it a method of player class if you wish)
for dealing with this. Here is my extremely high-level pseudo code
implementation which is not close to actual code at all:

    
    
    def handle_collisions(sprite_dict):
        '''given sprite dict, moves all entities in group1 out of group2's
           rectangle area'''
        for p in sprite_dict:
            for o in sprite_dict[p]:
                # move p in such a way that its rectangle is no longer overlapping
                # with the rectangle of o with the additional constraint that p must
                # be moved **as minimally as possible.**
    

I'm not going to implement the function for you since I feel it would be
better to leave the challenge to you. :) I will warn you that the logic is not
that simple, however.

Incidentally this type of maze/map structure is used in many popular games
including Legend of Zelda, Pacman, Bomberman, Tetris, etc, etc. I couldn't
possibly name them all but you get the point. This is a _proven_ method since
it seamlessly integrates itself with game design. But don't take my word for
it, there is [an entire website which explains why tile-based games are so
powerful.](http://www.tonypa.pri.ee/tbw/tut00.html)

# Method 2: Vertex-Edge Based Maze

Note this method is much harder to implement. It's purely [Graph
based.](http://en.wikipedia.org/wiki/Graph_%28mathematics%29) Each space in
the graph is a node which the player can traverse. What determines whether an
entity is allowed to move between two nodes (in other words...collision based
on the principle of _restriction_) is whether or not an _edge_ exists between
those two nodes in the underlying undirected (or directed, if you wish) graph.

I'm not really going to explain this in detail because it's just too difficult
to cover in one answer. You'll just have to do your own research if you want
to use this method but keep in mind it's a lot harder since Pygame doesn't
actually support you much for this strategy. If you're really interested in
this, the best place to start is probably [Google](http://google.com).

* * *

And that's it! Make an attempt with the information I've given you and if you
have any trouble with this, you can ask another question here or on [The
GameDev StackExchange](http://gamedev.stackexchange.com/). In the future when
you ask a question on SO, try and make sure that it is a _specific programming
question_ or you will very likely get lots of downvotes.

