def __init__(self, file_name):
        '''Sets everything up: camera, modes, lighting, sounds,  and the list of objects'''
        self.set_up_graphics()
        self.makeLights()
        self.objects, self.player_loc = LoadWorld.load(file_name)
        self.camera = Camera(self.player_loc[0],0,self.player_loc[1])
    
        glClearColor(.529,.8078,.980,0)

        glutIdleFunc(self.display)
        glutDisplayFunc(self.display)

        glutIgnoreKeyRepeat(GLUT_KEY_REPEAT_OFF)
        glutKeyboardFunc(self.keyPressed)
        glutKeyboardUpFunc(self.keyUp)

        glutSetCursor(GLUT_CURSOR_NONE)
        glutPassiveMotionFunc(self.mouseMove)

        self.door = Model('Graphics/basicdoor.obj','door')
        self.key = Model('Graphics/Key.obj', 'key')
        self.zombie = Model('Graphics/zombie.obj', 'zombie')
        self.chest = Model('Graphics/treasure.obj', 'chest')
        self.soundboard = GameSounds()
        self.footSound = self.soundboard.toSound("Sound/footsteps.wav")
        self.collisionSound = self.soundboard.toSound("Sound/crashsound.wav")
        self.pickSound = self.soundboard.toSound("Sound/picksound.wav")
        self.zomSound = self.soundboard.toSound("Sound/zombie.wav")
        self.fanSound = self.soundboard.toSound("Sound/fanfare.wav")
        self.soundboard.loadMusic("Sound/music.wav")
        self.soundboard.playMusic()
        
        self.zomstart = time()

        glutMainLoop()
Ejemplo n.º 2
0
 def __init__(self, persistent):
     super().__init__(persistent)
     self.tiled_map = load_pygame(self.persist['map_file'])
     if self.persist['player_party'] is not None:
         self.player_party = self.persist['player_party']
     else:
         self.player_party = PlayerParty(450, 450)
     if 'npc_reg' in self.persist.keys():
         self.npc_registry = self.persist['npc_reg']
     else:
         self.npc_registry = []
     self.tile_size = self.tiled_map.tilewidth
     self.scale_factor = 2  # Tiles are 16x16,so we must draw them 2 times larger
     self.scaled_size = self.tile_size * self.scale_factor
     w = self.tiled_map.width * self.scaled_size
     h = self.tiled_map.height * self.scaled_size
     self.camera = Camera(w, h)
     self.colliders = self.create_colliders()
     self.teleports = self.create_teleports()
     self.npcs = self.create_npcs()
     self.pause_menu = None
     self.menu = None
Ejemplo n.º 3
0
    def __init__(self, file_name):
        """Sets everything up: camera, modes, lighting, and the list of blocks"""
        self.camera = Camera()
        self.set_up_graphics()
        self.makeLights()
        self.objects = LoadWorld.load(file_name)

        glClearColor(0.529, 0.8078, 0.980, 0)
        glutIdleFunc(self.display)
        glutDisplayFunc(self.display)
        glutIgnoreKeyRepeat(GLUT_KEY_REPEAT_OFF)
        glutKeyboardFunc(self.keyPressed)
        glutKeyboardUpFunc(self.keyUp)
        glutSetCursor(GLUT_CURSOR_NONE)
        glutPassiveMotionFunc(self.mouseMove)
        self.fence = Model("Graphics/humanoid_quad.obj")
        glutMainLoop()
Ejemplo n.º 4
0
    def __init__(self, file_name):
        '''Sets up camera, modes, lighting, sounds, and objects.'''
        self.set_up_graphics()
        self.makeLights()
        self.objects, self.player_loc = LoadWorld.load(file_name)
        self.camera = Camera(self.player_loc[0],0,self.player_loc[1])

        glClearColor(.529,.8078,.980,0)

        glutIdleFunc(self.display)
        glutDisplayFunc(self.display)

        glutIgnoreKeyRepeat(GLUT_KEY_REPEAT_OFF)
        glutKeyboardFunc(self.keyPressed)
        glutKeyboardUpFunc(self.keyUp)

        glutSetCursor(GLUT_CURSOR_NONE)
        glutPassiveMotionFunc(self.mouseMove)

        self.floor_texture = Image.open("Graphics/checkerboard.bmp")
        self.ix, self.iy = self.floor_texture.size
        self.floor = self.floor_texture.tostring("raw", "RGBX", 0, -1)
        
        self.door = Model('Graphics/basicdoor.obj','door')
        self.key = Model('Graphics/Key.obj', 'key')
        self.zombie = Model('Graphics/zombie.obj', 'zombie')#try zombie5.obj for fun sometime
        self.chest = Model('Graphics/treasure.obj', 'chest')
        self.soundboard = GameSounds()
        self.footSound = self.soundboard.toSound("Sound/footsteps.wav")
        self.collisionSound = self.soundboard.toSound("Sound/crashsound.wav")
        self.pickSound = self.soundboard.toSound("Sound/picksound.wav")
        self.zomSound = self.soundboard.toSound("Sound/zombie.wav")
        self.fanSound = self.soundboard.toSound("Sound/fanfare.wav")
        self.soundboard.loadMusic("Sound/music.wav")
        self.soundboard.playMusic()

        self.zomstart = time()

        glutMainLoop()
Ejemplo n.º 5
0
class RenderWorld:
    """This is the class that renders blocks (and the floor that they sit on). Camera angles are handled by another class"""

    WINDOW_WIDTH = 400
    WINDOW_HEIGHT = 400

    def __init__(self, file_name):
        """Sets everything up: camera, modes, lighting, and the list of blocks"""
        self.camera = Camera()
        self.set_up_graphics()
        self.makeLights()
        self.objects = LoadWorld.load(file_name)

        glClearColor(0.529, 0.8078, 0.980, 0)
        glutIdleFunc(self.display)
        glutDisplayFunc(self.display)
        glutIgnoreKeyRepeat(GLUT_KEY_REPEAT_OFF)
        glutKeyboardFunc(self.keyPressed)
        glutKeyboardUpFunc(self.keyUp)
        glutSetCursor(GLUT_CURSOR_NONE)
        glutPassiveMotionFunc(self.mouseMove)
        self.fence = Model("Graphics/humanoid_quad.obj")
        glutMainLoop()

    def set_up_graphics(self):
        """Sets up the gl modes that are necessary"""
        glutInit()
        glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(self.WINDOW_WIDTH, self.WINDOW_HEIGHT)
        glutCreateWindow("Blockworld!")

        glMatrixMode(GL_PROJECTION)
        gluPerspective(45, 1, 0.15, 100)
        glMatrixMode(GL_MODELVIEW)

        glEnable(GL_DEPTH_TEST)

    def makeLights(self):
        """Sets up the light sources and their positions. We have an ambient light and two sets of specular/diffuse lights"""
        self.diffuse_pos1 = (50, 5, 0, 1)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (0.5, 0.5, 0.5, 1))
        glLightfv(GL_LIGHT0, GL_POSITION, self.diffuse_pos1)

        glLightfv(GL_LIGHT1, GL_AMBIENT, (0.2, 0.2, 0.2, 1))
        glLightfv(GL_LIGHT1, GL_POSITION, (0, 0, 1, 0))

        glLightfv(GL_LIGHT2, GL_SPECULAR, (0.8, 0.8, 0.8, 1))
        glLightfv(GL_LIGHT2, GL_POSITION, self.diffuse_pos1)

        self.diffuse_pos2 = (0, 1, 0, 1)
        glLightfv(GL_LIGHT3, GL_DIFFUSE, (0.5, 0.5, 0.5, 1))
        glLightfv(GL_LIGHT3, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT4, GL_SPECULAR, (0.8, 0.8, 0.8, 1))
        glLightfv(GL_LIGHT4, GL_POSITION, self.diffuse_pos2)

        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_LIGHT1)
        glEnable(GL_LIGHT2)

    def display(self, x=0, y=0):
        """Called for every refresh; redraws the floor and objects and based on the camera angle"""
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()
        self.camera.move()
        self.camera.hitTest(self.objects)
        self.camera.renderCamera()
        self.renderLightSource()
        self.makeFloor()
        # Transparent objects!
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        self.sort_by_dist()

        for object in self.objects[:]:

            color = object.get_color()
            pos = object.get_pos()
            glPushMatrix()
            # Set the objects shininess, ambient, diffuse, and specular reflections. The objects are slightly transparent.
            glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
            glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], 0.7])
            glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [0.4, 0.4, 0.4, 0.7])
            glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.9, 0.9, 0.9, 0.7])
            glTranslate(pos[0], pos[1], pos[2])
            if object.get_type() == "block":
                glutSolidCube(2)
            elif object.get_type() == "key":
                # glutSolidTeapot(2)
                pass
            else:
                glutSolidSphere(2, 40, 40)
            glPopMatrix()

        self.makefence()

        glDisable(GL_BLEND)

        glFlush()

    def mouseMove(self, x, y):
        """Called when the move is moved"""
        factor = 1
        padding = 10
        tmp_x = (self.camera.mouse_x - x) / factor
        tmp_y = (self.camera.mouse_y - y) / factor
        self.camera.rotate(tmp_y, tmp_x, 0)
        if x <= 0 + padding or x >= self.WINDOW_WIDTH - padding:
            x = self.WINDOW_WIDTH / 2
            glutWarpPointer(x, y)
        if y <= 0 + padding or y >= self.WINDOW_HEIGHT - padding:
            y = self.WINDOW_HEIGHT / 2
            glutWarpPointer(x, y)
        self.camera.mouse_x = x
        self.camera.mouse_y = y

    def keyPressed(self, key, x, y):
        """Called when a key is pressed"""
        if key.lower() in self.camera.keys:
            self.camera.keys[key] = True
        if key == "j":
            self.camera.rotate(0, 3, 0)
        elif key == "l":
            self.camera.rotate(0, -3, 0)
        elif key == "i":
            self.camera.rotate(3, 0, 0)
        elif key == "k":
            self.camera.rotate(-3, 0, 0)
        elif key == " ":
            self.camera.height(0.1)
        elif key == "c":
            self.camera.height(-0.1)
        elif key == "x":
            exit(0)

    def keyUp(self, key, x, y):
        """Called when a key is released"""
        if key.lower() in self.camera.keys:
            self.camera.keys[key] = False

    def renderLightSource(self):
        """Resets the light sources to the right position"""
        glLightfv(GL_LIGHT0, GL_POSITION, self.diffuse_pos1)
        glLightfv(GL_LIGHT2, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT3, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT4, GL_POSITION, self.diffuse_pos2)

    def makeFloor(self):
        """Makes a floor of size size and places an image (texture) on it"""
        glEnable(GL_TEXTURE_2D)
        size = 50
        image = Image.open("Graphics/checkerboard.bmp")

        ix = image.size[0]
        iy = image.size[1]
        image = image.tostring("raw", "RGBX", 0, -1)

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, ix, iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, image)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 0.0)
        glVertex(-size, -0.5, -size)
        glTexCoord2f(1.0, 0.0)
        glVertex(size, -0.5, -size)
        glTexCoord2f(1.0, 1.0)
        glVertex(size, -0.5, size)
        glTexCoord2f(0.0, 1.0)
        glVertex(-size, -0.5, size)
        glEnd()
        glDisable(GL_TEXTURE_2D)

    def makefence(self):

        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [0, 0, 1, 1])
        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [0.4, 0.4, 0.4, 1])
        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [0.9, 0.9, 0.9, 1])
        self.fence.rawDraw()

    def sort_by_dist(self):
        for obj in self.objects:
            obj.get_dist(self.camera.pos_X, self.camera.pos_Y, self.camera.pos_Z)
        self.objects = sorted(self.objects, key=lambda obj: obj.dist, reverse=True)
Ejemplo n.º 6
0
class MapState(GameState):
    def __init__(self, persistent):
        super().__init__(persistent)
        self.tiled_map = load_pygame(self.persist['map_file'])
        if self.persist['player_party'] is not None:
            self.player_party = self.persist['player_party']
        else:
            self.player_party = PlayerParty(450, 450)
        if 'npc_reg' in self.persist.keys():
            self.npc_registry = self.persist['npc_reg']
        else:
            self.npc_registry = []
        self.tile_size = self.tiled_map.tilewidth
        self.scale_factor = 2  # Tiles are 16x16,so we must draw them 2 times larger
        self.scaled_size = self.tile_size * self.scale_factor
        w = self.tiled_map.width * self.scaled_size
        h = self.tiled_map.height * self.scaled_size
        self.camera = Camera(w, h)
        self.colliders = self.create_colliders()
        self.teleports = self.create_teleports()
        self.npcs = self.create_npcs()
        self.pause_menu = None
        self.menu = None

    def update(self, dt):
        self.player_party.update(self.colliders, self.teleports, self.npcs)
        self.camera.update(self.player_party)

    def draw(self, surface):
        if self.bg:
            surface.blit(self.bg, (0, 0))

    def get_event(self, event):
        super().get_event(event)
        if event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:  # Handle pause menu (de)activation
            self.toggle_pause_menu()
        elif self.pause_menu is None and event.type == pg.KEYDOWN and event.key == pg.K_p:
            self.toggle_menu(UI.PartyWindow)
        elif self.pause_menu is None and event.type == pg.KEYDOWN and event.key == pg.K_i:
            self.toggle_menu(UI.InventoryWindow)
        elif self.pause_menu is None and event.type == EncounterEvent and isinstance(event.npc, MapTrader):
            self.toggle_menu(UI.TraderWindow)
        elif self.pause_menu is None and event.type == EncounterEvent and isinstance(event.npc, MapWizard):
            self.toggle_menu(UI.WizardWindow)
        elif event.type == EncounterEvent and isinstance(event.npc, MapNPC):
            self.enter_battle(event)
        elif event.type == MenuQuitEvent and event.window == UI.PauseWindow:
            self.toggle_pause_menu()
        elif event.type == MenuQuitEvent and event.window is not UI.SelectCharacterWindow:
            self.toggle_menu(event.window)
        elif event.type == pg.KEYDOWN and event.key == pg.K_l:  # Call game load\save menu
            self.toggle_menu(UI.LoadSaveWindow)
        elif self.pause_menu is None and self.menu is None:  # Handle player control only if menu is not active
            self.player_control(event)
        elif self.pause_menu is not None and event.type == pg.KEYDOWN:  # Let the pause menu handle input first
            self.pause_menu.update(event.key)
        elif self.menu is not None and event.type == pg.KEYDOWN:
            self.menu.update(event.key)

    def player_control(self, event):
        """
        Handle key press events related to player control
        :param event: pygame KEYDOWN or KEYUP event
        """
        if event.type == pg.KEYDOWN and event.key == pg.K_w:
            self.player_party.up = True
        elif event.type == pg.KEYUP and event.key == pg.K_w:
                self.player_party.up = False
        elif event.type == pg.KEYDOWN and event.key == pg.K_s:
            self.player_party.down = True
        elif event.type == pg.KEYUP and event.key == pg.K_s:
            self.player_party.down = False
        elif event.type == pg.KEYDOWN and event.key == pg.K_a:
            self.player_party.left = True
        elif event.type == pg.KEYUP and event.key == pg.K_a:
            self.player_party.left = False
        elif event.type == pg.KEYDOWN and event.key == pg.K_d:
            self.player_party.right = True
        elif event.type == pg.KEYUP and event.key == pg.K_d:
            self.player_party.right = False

    def toggle_pause_menu(self):
        if self.pause_menu is None:
            self.on_pause()
            width = self.screen_width / 4
            height = self.screen_height / 4
            x = self.screen_width / 2 - width / 2
            y = self.screen_height / 2 - height / 2
            self.pause_menu = UI.PauseWindow(x, y, width, height)
        else:
            self.pause_menu = None
            self.on_resume()

    def toggle_menu(self, menu):
        if self.menu is None:
            self.on_pause()
            width = self.screen_width * 0.55
            height = self.screen_height * 0.5
            x = self.screen_width / 2 - width / 2
            y = self.screen_height / 2 - height / 2
            self.menu = menu(x, y, width, height, self.player_party)
        else:
            self.menu = None
            self.on_resume()

    def on_pause(self):
        self.player_party.pause()

    def on_resume(self):
        self.player_party.resume()

    def on_save(self):
        self.tiled_map = None

    def on_load(self):
        self.tiled_map = load_pygame(self.persist['map_file'])  # reload tiled map
        self.player_party.on_load()  # reload all sprites
        for i in self.npcs:
            i.on_load()
        self.set_bg()

    def create_colliders(self):
        """
        Create rectangles to be used as colliders for collision check
        :return: list of pygame rect objects
        """
        size = self.scaled_size
        colliders = []
        for i in range(0, len(self.tiled_map.layers) - 2):
            for x, y, image in self.tiled_map.layers[i].tiles():
                p = self.tiled_map.get_tile_properties(x, y, i)
                if p['walkable'] == 'false':
                    rect = pg.Rect(x * size, y * size, self.scaled_size, self.scaled_size)
                    colliders.append(rect)
        return colliders

    def create_teleports(self):
        teleports = []
        size = self.scale_factor
        for obj in self.tiled_map.get_layer_by_name('teleports'):
            rect = pg.Rect(int(obj.x) * size, int(obj.y) * size, obj.height, obj.height)  # collision occurs too early if size is not halfed
            p = obj.properties
            pos_x = int(p['pos_x'])
            pos_y = int(p['pos_y'])
            map_f = MapsHelper.get_map(p['map_f'])
            world = p['world']
            tp = Teleport(rect, pos_x, pos_y, map_f, world)
            teleports.append(tp)

        return teleports

    def create_npcs(self):
        npcs = []
        for obj in self.tiled_map.get_layer_by_name('npc'):
            p = obj.properties
            name = p['npc']  # Reserved - Trader, Wizard
            x = int(obj.x) * self.scale_factor
            y = int(obj.y) * self.scale_factor
            if name == 'trader':
                npc = MapTrader(x, y)
            elif name == 'wizard':
                npc = MapWizard(x, y)
            else:
                party = p['party_members'].split(',') if 'party_members' in p.keys() else None
                bg = p['bg'] if 'bg' in p.keys() else None
                identifier = int(p['nid']) if 'nid' in p.keys() else None
                if identifier is not None and self.npc_registry.count(identifier) == 0:
                    npc = MapNPC(x, y, party, bg, identifier)
                else:
                    continue
            npcs.append(npc)

        return npcs

    def enter_battle(self, event):
        self.player_party.enter_battle()
        args_dict = {'player_party': self.player_party, 'party_members': event.npc.party, 'bg': event.npc.bg, 'id': event.npc.id}
        self.call_state(BattleState, args_dict)
Ejemplo n.º 7
0
class RenderWorld:
    '''This is the class that renders maze.
    Camera angles are handled by Camera.py.
    '''
    WINDOW_WIDTH = 700
    WINDOW_HEIGHT = 700
    MAP_SIZE =100

    def __init__(self, file_name):
        '''Sets up camera, modes, lighting, sounds, and objects.'''
        self.set_up_graphics()
        self.makeLights()
        self.objects, self.player_loc = LoadWorld.load(file_name)
        self.camera = Camera(self.player_loc[0],0,self.player_loc[1])

        glClearColor(.529,.8078,.980,0)

        glutIdleFunc(self.display)
        glutDisplayFunc(self.display)

        glutIgnoreKeyRepeat(GLUT_KEY_REPEAT_OFF)
        glutKeyboardFunc(self.keyPressed)
        glutKeyboardUpFunc(self.keyUp)

        glutSetCursor(GLUT_CURSOR_NONE)
        glutPassiveMotionFunc(self.mouseMove)

        self.floor_texture = Image.open("Graphics/checkerboard.bmp")
        self.ix, self.iy = self.floor_texture.size
        self.floor = self.floor_texture.tostring("raw", "RGBX", 0, -1)
        
        self.door = Model('Graphics/basicdoor.obj','door')
        self.key = Model('Graphics/Key.obj', 'key')
        self.zombie = Model('Graphics/zombie.obj', 'zombie')#try zombie5.obj for fun sometime
        self.chest = Model('Graphics/treasure.obj', 'chest')
        self.soundboard = GameSounds()
        self.footSound = self.soundboard.toSound("Sound/footsteps.wav")
        self.collisionSound = self.soundboard.toSound("Sound/crashsound.wav")
        self.pickSound = self.soundboard.toSound("Sound/picksound.wav")
        self.zomSound = self.soundboard.toSound("Sound/zombie.wav")
        self.fanSound = self.soundboard.toSound("Sound/fanfare.wav")
        self.soundboard.loadMusic("Sound/music.wav")
        self.soundboard.playMusic()

        self.zomstart = time()

        glutMainLoop()

    def set_up_graphics(self):
        '''Sets up OpenGL to provide double buffering, RGB coloring,
        depth testing, the correct window size, perspective
        rendering/fulcrum clipping, and a title.'''
        glutInit()
        glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH)
        glutInitWindowSize(self.WINDOW_WIDTH, self.WINDOW_HEIGHT)
        glutCreateWindow('Mazeworld!')

        glMatrixMode(GL_PROJECTION)
        gluPerspective(45,1,.15,100)
        glMatrixMode(GL_MODELVIEW)

        glEnable(GL_DEPTH_TEST)

    def makeLights(self):
        '''Sets up the light sources and their positions. We have an
        ambient light and two sets of specular/diffuse lights.'''
        self.diffuse_pos1 = (50,5,0,1)
        glLightfv(GL_LIGHT0, GL_DIFFUSE, (.5, .5, .5, 1))
        glLightfv(GL_LIGHT0, GL_POSITION, self.diffuse_pos1)

        glLightfv(GL_LIGHT1, GL_AMBIENT, (.2, .2, .2, 1))
        glLightfv(GL_LIGHT1, GL_POSITION, (0, 0, 1, 0))

        glLightfv(GL_LIGHT2, GL_SPECULAR, (.8, .8, .8, 1))
        glLightfv(GL_LIGHT2, GL_POSITION, self.diffuse_pos1)

        self.diffuse_pos2 = (0,1,0,1)
        glLightfv(GL_LIGHT3, GL_DIFFUSE, (.5, .5, .5, 1))
        glLightfv(GL_LIGHT3, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT4, GL_SPECULAR, (.8, .8, .8, 1))
        glLightfv(GL_LIGHT4, GL_POSITION, self.diffuse_pos2)

        glEnable(GL_LIGHTING)
        glEnable(GL_LIGHT0)
        glEnable(GL_LIGHT1)
        glEnable(GL_LIGHT2)

    def display(self, x=0, y=0):
        '''Called for every refresh; redraws the floor and objects
        based on the camera angle. Calls collision detection, handles
        the appropriate objects for keys, doors, etc.'''
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
        glLoadIdentity()

        self.camera.move(self.objects)
        self.camera.check_collisions(self.objects)
        self.camera.renderCamera()
        self.renderLightSource()
        self.makeFloor()

        # Transparent objects!
        glEnable(GL_BLEND)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)

        self.sort_by_dist()

        for obj in self.objects:
            if obj.get_dist(self.camera.pos_X, self.camera.pos_Y, self.camera.pos_Z) < 15:
                color = obj.get_color()
                pos = obj.get_pos()
                obj_type = obj.get_type()

                glPushMatrix()

            # Set the objects shininess, ambient, diffuse, and
            # specular reflections. The objects are slightly
            # transparent. <- (nick: Why?)
                glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 15)
                glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .5])
                glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, 1])
                glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .5])

                glTranslate(pos[0], pos[1], pos[2])
                
                if obj_type == 'block':
                    glutSolidCube(2)
            
                elif obj_type == 'key' or obj_type == 'chest':
                    if not obj.get_has():
                        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
                        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .5])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, .7])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .6])
                        self.makeobj(obj.get_type())

                elif obj_type == 'zombie':
                    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
                    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .5])
                    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, .7])
                    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .6])
                    zomX, zomY, zomZ = pos # We already grabbed pos.
                    self.makeobj(obj.get_type())

                elif obj_type == 'chest':
                    glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
                    glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .5])
                    glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, .7])
                    glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .6])
                    self.makeobj(obj.get_type())

                elif obj_type == 'door':
                    if obj.get_key().get_has():
                        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .2])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, .2])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .2])
                    else:
                        glMaterialfv(GL_FRONT_AND_BACK, GL_SHININESS, 75)
                        glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, [color[0], color[1], color[2], .5])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, [.4, .4, .4, .7])
                        glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, [.9, .9, .9, .6])
                    glRotate(obj.get_rotation(), 0, 1, 0)
                    self.makeobj(obj.get_type())

                else:
                    glutSolidSphere(2, 40, 40)

                glPopMatrix()
                
        glDisable(GL_BLEND)
                
        Overlay.draw_overlay(self.camera,
                             self.soundboard.paused)

        
        if self.camera.key_timeout > 0:
            Overlay.draw_text("Got a key!")
            self.camera.key_timeout -= 1
        if self.camera.dead_timeout > 0:
            Overlay.draw_text("A zombie killed you!")
            self.camera.dead_timeout -= 1
        if self.camera.treasure_timeout > 0:
            Overlay.draw_text("Got treasure!")
            self.camera.treasure_timeout -= 1
            
        glutSwapBuffers()

    def mouseMove(self, x, y):
        '''Called when the mouse is moved.'''
        factor = 2
        
        tmp_x = (self.camera.mouse_x - x)/factor
        tmp_y = (self.camera.mouse_y - y)/factor
        if tmp_x > self.camera.ROTATE:
            tmp_x = self.camera.ROTATE
        self.camera.rotate(0, tmp_x, 0)
        x = self.WINDOW_WIDTH/2
        y = self.WINDOW_HEIGHT/2
        glutWarpPointer(x, y)
        self.camera.mouse_x = x
        self.camera.mouse_y = y
        
    def keyPressed(self, key, x, y):
        '''Called when a key is pressed.'''
        if key.lower() in self.camera.keys:
            self.camera.keys[key.lower()] = True
        if glutGetModifiers() == GLUT_ACTIVE_SHIFT:
            self.camera.keys["shift"] = True
        if key == 'j':
            self.camera.rotate(0,3,0)
        elif key == 'l':
            self.camera.rotate(0,-3,0)
        elif key == 'i':
            self.camera.rotate(3,0,0)
        elif key == 'k':
            self.camera.rotate(-3,0,0)
        elif key == 'm':
            if self.soundboard.paused:
                self.soundboard.unpauseMusic()
            else:
                self.soundboard.pauseMusic()
        elif key == 'x':
            exit(0)

    def keyUp(self, key, x, y):
        '''Called when a key is released.'''
        # Speed things up by not checking if the key is in the map
        self.camera.keys[key.lower()] = False
        if not glutGetModifiers() == GLUT_ACTIVE_SHIFT:
            self.camera.keys["shift"] = False

    def renderLightSource(self):
        '''Resets the light sources to the right position.'''
        glLightfv(GL_LIGHT0, GL_POSITION, self.diffuse_pos1)
        glLightfv(GL_LIGHT2, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT3, GL_POSITION, self.diffuse_pos2)
        glLightfv(GL_LIGHT4, GL_POSITION, self.diffuse_pos2)

    def makeFloor(self):
        '''Makes a floor of the correct size and places an self.floor_texture
        (texture) on it.'''
        glEnable(GL_TEXTURE_2D)

        glPixelStorei(GL_UNPACK_ALIGNMENT,1)
        glTexImage2D(GL_TEXTURE_2D, 0, 3, self.ix, self.iy, 0, GL_RGBA, GL_UNSIGNED_BYTE, self.floor)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL)
        glBegin(GL_QUADS)
        glTexCoord2f(0.0, 0.0)
        glVertex(-self.MAP_SIZE,-.5,-self.MAP_SIZE)
        glTexCoord2f(1.0, 0.0)
        glVertex(self.MAP_SIZE,-.5,-self.MAP_SIZE)
        glTexCoord2f(1.0, 1.0)
        glVertex(self.MAP_SIZE,-.5,self.MAP_SIZE)
        glTexCoord2f(0.0, 1.0)
        glVertex(-self.MAP_SIZE,-.5,self.MAP_SIZE)
        glEnd()
        glDisable(GL_TEXTURE_2D)

    def makeobj(self, kind):
        '''Makes the desired object from the loaded obj file.'''

        if kind == 'key':
            self.key.rawDraw()
        elif kind == 'door':
            self.door.rawDraw()
        elif kind == 'zombie':
            self.zombie.rawDraw()
        elif kind == 'chest':
            self.chest.rawDraw()

    def sort_by_dist(self):
        for obj in self.objects:
            obj.get_dist(self.camera.pos_X, self.camera.pos_Y, self.camera.pos_Z)
        self.objects = sorted(self.objects, key=lambda obj: obj.dist, reverse=True)

    def get_visible(self, lst):
        '''Only draws the objects sitting in front of the camera.
        Everything behind it is left undrawn.'''
        to_use = []
        for item in lst:
            c = item.dist
            x,z = self.camera.project_move_other()
            b = self.camera.get_camera_distance(x, 0, z)
            a = item.get_dist(x, 0, z)
            angle = 0
            try:
                num = ((b**2)+(c**2)-(a**2))/(2*b*c)
                angle = math.acos(num)/math.pi*180
            except:
                pass
            if angle > 90:
                to_use.append(item)
        return to_use