示例#1
0
class NewRender(object):

    def __init__(self, filename):
        self.tmx_data = util_pygame.load_pygame(filename)

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(self.tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data, (640,640))
        self.map_layer.zoom = 1

        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=0)
        
    def draw_map(self, display, playChar):
        # center the map/screen on our Hero
        #self.group.center(self.hero.rect.center)
        self.group.center(playChar.rect.center)
        # draw the map and all sprites
        self.group.draw(display)
    
    def get_dims(self):
        props = self.tmx_data.properties
        width = int(props['Width'])
        height = int(props['Height'])
        
        return width, height
示例#2
0
class FarmGame(object):

    def __init__(self):
        self.screen = pygame.display.get_surface()
        GLOBALS.UI = UserInterface()

        GLOBALS.game_running = False
        GLOBALS.tile_map = TileMap()

        GLOBALS.tile_map.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=GLOBALS.tile_map.map_layer, default_layer=2)

        GLOBALS.hero = Hero()
        GLOBALS.hero.position = GLOBALS.tile_map.map_layer.map_rect.center

        for tree in GLOBALS.trees:
            self.group.add(tree)

        for ground in GLOBALS.ground:
            self.group.add(ground)
        self.group.add(GLOBALS.hero) # add player last!

        self.input = Input()

    def run(self):
        clock = pygame.time.Clock()
        GLOBALS.game_running = True

        try:
            while GLOBALS.game_running:
                dt = clock.tick(60)/1000. # limit to 60fps, but also damn milliseconds, you fast

                self.input.handle()
                self.update(dt)
                self.draw(self.screen)
                GLOBALS.UI.draw(self.screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            GLOBALS.game_running = False

    def update(self, dt):
        self.group.update(dt)

    def draw(self, surface):
        self.group.center(GLOBALS.hero.rect.center)
        self.group.draw(surface)
示例#3
0
class Map:
    def __init__(self, game):
        self.game = game
        self.screen = game.screen
        self.datahelper = game.datahelper
        self.hero = game.hero
        self.scriptengine = game.scriptengine
        self.hero.map = self

    def load(self, data):
        #loading map to creating group
        tmx_data = load_pygame(
            path.join(self.game.dir, "data",
                      self.datahelper.maps[data["mapname"]]["file"]))
        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_layer = pyscroll.BufferedRenderer(
            map_data, self.screen.surface.get_size(),
            clamp_camera=False)  #tall_sprites=1)
        self.map_layer.zoom = 2
        self.group = PyscrollGroup(map_layer=self.map_layer,
                                   default_layer=5)  #data["layer"])
        #setting up player
        self.mapname = data["mapname"]
        self.hero.position = [data["player"]["x"], data["player"]["y"] - 8]
        if data["player"]["walking"] == 1:
            self.hero.walking = True
            self.hero.movingx, self.hero.movingy = data["player"][
                "walkingx"], data["player"]["walkingy"]
            self.hero.steps = 16
        self.group.add(self.hero)
        self.hero.rect.topleft = self.hero.position

        #colliditon
        self.collidable = {}
        self.interactable = {}
        self.warps = {}
        self.npcs = {}
        i = j = k = l = 0
        for id in tmx_data.objects_by_id:
            #print(tmx_data.objects_by_id[id].name)
            if tmx_data.objects_by_id[id].name in self.datahelper.interactable:
                self.interactable[j] = tmx_data.objects_by_id[id]
                j += 1
            if tmx_data.objects_by_id[id].name in self.datahelper.collidable:
                self.collidable[i] = (tmx_data.objects_by_id[id].x,
                                      tmx_data.objects_by_id[id].y)
                i += 1
            if "Warp" in tmx_data.objects_by_id[id].name:
                self.warps[k] = tmx_data.objects_by_id[id]
                k += 1
            if "npc" in tmx_data.objects_by_id[id].name:
                self.npcs[l] = self.scriptengine.load_npc(
                    tmx_data.objects_by_id[id])
                #self.npcs[l] = NPC(tmx_data.objects_by_id[id].name)
                #self.npcs[l].position = [tmx_data.objects_by_id[id].x, tmx_data.objects_by_id[id].y-8]
                self.group.add(self.npcs[l])
                self.npcs[l].map = self
                #self.npcs[l].rect.topleft = self.npcs[l].position
                #if "dir" in tmx_data.objects_by_id[id].properties.keys():
                #self.npcs[l].dir = tmx_data.objects_by_id[id].properties["dir"]
                #self.scriptengine.load(self.npcs[l])
                #self.npcs[l].map = self
                l += 1
        #animations
        #print(self.warps)
        self.timer = 0
        self.warping = False
        self.nextmap = {}

    def draw(self):
        self.group.update()
        self.hero.tick()
        self.group.center(self.hero.rect.topleft)
        #self.group.draw(screen)
        #if self.loaded:
        self.group.draw(self.screen.surface)

    def change_map(self, data):
        self.warps = 0
        self.scriptengine.clear()
        self.load(data)

    def update(self):
        for key, warp in self.warps.items():
            if self.hero.rect.collidepoint(warp.x, warp.y):
                if not self.screen.state["fade"]:
                    self.screen.drawFade()
                if self.screen.fadein:
                    self.change_map(self.datahelper.warps[warp.name])

    def collide(self, rect, npc=False):
        for i in self.collidable:
            if rect.collidepoint(self.collidable[i]):
                return True
        for i in self.npcs:
            if self.npcs[i].walking:
                if rect.colliderect(self.npcs[i].facing):
                    return True
            if rect.collidepoint(self.npcs[i].position[0],
                                 self.npcs[i].position[1] + 8):
                return True
        if npc and rect.collidepoint(self.hero.position[0],
                                     self.hero.position[1] + 8):
            return True
        return False

    def interact(self):
        #print(self.interactable)
        for i in self.interactable:
            if self.hero.facing.collidepoint(self.interactable[i].x,
                                             self.interactable[i].y):
                dialogbox = Dialog(
                    self.datahelper.interactable[self.interactable[i].name],
                    self.screen.surface)
                self.screen.drawDialog(dialogbox)
        for i in self.npcs:
            if not self.npcs[i].walking:
                if self.hero.facing.collidepoint(self.npcs[i].rect.x,
                                                 self.npcs[i].rect.y + 8):
                    self.scriptengine.run(self.npcs[i])
示例#4
0
class Intro(tools._State):
    def __init__(self):
        super(Intro, self).__init__()

        tmx_data = load_pygame(MAP['intro'])

        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE)
        self.map_layer.zoom = 0.5

        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.animations = pg.sprite.Group()
        self.labels = pg.sprite.Group()
        self.letters = pg.sprite.Group()
        self.surface = GFX['intro'].convert_alpha()
        self.cheat = False


        timespan = 3000
        midbottom = (SCREEN_RECT.centerx, SCREEN_RECT.bottom - 20)
        font = FONTS["UbuntuMono-B"]
        self.prompt = Blinker("Press Enter key to continue", {"midbottom": midbottom},
                              500, text_color=(255, 255, 255), font_path=font,
                              font_size= 25)
        Label('UP-UP-DOWN-DOWN-LEFT-RIGHT-LEFT-RIGHT-B-A',{"topleft": (50, 0)},self.labels,font_path=font,font_size = 7)
        task = Task(self.labels.add, timespan, args=(self.prompt,))
        self.animations.add(task)


    def startup(self, persist):
        pg.mixer.init()
        song = MUSIC['intro']
        pg.mixer.music.load(song)
        pg.mixer.music.set_volume(0.1)
        pg.mixer.music.play()

        self.persist = persist
        self.mask = self.persist['surface']
        self.transition = Transition(self.mask)
        self.code = ''



    def cleanup(self):

        pg.mixer.quit()
        self.persist['surface']= pg.display.get_surface()
        return self.persist

    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYUP:
            if event.key == pg.K_ESCAPE:
                self.quit = True
            elif event.key == pg.K_RETURN:


                self.done = True
                self.next = 'BOTTOM'
            elif event.key == pg.K_UP:
                self.code += 'u'
            elif event.key == pg.K_DOWN:
                self.code += 'd'
            elif event.key == pg.K_LEFT:
                self.code += 'l'
            elif event.key == pg.K_RIGHT:
                self.code += 'r'
            elif event.key == pg.K_a:
                self.code += 'a'
            elif event.key == pg.K_b:
                self.code += 'b'
            else:
                pass


    def update(self, dt):
        if self.code.endswith('uuddlrlrba'):
            self.cheat = True
            self.persist['lives'] = CHEAT_LIVES
            self.code += 'a'
        if self.cheat == True:
            sound = SFX['cheat']
            sound.play()
            self.cheat = False
        self.animations.update(dt)
        self.labels.update(dt)

    def draw(self, surface):

        self.group.draw(surface)
        self.group.center((SCREEN_RECT.centerx,SCREEN_RECT.bottom))
        surface.blit(self.surface, (0, 0))
        self.transition.draw(surface)
        self.letters.draw(surface)
        self.labels.draw(surface)
示例#5
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)
    

    def __init__(self, state): 
        if state == False:
            screenMode = pygame.RESIZABLE
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            self.direction = "still"
            self.fps = 180

            self.counter = 1
            self.counter2 = 1

            heroPos1 = False

            # load data from pytmx
            tmx_data = load_pygame(self.filename)

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))
            
            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)
            self.hero = Hero('Tiles/character/character_still.png')
            self.hero.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)

    def map_change(self, map):
            mapfile = get_map(map)
            tmx_data = load_pygame(mapfile)
            print(tmx_data)
            map_data = pyscroll.data.TiledMapData(tmx_data)
            self.walls = list()
            for object in tmx_data.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))


            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

            self.hero = Hero('Tiles/character/character_still.png')
            self.hero.position = self.map_layer.map_rect.center


            
    def switcher(self):
        if len(doorX) == len(doorY) == len(targetPosX) == len(targetPosY) == len(currentMap) == len(targetMap) == len(animationDirection) == len(targetMapFile):
            for i in range(len(doorX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= doorX[i] <= self.hero.position[0] + 15:
                        print("OK!")
                        if self.hero.position[1] - 15 <= doorY[i] <= self.hero.position[1] + 15:
                            self.map_change(targetMapFile[i])
                            self.map = targetMap[i]
                            stats['map'] = targetMapFile[i]
                            heroPos = (targetPosX[i], targetPosY[i])
                            self.animation(animationDirection[i], 1)
                            self.hero.position = heroPos
                            print("Yeah!")
                            break
                    else:
                        print("Nope!")
                        print(str(doorX[i]) +" " +str(self.hero.position[0]))
                        print(str(doorY[i]) +" " +str(self.hero.position[1]))
                        
                else:
                    #print("Never!")
                    pass
        else:
            print("Error: Invalid number of door entries.")

##        elif self.map == "maze1":
##        #HOUSE2
##            if self.hero.position[0] >= -20 and self.hero.position[0] <= 20 and self.hero.position[1] <= 20 and self.hero.position[1] >= -15:
##                self.map_change(HOUSE1)
##                stats['map'] = HOUSE1
##                self.map = "house1"
##                heroPos = 206, 48
##                self.animation("down", 1)
##                self.hero.position = heroPos
##                self.group.remove(self)
##                self.group.empty()
##                self.group.add(self.hero)

    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self, keyset):
        """ Handle pygame input events
        """
        poll = pygame.event.poll
        
        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:
                

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value

                    elif event.key == K_KP0:
                        self.switcher()
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        print("Inventory")
                        pass

                    if event.key == K_ESCAPE:
                        pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb"))
                        pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset == "inventory":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        print("Game")
                        pass

                    if event.key == K_r:
                        self.genchests()
                    

                elif event.key == K_KP1:
                    self.menu = "game"
                    print("Game")
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.menu = "inventory"
                    print("Inventory")
                    pass

                elif event.key == K_KP4:
                    pass

                elif event.key == K_KP5:
                    pass

                elif event.key == K_KP6:
                    print("X :" +str(self.hero.position[0]) +", Y: " +str(self.hero.position[1]))
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass
                
                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    self.genchests()
                    pass

                elif event.key == K_F11:
                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w
                

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction2 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction2 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction2 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction2 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        self.counter += 1
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/character/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/character/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tiles/character/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/character/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/character/walking_' +direction +'/walking_' +direction +str(number) +'.png')

                
            self.group.remove(self)
            self.group.empty()
            self.group.add(self.hero)
        


    def genchests(self):
        itm1, itm2, itm3, itm4, itm5, itm6 = "0", "0", "0", "0", "0", "0"
        numberItems = random.randint(1, 6)
        for i in range(0, numberItems):
            item = random.randint(1, 5)
            if i == 1:
                itm1 = item
            if i == 2:
                itm2 = item
            if i == 3:
                itm3 = item
            if i == 4:
                itm4 = item
            if i == 5:
                itm5 = item
            if i == 6:
                itm6 = item
        print("Found Chest With "+str(numberItems) +" Items: " +str(itm1) +" " +str(itm2) +" " +str(itm3) +" " +str(itm4) +" " +str(itm5) +" " +str(itm6) +" ")
        if 1 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['sword'] = True
        else:
            inventory['sword'] = False

        if 2 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['axe'] = True
        else:
            inventory['axe'] = False

        if 3 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['shovel'] = True
        else:
            inventory['shovel'] = False

        if 4 in(itm1, itm2, itm3, itm4, itm5, itm6):
            inventory['bow'] = True
        else:
            inventory['bow'] = False
            
            
    def run(self):
        screenMode = pygame.RESIZABLE
        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip("maps/")
        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True
        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))        
        minutes = 0
        try:
            while self.running:                  
                dt = (clock.tick() / 500)
                clock.tick(self.fps)
                if self.counter2 == 5:
                    heroPos = self.hero.position
                    self.animation(self.direction, self.counter)
                    self.counter += 1
                    self.counter2 = 0
                    guiX = (dispWidth / 2) - 175
                    guiY = (dispHeight / 2) - 165
                    self.hero.position = heroPos
                self.counter2 += 1
                if self.counter > 9:
                    self.counter = 1
                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds
                self.group.remove(self)
                self.group.add(self.hero)


                    
                if debug == True:
                    location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white'))
                    fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50,100))
                    screen.blit(fps, (50, 50))
                    screen.blit(location, (50,75))
                    screen.blit(mapdebug, (50, 125))
                    

                if self.menu == "inventory":
                    screen.blit(load_image(os.path.join("Images", "transparent.png")),( 0, 0))
                    screen.blit(load_image(os.path.join("Images", "inventory.png")),(guiX, guiY))
                    if inventory["sword"] == True:
                        screen.blit(load_image(os.path.join("Images", "sword.png")),( guiX + 16, guiY + 168))
                    if inventory["axe"] == True:
                        screen.blit(load_image(os.path.join("Images", "axe.png")),( guiX + 52, guiY + 168))
                    if inventory["bow"] == True:
                        screen.blit(load_image(os.path.join("Images", "bow.png")),( guiX + 88, guiY + 168))
                    if inventory["shovel"] == True:
                        screen.blit(load_image(os.path.join("Images", "shovel.png")),( guiX + 124, guiY + 168))
                    
                pygame.display.update()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()
示例#6
0
class QuestGame:
    """This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """

    map_path = RESOURCES_DIR / "grasslands.tmx"

    def __init__(self, screen: pygame.Surface) -> None:
        self.screen = screen

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.map_path)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = []
        for obj in tmx_data.objects:
            self.walls.append(pygame.Rect(obj.x, obj.y, obj.width, obj.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(
            map_data, screen.get_size(), clamp_camera=False, tall_sprites=1
        )
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.hero = Hero()

        # put the hero in the center of the map
        self.hero.position = self.map_layer.map_rect.center
        self.hero._position[0] += 200
        self.hero._position[1] += 400

        # add our hero to the group
        self.group.add(self.hero)

    def draw(self) -> None:

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(self.screen)

    def handle_input(self) -> None:
        """Handle pygame input events"""
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

                elif event.key == K_EQUALS:
                    self.map_layer.zoom += 0.25

                elif event.key == K_MINUS:
                    value = self.map_layer.zoom - 0.25
                    if value > 0:
                        self.map_layer.zoom = value

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                self.screen = init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        if pressed[K_UP]:
            self.hero.velocity[1] = -HERO_MOVE_SPEED
        elif pressed[K_DOWN]:
            self.hero.velocity[1] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[1] = 0

        if pressed[K_LEFT]:
            self.hero.velocity[0] = -HERO_MOVE_SPEED
        elif pressed[K_RIGHT]:
            self.hero.velocity[0] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[0] = 0

    def update(self, dt):
        """Tasks that occur over time should be handled here"""
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def run(self):
        """Run the game loop"""
        clock = pygame.time.Clock()
        self.running = True

        from collections import deque

        times = deque(maxlen=30)

        try:
            while self.running:
                dt = clock.tick() / 1000.0
                times.append(clock.get_fps())

                self.handle_input()
                self.update(dt)
                self.draw()
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#7
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    counter = 1
    counter2 = 1

    def __init__(self, state):
        if state == False:
            self.fullscreen = False
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            # create all the directio variables
            self.direction = "still"
            self.EntityDirection = "still"
            self.EntityDirection1, self.EntityDirection2 = "still", "still"
            self.fps = 1000

            self.bypass = False

            entityPos1, heroPos1 = False, False

            # load data from pytmx
            tmx_data = load_pygame(self.filename)
            self.tmx_data = tmx_data

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(
                    pygame.Rect(object.x, object.y, object.width,
                                object.height))

            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                       screen.get_size())
            self.map_layer.zoom = 2

            self.group = PyscrollGroup(map_layer=self.map_layer,
                                       default_layer=4)
            self.hero = Hero('Tiles/hero/character_still.png')
            self.entity = Entity('Tiles/hero/character_still.png')
            self.hero.position = stats['pos']
            self.entity.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)
            #self.group.add(self.entity)

            self.entVel = (0, 0)

    def deep_thought(self):  # The 'AI' function, needs work
        if self.counter2 % 75 == 0 or self.bypass == True:
            self.bypass = False
            if random.randint(0, 1) == 1:
                self.entity.velocity[0], self.entity.velocity[1] = 0, 0
            movement = random.choice([
                "self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'",
                "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'",
                "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'",
                "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'"
            ])
            exec(movement)

    def EntityAnimation(self, direction, number, character="hero"):
        self.entVel = self.entity.velocity

        self.counter += 1
        if self.EntityDirection1 == "still" and self.EntityDirection2 == "still":
            if self.EntityDirection == "left":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_left/walking_left1.png')
            if self.EntityDirection == "right":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_right/walking_right1.png')
            if self.EntityDirection == "up":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_up/walking_up1.png')
            if self.EntityDirection == "down":
                self.entity = Entity('Tiles/' + character +
                                     '/walking_down/walking_down1.png')
        else:
            self.entity = Entity('Tiles/' + character + '/walking_' +
                                 direction + '/walking_' + direction +
                                 str(number) + '.png')
        self.entity.velocity = self.entVel

    def EntMoveBack(self):
        #self.deep_thought(self, True) # Comment this to disable the 'AI'
        pass

    def map_change(self, map, target=False):  # Does what it says on the tin
        mapfile = get_map(map)
        tmx_data = load_pygame(mapfile)
        self.tmx_data = tmx_data
        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # creates new 'camera'
        self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
        self.map_layer.zoom = 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

        #creates a new Hero to go on our new camera
        self.hero = Hero('Tiles/hero/character_still.png')
        try:
            self.hero.position = (target)
        except TypeError:
            self.hero.position = self.map_layer.map_rect.center
        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip(
            "m")  # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")

    def switcher(
        self
    ):  # Bunch of IF statements to decide if we're at a door or not, then changes the map.
        if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \
           len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType):
            heroPos = [0, 0]
            heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[
                1]
            for i in range(len(objectX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= int(
                            objectX[i]) <= self.hero.position[0] + 15:
                        if self.hero.position[1] - 15 <= int(
                                objectY[i]) <= self.hero.position[1] + 15:
                            if objectType[i] == "door":
                                used[i] = True
                                self.map_change(targetMapFile[i])
                                self.map = targetMap[i]
                                stats['map'] = targetMapFile[i]
                                heroPos = (int(targetPosX[i]),
                                           int(targetPosY[i]))
                                self.animation(animationDirection[i], 1)
                                self.hero.position = heroPos
                                return False
                            elif objectType[i] == "chest":
                                keyset, self.menu = "chest", "chest"
                                if used[i] == False:
                                    if chestContents[i] == None and used[
                                            i] == False:
                                        used[i] = True
                                        pickle.dump(
                                            used,
                                            open(
                                                os.path.join(
                                                    "data", "saves",
                                                    "used.dat"), "wb"))
                                        chestContents[i] = self.genchests()
                                        pickle.dump(
                                            chestContents,
                                            open(
                                                os.path.join(
                                                    "data", "saves",
                                                    "chestContents.dat"),
                                                "wb"))
                                self.chestNo = i
                            return False

    def generate_surrounding_maps(self):
        heroPos = [0, 0]
        heroPos = self.hero.position
        if int(self.hero.position[0]) in range((self.tmx_data.width * 32) - 64,
                                               (self.tmx_data.width * 32)):
            target = (32, heroPos[1])
            self.grid[0] = self.grid[0] + 1
            try:
                self.map_change(
                    str(self.grid[0] + 1) + ", " + str(self.grid[1]) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                self.animation("right", 1)
                target = (32, heroPos[1])
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(
            (self.tmx_data.height * 32) - 64, self.tmx_data.width * 32):
            target = (heroPos[0], 32)
            self.grid[1] = self.grid[1] + 1
            try:
                self.map_change(
                    str(self.grid[0]) + ", " + str(self.grid[1] + 1) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("up", 1)

            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[0]) in range(0, 64):
            target = (self.tmx_data.width * 32 - 32, heroPos[1])
            self.grid[0] = self.grid[0] - 1
            try:
                self.map_change(
                    str(self.grid[0] - 1) + ", " + str(self.grid[1]) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("left", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(0, 64):
            target = (heroPos[0], self.tmx_data.height * 32 - 32)
            self.grid[1] = self.grid[1] - 1
            try:
                self.map_change(
                    str(self.grid[0]) + ", " + str(self.grid[1] - 1) + ".tmx",
                    target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[
                    0], self.hero.position[1]
                self.animation("down", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        else:
            pass

    def generate_new_map(self, octaves, freq, area, target, position):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")

        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        for y in range(self.grid[1] + eval("-" + str(area)),
                       self.grid[1] + area):
            for x in range(self.grid[0] + eval("-" + str(area)),
                           self.grid[0] + area):
                if os.path.isfile("data/maps/" + str(x) + ", " + str(y) +
                                  ".tmx"):
                    pass
                else:
                    p = subprocess.Popen([
                        executeable, command,
                        ("data/maps/" + str(x) + ", " + str(y) + ".tmx"),
                        str(octaves),
                        str(freq),
                        str(x),
                        str(y)
                    ],
                                         close_fds=True)
        try:
            if p is not None:
                disp_width, disp_height = pygame.display.get_surface(
                ).get_size()
                #self.blit_inventory("speach", "Generating Map... Please Wait...")
                self.speach(disp_width, disp_height,
                            "Generating Map... Please Wait...")
                pygame.display.update()
                p.wait()
                self.map_change(
                    (str(target[0]) + ", " + str(target[1]) + ".tmx"),
                    position)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
        except UnboundLocalError:
            pass

    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def speach(self, dispWidth, dispHeight, text):
        ##        text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\
        ##                eu mea ullum legimus. Probo debitis te vel. Labores vulputate \
        ##                argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\
        ##                duo."
        screen.blit(
            pygame.transform.scale(
                load_image(os.path.join("images", "gui", "speach.png")),
                (dispWidth, 150)), (0, dispHeight - 150))
        text = textwrap.wrap(text, width=95)
        for i, line in enumerate(text):
            text_blit = pixel_font.render(line, False, pygame.Color('white'))
            screen.blit(text_blit, (60, dispHeight - 110 + 25 * i))

    def map_generate(self, output, octaves, freq, x, y):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())

        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")

        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        subprocess.Popen([
            executeable, command, output,
            str(octaves),
            str(freq),
            str(x),
            str(y)
        ],
                         close_fds=True)

    def handle_input(self, keyset):
        """ Handle pygame input events
        """

        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value
                        else:
                            self.map_layer.zoom = 0.1

                    elif event.key == K_KP0:
                        try:
                            if self.switcher() == True:
                                self.generate_surrounding_maps()
                        except FileNotFoundError:
                            print("Exception Caught")
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        pass

                    if event.key == K_ESCAPE:
                        for i in attack_stats_types:
                            stats[i] = attack_stats[i]
                        pickle.dump(
                            stats,
                            open(os.path.join("data", "saves", "save.dat"),
                                 "wb"))
                        pickle.dump(
                            inventory,
                            open(
                                os.path.join("data", "saves", "inventory.dat"),
                                "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset != "game":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        pass

                if keyset == "inventory":
                    if event.key == K_r:
                        self.genchests()

                if keyset == "chest":
                    if event.key == K_r:
                        chestContents[self.chestNo] = self.genchests()

                    if event.key == K_t:
                        if taken[self.chestNo] != True:
                            self.takeChest()
                            taken[self.chestNo] = True
                            pickle.dump(
                                taken,
                                open(
                                    os.path.join("data", "saves", "taken.dat"),
                                    "wb"))

                if keyset == "attack":
                    pass

                #Basically just debug keys
                if event.key == K_KP1:
                    self.menu = "game"
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.generate_new_map(4, 16, 3)
                    pass

                elif event.key == K_KP4:
                    self.map_generate(
                        str(self.grid[0]) + ", " + str(self.grid[1]) + ".tmx",
                        4, 16.0, self.grid[0], self.grid[1])
                    pass

                elif event.key == K_KP5:
                    self.enemy_stats = self.gen_enemy(attack_stats,
                                                      enemy_stats)
                    self.menu = "attack"
                    pass

                elif event.key == K_KP6:
                    print("X :" + str(int(self.hero.position[0])) + ", Y: " +
                          str(int(self.hero.position[1])) + ", Map: " +
                          self.map)
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass

                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    editor = db_interface.Editor()
                    conn = sqlite3.connect('data/saves/data.db')
                    c = conn.cursor()

                    for var in vars:
                        exec("del " + var + "[:]")
                        for data in c.execute(
                                "SELECT {} FROM csv".format(var)):
                            data = str(data[0])
                            exec("{}.append(\"{}\")".format(var, data))
                            pass

                elif event.key == K_F11:
                    for m in screeninfo.get_monitors():
                        displ = str(m)
                        w, h, mx, c = displ.split(", ")

                    if self.fullscreen:
                        self.fullscreen = False
                        screen = init_screen(
                            1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN)
                    else:
                        self.fullscreen = True
                        screen = init_screen(
                            w, h, pygame.HWSURFACE | pygame.RESIZABLE)

                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction1 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction1 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/hero/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/hero/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tileshero/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/hero/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/hero/walking_' + direction + '/walking_' +
                             direction + str(number) + '.png')

    def genchests(self):

        wr = WeightedRandomizer(itemsProbability)

        self.taken = False
        chest.clear()
        numItems = random.randint(1, random.randint(2, 4))
        if random.randint(0, 3) < 1:
            numItems += 1
        elif random.randint(0, 9) < 2:
            numItems += 2
        elif random.randint(0, 18) < 2:
            numItems += 5
        for i in range(0, numItems):
            item = wr.random()
            while item in chest:
                item = wr.random()
            chest.append(item)

        return chest

    def gen_enemy(self, player_stats, enemy_stat):
        stats = attack_stats_types
        stat = player_stats
        for i in range(len(player_stats)):
            j = stats[i]
            try:
                enemy_stat[
                    stats[i]] = int((stat[j] - (stat[j] * 0.2)) +
                                    random.randint(0, int(stat[j] * 0.4)))
            except TypeError:
                enemy_stat[j] = choice(attack_types)
        return enemy_stat
        pass

    def player_attack():
        type = None
        while type not in attack_types:
            type = input("[ QUESTION ] Enter attack type. ")
            if type not in attack_types:
                print(
                    "[ ERROR    ] Attack type {} not found. Must be {}".format(
                        type, attack_types))
            else:
                break
        return type
        pass

    def attack(self, attacker_stats, defender_stats, player_attack_type):
        fraction = attacker_stats['strength'] / defender_stats['blocking']
        print("[ INFO     ] Defender attack type: {}".format(
            defender_stats['attack']))
        if player_attack_type != defender_stats['attack']:
            if fraction > (0.8 + (randint(0, 40) / 100)):
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        elif player_attack_type == attacker_stats[
                'attack']:  # Better odds here
            if fraction > (0.9 + (randint(0, 40) / 100)):
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        else:
            if fraction > (0.70 +
                           (randint(0, 40) / 100)):  # Odds are worse here
                attacker_stats['health'] -= int(fraction * 10)
                pass  # Attacker Win
            else:
                defender_stats['health'] -= int(fraction * 10)
                pass  # Attacker Loss
        print("[ INFO     ] Attacker: {}  Defender: {}".format(
            attacker_stats['health'], defender_stats['health']))
        print("[ INFO     ] Health to be lost: {}".format(int(fraction * 10)))
        return attacker_stats, defender_stats

    def blit_inventory(self, screenMode, speach=None):
        if screenMode != "game":
            xCounter, counter, OverCounter = 0, 0, 0
            dispWidth, dispHeight = pygame.display.get_surface().get_size()
            guiX = (dispWidth / 2) - 175
            guiY = (dispHeight / 2) - 165
            screen.blit(
                load_image(os.path.join("images", "gui", "transparent.png")),
                (0, 0))
            screen.blit(
                load_image(os.path.join("images", "gui", screenMode + ".png")),
                (guiX, guiY))
        if screenMode == "inventory" or screenMode == "chest":
            dt = (clock.tick() / 500)
            clock.tick(self.fps)

            if len(inventory) > 0:
                for i in range(0, len(inventory)):
                    OverCounter += 1
                    if xCounter >= 9:
                        counter += 1
                        xCounter = 0
                    screen.blit(load_image(os.path.join("images", "items",\
                    str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter))
                    xCounter += 1
        if screenMode == "chest" and chestContents[self.chestNo] != None:
            itemNo = 0
            for i in range(0, len(chestContents[self.chestNo])):
                screen.blit(load_image(os.path.join("images", "items",\
                            items[str(chestContents[self.chestNo][i])]\
                            +".png")), (guiX + 123 + 36*itemNo,\
                            guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35))

                if itemNo < 2:
                    itemNo += 1
                else:
                    itemNo = 0

        if screenMode == "speach":
            self.speach(dispWidth, dispHeight, speach)
        if screenMode == "attack":
            picture = load_image(
                os.path.join("Tiles", "hero", "walking_down",
                             "walking_down1.png"))
            picture = pygame.transform.scale(picture, (100, 100))
            rect = picture.get_rect()
            rect = rect.move((guiX + 50, guiY + 28))
            screen.blit(picture, rect)
            text = font.render("Player : Enemy", True, pygame.Color('black'))
            screen.blit(text, (guiX + 172, guiY + 45))
            text = "Health: " + str(
                attack_stats['health']) + "    Skill: " + str(
                    attack_stats['skill']) + "    Attack: " + str(
                        attack_stats['attack'])
            text_render = pixel_font.render(text, False,
                                            pygame.Color('gray27'))
            screen.blit(text_render, (guiX + 20, guiY + 290))
            for i, attack in enumerate(attack_types):
                text = load_font(30, "data/PixelFont.ttf").render(
                    attack, False, pygame.Color('black'))
                screen.blit(text, (guiX + 172, guiY + 25 + 28 * (i + 2)))
            #
            if pygame.mouse.get_pressed()[0] == 1:
                #print(pygame.mouse.get_pos())
                mouse_pos = pygame.mouse.get_pos()
                if guiX + 160 < mouse_pos[0] and guiX + 330 > mouse_pos[0]:
                    for i, attack in enumerate(attack_types):
                        if guiY + 25 + 28 * (i + 2) < mouse_pos[1] and (
                                guiY + 25 + 28 * (i + 2)) + 28 > mouse_pos[1]:
                            print(attack)
                            self.attack(attack_stats, enemy_stats, attack)
                        else:
                            pass

            pass

    def takeChest(self):
        if len(inventory) < 27:
            if chestContents[self.chestNo] != None:
                for i in range(0, (len(chestContents[self.chestNo]))):
                    #print(i)
                    inventory.append(chestContents[self.chestNo][i])
                chestContents[self.chestNo][:] = []
            pickle.dump(
                chestContents,
                open(os.path.join("data", "saves", "chestContents.dat"), "wb"))

    def run(self):
        screenMode = pygame.RESIZABLE

        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True

        self.grid = [0, 0]

        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))
        minutes = 0

        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip(
            "m")  # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")

        try:
            while self.running:
                dt = (clock.tick() / 500)
                clock.tick(self.fps)

                if self.menu == "game":
                    #self.deep_thought()
                    if self.counter2 % 7 == 0:
                        heroPos = self.hero.position
                        self.animation(self.direction, self.counter)
                        self.hero.position = heroPos
                        #entityPos = self.entity.position
                        #self.EntityAnimation(self.EntityDirection, self.counter, "princess")
                        #self.entity.position = entityPos

                        self.counter += 1
                        guiX = (dispWidth / 2) - 175
                        guiY = (dispHeight / 2) - 165

                        self.group.remove(self.hero)
                        #self.group.remove(self.entity)
                        self.group.empty()
                        self.group.add(self.hero)
                        #self.group.add(self.entity)

                self.counter2 += 1
                if self.counter > 8:
                    self.counter = 1

                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds

                if debug == True and self.counter2 % 1 == 0:
                    location = font.render(
                        "Position: " +
                        str(round(round(self.hero.position[0], -1) / 10)) +
                        ", " +
                        str(round(round(self.hero.position[1], -1) / 10)),
                        False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False,
                                           pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    fps = font.render("FPS:" + str(int(clock.get_fps())),
                                      False, pygame.Color('white'))
                    screen.blit(fps, (50, 50))
                    screen.blit(playTime, (50, 100))
                    screen.blit(location, (50, 75))
                    screen.blit(mapdebug, (50, 125))

                    playTime = font.render(
                        "Timer: " + str(floor(minutes)) + " : " +
                        str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50, 100))

                self.blit_inventory(str(self.menu))

                pygame.display.update()
                #pygame,display.flip()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()
示例#8
0
class GameState(State):
    # Gamestate - run your stuff inside here (maybe another manager?
    # for your levelmanagment?)
    filename = get_map(MAP_FILENAME)
    def __init__(self, screen):
        State.__init__(self, screen)

        self.name = "GameState"
        self.description = "Draw your game inside here"

        # A whole Block just to display the Text ...
        self.font1 = pygame.font.SysFont("Monospaced", 50)
        self.font2 = pygame.font.SysFont("Monospaced", 32)
        # Render the text
        self.text1 = self.font1.render(self.name, True, (255,255, 255), (159, 182, 205))
        self.text2 = self.font2.render(self.description, True, (255,255, 255), (159, 182, 205))
        # Create Text-rectangles
        self.text1Rect = self.text1.get_rect()
        self.text2Rect = self.text2.get_rect()

        # Center the Text-rectangles
        self.text1Rect.centerx = self.screen.get_rect().centerx
        self.text1Rect.centery = self.screen.get_rect().centery

        self.text2Rect.centerx = self.screen.get_rect().centerx
        self.text2Rect.centery = self.screen.get_rect().centery+50

        self.screen_rect = screen.get_rect()
        self.done = False
        self.fps = 60
        self.done = False
        self.keys = pygame.key.get_pressed()
        # true while running
        self.running = False
         # load data from pytmx
        self.tmx_data = load_pygame(self.filename, pixelalpha=True)
        #print self.tmx_data.layers.TiledTileLayer.properties['under0']
        # setup level geometry with simple pygame rects, loaded from pytmx
        # create new data source for pyscroll
        self.map_data = pyscroll.data.TiledMapData(self.tmx_data)
        w, h = screen.get_size()
        # create new renderer (camera)
        # clamp_camera is used to prevent the map from scrolling past the map's edge
        # cambiar el 1 por el tamano de zoom
        self.map_layer = pyscroll.BufferedRenderer(self.map_data,
                                                   (w / 1, h / 1),
                                                   clamp_camera=True)
        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)
        #self.hero = Hero()
        # put the hero in the center of the map
        #self.hero.position = self.map_layer.map_rect.center


    def render(self, screen):
        # Rendering the State
        pygame.display.set_caption(self.name +"  "+self.description)
        screen.fill((20, 20, 20))

        self.screen.blit(self.text1, self.text1Rect)
        self.screen.blit(self.text2, self.text2Rect)

    def draw(self, surface):

        # center the map/screen on our Hero
        #self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def update(self):
        clock = pygame.time.Clock()
        scale = pygame.transform.scale
        self.running = True

        try:
            while self.running:
                dt = clock.tick() / 1000.

                self.draw(temp_surface)
                scale(temp_surface, self.screen.get_size(), self.screen)
                pygame.display.flip()
                #self.clocky.tick(self.fps)
                #self.display_fps()

        except KeyboardInterrupt:
            self.running = False
        pass

    def handle_events(self,events):
        # every State has its own eventmanagment
        for e in events:
            if e.type == QUIT:
                print ("Pressed Quit (Window)")
                return False

            elif e.type == KEYDOWN:

                if e.key == K_ESCAPE:
                    print ("Pressed Quit (Esc)")
                    return False
                # change State if user presses "2"
                if e.key == K_2:
                    self.manager.change(MenuState(self.screen))
                # change State if user presses "1"
                if e.key == K_1:
                    self.manager.change(IntroState(self.screen))
        return True
示例#9
0
class game_scene(object):
    def __init__(self, manager, engine, map_name, entrance_name):
        self._manager = manager
        self.finished = False
        self._engine = engine

        # Load images for UI
        self._ui_spritesheet = spritesheet.spritesheet('ui.png')
        self._ui_images = self._ui_spritesheet.load_all(
            (0, 0, DEFAULT_SPRITE_WIDTH, DEFAULT_SPRITE_HEIGHT), ALPHA_COLOUR)

        # Load the map
        self.load_map(map_name, entrance_name, self._engine.screen.get_size())

    def load_map(self, name, entrance_name, display_size):
        filename = get_map(name)

        # load data from pytmx
        tmx_data = load_pygame(filename)

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   display_size,
                                                   clamp_camera=True,
                                                   tall_sprites=1)
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        # put the hero in tile with name matching entrance_name
        player_start = tmx_data.get_object_by_name(entrance_name)
        self._engine.hero.position = [player_start.x, player_start.y]

        # add our hero to the group
        self.group.add(self._engine.hero)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        self.npcs = list()
        self.enemies = list()
        self.triggers = list()
        temp_npcs = list()
        # Also a pathfinding grid
        self.pathfinding_grid = pathfinding.weighted_grid(
            tmx_data.width, tmx_data.height)
        for object in tmx_data.objects:
            if object.type == 'wall':
                self.walls.append(
                    pygame.Rect(object.x, object.y, object.width,
                                object.height))
                # Add walls to the pathfinding grid
                grid_x = int(object.x / tmx_data.tilewidth)
                grid_y = int(object.y / tmx_data.tileheight)
                grid_width = int(object.width / tmx_data.tilewidth)
                grid_height = int(object.height / tmx_data.tileheight)
                for y in range(0, grid_height):
                    for x in range(0, grid_width):
                        self.pathfinding_grid.walls.append(
                            (grid_x + x, grid_y + y))
            elif object.type == 'npc' or object.type == 'enemy':
                # Process NPCs and enemies after walls are determined
                temp_npcs.append(object)
            elif object.type == 'trigger':
                self.triggers.append(
                    trigger.trigger(object.x, object.y, object.width,
                                    object.height, object.properties))

        # Process NPCs and enemies
        for object in temp_npcs:
            target_grid_x = int(object.target_x)
            target_grid_y = int(object.target_y)
            target_x = target_grid_x * tmx_data.tilewidth
            target_y = target_grid_y * tmx_data.tileheight
            origin_grid_x = int(object.x / tmx_data.tilewidth)
            origin_grid_y = int(object.y / tmx_data.tileheight)
            # Pathfinding
            came_from, cost_so_far = pathfinding.a_star_search(
                self.pathfinding_grid, (origin_grid_x, origin_grid_y),
                (target_grid_x, target_grid_y))
            path = pathfinding.reconstruct_path(came_from,
                                                (origin_grid_x, origin_grid_y),
                                                (target_grid_x, target_grid_y))
            path = [(t[0] * tmx_data.tilewidth, t[1] * tmx_data.tileheight)
                    for t in path]
            # Load sprite from JSON
            if object.type == 'npc':
                npc = character.npc(object.name, path)
                self.npcs.append(npc)
                self.group.add(npc)
            elif object.type == 'enemy':
                enemy = character.enemy(object.name, path)
                self.enemies.append(enemy)
                self.group.add(enemy)

        # Play background music
        if 'background_music' in tmx_data.properties:
            self._engine.play_music(tmx_data.properties['background_music'])

        # Initialise map
        self.update(0)

    def display_text(self, text):
        message_box = (0, 1 - DIALOG_HEIGHT, 1, DIALOG_HEIGHT)
        self._manager.append(
            text_scene.text_scene(self._manager, text, message_box))

    def interaction(self):
        index = self._engine.hero.interaction_rect.collidelist(self.npcs)
        # NPC
        if index > -1:
            self.display_text(self.npcs[index].name + ': ' +
                              self.npcs[index].dialogue)
        else:
            # Events, objects
            index = self._engine.hero.interaction_rect.collidelist(
                self.triggers)
            if index > -1:
                trigger = self.triggers[index]
                if not trigger.condition or eval(trigger.condition):
                    if trigger.on_interact == 'message':
                        self.display_text(trigger.message_text)
                    elif trigger.on_interact == 'load_map':
                        new_map = game_scene(self._manager, self._engine,
                                             trigger.map_name,
                                             trigger.entrance_name)
                        fade = fade_transition.fade_transition(
                            self._manager, FADE_TIME, FADE_COLOUR)
                        self._manager.change(new_map, fade)
                    elif trigger.on_interact == 'set':
                        exec_string = 'self.' + trigger.variable_name \
                            + ' = ' + trigger.value
                        exec(exec_string)
                        self.display_text(trigger.message_text)
                else:
                    self.display_text(trigger.error_text)

    def pause(self):
        pass

    def resume(self):
        pass

    def end(self):
        self.finished = True

    def draw_ui(self, surface):
        # Health
        full_count = int(self._engine.hero.health / 2)
        half_count = self._engine.hero.health % 2
        empty_count = int(
            (self._engine.hero.max_health - self._engine.hero.health) / 2)
        for i in range(0, full_count):
            #x = surface.get_width() - ((i / 2 + 1) * self._ui_images[0].get_width())
            x = i * self._ui_images[2].get_width()
            y = 0
            surface.blit(self._ui_images[2], (x, y))
        for i in range(0, half_count):
            x = (i + full_count) * self._ui_images[1].get_width()
            y = 0
            surface.blit(self._ui_images[1], (x, y))
        for i in range(0, empty_count):
            x = (i + full_count + half_count) * self._ui_images[0].get_width()
            y = 0
            surface.blit(self._ui_images[0], (x, y))

    def pause_menu(self):
        pause_menu = menu_scene.menu_scene(self._manager, PAUSE_MENU_IMAGE,
                                           PAUSE_MENU_RECT)
        pause_menu.append("Resume Game", True, pause_menu.end)
        pause_menu.append(
            "Quit", True,
            lambda: pygame.event.post(pygame.event.Event(pygame.QUIT)))
        self._manager.append(pause_menu)

    def game_over(self):
        self.end()
        message_box = (0, 1 - DIALOG_HEIGHT, 1, DIALOG_HEIGHT)
        self._manager.append(
            text_scene.text_scene(self._manager, ["GAME OVER", ":[ :[ :[ :["],
                                  message_box))

    def _button_attack(self):
        self._engine.hero.attack()

    def handle_input(self, events, pressed_keys):
        for event in events:
            if event.type == R_INPUT_EVENT:
                if event.button == buttons.R_A:
                    self.interaction()
                if event.button == buttons.R_B:
                    self._button_attack()
                if event.button == buttons.R_START:
                    self.pause_menu()
#                elif event.key == K_EQUALS:
#                    self.map_layer.zoom += .25
#
#                elif event.key == K_MINUS:
#                    value = self.map_layer.zoom - .25
#                    if value > 0:
#                        self.map_layer.zoom = value
#
#            # this will be handled if the window is resized
#            elif event.type == VIDEORESIZE:
#                scope.resize(event.w, event.h)
#                self.map_layer.set_size((event.w, event.h))
#
# using get_pressed is slightly less accurate than testing for events
# but is much easier to use.
        if pressed_keys[buttons.R_UP]:
            self._engine.hero.move_up()
        elif pressed_keys[buttons.R_DOWN]:
            self._engine.hero.move_down()
        else:
            self._engine.hero.stop_moving_vertical()

        if pressed_keys[buttons.R_LEFT]:
            self._engine.hero.move_left()
        elif pressed_keys[buttons.R_RIGHT]:
            self._engine.hero.move_right()
        else:
            self._engine.hero.stop_moving_horizontal()

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)
        # Check if NPCs are colliding with the hero
        for npc in self.npcs:
            if npc.feet.colliderect(self._engine.hero.feet):
                npc.move_back(dt)
                self._engine.hero.move_back(dt)
        for enemy in self.enemies:
            if enemy.alive and enemy.rect.colliderect(
                    self._engine.hero.hitbox):
                enemy.take_damage(
                    self._engine.hero.damage,
                    calculate_knockback(self._engine.hero.position,
                                        enemy.position,
                                        self._engine.hero.weapon.knockback))
                if enemy.dead:
                    enemy.remove(self.group)
            elif enemy.alive and enemy.feet.colliderect(
                    self._engine.hero.feet):
                enemy.move_back(dt)
                self._engine.hero.take_damage(
                    enemy.damage,
                    calculate_knockback(enemy.position,
                                        self._engine.hero.position,
                                        enemy.knockback))
            enemy.threat_target = self._engine.hero.position

        # If the player is dead, game over
        if self._engine.hero.dead:
            self.game_over()

    def draw(self, surface):
        # center the map/screen on our Hero
        self.group.center(self._engine.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

        # Draw user interface
        self.draw_ui(surface)
示例#10
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    def __init__(self):

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(pygame.Rect(
                object.x, object.y,
                object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.hero = Hero()

        # put the hero in the center of the map
        self.hero.position = self.map_layer.map_rect.center

        # add our hero to the group
        self.group.add(self.hero)

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self):
        """ Handle pygame input events
        """
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

                elif event.key == K_EQUALS:
                    self.map_layer.zoom += .25

                elif event.key == K_MINUS:
                    value = self.map_layer.zoom - .25
                    if value > 0:
                        self.map_layer.zoom = value

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        if pressed[K_UP]:
            self.hero.velocity[1] = -HERO_MOVE_SPEED
        elif pressed[K_DOWN]:
            self.hero.velocity[1] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[1] = 0

        if pressed[K_LEFT]:
            self.hero.velocity[0] = -HERO_MOVE_SPEED
        elif pressed[K_RIGHT]:
            self.hero.velocity[0] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[0] = 0

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def run(self):
        """ Run the game loop
        """
        clock = pygame.time.Clock()
        self.running = True

        try:
            while self.running:
                dt = clock.tick() / 1000.

                self.handle_input()
                self.update(dt)
                self.draw(screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#11
0
class MainGame:

    filename = load_map(MAP_FILENAME)

    def __init__(self):

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # set the current resolution
        self.res = get_screen_res()

        self.up = self.down = self.right = self.left = 0  # set up for declaration
        for key in config.items('KEY_CONFIG'):  # declare config keys
            exec('self.' + key[0] + ' = K_' + key[1])

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for obj in tmx_data.objects:
            self.walls.append(pygame.Rect(
                    obj.x, obj.y,
                    obj.width, obj.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        # Define characters
        self.prototype = Prototype(res=self.res)
        self.enemy = Enemy(enemy_type=enemy.suicide_explode, res=self.res)

        # Set character positions
        self.prototype.position = self.map_layer.map_rect.center
        self.enemy.position = (300, 300)

        # add our hero to the group
        self.group.add(self.enemy)
        self.group.add(self.prototype)

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.prototype.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self):
        # Handle pygame input events

        poll = pygame.event.poll

        event = poll()
        while event:
            if hasattr(event, "pos"):
                mx, my = event.pos
                self.prototype.m_pos = [mx, my]

            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

                elif event.key == K_EQUALS:
                    self.map_layer.zoom += .25

                elif event.key == K_MINUS:
                    value = self.map_layer.zoom - .25
                    if value > 0:
                        self.map_layer.zoom = value

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        if pressed[self.up]:
            self.prototype.velocity[1] = -movement_speed
        elif pressed[self.down]:
            self.prototype.velocity[1] = movement_speed
        else:
            self.prototype.velocity[1] = 0

        if pressed[self.left]:
            self.prototype.velocity[0] = -movement_speed
        elif pressed[self.right]:
            self.prototype.velocity[0] = movement_speed
        else:
            self.prototype.velocity[0] = 0

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)
        global i
        i += 1
        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.hit_box.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def run(self):
        """ Run the game loop
        """
        clock = pygame.time.Clock()
        self.running = True
        try:
            while self.running:
                dt = clock.tick() / 1000.

                self.handle_input()
                self.update(dt)
                self.draw(screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#12
0
class Game(object):
    """This class is essentially the Wizard of Oz"""
    def __init__(self,
                 charactername='Zaxim',
                 username='******',
                 password='******',
                 ip='127.0.0.1',
                 current_room=None):
        # Client for issuing requests to server and receiving responses
        self.client = GameClient(charactername=charactername,
                                 username=username,
                                 password=password,
                                 ip=ip)

        # Remote sprite controller
        self.rsc = RemoteSpriteController(self)

        # Rate that chat polls are sent to server
        self.poll_frequency = POLL_RATE
        self.poll_timer = self.poll_frequency
        self.out_going_message = None

        # true while running
        self.running = False

        # load data from pytmx
        if not current_room:
            current_room = STARTING_ROOM
        tmx_data = load_pygame(current_room)
        self.map_data = tmx_data

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
        self.map_layer.zoom = MAP_ZOOM

        # pyscroll supports layered rendering.
        self.group = PyscrollGroup(map_layer=self.map_layer,
                                   default_layer=DEFAULT_LAYER)

        # GUI ELEMENTS
        # Create text box
        text_box_x, text_box_y = self.screen_coords((3, 95))
        self.text_box = eztext.Input(maxlength=90,
                                     color=(255, 255, 255),
                                     x=text_box_x,
                                     y=text_box_y,
                                     font=pygame.font.Font(FONT, 22),
                                     prompt=': ')
        # Create InputLog
        self.inputlog = InputLog(coords=self.screen_coords((3, 88)),
                                 max_length=10,
                                 size=18,
                                 spacing=18,
                                 font=FONT)
        # Create Combatlog
        self.combatlog = InputLog(coords=(1050, 860),
                                  max_length=10,
                                  size=22,
                                  spacing=18,
                                  font=FONT)

        # Login to server:
        # Get room instance and player object id
        response = self.client.login()
        id = response['response']['id']
        sprite = response['response']['sprite']
        coords = response['response']['coords']
        self.hero = Hero(game=self, id=id, sprite=sprite, coords=coords)

        # Player input module
        self.input = PlayerController(game=self)

        # This is late -- ??? TODO This is garbage, current room needs to be discovered way earlier from login()
        self.current_room = response['response']['current_room']
        self.hero.position = STARTING_POSITION
        self.group.add(self.hero.remotesprite)

        self.rsc.initialize()

    @property
    def screen_size(self):
        return pygame.display.Info().current_w, pygame.display.Info().current_h

    @property
    def map_size(self):
        return self.map_data.width, self.map_data.height

    @property
    def charactername(self):
        return self.client.charactername

    def screen_coords(self, coords):
        """
        :param coords: percentage of each axis.  i.e. (50, 50) based on MAP position.
        :return: Actual co-ords per resolution
        """
        screen_x, screen_y = self.screen_size
        new_x = (coords[0] / 100) * screen_x
        new_y = (coords[1] / 100) * screen_y
        return new_x, new_y

    def poll_server(self, dt=60):
        """ get remotesprite coordinate updates from server and pass to remotesprite controller """
        self.poll_timer -= dt / 50.
        if self.poll_timer <= 0:
            self.poll_timer = self.poll_frequency
            # Interface with RemoteSpriteController and update all lifeform coords
            self.update_lifeforms()
            # Update target if hero has one
            self.hero.tgh.update_target()
            # Update our Hero's armor
            equipment_graphics = self.hero.remoteinventory.equipped_graphics()
            self.hero.remotesprite.visualequipment.update_sprites(
                equipment_graphics)
            # TODO: Update remote player's inventory graphics

    def update_lifeforms(self):
        """Update co-ordinates of all remote sprites with new information from server, also updates chat que and other
        important information from the server """
        # Update data on all lifeforms in room
        r = self.client.send('get_roomdata')
        coords_dict = r['response']['coords']
        if coords_dict:
            self.rsc.update_coords(coords_dict)

        # Update chat messages
        messages = r['response']['messages']
        for message in messages:
            self.inputlog.add_line(string=message['message'],
                                   color=message['color'])

        # Update remotesprite visual equipment (for remote players)
        payloads = r['response']['payloads']
        for payload in payloads:
            if payload['tag'] == 'visualequipment':
                playerid = payload['data']['playerid']
                if playerid == self.hero.id:
                    continue
                equip_data = payload['data']['visualequipment']
                remotesprite = self.rsc.remotesprites[playerid]
                graphics = [item for item in equip_data]
                if not remotesprite.visualequipment:
                    remotesprite.visualequipment = VisualEquipment(
                        remotesprite=remotesprite, group=self.group)
                remotesprite.visualequipment.update_sprites(graphics)

    def update(self, dt):
        """ Tasks that occur over time should be handled here"""
        # self.hero.remotesprite.visualequipment.update()
        # update all sprites in game world
        self.group.update(dt)
        # update camera position (follows player)
        self.hero.camera.update(dt)
        # move player (including animation) if we're moving
        self.move(dt)
        # perform auto attack if we're autoattacking
        self.autoattack(dt)

    def move(self, dt):
        self.hero.move_timer -= dt / 100.
        if self.hero.moving:
            distance_x, distance_y = (self.hero.target_coords[0] - self.hero.x,
                                      self.hero.target_coords[1] - self.hero.y)
            stepx, stepy = (negpos(distance_x), negpos(distance_y))

            self.hero.x += stepx
            self.hero.y += stepy

            if self.hero.move_timer <= 0:
                self.hero.moving = False
                self.hero.position = self.hero.target_coords
                r = self.client.send('update_coords',
                                     [self.hero.x, self.hero.y])
                self.hero.move_time = r['response']['move_time']
                self.hero.attack_time = r['response']['attack_time']

    def autoattack(self, dt):
        if self.hero.attacking:
            self.hero.attack_timer -= dt / 100.
            if self.hero.attack_timer <= 0:
                self.hero.attack_timer = self.hero.attack_time
                if self.hero.tgh.target:
                    if point_distance(self.hero.coords,
                                      self.hero.tgh.coords) < 14:
                        self.client.send('attack', self.hero.tgh.id)

    def draw(self, surface):
        # center the map/screen on our Hero
        self.group.center(self.hero.camera.rect.center)

        # draw the Pyscroll map group
        self.group.draw(surface)

    def run(self):
        """ Run the game loop"""
        clock = pygame.time.Clock()
        self.running = True

        pygame.mouse.set_visible(False)

        from collections import deque
        times = deque(maxlen=30)

        try:
            while self.running:
                dt = clock.tick(60)
                times.append(clock.get_fps())

                # Update From Server
                try:
                    self.poll_server(dt)
                except PacketSizeMismatch:
                    self.inputlog.add_line('Packet size mismatch!! Ignoring')

                # Handle input and render
                self.input.handle_input(dt)
                self.update(dt)
                self.draw(screen)

                if self.hero.particle:
                    self.hero.particle.update()

                # blit GUI objects to screen
                self.text_box.draw(screen)
                self.inputlog.draw(screen)
                self.combatlog.draw(screen)
                self.hero.tgh.display.draw(screen)

                # debug draw co-ordinates
                if DEBUG_MODE:

                    # # pos = [coord/16 for coord in self.hero.position]
                    # draw_text('hero.position:. . . . {0}'.format(str(self.hero.position)), screen, coords=(10, 10))
                    # draw_text('delta t:. . . . . . . {0}'.format(str(dt)), screen, coords=(10, 40))
                    # draw_text('server poll:. . . . . {0}'.format(str(self.poll_timer)), screen, coords=(10, 55))
                    # draw_text('moving: . . . . . . . {0}'.format(str(self.hero.moving)), screen, coords=(10, 70))
                    # draw_text('target_coords:. . . . {0}'.format(str(self.hero.target_coords)), screen, coords=(10, 85))
                    # draw_text('map_zoom: . . . . . . {0}'.format(str(self.map_layer.zoom)), screen, coords=(10, 100))
                    # draw_text('screen size:. . . . . {0}'.format(str(self.screen_size)), screen, coords=(10, 115))
                    # draw_text(str(pygame.display.Info().current_w), screen, coords=(10, 130))
                    #
                    # draw_text('Target ID: ', screen, coords=(10, 10))
                    # draw_text('Name: ', screen, coords=(10, 25))
                    # draw_text('Stats: ', screen, coords=(10, 40))

                    # draw_text('Center Offset: {0}'.format(offset), screen, coords=(10, 55))
                    # draw_text('MousePos: {0}'.format(pygame.mouse.get_pos()), screen, coords=(10, 70))
                    # draw_text('MousePosC: {0},{1}'.format(new_x, new_y), screen, coords=(10, 85))
                    # draw_text('PlayerCoords: {0}'.format(self.hero.coords), screen, coords=(10, 100))
                    # draw_text('CursorCoords: {0}'.format(cursor_coords), screen, coords=(10, 115))
                    # draw_text('Zoom: {0}'.format(zoom), screen, coords=(10, 130))

                    #draw_text('Nearby Lifeforms: {0}'.format(self.hero.nearby_lifeforms), screen, coords=(10, 130))

                    # if self.hero.tgh.target:
                    #     distance = point_distance(self.hero.coords, self.hero.tgh.coords)
                    #     draw_text('Target Distance: {0}'.format(distance), screen, coords=(10, 145))
                    #
                    # draw_text('Attacking: {0}'.format(self.hero.attacking), screen, coords=(10, 160))
                    pass

                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#13
0
class Level:
    """
    Class that holds map, and any game object that should be rendered or updated
    """
    def __init__(self, screen_size, logic_manager):
        self._logic_manager = logic_manager
        self.screen_size = screen_size
        self.tmx_data = None
        self.map_data = None
        self.map_layer = None
        self.group = None
        self.paths = []
        self.base = None

    def load(self, filename):
        """
        Loads map
        :param filename:
        :return:
        """
        self.tmx_data = load_pygame(filename)
        self.map_data = TiledMapData(self.tmx_data)
        self.map_layer = BufferedRenderer(self.map_data,
                                          self.screen_size, alpha=True)
        self.group = PyscrollGroup(map_layer=self.map_layer)
        Camera.set_up(self.group, self.map_layer, self.screen_size)
        for obj in self.tmx_data.get_layer_by_name("paths"):
            self.paths.append(obj.points)

        for obstacle in self.obstacle_iterator():
            obstacle.rect = Rect(obstacle.x, obstacle.y, obstacle.width,
                                 obstacle.height)

        for actor in self.tmx_data.get_layer_by_name("actors"):
            if actor.name == 'base':
                self.base = Base()
                self.base.position = Vector2(actor.x, actor.y)
                self.base.team = PLAYER_TEAM
                self.add(self.base)

    def add(self, obj):
        """
        Add actor
        :param obj:
        :return:
        """
        self.group.add(obj, layer=self.get_layer_index("actors"))
        self._logic_manager.on_object_added_to_scene(obj)

    def add_obstacle(self, obstacle):
        """
        Add obstacle
        :param obstacle:
        :return:
        """
        self.tmx_data.get_layer_by_name("obstacles").append(obstacle)

    def actor_iterator(self):
        """
        Returns iterator that goe through actors
        :return:
        """
        for o in self.group.sprites():
            if isinstance(o, Actor):
                yield o

    def obstacle_iterator(self):
        """
        Returns iterator that goes through obstacles
        :return:
        """
        for obstacle in self.tmx_data.get_layer_by_name("obstacles"):
            yield obstacle

    def get_layer_index(self, layer_name):
        """
        Returns index of layer by name
        :param layer_name:
        :return:
        """
        for i, layer in enumerate(self.tmx_data.layers):
            if layer.name == layer_name:
                return i
        return -1

    def is_rectangle_colliding(self, rectangle):
        """
        Checks if rect is colliding with any obstacle
        :param rectangle:
        :return:
        """
        for obstacle in self.obstacle_iterator():
            if rectangle.colliderect(obstacle.rect):
                return True
        return False

    def get_actor_on_position(self, position, lambda_filter=None):
        """
        Checks if given position collides with any actor and returns it
        :param position:
        :param lambda_filter:
        :return:
        """
        if lambda_filter is not None:
            for actor in self.actor_iterator():
                if actor.rect.collidepoint(position.x,
                                           position.y) and lambda_filter(actor):
                    return actor
        else:
            for actor in self.actor_iterator():
                if actor.rect.collidepoint(position.x, position.y):
                    return actor
        return None

    def update(self, dt):
        """
        Updates level
        :param dt:
        :return:
        """
        self.group.update(dt)
        for obj in self.actor_iterator():
            if obj.state != ActorState.DEATH:
                visible = pygame.sprite.spritecollide(obj, self.group.sprites(),
                                                      False, is_visible)
                obj.actors_in_attack_range = visible

        for new_object in GameObject.objects_to_create:
            self.add(new_object)

        GameObject.objects_to_create.clear()

    def draw(self, surface):
        """
        Draw level objects
        :param surface:
        :return:
        """
        self.group.draw(surface)
示例#14
0
class Game(object):

    filename = get_map(MAP_FILENAME)

    def __init__(self):

        # true while running
        self.currentAnim = CurrentAnim.RIGHT
        # load data from pytmx
        tmx_data = load_pygame(self.filename)
        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()

        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)
        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   screen.get_size(),
                                                   clamp_camera=False,
                                                   tall_sprites=0)
        self.map_layer.zoom = 1.8

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=1)

        self.doorPosX = 157
        self.doorPosY = 208
        self.offset = 0

        for j in range(2):
            for i in range(39):
                doors.append(Door(self.doorPosX, self.doorPosY))
                self.doorPosY += 113 - self.offset
                self.offset += 0.06

            self.doorPosX = 270
            self.offset = 0
            self.doorPosY = 208

        self.doorPosX = 457
        self.doorPosY = 208
        self.offset = 0
        for j in range(2):
            for i in range(39):
                doors.append(Door(self.doorPosX, self.doorPosY))
                self.doorPosY += 113 - self.offset
                self.offset += 0.06

            self.doorPosX = 588
            self.offset = 0
            self.doorPosY = 208

        self.elevatorInitX = 350
        self.elevatorInitY = 200

        for i in range(20):
            elevator.append(
                Elevator(ElevatorImage, self.elevatorInitX,
                         self.elevatorInitY))
            self.elevatorInitY += 250

        for i in elevator:
            self.group.add(i)

        self.playerCharacter = Character(PlayerWalkAnimList[0])
        #self.playerCharacter._position = self.map_layer.map_rect.center
        self.playerCharacter._positionX += 300
        self.playerCharacter._positionY += 20

        self.group.add(self.playerCharacter)

        #Variables
        self.animDelay = 50
        self.JumpTimer = 1700
        self.FireDelay = 2000
        self.lastUpdate = 0
        self.SpawnlastUpdate = 0
        self.JumplastUpdate = 0
        self.AttacklastUpdate = 0

        self.ScoreIncreaseTimer = 0

        self.playerVel = [0, 0]
        self.velX = 0
        self.velY = 0
        self.jumpVel = 0.5

        self.Gravity = 0
        self.bIsJumping = False
        self.bCanJump = True
        self.WalkAnimIndex = 0
        self.CrouchAnimIndex = 0
        self.AttackAnimIndex = 0
        self.bIsWalking = False
        self.bCollided = False
        self.bCanMoveRight = True
        self.bCanMoveLeft = True

        self.bIsFiring = False
        self.bHasFired = False
        self.bCanFire = True

        self.bAddEnemy = False
        self.facing = 1
        self.PlayeBulletOffset = 0

        self.bCanSpawnEnemy = True

        self.WalkSoundTimer = 0

        pygame.display.set_caption("Elevator action")

        self.clock = pygame.time.Clock()

        self.score = 0
        self.health = 10
        self.bHealthCheck = True
        self.bGameOver = False
        self.bLevelPassed = False

    def MovementHandle(self):

        self.keys = pygame.key.get_pressed()

        if self.keys[pygame.K_LEFT]:
            self.bIsWalking = True
            self.currentAnim = CurrentAnim.LEFT

        elif self.keys[pygame.K_RIGHT]:
            self.bIsWalking = True
            self.currentAnim = CurrentAnim.RIGHT

        if self.bIsWalking == True:

            if self.currentAnim == CurrentAnim.LEFT:
                if self.bCanMoveLeft == True:
                    self.velX = -2.5

            elif self.currentAnim == CurrentAnim.RIGHT:
                if self.bCanMoveRight == True:
                    self.velX = 2.5

    def AddEnemy_thread(self):
        count = 0
        if count < 1 and len(Enemies) < 50:

            for i in doors:
                if self.playerCharacter._positionY >= i.positionY - random.randrange(
                        20, 200
                ) and self.playerCharacter._positionY <= i.positionY + random.randrange(
                        20, 200
                ) and self.playerCharacter._positionX >= i.positionX - random.randrange(
                        20, 200
                ) and self.playerCharacter._positionX <= i.positionX + random.randrange(
                        20, 200):
                    enemy = Enemy(WalkAnimList[0])
                    enemy._positionX = i.positionX
                    enemy._positionY = i.positionY
                    Enemies.append(enemy)
                    self.group.add(enemy)
                    count += 1
                    self.bCanSpawnEnemy = False
                    if count >= 2:
                        count = 0

    def Bullet_thread_player(self):
        if self.currentAnim == CurrentAnim.LEFT:
            self.facing = -1
            self.PlayeBulletOffset = -10
        elif self.currentAnim == CurrentAnim.RIGHT:
            self.facing = 1
            self.PlayeBulletOffset = 10
        BulletsPlayer.append(
            Bullet(BulletImage,
                   self.playerCharacter._positionX + self.PlayeBulletOffset,
                   self.playerCharacter._positionY + 20, self.facing))
        self.group.add(BulletsPlayer[len(BulletsPlayer) - 1])

    def Bullet_thread_enemy(self):
        for i in Enemies:
            BulletsEnemy.append(
                Bullet(BulletImage, i._positionX, i._positionY + 5, i.facing))
            self.group.add(BulletsEnemy[len(BulletsEnemy) - 1])

    def run(self, done):

        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                pygame.quit()

        if self.bIsWalking == True:
            if pygame.time.get_ticks() - self.WalkSoundTimer > 500:
                runSound.play(0)
                self.WalkSoundTimer = pygame.time.get_ticks()

        self.keys = pygame.key.get_pressed()

        if self.keys[pygame.K_SPACE]:
            if self.bCanJump == True:
                jumpSound.play(0)
                self.bIsJumping = True
                self.bCanJump = False

        if self.keys[pygame.K_z]:
            if self.bCanFire == True:
                self.bIsFiring = True
                self.bHasFired = True
                self.bCanFire = False
                pistolFire()
            else:
                self.bIsFiring = False
        else:
            self.bIsFiring = False
            self.bCanFire = True

        if self.bIsWalking == False:
            self.playerCharacter.setAnim(PlayerIdleAnimList[0],
                                         self.currentAnim)

        if self.keys[pygame.K_x]:
            pass

        if self.keys[pygame.K_q]:
            pass

        if self.keys[pygame.K_e]:
            if self.bAddEnemy == False:
                self.bAddEnemy = True

        else:
            self.bIsWalking = False

        if self.keys[pygame.K_DOWN]:
            self.playerCharacter.bPlayerCrouching = True
        else:
            self.playerCharacter.bPlayerCrouching = False

        if self.bIsWalking == False:
            self.velX = 0

        if self.bIsJumping == True:
            self.bIsInAir = True
            self.bCollided = False
            if self.jumpVel > 0:
                self.velY -= self.jumpVel
                self.jumpVel -= 0.03
            else:
                self.jumpVel = 0.5
                self.velY = 0

                self.bIsJumping = False

        self.MovementHandle()

        for sprite in self.group.sprites():

            if sprite.bIsPlayer == ObjectType.PLAYER:

                for i in elevator:
                    if sprite.feet.collidelist(
                            self.walls) > -1 or i.CollideWithElavator == True:

                        self.bCollided = True

                        if self.bIsJumping == False:
                            self.velY = 0
                            if self.bCanJump == False:
                                if self.bCollided == True:
                                    self.bCanJump = True

                    else:
                        self.bCollided = False

            elif sprite.bIsPlayer == ObjectType.ENEMY:
                if sprite.feet.collidelist(
                        self.walls) > -1 and i.CollideWithElavator == False:
                    sprite.bCollided = True
                else:
                    sprite.bCollided = False

        for i in elevator:
            if i.CollideWithElavator == False:
                if self.bCollided == False:
                    self.velY += 0.1 / len(elevator)

            else:
                if i.Dir == ElevatorDir.DOWN:
                    if self.bIsJumping == False:
                        self.velY += 1.0 / len(elevator) + 0.82
                else:
                    self.velY -= 1.0 * 1.1

        for i in Enemies:
            if i.bCollided == False:
                i.velY += 0.1
            else:
                i.velY = 0.0

            i.setVelocity()
            i.result = self.playerCharacter._positionX - i._positionX

            i.updateDir()
            #print(i.result)
            if i.result <= 100 and i.result >= -100 and i._positionY >= self.playerCharacter._positionY - 20 and i._positionY <= self.playerCharacter._positionY + 20:
                i.AIRotate()
                i.velocityX = 0

            if i.bIsFiring == True and i.result <= 600 and i.result >= -600 and i._positionY >= self.playerCharacter._positionY - 20 and i._positionY <= self.playerCharacter._positionY + 20:
                thread = threading.Thread(target=self.Bullet_thread_enemy)
                enemyGun.play(0)
                thread.start()
                i.bIsFiring = False

            if i.bIsFiring == False:
                if pygame.time.get_ticks(
                ) - i.FireUpdate > self.FireDelay * random.randrange(2, 8):
                    i.bIsFiring = True
                    i.FireUpdate = pygame.time.get_ticks()

            i.UpdatePosition()

            if i.bIsDead == False:
                if i.velocityX != 0:
                    i.UpdateAnim(self.animDelay)
                else:
                    i.setAnim(IdleAnimList[0])
            else:
                i.UpdateAnim(self.animDelay)

        if self.playerCharacter.right.collidelist(self.walls) > -1:

            self.bCanMoveRight = False
        else:
            self.bCanMoveRight = True

        if self.playerCharacter.left.collidelist(self.walls) > -1:
            self.bCanMoveLeft = False
        else:
            self.bCanMoveLeft = True

        for i in Enemies:
            if i.left.collidelist(self.walls) > -1:
                i.velocityX = 0
                i.facing = 1
            elif i.right.collidelist(self.walls) > -1:
                i.velocityX = 0
                i.facing = -1

        if self.bIsFiring == True:
            self.playerCharacter.bPlayShootingAnim = True

        if self.playerCharacter.bPlayShootingAnim == False:

            if self.playerCharacter.bPlayerCrouching == False:

                if self.bIsWalking == True:

                    self.playerCharacter.setAnim(
                        PlayerWalkAnimList[self.WalkAnimIndex],
                        self.currentAnim)
                    if self.WalkAnimIndex < len(PlayerWalkAnimList) - 1:
                        if pygame.time.get_ticks(
                        ) - self.lastUpdate > self.animDelay:
                            self.WalkAnimIndex += 1
                            self.lastUpdate = pygame.time.get_ticks()
                    else:
                        self.WalkAnimIndex = 0

                else:
                    self.WalkAnimIndex = 0
            else:
                self.playerCharacter.setAnim(
                    playerCrouchAnimList[self.CrouchAnimIndex],
                    self.currentAnim)
                if self.CrouchAnimIndex < len(playerCrouchAnimList) - 1:
                    if pygame.time.get_ticks(
                    ) - self.lastUpdate > self.animDelay:
                        self.CrouchAnimIndex += 1
                        self.lastUpdate = pygame.time.get_ticks()

                else:
                    self.CrouchAnimIndex = len(playerCrouchAnimList) - 1

        else:
            self.playerCharacter.PlayShootAnim(self.currentAnim)

        self.playerCharacter.setVelocity(self.velX, self.velY)

        if self.bCanSpawnEnemy == True:
            threadAddEnemy = threading.Thread(target=self.AddEnemy_thread)
            threadAddEnemy.start()

        if self.bCanSpawnEnemy == False:
            if pygame.time.get_ticks() - self.SpawnlastUpdate > 8000:
                self.SpawnlastUpdate = pygame.time.get_ticks()
                self.bCanSpawnEnemy = True

        self.group.center(self.playerCharacter.rect.center)
        self.playerCharacter.UpdatePosition()

        #print(self.bCanSpawnEnemy)

        if self.bIsFiring == True:
            thread = threading.Thread(target=self.Bullet_thread_player)
            thread.start()

        if BulletsPlayer:
            for i in BulletsPlayer:
                i.UpdatePosition()

                #print("[ "+str(i.positionX)+", "+str(i.positionY)+" ]")
                if i.positionX > W or i.positionX < 0:
                    self.group.remove(i)
                    BulletsPlayer.pop(BulletsPlayer.index(i))

        if len(BulletsPlayer) > 20:
            for i in BulletsPlayer:
                BulletsPlayer.pop(BulletsPlayer.index(i))

        if BulletsEnemy:
            for i in BulletsEnemy:
                i.UpdatePosition()

                if i.positionX > W or i.positionX < 0:
                    self.group.remove(i)

                    BulletsEnemy.pop(BulletsEnemy.index(i))

        for i in elevator:

            if self.playerCharacter.rect[
                    1] >= i.rect[1] - 20 and self.playerCharacter.rect[
                        1] <= i.rect[1] + 20 and self.playerCharacter.rect[
                            0] >= i.rect[0] - 50 and self.playerCharacter.rect[
                                0] <= i.rect[0] + 50:
                i.CollideWithElavator = True
            else:
                i.CollideWithElavator = False
            i.setVelocity()
            i.UpdatePosition()

        for i in Enemies:
            if i._positionY >= self.playerCharacter._positionY + 200 or i._positionY <= self.playerCharacter._positionY - 200:
                self.group.remove(i)
                Enemies.pop(Enemies.index(i))
            if i.velocityY > 20:
                self.group.remove(i)
                Enemies.pop(Enemies.index(i))
            if i.bDeathAnimCompleted == True:
                self.group.remove(i)
                Enemies.pop(Enemies.index(i))

        for i in BulletsPlayer:
            if i.rect.collidelist(self.walls) > -1:
                self.group.remove(i)
                BulletsPlayer.pop(BulletsPlayer.index(i))

        for i in BulletsEnemy:
            if i.rect.collidelist(self.walls) > -1:
                self.group.remove(i)
                BulletsEnemy.pop(BulletsEnemy.index(i))

        for i in BulletsPlayer:
            for j in Enemies:
                if (i.rect[1] <= j.rect[1] + 20 and i.rect[1] >= j.rect[1] - 20
                    ) and (i.rect[0] <= j.rect[0] + 5
                           and i.rect[0] >= j.rect[0] - 5):
                    j.bIsDead = True
                    if pygame.time.get_ticks(
                    ) - self.ScoreIncreaseTimer > 1000:
                        self.score += 50
                        self.ScoreIncreaseTimer = pygame.time.get_ticks()

                    self.bHealthCheck = True
                    hitmarkSound.play(0)

                    self.group.remove(i)

                    try:
                        BulletsPlayer.pop(BulletsPlayer.index(i))
                    except:
                        continue

        for i in BulletsEnemy:
            if self.playerCharacter.bPlayerCrouching == False and self.bIsJumping == False:
                if (i.rect[1] <= self.playerCharacter.rect[1] + 20
                        and i.rect[1] >= self.playerCharacter.rect[1] - 20
                    ) and (i.rect[0] <= self.playerCharacter.rect[0] + 5
                           and i.rect[0] >= self.playerCharacter.rect[0] - 5):
                    #print("PLAYER HIT")
                    self.playerCharacter._positionY -= 4
                    print(i.facing)
                    if i.facing < 0:
                        self.playerCharacter._positionX -= 5

                    elif i.facing > 0:
                        self.playerCharacter._positionX += 5
                    self.health -= 1
                    self.score -= 75
                    damageTakenSound.play(0)
                    self.group.remove(i)
                    BulletsEnemy.pop(BulletsEnemy.index(i))

        if self.score == 250 and self.bHealthCheck == True:
            self.health += 1
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 500 and self.bHealthCheck == True:
            self.health += 1
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 750 and self.bHealthCheck == True:
            self.health += 1
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 1000 and self.bHealthCheck == True:
            self.health += 1
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 1500 and self.bHealthCheck == True:
            self.health += 1
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 2000 and self.bHealthCheck == True:
            self.health += 2
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 3000 and self.bHealthCheck == True:
            self.health += 3
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 4000 and self.bHealthCheck == True:
            self.health += 3
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 5000 and self.bHealthCheck == True:
            self.health += 3
            hpGain.play(0)
            self.bHealthCheck = False
        if self.score == 10000 and self.bHealthCheck == True:
            self.health += 5
            hpGain.play(0)
            self.bHealthCheck = False

        if self.playerCharacter._positionX >= 687 - 40 and self.playerCharacter._positionX <= 687 + 40 and self.playerCharacter._positionY >= 4657 - 40 and self.playerCharacter._positionY <= 4657 + 40:
            self.bLevelPassed = True
        if self.health <= 0:
            self.bGameOver = True

        print(
            str(self.playerCharacter._positionX) + ", " +
            str(self.playerCharacter._positionY))

        self.group.draw(screen)
        draw_score(screen, 30, 30, self.score)
        draw_health(screen, 1120, 30, self.health)
        pygame.display.flip()

        self.clock.tick(60)
示例#15
0
class TitleScreen(tools._State):
    def __init__(self):
        super(TitleScreen, self).__init__()

        pg.mixer.init()

        song = MUSIC['bg']
        pg.mixer.music.load(song)
        pg.mixer.music.set_volume(0.1)
        pg.mixer.music.play()

        tmx_data = load_pygame(MAP['title0'])

        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE)
        self.map_layer.zoom = 1
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.animations = pg.sprite.Group()
        self.labels = pg.sprite.Group()
        self.letters = pg.sprite.Group()

        imgs0 = [GFX["letter_{}".format(letter)] for letter in "UPSIDE"]
        delays0 = [x * 250 for x in (1, 2, 3, 4, 5, 6)]
        w, h = imgs0[0].get_size()
        space = 10
        left0 = 70
        top0 = SCREEN_RECT.centery - 90
        timespan = 1500
        for img, delay in zip(imgs0, delays0):
            icon = Icon(img, (left0, -100), False, self.letters)
            left0 += w + space
            ani = Animation(top=top0,
                            duration=timespan,
                            delay=delay,
                            transition="out_bounce",
                            round_values=True)
            ani.start(icon.rect)
            self.animations.add(ani)

        imgs1 = [GFX["letter_{}".format(letter)] for letter in "DOWN"]
        delays1 = [x * 250 for x in (3, 4, 5, 6)]

        space = 10
        left1 = 280
        top1 = SCREEN_RECT.centery

        for img, delay in zip(imgs1, delays1):
            icon = Icon(img, (left1, 580), True, self.letters)
            left1 += w + space
            ani = Animation(top=top1,
                            duration=timespan,
                            delay=delay,
                            transition="out_bounce",
                            round_values=True)
            ani.start(icon.rect)
            self.animations.add(ani)
        midbottom = (SCREEN_RECT.centerx, SCREEN_RECT.bottom - 120)
        font = FONTS["UbuntuMono-B"]
        self.prompt = Blinker("Press any key to continue",
                              {"midbottom": midbottom},
                              500,
                              text_color=(255, 255, 255),
                              font_path=font,
                              font_size=30)
        task = Task(self.labels.add,
                    max(delays1) + timespan,
                    args=(self.prompt, ))
        self.animations.add(task)

    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYUP:
            if event.type == pg.K_ESCAPE:
                self.quit = True
            else:
                self.done = True
                self.next = "INTRO"

    def cleanup(self):
        pg.mixer.quit()
        self.persist['surface'] = pg.display.get_surface()
        return self.persist

    def update(self, dt):

        self.animations.update(dt)
        self.labels.update(dt)

    def draw(self, surface):
        self.group.draw(surface)
        self.letters.draw(surface)
        self.labels.draw(surface)
示例#16
0
文件: quest.py 项目: d4g33z/pyscroll
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    def __init__(self):

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        w, h = screen.get_size()

        # create new renderer (camera)
        # clamp_camera is used to prevent the map from scrolling past the map's edge
        self.map_layer = pyscroll.BufferedRenderer(map_data, (w / 2, h / 2),
                                                   clamp_camera=True)

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.hero = Hero()

        # put the hero in the center of the map
        self.hero.position = self.map_layer.map_rect.center

        # add our hero to the group
        self.group.add(self.hero)

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self):
        """ Handle pygame input events
        """
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w / 2, event.h / 2))

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        if pressed[K_UP]:
            self.hero.velocity[1] = -HERO_MOVE_SPEED
        elif pressed[K_DOWN]:
            self.hero.velocity[1] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[1] = 0

        if pressed[K_LEFT]:
            self.hero.velocity[0] = -HERO_MOVE_SPEED
        elif pressed[K_RIGHT]:
            self.hero.velocity[0] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[0] = 0

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def run(self):
        """ Run the game loop
        """
        clock = pygame.time.Clock()
        scale = pygame.transform.scale
        self.running = True

        try:
            while self.running:
                dt = clock.tick() / 1000.

                self.handle_input()
                self.update(dt)
                self.draw(temp_surface)
                scale(temp_surface, screen.get_size(), screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#17
0
class BinalGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    def __init__(self, filename, oldEntrance=None, oldmap=None, hero=None):
        self.portalName = ''
        self.portalsIn = list()
        self.portalsOut = list()

        self.olfFilename = None
        self.filename = get_map(filename)

        if self.filename in heroStates:
            self.mode = heroStates[self.filename]
        else:
            self.mode = "Peaceful"

        if oldmap == None:
            self.oldMap = filename
        else:
            self.oldMap = oldmap

        overworld = 'BinalOverworld2.tmx'
        self.oldEntrance = oldEntrance
        self.battleInstance = False

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   screen.get_size(),
                                                   clamp_camera=False,
                                                   tall_sprites=1)
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)

        self.hero = Hero()

        # put the hero in the center of the map
        # self.hero.position = self.map_layer.map_rect.center
        # self.hero._position[0] += 200
        # self.hero._position[1] += 400

        # add our hero to the group
        self.group.add(self.hero)

        # startpoints
        self.startpoints = []
        for object in tmx_data.objects:
            if object.name == "startpoint":
                self.startpoints.append((object.x, object.y))

        self.hero.position = (self.startpoints[0][0], self.startpoints[0][1])
        self.oldPosition = self.hero.position
        self.group.add(self.hero)
        self.steps = 0
        self.battle = 1

        # set default zoom when not in overworld
        if self.oldMap == overworld and self.filename != "data/" + overworld:
            self.map_layer.zoom = self.map_layer.zoom - .25

        self.portalNames = list()
        # add portals to collider lists
        for object in tmx_data.objects:
            if object.type == "portalIn":
                self.portalNames.append(object)
                self.portalsIn.append(
                    pygame.Rect(object.x, object.y, object.width,
                                object.height))
            elif object.type == "portalO":
                self.portalsOut.append(
                    pygame.Rect(object.x, object.y, object.width,
                                object.height))

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

    def nearestPortal(self, trigger=False):
        (x, y) = self.hero.position
        for portal in self.portalsIn:
            if trigger == False:
                trigger = True
                self.oldEntrance = (portal.x, portal.y)
                (p, q) = self.oldEntrance
            distanceNew = (math.sqrt((x - portal.x)**2 + (y - portal.y)**2))
            distanceOld = (math.sqrt((x - p)**2 + (y - q)**2))

            if distanceNew < distanceOld:
                distanceOld = distanceNew
                self.oldEntrance = (portal.x, portal.y)
                (p, q) = (portal.x, portal.y)
        for portal in self.portalNames:
            if self.almostEqual((p, q), (portal.x, portal.y)):
                self.portalName = portal.name

    def handle_input(self):
        """ Handle pygame input events
        """
        poll = pygame.event.poll
        clock = pygame.time.Clock()

        event = poll()
        while event:
            ticks = pygame.time.get_ticks()

            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

                elif event.key == K_EQUALS:
                    self.map_layer.zoom += .25

                elif event.key == K_MINUS:
                    value = self.map_layer.zoom - .25
                    if value > 0:
                        self.map_layer.zoom = value

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        # if pressed[K_UP]:
        #     self.hero.velocity[1] = -HERO_MOVE_SPEED
        # elif pressed[K_DOWN]:
        #     self.hero.velocity[1] = HERO_MOVE_SPEED
        # else:
        #     self.hero.velocity[1] = 0

        # if pressed[K_LEFT]:
        #     self.hero.velocity[0] = -HERO_MOVE_SPEED
        # elif pressed[K_RIGHT]:
        #     self.hero.velocity[0] = HERO_MOVE_SPEED
        # else:
        #     self.hero.velocity[0] = 0

        # if self.moving != False:
        ticks = pygame.time.get_ticks()
        if pressed[K_UP]:
            self.hero.currImageList = self.hero.downs
            self.hero.walkAnimation(ticks)
            self.hero.velocity[1] = -HERO_MOVE_SPEED
            #self.steps += 1
        elif pressed[K_DOWN]:
            self.hero.currImageList = self.hero.ups
            self.hero.walkAnimation(ticks)
            self.hero.velocity[1] = HERO_MOVE_SPEED
            #self.steps += 1
        else:
            self.hero.velocity[1] = 0
        if pressed[K_LEFT]:
            self.hero.currImageList = self.hero.lefts
            self.hero.walkAnimation(ticks)
            self.hero.velocity[0] = -HERO_MOVE_SPEED
            #self.steps += 1
        elif pressed[K_RIGHT]:
            self.hero.currImageList = self.hero.rights
            self.hero.walkAnimation(ticks)
            self.hero.velocity[0] = HERO_MOVE_SPEED
            #self.steps += 1

        else:
            self.hero.velocity[0] = 0
        # sprint
        if pressed[K_SPACE]:
            self.hero.velocity[0] *= 1.7
            self.hero.velocity[1] *= 1.7
            # more likely to battle encounter if sprinting
            # if self.hero.velocity[0] > 0 or self.hero.velocity[1] > 0:
            #     #self.steps += 2
            # if self.hero.velocity[0] >= 1.5 * HERO_MOVE_SPEED:
            #     pass
            # if self.hero.velocity[1] >= 1.5 * HERO_MOVE_SPEED:
            #     pass

        # stops character from moving when battlescreen is initiated
        #if self.mode == "Battle":
        #    (self.hero.velocity[0], self.hero.velocity[1]) = (0, 0)

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.portalsIn) > -1:
                if sprite.type == "hero":

                    self.nearestPortal()
                    self.filename = inPortalDict[self.filename +
                                                 self.portalName]
                    self.hero.position = (self.startpoints[0][0],
                                          self.startpoints[0][1])
            elif sprite.feet.collidelist(self.portalsOut) > -1:
                if sprite.type == "hero":
                    filename = outPortalDict[self.filename]
                    self.filename = filename
                    self.hero.position = (self.startpoints[0][0],
                                          self.startpoints[0][1])
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    # plays music based on map file keyed to dictionary
    # also covers changing map sound effect
    # def changeMusicAndInstance(self, surface, oldMusic=None):
    #     tmap = self.filename
    #     song = MusicDict[tmap]
    #     # instance change sound, from Zelda stairs sound
    #     playSound("Enter.wav", .15)

    #     if oldMusic == None:
    #         oldMusic = MusicDict[self.oldMap]

    #     if self.mode != "Overworld":
    #         if song == oldMusic: return None

    #     # loops music indefinitely for that map
    #     playMusic(song)
    #     def showStartScreen(self):
    #     self.draw('title_demo')
    #     if checkForKeyPress():
    #         self.run()

    @staticmethod
    def almostEqual(position1, position2):
        (x1, y1) = position1
        (x2, y2) = position2
        epsilon = 60
        if abs(x1 - x2) < epsilon:
            if abs(y1 - y2) < epsilon:
                return True
        return False

    def randomBattle(self):
        # prevents battle from happening right on town portal
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.portalsIn) > -1:
                return None
        if self.almostEqual(position, self.oldPosition):
            return None
        if self.mode == "Peaceful" or self.mode == "Battle":
            return None
        diceRoll = random.randint(0, 100)
        #increased encounter rate when walking without encountering
        # a single battle for a certain number of steps
        threshold = 600
        if self.steps > threshold:
            if diceRoll < 50:
                self.mode = "Battle"
                self.steps = 0

        if self.steps > 200:
            # lower encounter rate when just beginning to walk
            if diceRoll < 200:
                self.mode = "Battle"
                self.steps = 0

        self.oldPosition = position

    def run(self):
        """ Run the game loop
        """
        filename = self.filename
        clock = pygame.time.Clock()
        self.running = True

        from collections import deque
        times = deque(maxlen=30)

        #idle hero animation
        ticks = pygame.time.get_ticks()
        self.hero.walkAnimation(ticks)
        playMusic('overworld.wav')

        try:
            while self.running:
                dt = clock.tick() / 1000.
                times.append(clock.get_fps())
                # print(sum(times)/len(times))#idle hero animation
                ticks = pygame.time.get_ticks()
                self.hero.walkAnimation(ticks)

                # beginning of random battle
                # self.randomBattle()

                # changing map
                if self.filename != filename:
                    # leaving map toward overworld
                    if self.oldMap == os.path.join(RESOURCES_DIR,
                                                   self.filename):
                        oldMap = inPortalDict[
                            str(os.path.join(RESOURCES_DIR, self.filename)) +
                            self.portalName]
                    else:
                        oldMap = outPortalDict[str(
                            os.path.join(RESOURCES_DIR, self.filename))]
                    self.__init__(self.filename, self.oldEntrance, oldMap,
                                  self.hero)
                    self.oldEntrance = OldEntranceDict[filename]

                    if os.path.join(RESOURCES_DIR,
                                    outPortalDict[filename]) == self.filename:
                        if self.oldEntrance != None:
                            position = (self.oldEntrance[0],
                                        self.oldEntrance[1])
                            self.hero.position = position
                            self.oldPosition = position
                    self.run()

                self.handle_input()
                self.update(dt)
                self.draw(screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#18
0
class QuestGame(object):
    """ This class is a basic game.
    This class will load resources, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    def __init__(self):

        # true while running
        self.running = False

        # create new data source for pyscroll
        self.map_data = InfiniteMap()

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(self.map_data,
                                                   screen.get_size())
        self.map_layer.zoom = 1

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)
        self.hero = Hero()
        self.hero.position = 518 * 32, 560 * 32

        # add our hero to the group
        self.group.add(self.hero)

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self):
        """ Handle pygame input events
        """
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                if event.key == K_ESCAPE:
                    self.running = False
                    break

                elif event.key == K_r:
                    self.map_data.reload()
                    self.map_layer.redraw_tiles(self.map_layer._buffer)

                elif event.key == K_q:
                    self.map_data.NOISE_SIZE -= .5
                    self.hero.position = self.hero.position[
                        0] * .985, self.hero.position[1] * .985
                    self.map_data.reload()
                    self.map_layer.redraw_tiles(self.map_layer._buffer)

                elif event.key == K_w:
                    self.map_data.NOISE_SIZE += .5
                    self.map_data.reload()
                    self.hero.position = self.hero.position[
                        0] * 1.015, self.hero.position[1] * 1.015
                    self.map_layer.redraw_tiles(self.map_layer._buffer)

                elif event.key == K_EQUALS:
                    self.map_layer.zoom += .25

                elif event.key == K_MINUS:
                    value = self.map_layer.zoom - .25
                    if value > 0:
                        self.map_layer.zoom = value

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        pressed = pygame.key.get_pressed()
        if pressed[K_UP]:
            self.hero.velocity[1] = -HERO_MOVE_SPEED
        elif pressed[K_DOWN]:
            self.hero.velocity[1] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[1] = 0

        if pressed[K_LEFT]:
            self.hero.velocity[0] = -HERO_MOVE_SPEED
        elif pressed[K_RIGHT]:
            self.hero.velocity[0] = HERO_MOVE_SPEED
        else:
            self.hero.velocity[0] = 0

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

    def run(self):
        """ Run the game loop
        """
        clock = pygame.time.Clock()
        self.running = True

        from collections import deque
        times = deque(maxlen=300)

        noise = SimplexNoise().noise2
        two_pi = 2 * math.pi

        poll = 1

        try:
            while self.running:
                dt = clock.tick_busy_loop(60) / 1000.

                self.handle_input()
                self.update(dt)

                begin = time()
                self.draw(screen)
                times.append(time() - begin)

                # if len(times) > 0:
                #     print(len(times), round(sum(times) / len(times), 4))

                #
                # poll -= dt
                # if poll < 0:
                #     self.map_data._first_draw = True
                #     self.map_data.reload()
                #     self.map_layer.redraw_tiles(self.map_layer._buffer)

                # xx, yy = self.hero.position
                #
                # xx /= 1000
                # yy /= 1000
                #
                # for y in range(0, 320, 32):
                #     for x in range(0, 320, 32):
                #         v = (noise(xx + x / 1000, yy + y / 1000) + 1) * 128
                #         color = v, v, v
                #         print(color)
                #         screen.fill(color, (x, y, 32, 32))

                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#19
0
class Hunting(GameState):
    """The main game state."""

    roast_live_time = 10000
    roast_fade_time = 1000

    def __init__(self):
        super(Hunting, self).__init__()
        map_data = MapData()
        map_layer = BufferedRenderer(map_data, prepare.SCREEN_SIZE)
        self.all_sprites = PyscrollGroup(map_layer=map_layer)

        self.colliders = pg.sprite.Group()
        self.ui = pg.sprite.Group()
        self.noise_detector = NoiseDetector((10, 80), self.ui)

        self.animations = pg.sprite.Group()
        self.hunter = Hunter(map_layer.map_rect.center, 0,
                             self.noise_detector, self.all_sprites)

        self.leaves = pg.sprite.Group()
        self.roasts = pg.sprite.Group()
        self.flocks = pg.sprite.Group()
        self.turkeys = self.add_turkeys()
        self.bullets = pg.sprite.Group()
        self.make_trees()
        hx, hy = self.hunter.rect.center
        self.ammo_crate = AmmoCrate((hx - 50, hy - 50), self.colliders,
                                    self.all_sprites)

        self.rustle_sounds = [prepare.SFX["rustle{}".format(x)]
                              for x in range(1, 21)]
        self.wind_gust()
        style = {"font_path": prepare.FONTS["pretzel"],
                 "font_size": 24, "text_color": (58, 41, 18)}
        self.shell_label = Label("{}".format(self.hunter.shells),
                                 {"topleft": (50, 10)}, **style)
        self.roasts_label = Label("{}".format(self.hunter.roasts),
                                  {"topleft": (50, 50)}, **style)
        Icon((20, 3), "shell", self.ui)
        Icon((10, 45), "roast", self.ui)
        self.add_flock()

    def wind_gust(self):
        """Play wind sound and set up next gust."""
        prepare.SFX["wind"].play()
        task = Task(self.wind_gust, randint(15000, 45000))
        self.animations.add(task)

    def add_turkeys(self):
        """Spawn turkeys."""
        turkeys = pg.sprite.Group()
        w, h = prepare.WORLD_SIZE
        for _ in range(35):
            pos = randint(20, w - 20), randint(20, h - 20)
            Turkey(pos, turkeys, self.all_sprites)

        return turkeys

    def make_trees(self):
        """Spawn trees."""
        self.trees = pg.sprite.Group()
        w, h = prepare.WORLD_SIZE
        for _ in range(120):
            while True:
                pos = (randint(50, w - 20), randint(20, h - 20))
                tree = Tree(pos)
                collisions = (tree.collider.colliderect(other.collider)
                              for other in self.colliders)
                if not any(collisions) and not tree.collider.colliderect(self.hunter.collider):
                    break
            self.trees.add(tree)
            self.colliders.add(tree)
            self.all_sprites.add(tree)

    def add_flock(self):
        """Add a Flock of birds."""
        flock = Flock((self.hunter.collider.centerx, -1500), self.animations,
                      self.all_sprites, self.flocks)
        next_flock = randint(45000, 150000) #next flock in 45-150 seconds
        task = Task(self.add_flock, next_flock)
        self.animations.add(task)

    def add_roast(self, position):
        roast = Roast(position, self.roasts, self.all_sprites)
        task = Task(roast.kill, self.roast_live_time)
        self.animations.add(task)
        return roast

    def update(self, dt):
        self.animations.update(dt)
        keys = pg.key.get_pressed()
        self.hunter.update(dt, keys, self.bullets, self.turkeys,
                           self.colliders, self.all_sprites, self.animations)
        self.turkeys.update(dt, self.trees)
        self.bullets.update(dt)

        for sprite in self.all_sprites:
            self.all_sprites.change_layer(sprite, sprite.collider.bottom)

        view_rect = self.all_sprites._map_layer.view_rect
        for bullet in self.bullets:
            if not bullet.rect.colliderect(view_rect):
                bullet.kill()

        tree_hits = pg.sprite.groupcollide(self.bullets, self.trees, True,
                                           False, footprint_collide)
        for bullet in tree_hits:
            for tree in tree_hits[bullet]:
                choice(self.rustle_sounds).play()
                num = randint(3, 9)
                for spot_info in sample(leaf_spots[tree.trunk], num):
                    self.add_leaf(tree, spot_info)

        turkey_hits = pg.sprite.groupcollide(self.bullets, self.turkeys,
                                             True, True, footprint_collide)

        for t_bullet in turkey_hits:
            for turkey in turkey_hits[t_bullet]:
                self.add_roast(turkey.pos)

        if self.hunter.shells < self.hunter.max_shells:
            if self.hunter.collider.colliderect(self.ammo_crate.rect.inflate(16, 16)):
                prepare.SFX["gunload"].play()
                self.hunter.shells = self.hunter.max_shells

        if self.hunter.state == "move":
            self.scare_turkeys()
        self.noise_detector.update(dt)
        self.shell_label.set_text("{}".format(self.hunter.shells))
        self.roasts_label.set_text("{}".format(self.hunter.roasts))
        roast_collisions = pg.sprite.spritecollide(self.hunter, self.roasts,
                                                   True, footprint_collide)
        if roast_collisions:
            prepare.SFX["knifesharpener"].play()
            self.hunter.roasts += len(roast_collisions)
        self.flocks.update(self.hunter)

    def scare_turkeys(self):
        """Make turkeys flee depending on distance and the player's noise level."""
        size = self.noise_detector.noise_level
        scare_rect = self.hunter.collider.inflate(size, size)
        scared_turkeys = (t for t in self.turkeys
                          if t.collider.colliderect(scare_rect) and t.state.name != "flee")
        for scared in scared_turkeys:
            scared.flee(self.hunter)

    def add_leaf(self, tree, spot_info):
        """Add a falling leaf."""
        fall_time = randint(2000, 2500)
        leaf = Leaf(tree, spot_info, self.leaves, self.all_sprites)
        y = leaf.rect.centery + leaf.fall_distance
        ani = Animation(centery=y, duration=fall_time, round_values=True)
        ani.callback = leaf.land
        ani.start(leaf.rect)
        ani2 = Animation(centery=leaf.collider.centery + leaf.fall_distance,
                         duration=fall_time, round_values=True)
        ani2.start(leaf.collider)
        fade = Animation(img_alpha=0, duration=3000, delay=fall_time,
                         round_values=True)
        fade.callback = leaf.kill
        fade.update_callback = leaf.set_alpha
        fade.start(leaf)
        self.animations.add(ani, ani2, fade)

    def draw(self, surface):
        self.all_sprites.center(self.hunter.pos)
        self.all_sprites.draw(surface)
        self.shell_label.draw(surface)
        self.roasts_label.draw(surface)
        self.ui.draw(surface)
示例#20
0
class Game:
    def __init__(self):
        self.running = False
        self.file_name = 'map/map.tmx'
        self.tmx_data = load_pygame(self.file_name)
        self.map = Map(tmx_data=self.tmx_data)
        self.font = pygame.font.Font('freesansbold.ttf', 32)
        self.focus_car = False

    def init_group(self):
        map_data = pyscroll.data.TiledMapData(self.tmx_data)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   screen.get_size(),
                                                   clamp_camera=True)
        self.map_layer.zoom = 0.3
        self.zoomchange = 1
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=1)

    def init_world(self):
        self.car = Car('mymap/car.png', (450, 450), 45)
        self.render_car()

    def update(self, dt):
        self.group.update(dt)

    def draw(self, surface):
        if self.focus_car:
            self.group.center(self.car.rect.center)
        self.group.draw(surface)

    def render_car(self):
        self.focus_car = True
        self.group.add(self.car)

    def handle_input(self, event):
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_EQUALS:
                self.map_layer.zoom += .25
            elif event.key == pygame.K_MINUS:
                value = self.map_layer.zoom - .25
                if value > 0:
                    self.map_layer.zoom = value

            if event.key == pygame.K_UP:
                self.car.speed += 1
            elif event.key == pygame.K_DOWN:
                self.car.speed -= 1
            elif event.key == pygame.K_LEFT:
                self.car.angle_speed = -4
            elif event.key == pygame.K_RIGHT:
                self.car.angle_speed = 4
        elif event.type == pygame.KEYUP:
            if event.key == pygame.K_LEFT:
                self.car.angle_speed = 0
            elif event.key == pygame.K_RIGHT:
                self.car.angle_speed = 0

    def run(self):
        clock = pygame.time.Clock()
        self.running = True

        while self.running:
            dt = clock.tick(60) / 1000
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                    sys.exit(0)
                self.handle_input(event)

            self.update(dt)
            self.draw(screen)

            pygame.display.flip()
示例#21
0
class Invertibles(object):
    filename = get_map(MAP_FILENAME)

    def __init__(self):
        pygame.mixer.pre_init(44100, 16, 1, 4096)
        pygame.init()
        pygame.font.init()
        self.screen = init_screen(800, 600)
        pygame.display.set_caption('Polaria')

        # Music channel
        self.music_channel = pygame.mixer.Channel(1)
        self.sounds = Sounds()

        # Store projectiles in a group
        self.projectiles = Group()

        # true while running
        self.running = False

        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   self.screen.get_size())
        self.map_layer.zoom = 3.75

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=3)
        self.hero = Hero()
        self.heroes = list()
        self.heroes.append(self.hero)

        # Spawn an npc
        self.npc = NPC()
        self.npc.position = self.map_layer.map_rect.move(544, 592).topleft
        self.group.add(self.npc)
        self.npcs = list()
        self.npcs.append(self.npc)

        # Spawn an elemental below the house
        self.spawn_elementals()

        # Spawn the hero outside his house
        self.hero.position = self.map_layer.map_rect.move(528, 592).topleft

        # add our hero to the group
        self.group.add(self.hero)

        self.projectile_skin = 0  # Which spell the user has selected
        self.clock = pygame.time.Clock()

        # Dictionary to hold onto what keys are being held down
        self.movement_keys = {
            'UP': False,
            'DOWN': False,
            'LEFT': False,
            'RIGHT': False
        }

    def draw(self, surface, text=None):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect.center)

        # draw the map and all sprites

        self.group.draw(surface)
        #self.projectiles.draw(self.screen)

        score = Text(self.screen,
                     str(len(self.elementals)) + " dark elementals remaining",
                     (0, 0, 0), 650, 10)
        score.blitme()

        if text:
            dialogbox = DialogBox(self.screen)
            dialogbox.blitme()

            rendered_text = dialogbox.render_textrect(text)
            if rendered_text:
                self.screen.blit(rendered_text, dialogbox.textarea_rect)

    def handle_input(self):
        """ Handle pygame input events """
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break

            elif event.type == KEYDOWN:
                self.check_keydown_events(event)
            elif event.type == KEYUP:
                self.check_keyup_events(event)
            self.move_hero()

            if not self.running:
                break

            # this will be handled if the window is resized
            elif event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))

            event = poll()

    def reset_movement_keys(self):
        """Reset movement keys to False."""
        self.movement_keys = {
            'UP': False,
            'DOWN': False,
            'LEFT': False,
            'RIGHT': False
        }

    def check_keydown_events(self, event):
        """Check for keypresses and respond to them."""
        if event.key == K_ESCAPE or event.key == K_q:
            self.running = False

        # Set movement key flags
        if event.key == K_a:
            self.reset_movement_keys()
            self.hero.reset_velocity()
            self.movement_keys['LEFT'] = True
        elif event.key == K_d:
            self.reset_movement_keys()
            self.hero.reset_velocity()
            self.movement_keys['RIGHT'] = True
        elif event.key == K_w:
            self.reset_movement_keys()
            self.hero.reset_velocity()
            self.movement_keys['UP'] = True
        elif event.key == K_s:
            self.reset_movement_keys()
            self.hero.reset_velocity()
            self.movement_keys['DOWN'] = True

        # Cast spells
        if event.key == K_UP:
            new_projectile = Projectile(self.screen, self.hero, 'UP',
                                        self.projectile_skin)
            self.group.add(new_projectile)
            self.sounds.fireball.play()
        elif event.key == K_LEFT:
            new_projectile = Projectile(self.screen, self.hero, 'LEFT',
                                        self.projectile_skin)
            self.group.add(new_projectile)
            self.sounds.fireball.play()
        elif event.key == K_RIGHT:
            new_projectile = Projectile(self.screen, self.hero, 'RIGHT',
                                        self.projectile_skin)
            self.group.add(new_projectile)
            self.sounds.fireball.play()
        elif event.key == K_DOWN:
            new_projectile = Projectile(self.screen, self.hero, 'DOWN',
                                        self.projectile_skin)
            self.group.add(new_projectile)
            self.sounds.fireball.play()

        # Change spells
        if event.key == K_1:
            self.projectile_skin = 0
            self.sounds.select_spell.play()
        elif event.key == K_2:
            self.projectile_skin = 1
            self.sounds.select_spell.play()
        elif event.key == K_3:
            self.projectile_skin = 2
            self.sounds.select_spell.play()
        elif event.key == K_4:
            self.projectile_skin = 3
            self.sounds.select_spell.play()

    def check_keyup_events(self, event):
        """Check for keyreleases and respond to them."""
        # Set movement key flags
        if event.key == K_a:
            self.movement_keys['LEFT'] = False
        if event.key == K_d:
            self.movement_keys['RIGHT'] = False
        if event.key == K_w:
            self.movement_keys['UP'] = False
        if event.key == K_s:
            self.movement_keys['DOWN'] = False

    def move_hero(self):
        """Only move hero if one movement key is being pressed."""
        count = 0
        key_pressed = ''
        for key, pressed in self.movement_keys.items():
            if pressed:
                key_pressed = key
                count += 1
        if count == 1:
            self.hero.set_direction(key_pressed)
        else:
            self.hero.set_idle()

    def update_projectiles(self):
        """Update position of projectiles and get rid of old bullets."""
        # Update projectile positions
        self.projectiles.update()

        # Get rid of projectiles that have gone off screen
        for projectile in self.projectiles.copy():
            if projectile.rect.bottom <= 0:
                self.projectiles.remove(projectile)

    def update(self, dt):
        """ Tasks that occur over time should be handled here"""
        self.group.update(dt)
        self.update_projectiles()

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail

        for sprite in self.group.sprites():
            if sprite.name == 'hero':
                if sprite.feet.collidelist(self.walls) > -1:
                    sprite.move_back(dt)
                elif sprite.feet.collidelist(self.elementals) > -1:
                    sprite.move_back(dt)
                elif sprite.feet.collidelist(self.npcs) > -1:
                    sprite.move_back(dt)
            elif sprite.name == 'elemental':
                if sprite.feet.collidelist(self.walls) > -1:
                    sprite.move_back(dt)
                elif sprite.feet.collidelist(self.heroes) > -1:
                    sprite.move_back(dt)

            elif sprite.name == 'projectile':
                collide_elemental = sprite.rect.collidelist(self.elementals)
                if sprite.rect.collidelist(self.walls) > -1:
                    self.group.remove(sprite)
                elif collide_elemental > -1:
                    self.group.remove(sprite)
                    self.group.remove(self.elementals[collide_elemental])
                    self.elementals.pop(collide_elemental)
                    self.sounds.monster_kill.play()

    def run(self):
        """ Run the game loop"""

        self.running = True
        self.music_channel.play(self.sounds.town_theme, -1)

        text = [
            'We, the people of Polaria have summoned thee, the Lord of Light!\n\nPress enter to continue.',
            'Our beloved town has been overrun by evil dark elementals! Their dark magic can only be fought with the magic of Light!\n\nPress Enter to continue.',
            'Use WASD to move around and the arrow keys to cast your spells. You can switch spells with keys 1-4.\n\nPress Enter to continue.',
            'Good luck! And may the power of Light be with you!\n\nPress enter to continue.'
        ]
        self.run_dialog(text)

        while self.running:
            dt = self.clock.tick(60) / 1000.

            self.handle_input()
            self.update(dt)
            if len(self.elementals) <= 0:
                self.run_dialog([
                    "Congratulations! You saved our town! Polaria is safe once more!"
                ])
                self.running = False
            else:
                self.draw(self.screen)
            pygame.display.update()

    def run_dialog(self, text):
        self.update(0)
        while text:
            self.clock.tick(60)
            self.draw(self.screen, text[0])
            if self.handle_dialog_box_input():
                text.remove(text[0])
            pygame.display.update()

    def spawn_elementals(self):
        """Spawn elementals in random positions on the map."""
        self.elementals = list()
        count = 0
        while count < 100:
            x = randint(0, 1120)
            y = randint(0, 1120)
            elemental = Elementals()
            elemental.position = self.map_layer.map_rect.move(x, y).topleft
            elemental.set_rect(x, y)
            if elemental.rect.collidelist(self.walls) == -1:
                self.elementals.append(elemental)
                self.group.add(elemental)
                count += 1

    def handle_dialog_box_input(self):
        for event in pygame.event.get():
            if event.type == QUIT:
                sys.exit()
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_RETURN:
                    return True
                if event.key == K_ESCAPE or event.key == K_q:
                    sys.exit()
            if event.type == VIDEORESIZE:
                init_screen(event.w, event.h)
                self.map_layer.set_size((event.w, event.h))
示例#22
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    def __init__(self):

        # true while running
        self.running = True
        self.time_step = 0
        # load data from pytmx
        tmx_data = load_pygame(self.filename)

        # setup level geometry with simple pygame rects, loaded from pytmx
        self.walls = list()
        for object in tmx_data.objects:
            self.walls.append(
                pygame.Rect(object.x, object.y, object.width, object.height))

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(tmx_data)

        # create new renderer (camera)
        screens = screen.get_size()
        self.map_layer = pyscroll.BufferedRenderer(map_data, (10, 40),
                                                   clamp_camera=True,
                                                   tall_sprites=1)
        self.map_layer.zoom = 0.75

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the defaultmm m,m
        # layer for sprites as 2
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=3)

        self.hero = Hero()

        # put the hero in the center of the map

        self.hero.vi_tri[0] += 200
        self.hero.vi_tri[1] += 100

        # add our hero to the group
        self.group.add(self.hero)

        self.map_layer.set_size(screens)

    def draw(self, surface):

        # center the map/screen on our Hero
        self.group.center(self.hero.rect)

        # draw the map and all sprites
        self.group.draw(surface)

    def handle_input(self, dt):
        """ xử lý sự kiện nhấn nút """
        for event in pygame.event.get():

            if event.type == pygame.QUIT:
                if event.key == pygame.K_ESCAPE:
                    return False
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    return False
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_LEFT:
                    self.hero.go_left(dt)

                if event.key == pygame.K_RIGHT:
                    self.hero.go_right(dt)

                if event.key == pygame.K_UP:

                    for sprite in self.group.sprites():
                        if sprite.feet.collidelist(self.walls) > -1:
                            self.hero.jump(dt)

            else:
                self.hero.stop(dt)

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                self.hero.move_back(dt)
                self.hero.va_cham = True

            else:
                self.hero.vi_tri[1] += 2

        print(self.hero.direction)

    def run(self):
        """ Run the game loop
        """
        clock = pygame.time.Clock()
        self.running = True

        from collections import deque
        times = deque(maxlen=30)

        try:
            while self.running:
                dt = clock.tick() / 1000.
                times.append(clock.get_fps())
                #print(sum(times)/len(times))

                self.handle_input(dt)
                self.update(dt)
                self.draw(screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False
示例#23
0
文件: scroll_map.py 项目: kztd/pgz
class ScrollMap(object):
    """Scroll Map object.

    The implementation is based on [pyscroll](https://github.com/bitcraft/pyscroll)

    This class provides functionality:
    - create and manage a pyscroll group
    - load a collision layers
    - manage sprites added to the map
    - allows to detect collisions with loaded collision layers
    - render the map and the sprites on top
    """
    def __init__(self,
                 screen_size: Tuple[int, int],
                 tmx: pytmx.TiledMap,
                 collision_layers: List[str] = []) -> None:
        """Create scroll map object.

        Args:
            screen_size (Tuple[int, int]): screen resolution will be used to the map rendering
            tmx (pytmx.TiledMap): loaded `pytmx.TiledMap` object
            collision_layers (List[str], optional): List of `pytmx.TiledMap` layer names will be used for tiles collision detection. Defaults to [].
        """
        self._tmx = tmx

        # create new data source for pyscroll
        map_data = pyscroll.data.TiledMapData(self._tmx)

        # create new renderer (camera)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   screen_size,
                                                   clamp_camera=False,
                                                   tall_sprites=1)
        self.map_layer.zoom = 1

        # pyscroll supports layered rendering.  our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self._map_group = PyscrollGroup(map_layer=self.map_layer,
                                        default_layer=2)

        self._map_collision_obj: List[pygame.Rect] = []

        self.add_collision_layers(collision_layers)

    def add_collision_layers(self, collision_layers: List[str]) -> None:
        """Load `pytmx.TiledMap` layer tiles for collision detection.

        Some layer in the `pytmx.TiledMap` might be be used for collision detection.
        For example: the layer includes "island tiles" might be used for collision detection with a "ship" actor.

        Args:
            collision_layers (List[str]): List of `pytmx.TiledMap` layer names will be used for tiles collision detection.
        """
        # setup level geometry with simple pygame rects, loaded from pytmx
        self._map_collision_obj += extract_collision_objects_from_tile_layers(
            self._tmx, collision_layers)

    def view(self) -> Any:
        return self._map_group.view

    def transform(self, pos: Tuple[int, int]) -> Tuple[int, int]:
        return (pos[0] + self._map_group.view.left,
                pos[1] + self._map_group.view.top)

    def draw(self, screen: Screen) -> None:
        """Draw method similar to the `pgz.scene.Scene.draw` method.

        Will draw the map and all actors on top.

        Args:
            dt (float): time in milliseconds since the last update
        """

        self._map_group.draw(screen.surface)

    def update(self, dt: float) -> None:
        """Update method similar to the `pgz.scene.Scene.update` method.

        All the actors attached to the map will be updated.

        Args:
            dt (float): time in milliseconds since the last update
        """
        self._map_group.update(dt)

    def add_sprite(self, sprite: pygame.sprite.Sprite) -> None:
        """Add actor/sprite to the map

        Args:
            sprite (pygame.sprite.Sprite): sprite object to add
        """
        self._map_group.add(sprite)

    def remove_sprite(self, sprite: pygame.sprite.Sprite) -> None:
        """Remove sprite/actor from the map.

        Args:
            sprite (pygame.sprite.Sprite): sprite object to remove
        """
        sprite.remove(self._map_group)

    def set_center(self, point: Tuple[int, int]) -> None:
        self._map_group.center(point)

    def get_center(self) -> Tuple[int, int]:
        if not self.map_layer.map_rect:
            raise Exception("Map was not configured properly")
        return self.map_layer.map_rect.center  # type: ignore

    def change_zoom(self, change: float) -> None:
        value = self.map_layer.zoom + change
        if value > 0:
            self.map_layer.zoom = value

    def set_size(self, size: Tuple[int, int]) -> None:
        self.map_layer.set_size(size)

    def collide_map(self, sprite: pygame.sprite.Sprite) -> bool:
        """Detect a collision with tiles on the map

        Args:
            sprite (pygame.sprite.Sprite): sprite/actor for detection

        Returns:
            bool: True is the collision with the colision layers was detected
        """
        if not sprite.rect:
            return False
        return bool(sprite.rect.collidelist(self._map_collision_obj) > -1)
示例#24
0
文件: base.py 项目: induane/harrenrpg
class BaseLevel:
    def __init__(self, filename, game_loop, **kwargs):
        self.map_filename = filename
        self.map_path = os.path.join(resources.TMX_FOLDER, filename)
        self.name = kwargs.get("name", os.path.splitext(filename)[0])
        LOG.debug("Initializing level with map %s", self.map_path)
        self.game_loop = game_loop
        self.battles_allowed = kwargs.get("battles_allowed", False)
        self.exclude_players = kwargs.get("exclude_players", False)
        self.music = kwargs.get("music", None)
        self.keydown_only = False
        self.keydown_orig = self.keydown_only  # Stash for flipping back to
        self.current_dialog = []
        self.poster_image = None
        self.velocity = 2  # Default movement velocity

        LOG.debug("Populating image cache...")
        self.image_cache = []
        for image in kwargs.get("images", []):
            # If there is no location data tuple, just blit to the middle
            if isinstance(image, str):
                img = get_image(image)
                self.image_cache.append((img, None, None))
            else:
                # Assuming a data tuple of path, x, y
                img_path, x, y = image
                img = get_image(img_path)
                self.image_cache.append((img, x, y))

        LOG.debug("Collecting TMX data...")
        # Collect tmx_data and a surface
        self.map_data = TiledMapData(self.tmx_data)
        self.map_layer = BufferedRenderer(
            self.map_data,
            self.game_screen.get_size(),
            clamp_camera=False,
            background_color=self.map_data.background_color,
            alpha=True,
        )
        self.map_layer.zoom = 2

        # pyscroll supports layered rendering. Our map has 3 'under' layers
        # layers begin with 0, so the layers are 0, 1, and 2.
        # since we want the sprite to be on top of layer 1, we set the default
        # layer for sprites as 2
        self.scroll_group = PyscrollGroup(map_layer=self.map_layer,
                                          default_layer=10)
        if self.player1:
            self.scroll_group.add(self.player1)
        objects = self.custom_objects
        for s_npc in objects["static_npcs"]:
            if s_npc.image:
                try:
                    self.scroll_group.add(s_npc)
                except Exception:
                    LOG.exception("Cannot add static npc")
        for npc in objects["npcs"]:
            if npc.image:
                try:
                    self.scroll_group.add(npc)
                except Exception:
                    LOG.exception("Cannot add npc")
        self.game_screen.fill((0, 0, 0))

    def __call__(self):
        self.start()

    def start(self):
        self.play_music()
        self.draw()

    @cachedproperty
    def tmx_data(self):
        return load_pygame(self.map_path)

    @property
    def font_15(self):
        return self.game_loop.font_15

    @property
    def font_20(self):
        return self.game_loop.font_20

    @property
    def font_25(self):
        return self.game_loop.font_25

    @property
    def font_40(self):
        return self.game_loop.font_40

    @property
    def font_60(self):
        return self.game_loop.font_60

    @cachedproperty
    def music_file(self):
        """Randomly returns a music file if more than one are specified."""
        if not hasattr(self, "_music_files"):
            # Load all properties starting with "music"
            music_files = []
            for key, value in self.tmx_data.properties.items():
                if key.lower().startswith("music"):
                    music_files.append(value)
            self._music_files = music_files

        if not self._music_files:
            LOG.debug("Map %s has no music specified", self.map_filename)
            return None  # No music specified in file

        # If there is only one, just return it every time
        if len(self._music_files) == 1:
            return self._music_files[0]

        rand_idx = random.randint(1, len(self._music_files)) - 1
        return self._music_files[rand_idx]

    @property
    def state(self):
        """Return the state from the parent game loop for convenience."""
        return self.game_loop.state

    @property
    def game_screen(self):
        return self.game_loop.surface

    def play_music(self):
        if not self.game_loop.sound_enabled:
            return  # Don't play the music

        pg.mixer.music.fadeout(100)
        if self.music_file:
            load_music(self.music_file)
            pg.mixer.music.set_volume(self.state["volume"])
            pg.mixer.music.play(-1)
        else:
            pg.mixer.music.fadeout(100)

    def _simple_draw(self):
        """Simple draw used in menus and other non-player based levels."""
        viewport = self.game_screen.get_rect()
        surface = pg.Surface((viewport.width, viewport.height))

        # Alias so we can avoid an attribute lookup on each loop iteration
        surface_blit = surface.blit

        # Draw the map and all sprites
        self.scroll_group.draw(surface)

        # If there are any images, draw them
        for img, x, y in self.image_cache:
            img_rect = img.get_rect()

            # If there is no location data tuple, just blit to the middle
            if x is None or y is None:
                img_rect.center = viewport.center
                surface.blit(img, img_rect)
            else:
                img_rect.midbottom = self.viewport.midbottom
                img_rect.y = y
                img_rect.x = x
            surface_blit(img, img_rect)

        # Draw any text on the surface
        self.draw_text(surface)

        self.game_screen.blit(surface, (0, 0), viewport)

    def draw(self):
        player1 = self.player1
        viewport = self.game_screen.get_rect()
        surface = pg.Surface((viewport.width, viewport.height))
        colliders = self.custom_objects["colliders"]
        portals = self.custom_objects["portals"]
        static_npcs = self.custom_objects["static_npcs"]
        npcs = self.custom_objects["npcs"]
        posters = self.custom_objects["posters"]

        # Center the viewport on player 1
        player1.update()
        self.scroll_group.center(player1.rect)

        if player1.state.startswith("move"):
            orig_x = player1.rect.x
            orig_y = player1.rect.y
            check_box = player1.rect.move(
                player1.x_velocity,
                player1.y_velocity,
            )
            move_player = True

            for portal in portals:
                if portal["rect"].colliderect(check_box):
                    player1.state = "teleporting"
                    player1.teleport_target = portal["teleport_target"]
                    self.state["player1"] = player1.get_state()
                    self.game_loop.current_level = portal["destination"]
                    return

            for poster in posters:
                if poster["rect"].colliderect(check_box):
                    self.reset_player1(orig_x, orig_y)
                    move_player = False
                    for item in poster["requires"]:
                        if item not in self.game_loop.quest_inventory:
                            LOG.debug("Player has not completed the quest")
                            break
                    else:
                        self.poster_image = poster["image"]
                    break

            for s_npc in static_npcs:
                if s_npc.rect.colliderect(check_box):
                    self.reset_player1(orig_x, orig_y)
                    self.current_dialog = s_npc.dialog[:]  # Copy the dialog
                    move_player = False
                    break

            for npc in npcs:
                if npc.rect.colliderect(check_box):
                    self.reset_player1(orig_x, orig_y)
                    self.current_dialog = npc.interact()
                    move_player = False
                    break

            if move_player:
                for collider in colliders:
                    if collider.colliderect(check_box):
                        self.reset_player1(orig_x, orig_y)
                        break

            if move_player is True:
                player1.rect.move_ip(player1.x_velocity, player1.y_velocity)

            if player1.rect.x % 16 == 0 and player1.rect.y % 16 == 0:
                player1.state = "resting"
                self.state["player1"] = player1.get_state()

        # Collect all images to blit
        images_to_blit = []
        img_blit_append = images_to_blit.append  # Alias for performance

        # If there are any images, draw them
        for img, x, y in self.image_cache:
            img_rect = img.get_rect()

            # If there is no location data tuple, just blit to the middle
            if x is None or y is None:
                img_rect.center = viewport.center
            else:
                img_rect.midbottom = self.viewport.midbottom
                img_rect.y = y
                img_rect.x = x
            img_blit_append((img, img_rect))

        # Draw the main scroll group
        self.scroll_group.draw(surface)

        # Draw all collected images to blit
        surface.blits(images_to_blit, doreturn=False)

        # If we have encountered a poster, draw it
        if self.poster_image:
            if isinstance(self.poster_image, str):
                self.poster_image = get_image(self.poster_image)
            poster_rect = self.poster_image.get_rect()
            poster_rect.center = viewport.center
            surface.blit(self.poster_image, poster_rect)

        # Draw any text on the surface
        self.draw_text(surface)

        # Draw any dialog
        self.draw_dialog(surface, viewport)

        # Draw any notifications
        self.draw_notifications(surface, viewport)

        # Draw fps if applicable
        self.draw_fps(surface, viewport)

        self.game_screen.blit(surface, (0, 0), viewport)

    def draw_text(self, surface):
        pass

    def draw_fps(self, surface, viewport):
        """Draw fps if show_fps is set on game loop."""
        if getattr(self.game_loop, "show_fps", False) is True:
            fps = f"{self.game_loop.clock.get_fps():.2f} FPS"
            text = self.font_15.render(fps, True, (255, 255, 255))
            text_rect = text.get_rect()
            text_rect.bottomleft = viewport.bottomleft
            text_rect.x += 5
            text_rect.y -= 5
            surface.blit(text, text_rect)

    def draw_dialog(self, surface, viewport):
        """Draw any current dialog."""
        if not self.current_dialog:
            return
        try:
            text = self.current_dialog[0]
        except Exception:
            LOG.exception("Could not draw dialog text.")
            return

        img = self.dialog_image
        img_rect = img.get_rect()
        img_rect.bottomright = viewport.bottomright
        img_rect.x -= 3
        img_rect.y -= 3
        surface.blit(img, img_rect)

        dialog_text = self.font_20.render(text, True, (255, 255, 255))
        dialog_text_rect = dialog_text.get_rect()
        dialog_text_rect.center = img_rect.center
        surface.blit(dialog_text, dialog_text_rect)

    def draw_notifications(self, surface, viewport):
        """Draw any current notifications."""
        notification = self.game_loop.notification

        if not notification:
            return

        img = self.dialog_image
        img_rect = img.get_rect()
        img_rect.topright = viewport.topright
        img_rect.x -= 3
        img_rect.y += 3
        surface.blit(img, img_rect)

        notification_text = self.font_25.render(notification, True,
                                                (255, 255, 255))
        notification_text_rect = notification_text.get_rect()
        notification_text_rect.center = img_rect.center
        surface.blit(notification_text, notification_text_rect)

    def reset_player1(self, x, y):
        self.player1.rect.x = x
        self.player1.rect.y = y
        self.player1.x_velocity = 0
        self.player1.y_velocity = 0
        self.player1.state = "resting"
        self.state["player1"] = self.player1.get_state()

    @cachedproperty
    def player1(self):
        """
        Create a player instance.

        If starting fresh, load at the levels starting point. Otherwise,
        either restore a previous location or setup a teleport and look for a
        teleport target.
        """
        player1 = Player(self.game_loop, "player.png")
        player1.rect.center = self.start_point.center
        player1.rect.x = self.start_point.x
        player1.rect.y = self.start_point.y

        state_data = self.state["player1"]
        if state_data:
            is_teleporting = state_data["state"] == "teleporting"
            teleport_target = state_data.get("teleport_target")
            state_data["state"] = "resting"
            state_data["x_velocity"] = 0
            state_data["y_velocity"] = 0
            state_data["teleport_target"] = None
            player1.set_state(state_data)

            # If the player was teleporting, place them at the starting point
            if is_teleporting:
                # Try to find a portal with target name if one available
                if teleport_target:
                    for p_target in self.custom_objects["portal_targets"]:
                        if p_target.get("name") == teleport_target:
                            player1.rect.center = p_target["rect"].center
                            player1.rect.x = p_target["rect"].x
                            player1.rect.y = p_target["rect"].y
                            break
                    else:
                        LOG.warning("Could not find target portal %s",
                                    teleport_target)
        return player1

    @cachedproperty
    def dialog_image(self):
        return get_image("dialog_box.png")

    @cachedproperty
    def custom_objects(self):
        """
        All important data types collected in a single iteration.

        Gathers colliders, portals, and start points.
        """
        colliders = []
        start_point = None
        portals = []
        portal_targets = []
        static_npcs = []
        npcs = []
        posters = []
        pg_rect = pg.Rect
        for obj in self.tmx_data.objects:
            name = obj.name
            asset_type = obj.type
            if asset_type == "blocker" or name == "blocker":
                colliders.append(pg_rect(obj.x, obj.y, 16, 16))
            elif not start_point and any((
                    asset_type
                    in ("start_point", "start point", "starting point"),
                    name in ("start_point", "start point", "starting point"),
            )):
                start_point = pg_rect(obj.x, obj.y, 16, 16)
            elif asset_type == "portal_target":
                portal_targets.append({
                    "name": name,
                    "rect": pg_rect(obj.x, obj.y, 16, 16)
                })
            elif asset_type == "portal" or name == "portal":
                custom_properties = obj.properties
                destination = custom_properties.get("destination")
                teleport_target = custom_properties.get("portal")
                if not destination:
                    LOG.warning("Portal at %s, %s missing destination.", obj.x,
                                obj.y)
                else:
                    portals.append({
                        "name": name,
                        "rect": pg_rect(obj.x, obj.y, 16, 16),
                        "destination": destination,
                        "teleport_target": teleport_target,
                    })
            elif asset_type == "static_npc":
                custom_properties = obj.properties
                sprite = custom_properties.get("sprite")
                direction = custom_properties.get("direction", "down")
                static_npcs.append(
                    StaticNPC(
                        self.game_loop,
                        sprite,
                        pg_rect(obj.x, obj.y, 16, 16),
                        direction=direction,
                        dialog=dialog_from_props(custom_properties),
                    ))
            elif asset_type == "npc":
                custom_properties = obj.properties
                custom_properties["name"] = name  # Add name to custom data
                sprite = custom_properties.get("sprite")
                npcs.append(
                    NPC(self.game_loop,
                        sprite,
                        pg_rect(obj.x, obj.y, 16, 16),
                        data=custom_properties))
            elif asset_type == "poster":
                custom_properties = obj.properties
                sprite = custom_properties.get("sprite")
                requires = custom_properties.get("requires").split(",")
                posters.append({
                    "image": custom_properties.get("poster_image"),
                    "requires": [x.strip() for x in requires],
                    "rect": pg_rect(obj.x, obj.y, 16, 16),
                })

        return {
            "colliders": colliders,
            "start_point": start_point,
            "portals": portals,
            "portal_targets": portal_targets,
            "static_npcs": static_npcs,
            "npcs": npcs,
            "posters": posters,
        }

    @cachedproperty
    def start_point(self):
        """
        Returns rectangle representing the starting point in the level.

        If more than one is found, the others will be ignored. If none are
        found a default one will be created at 0, 0
        """
        start_point = self.custom_objects["start_point"]
        if not start_point:
            start_point = pg.Rect(0, 0, 16, 16)
        LOG.debug("Got start point %s", start_point)
        return start_point

    def _pop_dialog(self):
        try:
            d = self.current_dialog.pop(0)
        except IndexError:
            pass
        else:
            LOG.debug("%s dropped from dialog queue", d)

    def down_pressed(self):
        if self.current_dialog or self.poster_image:
            return  # Don't do anything while in dialog mode
        if self.player1.state == "resting":
            self.player1.state = "move-down"
            self.player1.y_velocity = self.velocity
            self.player1.x_velocity = 0

    def up_pressed(self):
        if self.current_dialog or self.poster_image:
            return  # Don't do anything while in dialog mode
        if self.player1.state == "resting":
            self.player1.state = "move-up"
            self.player1.y_velocity = self.velocity * -1
            self.player1.x_velocity = 0

    def left_pressed(self):
        if self.current_dialog or self.poster_image:
            return  # Don't do anything while in dialog mode
        if self.player1.state == "resting":
            self.player1.state = "move-left"
            self.player1.y_velocity = 0
            self.player1.x_velocity = self.velocity * -1

    def right_pressed(self):
        if self.current_dialog or self.poster_image:
            return
        if self.player1.state == "resting":
            self.player1.state = "move-right"
            self.player1.y_velocity = 0
            self.player1.x_velocity = self.velocity

    def space_pressed(self):
        accept_spaces = getattr(self, "accept_spaces", True)
        if accept_spaces:
            self.player1.state = "resting"
            self.player1.y_velocity = 0
            self.player1.x_velocity = 0
            self._pop_dialog()
            self.poster_image = None
            self.accept_spaces = False
        else:
            self.accept_spaces = True
        pg.time.delay(30)
        pg.event.clear()

    def escape_pressed(self):
        self.current_dialog = []
        self.accept_spaces = True
        pass

    def esc_pressed(self):
        return self.escape_pressed()

    def up_released(self):
        pass

    def left_released(self):
        pass

    def right_released(self):
        pass

    def w_released(self):
        pass

    def a_released(self):
        pass

    def s_released(self):
        pass

    def d_released(self):
        pass

    def enter_released(self):
        pass

    def space_released(self):
        pass

    def escape_released(self):
        pass

    def w_pressed(self):
        pass

    def a_pressed(self):
        pass

    def s_pressed(self):
        pass

    def d_pressed(self):
        pass

    def enter_pressed(self):
        return self.space_pressed()
示例#25
0
class QuestGame(object):
    """ This class is a basic game.

    This class will load data, create a pyscroll group, a hero object.
    It also reads input and moves the Hero around the map.
    Finally, it uses a pyscroll group to render the map and Hero.
    """
    filename = get_map(MAP_FILENAME)

    counter = 1
    counter2 = 1

    def __init__(self, state): 
        if state == False:
            self.fullscreen = False
            # true while running.
            self.running = False
            self.clock = pygame.time.Clock()
            # create all the directio variables
            self.direction = "still"
            self.EntityDirection = "still"
            self.EntityDirection1, self.EntityDirection2 = "still", "still"  
            self.fps = 1000

            self.bypass = False

            entityPos1, heroPos1 = False, False
                     
            # load data from pytmx
            tmx_data = load_pygame(self.filename)
            self.tmx_data = tmx_data

            mapPlay = load_pygame(get_map(stats['map']))
            # create new data source for pyscroll
            map_data = pyscroll.data.TiledMapData(mapPlay)
            # setup level geometry with simple pygame rects, loaded from pytmx.
            self.walls = list()
            for object in mapPlay.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))
            
            # create new renderer (camera)
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2

            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)
            self.hero = Hero('Tiles/hero/character_still.png')
            self.entity = Entity('Tiles/hero/character_still.png')
            self.hero.position = stats['pos']
            self.entity.position = stats['pos']
            # add our hero to the group
            self.group.add(self.hero)
            #self.group.add(self.entity)
            
            self.entVel = (0, 0)

    def deep_thought(self): # The 'AI' function, needs work
        if self.counter2 % 75 == 0 or self.bypass == True:
            self.bypass = False
            if random.randint(0, 1) == 1:
                self.entity.velocity[0], self.entity.velocity[1] = 0, 0
            movement = random.choice(["self.entity.velocity[0] = -45; self.EntityDirection = 'left'; self.EntityDirection2 = 'left'",
                                      "self.entity.velocity[0] = 45; self.EntityDirection = 'right'; self.EntityDirection2 = 'right'",
                                      "self.entity.velocity[1] = -45; self.EntityDirection = 'up'; self.EntityDirection1 = 'up'",
                                      "self.entity.velocity[1] = 45; self.EntityDirection = 'down'; self.EntityDirection1 = 'down'"])
            exec(movement)
            
    def EntityAnimation(self, direction, number, character="hero"):
        self.entVel = self.entity.velocity
        
        self.counter += 1
        if self.EntityDirection1 == "still" and self.EntityDirection2 == "still":
            if self.EntityDirection == "left":
                self.entity = Entity('Tiles/' +character +'/walking_left/walking_left1.png')
            if self.EntityDirection == "right":
                self.entity = Entity('Tiles/' +character +'/walking_right/walking_right1.png')
            if self.EntityDirection == "up":
                self.entity = Entity('Tiles/' +character +'/walking_up/walking_up1.png')
            if self.EntityDirection == "down":
                self.entity = Entity('Tiles/' +character +'/walking_down/walking_down1.png')
        else:
            self.entity = Entity('Tiles/' +character +'/walking_' +direction +'/walking_' +direction +str(number) +'.png')
        self.entity.velocity = self.entVel

    def EntMoveBack(self):
        #self.deep_thought(self, True) # Comment this to disable the 'AI'
        pass

    def map_change(self, map, target=False): # Does what it says on the tin
            mapfile = get_map(map)
            tmx_data = load_pygame(mapfile)
            self.tmx_data = tmx_data
            map_data = pyscroll.data.TiledMapData(tmx_data)
            self.walls = list()
            for object in tmx_data.objects:
                self.walls.append(pygame.Rect(
                    object.x, object.y,
                    object.width, object.height))

            # creates new 'camera'
            self.map_layer = pyscroll.BufferedRenderer(map_data, screen.get_size())
            self.map_layer.zoom = 2
            self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)

            #creates a new Hero to go on our new camera
            self.hero = Hero('Tiles/hero/character_still.png')
            try:
                self.hero.position = (target)
            except TypeError:
                self.hero.position = self.map_layer.map_rect.center
            self.map = stats['map'][:-4].lower()
            self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1"
            self.map = self.map.lstrip("aps/")
            
    def switcher(self): # Bunch of IF statements to decide if we're at a door or not, then changes the map.
        if len(objectX) == len(objectY) == len(targetPosX) == len(targetPosY) == len(currentMap) == \
           len(targetMap) == len(animationDirection) == len(targetMapFile) == len(objectType):
            heroPos = [0, 0]
            heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
            for i in range(len(objectX)):
                if self.map == currentMap[i]:
                    if self.hero.position[0] - 15 <= int(objectX[i]) <= self.hero.position[0] + 15:
                        if self.hero.position[1] - 15 <= int(objectY[i]) <= self.hero.position[1] + 15:
                            if objectType[i] == "door":
                                used[i] = True
                                self.map_change(targetMapFile[i])
                                self.map = targetMap[i]
                                stats['map'] = targetMapFile[i]
                                heroPos = (int(targetPosX[i]), int(targetPosY[i]))
                                self.animation(animationDirection[i], 1)
                                self.hero.position = heroPos
                                return False
                            elif objectType[i] == "chest":
                                keyset, self.menu = "chest", "chest"                  
                                if used[i] == False:
                                    if chestContents[i] == None and used[i] == False:
                                        used[i] = True
                                        pickle.dump(used, open(os.path.join("data", "saves", "used.dat"), "wb"))
                                        chestContents[i] = self.genchests()
                                        pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb"))
                                self.chestNo = i                    
                            return False
                        
    def generate_surrounding_maps(self):
        heroPos = [0, 0]
        heroPos = self.hero.position
        if int(self.hero.position[0]) in range((self.tmx_data.width*32)-64,
                                                 (self.tmx_data.width*32)):
            target = (32, heroPos[1])
            self.grid[0] = self.grid[0]+1
            try:
                self.map_change(str(self.grid[0]+1) +", "+ str(self.grid[1]) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                self.animation("right", 1)
                target = (32, heroPos[1])
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range((self.tmx_data.height*32)-64,
                                                 self.tmx_data.width*32):
            target = (heroPos[0], 32)
            self.grid[1] = self.grid[1]+1
            try:
                self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]+1) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("up", 1)
                
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[0]) in range(0, 64):
            target = (self.tmx_data.width*32 - 32, heroPos[1])
            self.grid[0] = self.grid[0]-1
            try:
                self.map_change(str(self.grid[0]-1) +", "+ str(self.grid[1]) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("left", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        elif int(self.hero.position[1]) in range(0, 64):
            target = (heroPos[0], self.tmx_data.height*32 - 32)
            self.grid[1] = self.grid[1]-1
            try:
                self.map_change(str(self.grid[0]) +", "+ str(self.grid[1]-1) +".tmx",
                                target)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
                heroPos[0], heroPos[1] = self.hero.position[0], self.hero.position[1]
                self.animation("down", 1)
                #self.hero.position = target
            except FileNotFoundError:
                self.generate_new_map(4, 16, 2, self.grid, target)
        else:
            pass

    def generate_new_map(self, octaves, freq, area, target, position):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")
            
        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")

        for y in range(self.grid[1] + eval("-"+ str(area)),self.grid[1] +  area):
            for x in range(self.grid[0] + eval("-"+ str(area)),self.grid[0] +  area):
                if os.path.isfile("data/maps/"+str(x)+", "+str(y)+".tmx"):
                    pass
                else:
                    p = subprocess.Popen([executeable, command, ("data/maps/"+
                                                    str(x)+", "+str(y)+".tmx"),
                                      str(octaves), str(freq), str(x), str(y)],
                                         close_fds=True)
        try:
            if p is not None:
                disp_width, disp_height = pygame.display.get_surface().get_size()
                #self.blit_inventory("speach", "Generating Map... Please Wait...")
                self.speach(disp_width, disp_height,
                            "Generating Map... Please Wait...") 
                pygame.display.update()
                p.wait()
                self.map_change((str(target[0])+", "+str(target[1])+".tmx"), position)
                self.map = str(self.grid).lstrip("[").rstrip("]")
                stats['map'] = self.map + ".tmx"
        except UnboundLocalError:
            pass
                    
    def draw(self, surface):
        self.group.center(self.hero.rect.center)
        # draw the map and all sprites
        self.group.draw(surface)

    def speach(self, dispWidth, dispHeight, text):
##        text = "Laudem bonorum salutandi pri te, tollit melius delicata mel cu,\
##                eu mea ullum legimus. Probo debitis te vel. Labores vulputate \
##                argumentum sea id. Cibo vitae vocent eos no, ne odio molestiae\
##                duo."
        screen.blit(pygame.transform.scale(load_image(os.path.join(
            "images", "gui", "speach.png")), (dispWidth, 150)), (0, dispHeight-150))
        text = textwrap.wrap(text, width=95)
        for i, line in enumerate(text): 
            text_blit = pixel_font.render(line, False, pygame.Color('white'))
            screen.blit(text_blit, (60, dispHeight-110 + 25*i))

    def map_generate(self, output, octaves, freq, x, y):
        command = "{}/lib/generate/__init__.py".format(os.getcwd())
        
        if sys.platform.startswith('win32'):
            executeable = ("Python35\python.exe")
            
        elif sys.platform.startswith('linux'):
            executeable = ("python3.5")
            
        subprocess.Popen([executeable, command, output, str(octaves), str(freq),
                          str(x), str(y)],close_fds=True) 

    def handle_input(self, keyset):
        """ Handle pygame input events
        """
        
        poll = pygame.event.poll
        
        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                pygame.quit()
                break

            elif event.type == KEYDOWN:
                

                if keyset == "game":
                    if event.key == K_EQUALS:
                        self.map_layer.zoom += .25

                    elif event.key == K_MINUS:
                        value = self.map_layer.zoom - .25
                        if value > 0:
                            self.map_layer.zoom = value
                        else:
                            self.map_layer.zoom = 0.1

                    elif event.key == K_KP0:
                        try:
                            if self.switcher() == True:
                                self.generate_surrounding_maps()
                        except FileNotFoundError:
                            print("Exception Caught")
                        pass

                    elif event.key == K_e:
                        self.menu = "inventory"
                        pass

                    if event.key == K_ESCAPE:
                        for i in attack_stats_types:
                            stats[i] = attack_stats[i]
                        pickle.dump(stats, open(os.path.join("data", "saves", "save.dat"), "wb"))
                        pickle.dump(inventory, open(os.path.join("data", "saves", "inventory.dat"), "wb"))
                        self.running = False
                        pygame.quit()
                        print(" ")
                        sleep(0.5)
                        print("Shutdown... Complete")
                        sys.exit()
                        break

                if keyset != "game":
                    if event.key == K_ESCAPE:
                        self.menu = "game"
                        pass

                if keyset == "inventory":
                    if event.key == K_r:
                        self.genchests()

                if keyset == "chest":
                    if event.key == K_r:
                        chestContents[self.chestNo] = self.genchests()

                    if event.key == K_t:
                        if taken[self.chestNo] != True:
                            self.takeChest()
                            taken[self.chestNo] = True
                            pickle.dump(taken, open(os.path.join("data", "saves", "taken.dat"), "wb"))

                if keyset == "attack":
                    pass

                #Basically just debug keys
                if event.key == K_KP1:
                    self.menu = "game"
                    pass

                elif event.key == K_KP2:
                    self.map_change(FOREST)
                    self.map = "forest"

                elif event.key == K_KP3:
                    self.generate_new_map(4, 16, 3)
                    pass

                elif event.key == K_KP4:
                    self.map_generate(str(self.grid[0]) +", "+ str(self.grid[1]) +".tmx", 4, 16.0, self.grid[0], self.grid[1])  
                    pass

                elif event.key == K_KP5:
                    self.enemy_stats = self.gen_enemy(attack_stats, enemy_stats)
                    self.menu = "attack"
                    pass

                elif event.key == K_KP6:
                    print("X :" +str(int(self.hero.position[0])) +
                          ", Y: " +str(int(self.hero.position[1])) +
                          ", Map: "+ self.map)
                    pass

                elif event.key == K_KP7:
                    print(str(pygame.mouse.get_pos()))
                    pass
                
                elif event.key == K_KP8:
                    sleep(0.5)

                elif event.key == K_KP9:
                    editor = db_interface.Editor()
                    conn = sqlite3.connect('data/saves/data.db')
                    c = conn.cursor()

                    for var in vars:
                        exec("del "+var+"[:]")
                        for data in c.execute("SELECT {} FROM csv".format(var)):
                            data = str(data[0])
                            exec("{}.append(\"{}\")".format(var, data))
                            pass

                elif event.key == K_F11:
                    for m in screeninfo.get_monitors():
                        displ = str(m)
                        w, h, mx, c = displ.split(", ")
                        
                    if self.fullscreen:
                        self.fullscreen = False
                        screen = init_screen(1024, 700, pygame.HWSURFACE | pygame.FULLSCREEN )
                    else:
                        self.fullscreen = True
                        screen = init_screen(w, h, pygame.HWSURFACE | pygame.RESIZABLE )

                    pygame.display.toggle_fullscreen()

            elif event.type == VIDEORESIZE:
                self.map_layer.set_size((event.w, event.h))
                dispHeight = event.h
                dispWidth = event.w
                

            event = poll()

        # using get_pressed is slightly less accurate than testing for events
        # but is much easier to use.
        if keyset == "game":
            pressed = pygame.key.get_pressed()
            if pressed[K_UP]:
                self.hero.velocity[1] = -HERO_MOVE_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_DOWN]:
                self.hero.velocity[1] = HERO_MOVE_SPEED
                self.direction = "down"
                self.direction2 = "down"
            elif pressed[K_w]:
                self.hero.velocity[1] = -HERO_SPRINT_SPEED
                self.direction = "up"
                self.direction2 = "up"
            elif pressed[K_s]:
                self.hero.velocity[1] = HERO_SPRINT_SPEED
                self.direction = "down"
                self.direction2 = "down"
            else:
                self.hero.velocity[1] = 0
                self.direction2 = "still"
            if pressed[K_LEFT]:
                self.hero.velocity[0] = -HERO_MOVE_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_RIGHT]:
                self.hero.velocity[0] = HERO_MOVE_SPEED
                self.direction = "right"
                self.direction1 = "right"
            elif pressed[K_a]:
                self.hero.velocity[0] = -HERO_SPRINT_SPEED
                self.direction = "left"
                self.direction1 = "left"
            elif pressed[K_d]:
                self.hero.velocity[0] = HERO_SPRINT_SPEED
                self.direction = "right"
                self.direction1 = "right"
            else:
                self.hero.velocity[0] = 0
                self.direction1 = "still"

            if self.direction1 == "still" and self.direction2 == "still":
                self.direction = "still"

    def update(self, dt):
        """ Tasks that occur over time should be handled here
        """
        self.group.update(dt)

        # check if the sprite's feet are colliding with wall
        # sprite must have a rect called feet, and move_back method,
        # otherwise this will fail
        for sprite in self.group.sprites():
            if sprite.feet.collidelist(self.walls) > -1:
                sprite.move_back(dt)

    def animation(self, direction, number):
        if self.direction1 == "still" and self.direction2 == "still":
            if self.direction == "left":
                self.hero = Hero('Tiles/hero/walking_left/walking_left1.png')
            if self.direction == "right":
                self.hero = Hero('Tiles/hero/walking_right/walking_right1.png')
            if self.direction == "up":
                self.hero = Hero('Tileshero/walking_up/walking_up1.png')
            if self.direction == "down":
                self.hero = Hero('Tiles/hero/walking_down/walking_down1.png')

        else:
            self.hero = Hero('Tiles/hero/walking_' +direction +'/walking_' +direction +str(number) +'.png')      

    def genchests(self):

        wr = WeightedRandomizer(itemsProbability)
        
        self.taken = False
        chest.clear()
        numItems = random.randint(1, random.randint(2, 4))
        if random.randint(0, 3) < 1:
            numItems += 1
        elif random.randint(0, 9) < 2:
            numItems += 2
        elif random.randint(0, 18) < 2:
            numItems += 5
        for i in range(0, numItems):
            item = wr.random()
            while item in chest: 
                item = wr.random()
            chest.append(item)

        return chest

    def gen_enemy(self, player_stats, enemy_stat):
        stats = attack_stats_types
        stat = player_stats
        for i in range(len(player_stats)):
            j = stats[i]
            try:
                enemy_stat[stats[i]] = int((stat[j]-(stat[j]*0.2)) + random.randint(0, int(stat[j]*0.4)))
            except TypeError:
                enemy_stat[j] = choice(attack_types)
        return enemy_stat
        pass

    def player_attack():
        type = None
        while type not in attack_types:
            type = input("[ QUESTION ] Enter attack type. ")
            if type not in attack_types:
                print("[ ERROR    ] Attack type {} not found. Must be {}".format(type, attack_types))
            else:
                break
        return type
        pass

    def attack(self, attacker_stats, defender_stats, player_attack_type):
        fraction = attacker_stats['strength'] / defender_stats['blocking']
        print("[ INFO     ] Defender attack type: {}".format(defender_stats['attack']))
        if player_attack_type != defender_stats['attack']:
            if fraction > (0.8 + (randint(0, 40)/100)):
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        elif player_attack_type == attacker_stats['attack']: # Better odds here
            if fraction > (0.9 + (randint(0, 40)/100)):
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        else:
            if fraction > (0.70 + (randint(0, 40)/100)): # Odds are worse here
                attacker_stats['health'] -= int(fraction*10)
                pass # Attacker Win
            else:
                defender_stats['health'] -= int(fraction*10)
                pass # Attacker Loss
        print("[ INFO     ] Attacker: {}  Defender: {}".format(attacker_stats['health'], defender_stats['health']))
        print("[ INFO     ] Health to be lost: {}".format(int(fraction*10)))
        return attacker_stats, defender_stats
        
    def blit_inventory(self, screenMode, speach=None):
        if screenMode != "game":
            xCounter, counter, OverCounter = 0, 0, 0
            dispWidth, dispHeight = pygame.display.get_surface().get_size()
            guiX = (dispWidth / 2) - 175
            guiY = (dispHeight / 2) - 165
            screen.blit(load_image(os.path.join("images", "gui", "transparent.png")),( 0, 0))
            screen.blit(load_image(os.path.join("images", "gui", screenMode +".png")),(guiX, guiY))
        if screenMode == "inventory" or screenMode == "chest":
            dt = (clock.tick() / 500)
            clock.tick(self.fps)

            if len(inventory) > 0:
                for i in range(0, len(inventory)):
                    OverCounter += 1
                    if xCounter >= 9:
                        counter += 1
                        xCounter = 0
                    screen.blit(load_image(os.path.join("images", "items",\
                    str(items[inventory[i]])+".png")), (guiX + 16 + 36*xCounter, guiY + 168 + 36*counter))
                    xCounter += 1
        if screenMode == "chest" and chestContents[self.chestNo] != None:
            itemNo = 0
            for i in range(0, len(chestContents[self.chestNo])):
                screen.blit(load_image(os.path.join("images", "items",\
                            items[str(chestContents[self.chestNo][i])]\
                            +".png")), (guiX + 123 + 36*itemNo,\
                            guiY + 34 + int(35 * (i/3)) - int(35 * (i/3)) % 35))

                if itemNo < 2:
                    itemNo += 1
                else:
                    itemNo = 0

        if screenMode == "speach":
            self.speach(dispWidth, dispHeight, speach)
        if screenMode == "attack":
            picture = load_image(os.path.join("Tiles", "hero", "walking_down", "walking_down1.png"))
            picture = pygame.transform.scale(picture, (100, 100))
            rect = picture.get_rect()
            rect = rect.move((guiX + 50, guiY + 28))
            screen.blit(picture, rect)
            text = font.render("Player : Enemy", True, pygame.Color('black'))
            screen.blit(text, (guiX + 172, guiY + 45))
            text = "Health: "+str(attack_stats['health'])+"    Skill: "+str(attack_stats['skill'])+"    Attack: "+str(attack_stats['attack'])
            text_render = pixel_font.render(text, False, pygame.Color('gray27'))
            screen.blit(text_render, (guiX+20, guiY+290))
            for i, attack in enumerate(attack_types):
                text = load_font(30, "data/PixelFont.ttf").render(attack, False, pygame.Color('black'))
                screen.blit(text, (guiX+172, guiY+25+28*(i+2)))
            #
            if pygame.mouse.get_pressed()[0] == 1:
                #print(pygame.mouse.get_pos())
                mouse_pos = pygame.mouse.get_pos()
                if guiX+160 < mouse_pos[0] and guiX+330 > mouse_pos[0]: 
                    for i, attack in enumerate(attack_types):
                        if guiY+25+28*(i+2) < mouse_pos[1] and (guiY+25+28*(i+2))+28 > mouse_pos[1]:
                            print(attack)
                            self.attack(attack_stats, enemy_stats, attack)
                        else:
                            pass

            pass
                
    def takeChest(self):
        if len(inventory) < 27:  
            if chestContents[self.chestNo] != None:
                for i in range(0, (len(chestContents[self.chestNo]))):
                    #print(i)
                    inventory.append(chestContents[self.chestNo][i])
                chestContents[self.chestNo][:] = []
            pickle.dump(chestContents, open(os.path.join("data", "saves", "chestContents.dat"), "wb"))
            
                
    def run(self):
        screenMode = pygame.RESIZABLE

        oldPlay = stats['playTime']
        clock = pygame.time.Clock()
        self.running = True

        self.grid = [0, 0]

        debug = True
        dispWidth, dispHeight = 1024, 768
        self.menu = "game"
        game_time = pygame.time.get_ticks()
        playTime = font.render("Timer: ", False, pygame.Color('white'))        
        minutes = 0

        self.map = stats['map'][:-4].lower()
        self.map = self.map.lstrip("m") # Fix that stupid bug that changes "maze1" to "ze1"
        self.map = self.map.lstrip("aps/")
        
        try:
            while self.running:
                dt = (clock.tick() / 500)
                clock.tick(self.fps)

                if self.menu == "game":
                    #self.deep_thought()
                    if self.counter2 % 7 == 0:
                        heroPos = self.hero.position
                        self.animation(self.direction, self.counter)
                        self.hero.position = heroPos
                        #entityPos = self.entity.position
                        #self.EntityAnimation(self.EntityDirection, self.counter, "princess")
                        #self.entity.position = entityPos
                        
                        self.counter += 1
                        guiX = (dispWidth / 2) - 175
                        guiY = (dispHeight / 2) - 165
                        
                        self.group.remove(self.hero)
                        #self.group.remove(self.entity)
                        self.group.empty()
                        self.group.add(self.hero)
                        #self.group.add(self.entity)

                self.counter2 += 1
                if self.counter > 8:
                    self.counter = 1

                stats['pos'] = self.hero.position
                currentTime = systime()
                seconds = currentTime - gameStart + oldPlay
                dispWidth, dispHeight = pygame.display.get_surface().get_size()
                stats['playTime'] = seconds

                

                if debug == True and self.counter2 % 1 == 0:
                    location = font.render("Position: " + str(round(round(self.hero.position[0], -1) / 10)) + ", " + str(round(round(self.hero.position[1], -1) / 10)), False, pygame.Color('white'))
                    mapdebug = font.render("Map Name: " + str(self.map), False, pygame.Color('white'))
                    minutes = seconds // 60
                    secondsDisp = seconds % 60
                    if minutes < 1:
                        minutes = 0
                    if secondsDisp == 60:
                        secondsDisp = 0
                        minutes += 1
                    fps = font.render("FPS:" + str(int(clock.get_fps())), False, pygame.Color('white'))
                    screen.blit(fps, (50, 50))
                    screen.blit(playTime, (50,100))
                    screen.blit(location, (50,75))
                    screen.blit(mapdebug, (50, 125))

                    playTime = font.render("Timer: " + str(floor(minutes)) + " : " + str(round(secondsDisp)), True, pygame.Color('white'))
                    screen.blit(playTime, (50,100))    


                self.blit_inventory(str(self.menu))
                      
                pygame.display.update()
                #pygame,display.flip()
                self.handle_input(self.menu)
                self.update(dt)
                self.draw(screen)

        except KeyboardInterrupt:
            self.running = False
            pygame.quit()
示例#26
0
class WorldInfo(tools._State):
    def __init__(self,map,surface,world,music):
        super(WorldInfo, self).__init__()
        tmx_data = load_pygame(map)
        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE)
        self.map_layer.zoom = 0.5
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)
        self.animations = pg.sprite.Group()
        self.labels = pg.sprite.Group()
        self.letters = pg.sprite.Group()
        self.surface = surface.convert_alpha()
        self.world = world
        self.music = music

        for object in tmx_data.objects:
            if object.name == 'enemy':
                Enemy(object.x, object.y, self.group)
            elif object.name == 'fish':
                Fish(object.x, object.y, self.group)
            elif object.name == 'fly':
                Fly(object.x, object.y, self.group)
            elif object.name == 'coin':
                Coin(object.x, object.y, self.group)
            elif object.name == 'bat':
                Bat(object.x, object.y, self.group)
            elif object.name == 'enimy':
                Enimy(object.x, object.y, self.group)
            elif object.name == 'f1sh':
                F1sh(object.x, object.y, self.group)


        self.font = FONTS["UbuntuMono-B"]
        timespan = 3000
        midbottom = (SCREEN_RECT.centerx, SCREEN_RECT.bottom - 20)

        self.prompt = Blinker("Press Enter key to continue", {"midbottom": midbottom},
                              500, text_color=(255, 255, 255), font_path=self.font,
                              font_size= 25)

        task = Task(self.labels.add, timespan, args=(self.prompt,))
        self.animations.add(task)


    def startup(self, persist):
        pg.mixer.init()
        song = self.music
        pg.mixer.music.load(song)
        pg.mixer.music.set_volume(0.1)
        pg.mixer.music.play()

        self.done = False
        self.persist = persist
        self.mask = self.persist['surface']
        self.transition = Transition(self.mask)
        if 'lives' in self.persist:
            self.lives = self.persist['lives']
        else:
            self.lives = LIVES
        if 'coins' in self.persist:
            self.coins = self.persist['coins']
        else:
            self.coins = 0


        font_color = (197, 143, 92)
        text = 'Bottom World' if self.world =='bottom' else 'Upper World'
        Label(text,{"topleft": (10, 10)}, self.labels, font_path=self.font, font_size=20,text_color = font_color)

        self.live_surf = pg.Surface((100,20),pg.SRCALPHA)
        image = pg.transform.scale(GFX['hud_0'],(20,20))
        self.live_surf.blit(image, (30,0))
        labels = pg.sprite.Group()
        Label(' X {}'.format(self.lives), {"topleft": (50, 0)}, labels, font_path= self.font, font_size=20,text_color = font_color)
        labels.draw(self.live_surf)

        self.coin_surf = pg.Surface((100,20),pg.SRCALPHA)
        img = pg.transform.scale(GFX['hud_coins'], (20, 20))
        self.coin_surf.blit(img,(30,0))
        lab = pg.sprite.Group()
        Label(' X {}'.format(self.coins), {"topleft": (50, 0)}, lab, font_path=self.font, font_size=20,
              text_color=font_color)
        lab.draw(self.coin_surf)


    def cleanup(self):
        pg.mixer.quit()
        self.persist['coins'] = self.coins
        self.persist['lives'] = self.lives
        self.persist['surface']= pg.display.get_surface()
        return self.persist

    def get_event(self, event):
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYUP:
            if event.type == pg.K_ESCAPE:
                self.quit = True
            elif event.key == pg.K_RETURN:
                self.done = True
                self.next = "LEVELPLAY"

    def update(self, dt):
        self.group.update(dt)
        self.animations.update(dt)
        self.labels.update(dt)

    def draw(self, surface):
        self.group.draw(surface)
        self.group.center((SCREEN_RECT.centerx,SCREEN_RECT.bottom))
        surface.blit(self.surface, (0, 0))
        surface.blit(self.live_surf,(0,40))
        surface.blit(self.coin_surf,(0,80))
        self.letters.draw(surface)
        self.labels.draw(surface)
        self.transition.draw(surface)
示例#27
0
class LevelPlay(tools._State):
    def __init__(self):
        super(LevelPlay, self).__init__()

        tmx_data = load_pygame(MAP['map0'])

        map_data = pyscroll.data.TiledMapData(tmx_data)
        self.map_rect = pg.Rect(0, 0,
                                map_data.map_size[0] * map_data.tile_size[0],
                                map_data.map_size[1] * map_data.tile_size[1])
        self.map_layer = pyscroll.BufferedRenderer(map_data, SCREEN_SIZE)
        self.map_layer.zoom = 1
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=2)
        self.animations = pg.sprite.Group()
        self.labels = pg.sprite.Group()
        self.enemies = pg.sprite.Group()
        self.coins = pg.sprite.Group()
        self.pos_x = None
        self.pos_y = None
        self.pos_x_r = None
        self.pos_y_r = None
        self.upper_world = False

        self.time = 0
        self.timer = TIME
        self.coin_num = 0
        self.player_lives = 0
        self.hud = Hud()

        self.walls = list()
        for object in tmx_data.objects:
            if object.name == 'collide':
                self.walls.append(
                    pg.Rect(object.x, object.y, object.width, object.height))
            elif object.name == 'playerpos':
                self.pos_x = object.x
                self.pos_y = object.y
                self.player = Player(self.pos_x, self.pos_y, False, self.group)
            elif object.name == 'playerpos_r':
                self.pos_x_r = object.x
                self.pos_y_r = object.y
            elif object.name == 'enemy':
                Enemy(object.x, object.y, self.enemies)
            elif object.name == 'fish':
                Fish(object.x, object.y, self.enemies)
            elif object.name == 'fly':
                Fly(object.x, object.y, self.enemies)
            elif object.name == 'coin':
                Coin(object.x, object.y, self.coins)
            elif object.name == 'bat':
                Bat(object.x, object.y, self.enemies)
            elif object.name == 'enimy':
                Enimy(object.x, object.y, self.enemies)
            elif object.name == 'f1sh':
                F1sh(object.x, object.y, self.enemies)
            elif object.name == 'over_event':
                self.over_rect = pg.Rect(object.x, object.y, object.width,
                                         object.height)
            elif object.name == 'over_event_r':
                self.over_rect_r = pg.Rect(object.x, object.y, object.width,
                                           object.height)

        self.player.platform = self.walls

    def get_event(self, event):

        self.player.get_event(event)
        if event.type == pg.QUIT:
            self.quit = True
        elif event.type == pg.KEYDOWN:
            if event.key == pg.K_SPACE:
                self.map_layer.zoom = 0.5
        elif event.type == pg.KEYUP:
            if event.type == pg.K_ESCAPE:
                self.quit = True
            elif event.key == pg.K_SPACE:
                self.map_layer.zoom = 1
            else:
                pass

    def startup(self, persist):
        pg.mixer.init()

        song = MUSIC['bg']
        pg.mixer.music.load(song)
        pg.mixer.music.set_volume(0.1)
        pg.mixer.music.play()

        self.done = False
        self.persist = persist
        self.mask = self.persist['surface']
        self.transition = Transition(self.mask)
        self.player_lives = self.persist['lives']
        self.coin_num = self.persist['coins']

        if self.player.reverse == True:
            self.fog = pg.Surface(SCREEN_RECT.size, pg.SRCALPHA)
            self.fog_color = (0, 0, 0, 200)
            self.fog.fill(self.fog_color)

    def player_dead(self):
        sound = SFX['dead0']
        sound.play()

        self.player_lives -= 1
        if self.player_lives < 1:
            self.done = True
            self.next = 'LOSE'
        buffer = pg.display.get_surface()
        self.switch_screen = Transition(buffer)
        if self.player.reverse == False:
            self.player.rect.x, self.player.rect.y = self.pos_x, self.pos_y
        elif self.player.reverse == True:
            self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r

    def update(self, dt):
        self.offset_x, self.offset_y = self.group._map_layer.get_center_offset(
        )

        self.time += dt
        if self.time > self.timer:
            self.time -= self.timer
            self.player_dead()

        self.group.update(dt)
        self.enemies.update(dt)
        self.coins.update(dt)
        self.hud.update(self, dt)
        self.animations.update(dt)

        if self.player.rect.colliderect(self.over_rect_r):
            if self.player.reverse == True:
                self.done = True
                self.next = 'WIN'

        if self.player.rect.colliderect(self.over_rect):
            self.player.rect.x, self.player.rect.y = self.pos_x_r, self.pos_y_r
            if self.coin_num >= 30:
                self.player.kill()
                self.player = Player(self.pos_x_r, self.pos_y_r, True,
                                     self.group)
                self.player.platform = self.walls
                self.done = True
                self.next = 'UPPER'
            elif self.coin_num < 30:
                self.player.reverse = False
                self.done = True
                self.next = 'BOTUP'

        if pg.sprite.spritecollide(self.player, self.coins, True):
            self.coin_num += 1
            sound = SFX['coin']
            sound.play()
            self.labels.empty()
            self.animations.empty()
            coin_sprite = pg.sprite.Sprite(self.labels)
            coin_sprite.image = GFX['hud_coins']
            x = self.offset_x + self.player.rect.x
            y = self.offset_y + self.player.rect.y
            coin_sprite.rect = pg.Rect((x, y), coin_sprite.image.get_size())
            ani = Animation(x=50, y=10, duration=100, transition="out_bounce")
            ani.start(coin_sprite.rect)
            self.animations.add(ani)

        if not self.map_rect.contains(self.player.rect):
            self.player_dead()

        if pg.sprite.spritecollide(self.player, self.enemies, False):
            self.player_dead()

        self.labels.update(dt)

    def cleanup(self):
        pg.mixer.quit()
        self.persist = {}
        self.persist['coins'] = self.coin_num
        self.persist['lives'] = self.player_lives
        self.persist['surface'] = pg.display.get_surface()
        return self.persist

    def draw(self, surface):
        self.group.empty()
        if self.player.reverse == True:
            close = (enemy for enemy in self.enemies if get_distance(
                enemy.rect.center, self.player.rect.center) <= 100)
            close_enemies = pg.sprite.Group(close)
            self.group.add(self.player, self.coins, close_enemies)
        elif self.player.reverse == False:
            close = (enemy for enemy in self.enemies if get_distance(
                enemy.rect.center, self.player.rect.center) <= SCREEN_SIZE[0])
            close_enemies = pg.sprite.Group(close)
            self.group.add(self.player, self.coins, close_enemies)

        self.group.draw(surface)
        self.group.center(self.player.rect.center)

        if hasattr(self, 'fog') and self.map_layer.zoom == 1:
            self.fog.fill(self.fog_color)
            for i in range(200):
                pg.draw.circle(self.fog, pg.Color(0, 0, 0, 200 - i),
                               (self.player.rect.centerx + self.offset_x,
                                self.player.rect.centery + self.offset_y),
                               int(100 - i * 0.5))
            surface.blit(self.fog, (0, 0))
        elif hasattr(self, 'fog') and self.map_layer.zoom == 0.5:
            self.fog.fill(self.fog_color)
            surface.blit(self.fog, (0, 0))

        self.hud.draw(surface)
        self.transition.draw(surface)
        self.labels.draw(surface)

        if hasattr(self, 'switch_screen'):
            self.switch_screen.draw(surface)
示例#28
0
class TravelGame(object):
    filename = get_map('testing.tmx')

    def __init__(self, *args, **kwargs):
        self.running = False

        tilemap_data = load_pygame(self.filename)
        map_data = pyscroll.data.TiledMapData(tilemap_data)
        self.map_layer = pyscroll.BufferedRenderer(map_data,
                                                   screen.get_size(),
                                                   clamp_camera=False)
        self.map_layer.zoom = 5
        self.group = PyscrollGroup(map_layer=self.map_layer, default_layer=4)
        self.player = Player()
        self.player.position = (128, 248)
        self.group.add(self.player)
        self.blockers = []
        for obj in tilemap_data.get_layer_by_name("collision"):
            properties = obj.__dict__
            if properties['name'] == 'blocker':
                x = properties['x']
                y = properties['y']
                width = properties['width']
                height = properties['height']
                new_rect = pygame.Rect(x, y, width, height)
                self.blockers.append(new_rect)

    def draw(self, surface):
        self.group.center(self.player.rect.center)
        self.group.draw(surface)

    def handle_input(self):
        poll = pygame.event.poll

        event = poll()
        while event:
            if event.type == QUIT:
                self.running = False
                break
            event = poll()

        pressed = pygame.key.get_pressed()
        if pressed[K_DOWN]:
            self.player.vely = SPEED
        elif pressed[K_UP]:
            self.player.vely = -SPEED
        else:
            self.player.vely = 0

        if pressed[K_LEFT]:
            self.player.velx = -SPEED
        elif pressed[K_RIGHT]:
            self.player.velx = SPEED
        else:
            self.player.velx = 0

        # TODO Fix collision so they player stops when they hit a collider
        for blocker in self.blockers:
            if self.player.rect.colliderect(blocker):
                print("collide")

    def update(self, dt):
        self.group.update(dt)

    def run(self):
        clock = pygame.time.Clock()
        self.running = True

        from collections import deque
        times = deque(maxlen=30)

        try:
            while self.running:
                dt = clock.tick() / 1000.
                times.append(clock.get_fps())

                self.handle_input()
                self.update(dt)
                self.draw(screen)
                pygame.display.flip()

        except KeyboardInterrupt:
            self.running = False