예제 #1
0
 def __init__(self, msg, size, align="c", bgcolor=(0,0,0)):
     StaticWidget.__init__(self, size)
     self.msg = msg
     self.align = align
     self.bgcolor = bgcolor
     self.changed = 0
     self.show_msg()
예제 #2
0
    def __init__(self, img=None, lost=False):
        img = pygame.Surface((800, 600))
        BgState.__init__(self, img)
        self.game_bg = img.copy()
        pygame.mouse.set_visible(1)

        #background of message
        size = (300, 300)
        msg_bg = StaticWidget(size)
        #draw_border(msg_bg)
        pos = utils.center(size, (800, 600))
        msg_bg.set_pos(pos)
        self.msg_bg = msg_bg
        msg_pos = pos

        #message
        img = GFX["win"]
        if lost:
            img = GFX["lose"]
        pos = (utils.center(img.get_size(), size)[0], 1)
        msg_bg.blit(img, pos)

        score = SAVE["cur"]["score"] + 100 * SAVE["cur"]["lives"]
        txt = "Score: " + str(score)
        txt_img = TextLine(txt, fontsize=20)
        pos = (utils.center(txt_img.get_size(), size)[0], size[1] - 60)
        msg_bg.blit(txt_img, pos)

        scr_list = ScoreList()
        scr_list.max = 10
        scr_list.set_list(SAVE["overhigh"])

        #add highscore entry
        if scr_list.check(score):
            txt = "New Highscore!"
            txt_img = TextLine(txt, fontsize=20)
            pos = (utils.center(txt_img.get_size(), size)[0], size[1] - 30)
            msg_bg.blit(txt_img, pos)

            scr_list.max = 10
            scr_list.add(SAVE["cur"]["name"], score, SAVE["cur"]["lives"])
            SAVE["overhigh"] = scr_list.get_list()
            save_data()

        btn = FixedTextButton((120, 25), "Exit", callback=self.quit)
        btn.draw_border()
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 4))
        self.add_button("continue", btn)

        btn = FixedTextButton((120, 25),
                              "Highscore",
                              callback=self.to_highscore)
        btn.draw_border()
        btn.set_pos((msg_pos[0] + size[0] - 120, msg_pos[1] + size[1] + 4))
        self.add_button("highscore", btn)

        SAVE["cur"] = {}  #delete savegame
        save_data()

        self.redraw()
예제 #3
0
 def __init__(self, width, bgcolor, msg):
     lines = self.gen_lines(msg, width)
     width = width
     height = 7 * len(lines)
     self.bgcolor = bgcolor
     StaticWidget.__init__(self, (width, height))
     self.gen_image(lines)
    def __init__(self, max=15):
        size = (max * 14, 20)
        StaticWidget.__init__(self, size)
        self.fill((0, 0, 0))

        self.text_line = TextLine(" " * max, 14)
        self.max = max
        self.text = ""
예제 #5
0
 def __init__(self):
     State.__init__(self)
     self.bg_image = GLOBALS["backgrounds"]["the_end.png"]
     self.overlay = StaticWidget((638, 169))
     self.overlay.set_pos((2, 160))
     self.overlay.set_alpha(255)
     self.overlay.fill((0, 0, 0))
     self.wait = Timer(50)
예제 #6
0
 def __init__(self, images, delay=5):
     size = images[0].get_size()
     StaticWidget.__init__(self, size)
     self.images = images
     self.bg = pygame.Surface(size)
     self.delay = delay
     self.nr = 0
     self.timer = Timer(delay)
     self.active = 0
     self.flip()
예제 #7
0
    def __init__(self, size=(160, 22), fontsize=20, text="", blinky="|"):
        self.text = text
        self.fsize = fontsize
        self.text_img = TextLine(self.text, fontsize=fontsize)
        self.blinky = TextLine(blinky, fontsize=fontsize)
        self.do_blink = False
        StaticWidget.__init__(self, size)
        self.timer = utils.Timer(20)

        self.changed = 1
        self.update()
예제 #8
0
    def __init__(self, bgimg=None):
        BgState.__init__(self, bgimg)

        pygame.mouse.set_visible(1)

        #background of message
        size = (250, 100)
        msg_bg = StaticWidget(size)
        draw_border(msg_bg)
        pos = utils.center(size, (800, 600))
        msg_bg.set_pos(pos)
        self.msg_bg = msg_bg
        msg_pos = pos

        txt_img = TextLine("Paused", fontsize=30)
        pos = (utils.center(txt_img.get_size(), size))
        msg_bg.blit(txt_img, pos)
        msg_bg.draw(self.background)

        #continue/cancel buttons
        btn = FixedTextButton((100, 24), "Abort Game", callback=self.to_menu)
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("cancel", btn)
        btn.draw(self.background)

        btn = FixedTextButton((100, 24), "Continue", callback=self.quit)
        btn.set_pos((msg_pos[0] + size[0] - 100, msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("start", btn)
        btn.draw(self.background)

        self.upd = 1
예제 #9
0
    def __init__(self, img, map, mapname="", folder="custom"):
        BgState.__init__(self, img)
        self.map = map
        self.folder = folder
        pygame.mouse.set_visible(1)

        #background image + "save as"
        self.menu = StaticWidget((250, 100))
        self.menu.fill((0, 0, 0))
        txt = TextLine("Save as:", fontsize=15)
        self.menu.blit(txt, (10, 10))
        w, h = self.menu.get_size()
        pygame.draw.lines(self.menu, (0, 0, 255), True,
                          ((0, 0), (w - 4, 0), (w - 4, h - 4), (0, h - 4)), 4)
        x, y = utils.center((w, h), (800, 600))
        self.menu.set_pos((x, y))

        #text entry + ".map"
        self.entry = TextEntry(text=mapname[:-4])
        self.entry.set_pos((x + 10, y + 30))
        txt = TextLine(".map", fontsize=20)
        self.menu.blit(txt, (self.entry.get_size()[0] + 15, 30))

        #save/cancel buttons
        msg_pos = self.menu.get_pos()
        size = self.menu.get_size()
        btn = FixedTextButton((100, 24), "Cancel", callback=self.quit)
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("cancel", btn)
        btn.draw(self.background)

        btn = FixedTextButton((100, 24), "Save", callback=self.submit)
        btn.set_pos((msg_pos[0] + size[0] - 100, msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("save", btn)
        btn.draw(self.background)

        self.redraw()

        self.quit_timer = utils.Timer(20)
        self.quit_timer.deactivate()

        self.add_kbevent(KEYDOWN, K_ESCAPE, callback=self.quit)
        self.add_textentry_events(self.entry)
예제 #10
0
    def __init__(self, dialog):
        self.done = 0
        size = (590, 140)
        pos = (utils.center(size, GLOBALS["screen_size"])[0], 30)
        StaticWidget.__init__(self, size)
        self.set_pos(pos)

        self.dialog = dialog
        self.cur_page = 0

        #txt and portrait placement
        self.txt_length = 45
        self.txt_pos = (130, 15)
        self.port_pos = (20, 15)

        #blinky <press space> textline
        self.blink_timer = utils.Timer(20)
        self.draw_textline = 0
        self.textline = TextLine("PRESS X", fontsize=12)
        x = size[0] - self.textline.get_size()[0] - 5
        y = size[1] - self.textline.get_size()[1] - 2
        self.textline.set_pos((x, y))

        self.bg = pygame.Surface(size)  #may add some border/decoration
예제 #11
0
    def __init__(self, bgimg=None, mapname="", folder="", pacmode=False):
        BgState.__init__(self, bgimg)
        pygame.mouse.set_visible(1)

        self.pacmode = pacmode
        self.mapname = mapname
        self.folder = folder

        #background of message
        size = (250, 100)
        msg_bg = StaticWidget(size)
        draw_border(msg_bg)
        pos = utils.center(size, (800, 600))
        msg_bg.set_pos(pos)
        self.msg_bg = msg_bg
        msg_pos = pos

        txt_img = TextLine("You lose.", fontsize=30)
        pos = (utils.center(txt_img.get_size(), size))
        msg_bg.blit(txt_img, pos)
        msg_bg.draw(self.background)

        #continue/cancel buttons
        btn = FixedTextButton((100, 24), "Abort Game", callback=self.quit)
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("cancel", btn)
        btn.draw(self.background)

        btn = FixedTextButton((100, 24), "Try Again", callback=self.tryagain)
        btn.set_pos((msg_pos[0] + size[0] - 100, msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("start", btn)
        btn.draw(self.background)

        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)
        self.upd = 1
예제 #12
0
class SaveMenu(BgState):
    def __init__(self, img, map, mapname="", folder="custom"):
        BgState.__init__(self, img)
        self.map = map
        self.folder = folder
        pygame.mouse.set_visible(1)

        #background image + "save as"
        self.menu = StaticWidget((250, 100))
        self.menu.fill((0, 0, 0))
        txt = TextLine("Save as:", fontsize=15)
        self.menu.blit(txt, (10, 10))
        w, h = self.menu.get_size()
        pygame.draw.lines(self.menu, (0, 0, 255), True,
                          ((0, 0), (w - 4, 0), (w - 4, h - 4), (0, h - 4)), 4)
        x, y = utils.center((w, h), (800, 600))
        self.menu.set_pos((x, y))

        #text entry + ".map"
        self.entry = TextEntry(text=mapname[:-4])
        self.entry.set_pos((x + 10, y + 30))
        txt = TextLine(".map", fontsize=20)
        self.menu.blit(txt, (self.entry.get_size()[0] + 15, 30))

        #save/cancel buttons
        msg_pos = self.menu.get_pos()
        size = self.menu.get_size()
        btn = FixedTextButton((100, 24), "Cancel", callback=self.quit)
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("cancel", btn)
        btn.draw(self.background)

        btn = FixedTextButton((100, 24), "Save", callback=self.submit)
        btn.set_pos((msg_pos[0] + size[0] - 100, msg_pos[1] + size[1] + 4))
        btn.draw_border()
        self.add_button("save", btn)
        btn.draw(self.background)

        self.redraw()

        self.quit_timer = utils.Timer(20)
        self.quit_timer.deactivate()

        self.add_kbevent(KEYDOWN, K_ESCAPE, callback=self.quit)
        self.add_textentry_events(self.entry)

    def redraw(self):
        self.menu.draw(self.background)
        for b in self.buttons.keys():
            self.buttons[b].draw(self.background)
        self.entry.draw(self.background)
        self.upd = 1

    def update_other(self):
        if self.quit_timer.active:
            if self.quit_timer.update():
                self.quit()
        elif self.entry.update():
            self.redraw()

    def submit(self):
        if self.quit_timer.active:
            return

        filename = self.entry.text + ".map"
        if not self.map.save(filename, self.folder):
            txt = "Ok, map saved."
            self.next = Editor(filename, folder=self.folder)
        else:
            txt = "ERROR: Could not save map."

        size = self.menu.get_size()
        msg = pygame.Surface((size[0] - 2, size[1] - 2))
        msg.fill((0, 0, 0))
        txt = TextLine(txt)
        msg.blit(txt, utils.center(txt.get_size(), msg.get_size()))
        self.menu.blit(msg, (1, 1))
        self.menu.draw(self.background)
        self.upd = 1

        self.quit_timer.activate()
예제 #13
0
    def __init__(self, bgimg=None):
        BgState.__init__(self, bgimg)

        #background of message
        size = (300, 200)
        msg_bg = StaticWidget(size)
        #msg_bg.fill((0,0,128))
        draw_border(msg_bg)
        pos = utils.center(size, (800, 600))
        msg_bg.set_pos(pos)
        self.msg_bg = msg_bg
        msg_pos = pos

        txt = "New game"
        txt_img = TextLine(txt, fontsize=30)
        pos = (utils.center(txt_img.get_size(), size)[0], 10)
        msg_bg.blit(txt_img, pos)

        #message
        txt = "Enter name:"
        txt_img = TextLine(txt, fontsize=15)
        pos = (10, 80)
        msg_bg.blit(txt_img, pos)

        self.entry = TextEntry(size=(130, 22))
        self.entry.max = 10
        self.entry.set_pos(
            (msg_pos[0] + txt_img.get_size()[0] + 20, msg_pos[1] + 75))

        txt = "Note: Any previous savegame will be "
        txt_img = TextLine(txt, fontsize=12)
        pos = (10, 150)
        msg_bg.blit(txt_img, pos)

        txt = "overwritten!"
        txt_img = TextLine(txt, fontsize=12)
        pos = (10, pos[1] + 18)
        msg_bg.blit(txt_img, pos)

        #start/cancel buttons
        btn = FixedTextButton((100, 24), "Cancel", callback=self.quit)
        btn.set_pos((msg_pos[0], msg_pos[1] + size[1] + 2))
        btn.draw_border()
        self.add_button("cancel", btn)

        btn = FixedTextButton((100, 24), "Start!", callback=self.submit)
        btn.set_pos((msg_pos[0] + size[0] - 100, msg_pos[1] + size[1] + 2))
        btn.draw_border()
        self.add_button("start", btn)

        self.add_textentry_events(self.entry)
        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)

        self.redraw()
예제 #14
0
    def __init__(self,
                 img,
                 mapname,
                 score,
                 custom=False,
                 name="",
                 pacmode=False,
                 win=True):
        BgState.__init__(self, img)
        score_str = str(score)

        #background of message
        size = (300, 200)
        msg_bg = StaticWidget(size)
        #msg_bg.fill((0,0,128))
        draw_border(msg_bg)
        pos = utils.center(size, (800, 600))
        msg_bg.set_pos(pos)
        self.msg_bg = msg_bg
        msg_pos = pos

        #message
        if win:
            txt = "Map completed!"
        else:
            txt = "You were caught!"
        txt_img = TextLine(txt, fontsize=30)
        pos = (utils.center(txt_img.get_size(), size)[0], 10)
        msg_bg.blit(txt_img, pos)

        txt = "Score: " + score_str
        txt_img = TextLine(txt, fontsize=20)
        pos = (utils.center(txt_img.get_size(), size)[0], 60)
        msg_bg.blit(txt_img, pos)

        #check if highscore
        type = "camphigh"
        if custom:
            type = "custhigh"

        if pacmode:
            type = "pachighca"
            if custom:
                type = "pachighcu"

        scr_list = []
        if SAVE[type].has_key(mapname):
            scr_list = SAVE[type][mapname]
        else:
            SAVE[type][mapname] = []

        self.type = type
        self.mapname = mapname
        self.score = score
        self.scr_list = ScoreList()
        self.scr_list.set_list(scr_list)

        self.entry = None
        #add highscore entry
        if self.scr_list.check(score):
            txt = "New Highscore!"
            txt_img = TextLine(txt, fontsize=20)
            pos = (utils.center(txt_img.get_size(), size)[0], 120)
            msg_bg.blit(txt_img, pos)

            txt = "Enter name:"
            txt_img = TextLine(txt, fontsize=20)
            pos = (10, 150)
            msg_bg.blit(txt_img, pos)

            self.entry = TextEntry(text=name, size=(130, 22))
            self.entry.max = 10
            self.entry.set_pos(
                (msg_pos[0] + txt_img.get_size()[0] + 20, msg_pos[1] + 150))

            self.add_textentry_events(self.entry)
        btn = FixedTextButton((120, 25), "Continue", callback=self.submit)
        btn.draw_border()
        btn.set_pos((msg_pos[0] + size[0] - 120, msg_pos[1] + size[1] + 4))
        self.add_button("continue", btn)
        self.add_kbevent(KEYDOWN, K_RETURN, self.quit)
        self.redraw()

        #keys
        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)
    def show_signet(self, clans):
        #show recently gained signet(s)
        self.cur_blending = []
        self.cur_blinking = []
        for clan in clans:
            #signet
            signet = self.signets[clan][0]
            blend = StaticWidget(signet.get_size())
            blend.fill((255, 0, 255))
            blend.set_colorkey((255, 0, 255))
            blend.blit(signet, (0, 0))
            blend.set_pos(self.signet_pos[clan])
            blend.set_alpha(0)
            self.cur_blending.append(blend)

            #green light
            img = self.light
            blink = StaticWidget(img.get_size())
            blink.fill((255, 0, 255))
            blink.set_colorkey((255, 0, 255))
            blink.blit(img, (0, 0))
            blink.set_pos(self.light_pos[clan])
            self.cur_blinking.append(blink)
            self.blink_timer.set_interval(3)
예제 #16
0
class TheEnd(State):
    def __init__(self):
        State.__init__(self)
        self.bg_image = GLOBALS["backgrounds"]["the_end.png"]
        self.overlay = StaticWidget((638, 169))
        self.overlay.set_pos((2, 160))
        self.overlay.set_alpha(255)
        self.overlay.fill((0, 0, 0))
        self.wait = Timer(50)

    def main_start(self):
        pygame.mouse.set_visible(0)
        GLOBALS["jb"].stop()

    def update_screen(self):
        self.background.fill((0, 0, 0))
        self.background.blit(self.bg_image, (0, 0))

        if not self.wait.active:
            alpha = self.overlay.get_alpha()
            if alpha > 0:
                self.overlay.set_alpha(alpha - 10)
            if alpha < 20:
                self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)
        elif self.wait.update():
            self.wait.deactivate()

        self.overlay.draw(self.background)
        State.update_screen(self)
    def __init__(self):
        State.__init__(self)
        self.buttons = {}

        #tileset area
        self.tileset_area = StaticWidget((1020, 280))
        self.tileset_area.set_pos((2, 485))
        self.tileset_area.pos = (2, 485)
        ca = ClickArea(pygame.Rect([2, 485, 1024, 280]), self.choose_tiletype)
        self.widgets.append(ca)
        self.tileset_id = "ts_tileset"
        self.marked_type = None
        self.load_tileset()

        #set clan
        buttons = [
            "wood", "day", "fire", "life", "earth", "night", "metal", "water",
            "death"
        ]

        x, y = 900, 50
        for clan in buttons:
            btn = ImgButton(GLOBALS["signets"][clan][1], \
                self.set_clan, clan=clan)
            btn.set_pos((x, y))
            self.widgets.append(btn)
            self.buttons[clan] = btn
            btn.draw(self.background)
            y = y + btn.get_size()[1] + 5
        self.clan = "fire"

        #Camera
        self.camera = Camera(None)

        #load empty map
        self.filename = ""
        self.load_map(new=True)

        #map area
        self.map_area = StaticWidget((640, 480))
        self.map_area.set_pos((0, 0))
        self.map_area_rect = pygame.Rect([0, 0, 640, 480])
        self.widgets.append(ca)

        #grid overlay for map area
        w, h = self.map_area.get_size()
        self.grid = StaticWidget((w, h))
        self.grid.fill((255, 0, 255))
        self.grid.set_colorkey((255, 0, 255))
        self.grid.set_alpha(100)
        for row in xrange(h / tsize):
            for col in xrange(w / tsize):
                pygame.draw.line(self.grid, (255, 255, 255), (col * 32, 0),
                                 (col * 32, h))
                pygame.draw.line(self.grid, (255, 255, 255), (0, row * 32),
                                 (w, row * 32))
        self.grid.set_pos(self.map_area.get_pos())

        #buttons
        buttons = [(" NEW ", self.new_map), (" LOAD ", self.open_file),
                   (" SAVE AS ", self.save_file), (" SAVE ", self.save_map)]

        x, y = 650, 1
        for b in buttons:
            name, callback = b
            btn = ImgButton(TextLine(name), callback)
            btn.set_pos((x, y))
            btn.draw_border((255, 255, 255))
            self.widgets.append(btn)
            btn.draw(self.background)
            x = x + btn.get_size()[0] + 4

        #add objects
        buttons = [
            (" delete obj", "delete"),
            (" add start ", "start"),
            (" add exit ", "exit"),
            (" add enemy ", "enemy"),
            (" add dialog-trigger ", "dtrigger"),
        ]

        x, y = 650, 50
        for b in buttons:
            name, cmd = b
            btn = ImgButton(TextLine(name, fontsize=15), \
                self.select_add_object, cmd=cmd)
            btn.set_pos((x, y))
            self.widgets.append(btn)
            btn.draw(self.background)
            y = y + btn.get_size()[1] + 5
            self.buttons[cmd] = btn

        #TEST button :)
        btn = ImgButton(TextLine(" TEST ", fontsize=25), self.test)
        btn.set_pos((900, 420))
        btn.draw_border((255, 255, 255))
        self.widgets.append(btn)
        btn.draw(self.background)

        #keyboard events
        pygame.key.set_repeat(10, 20)

        #scroll map
        self.add_kbevent(KEYDOWN, K_UP, self.scroll_map, vy=-1)
        self.add_kbevent(KEYDOWN, K_DOWN, self.scroll_map, vy=1)
        self.add_kbevent(KEYDOWN, K_LEFT, self.scroll_map, vx=-1)
        self.add_kbevent(KEYDOWN, K_RIGHT, self.scroll_map, vx=1)
예제 #18
0
class Outro(State):
    def __init__(self):
        State.__init__(self)
        self.fps = 40

        #animation checkpoints and flags
        self.opening = 0
        self.closing = 0
        self.door_timer = Timer(15)  #open slowly, then faster
        self.maelstrom_timer = Timer(30)  #open doors a bit.. then pull
        self.nanji_command = None

        #generate pseudo-map
        screen_size = GLOBALS["screen_size"]
        self.bg_image = pygame.Surface(screen_size)
        self.top_layer = pygame.Surface(screen_size)
        self.top_layer.set_colorkey((255, 0, 255))
        self.top_layer.fill((255, 0, 255))

        #draw map background
        bg = GLOBALS["backgrounds"]["fuji.png"]
        self.bg_image.blit(bg, (0, 0))

        #draw grass
        tsize = GLOBALS["tile_size"]
        grass_tile = GLOBALS["ts_tileset"][1, 0]
        x = -tsize
        y = screen_size[1] - tsize
        for i in xrange(22):
            self.top_layer.blit(grass_tile, (x, y))
            x += tsize

        #draw mysterious
        myst = GLOBALS["ui_stuff"]["mysterious.png"]

        #draw full signet board on mysterious
        board = GLOBALS["ui_stuff"]["board_filled.png"]
        x, y = 66, 197
        myst.blit(board, (x, y))

        x = 5 * tsize
        y = screen_size[1] - myst.get_size()[1] - tsize
        self.myst = StaticWidget(myst.get_size())
        self.myst.set_colorkey((255, 0, 255))
        self.myst.fill((255, 0, 255))
        self.myst.blit(myst, (0, 0))
        self.myst.set_pos((x, y))
        self.myst.pos = (x, y)
        self.myst.draw(self.top_layer)
        myst_centerx = x + myst.get_size()[0] / 2
        myst_top = y + 30

        #init doors
        self.door_speed = 1
        door_left_image = GLOBALS["ui_stuff"]["door_left.png"]
        door_right_image = GLOBALS["ui_stuff"]["door_right.png"]
        self.door_left = StaticWidget(door_left_image.get_size())
        self.door_left.blit(door_left_image, (0, 0))
        self.door_left.set_pos((self.myst.pos[0] + 99, self.myst.pos[1] + 63))
        self.door_right = StaticWidget(door_right_image.get_size())
        self.door_right.blit(door_right_image, (0, 0))
        self.door_right.set_pos(
            (self.myst.pos[0] + 177, self.myst.pos[1] + 63))

        #init whirling vortex
        self.vortex = Vortex(centerpos=(myst_centerx, myst_top))

        #init Nanji
        self.nanji = Nanji(cam=None)
        self.nanji.status = 0
        self.nanji.set_pos((205, 401))
        self.nanji_angle = 0
        self.nanji_fly_img = self.nanji.all_images["landing"][0]
        self.nanji_shrink = 1
        self.sprites.add(self.nanji)

        self.nanji_do("throw")

    def main_start(self):
        pygame.mouse.set_visible(0)
        State.main_start(self)

    def update_doors(self):
        if self.opening:
            lx, ly = self.door_left.get_pos()
            rx, ry = self.door_right.get_pos()
            self.door_left.set_pos((lx - self.door_speed, ly))
            self.door_right.set_pos((rx + self.door_speed, ry))
            if self.door_timer.update():
                self.door_speed = 2
            self.opening = lx > 165
        elif self.closing:
            self.door_speed = 1
            lx, ly = self.door_left.get_pos()
            rx, ry = self.door_right.get_pos()
            self.door_left.set_pos((lx + 1, ly))
            self.door_right.set_pos((rx - 1, ry))
            self.closing = lx < 258
            if not self.closing:
                self.maelstrom_timer.set_interval(50)
                self.nanji_do("waitquit")

        self.door_left.draw(self.background)
        self.door_right.draw(self.background)

    def nanji_do(self, do="throw"):
        self.nanji_command = do

        if do == "throw":  #lift paw
            self.nanji.change_images("throwing")
            self.nanji.anim_timer.set_interval(5)
            self.nanji.play()
        elif do == "unthrow":  #put paw down
            images = self.nanji.images[:]
            images.reverse()
            self.nanji.set_images(images)
            self.nanji.play()
        elif do == "wait_door":
            self.nanji.change_images("idle")
            self.opening = 1
            self.nanji.pause()
        elif do == "walk" or do == "walk2":
            self.nanji.look = -1
            self.nanji.change_images("walking")
            self.nanji.anim_timer.set_interval(8)
            self.nanji.play()
        elif do == "sprint" or do == "sprint2":
            self.nanji.change_images("sprinting")
            self.nanji.anim_timer.set_interval(8)
            self.nanji.play()
        elif do == "duck":
            self.nanji.change_images("ducking")
            self.nanji.pause()
        elif do == "lift":
            self.nanji.change_images("landing")
            self.nanji.pause()

    def update_nanji(self):
        if self.nanji_command is None:
            return

        #update old command
        cmd = self.nanji_command
        x, y = self.nanji.pos  #get pulled
        if cmd == "throw" and self.nanji.cur_image >= 3:  #paw up
            self.nanji_do("unthrow")
        elif cmd == "unthrow" and self.nanji.cur_image >= 3:  #paw down
            self.nanji_do("wait_door")
        elif cmd == "wait_door" and self.maelstrom_timer.update():  #wait
            self.nanji_do("walk")
        elif cmd == "walk":
            if x > 150:  #walk left
                self.nanji.set_pos((x - 1, y))
            else:
                self.nanji_do("walk2")
        elif cmd == "walk2":
            if x < 190:
                self.nanji.set_pos((x + 1, y))
            else:
                self.nanji_do("sprint")
        elif cmd == "sprint":  #try to sprint
            if x > 170:
                self.nanji.set_pos((x - 1, y))
            else:
                self.nanji_do("sprint2")
        elif cmd == "sprint2":
            self.nanji.set_pos((x + 1, y))
            if self.maelstrom_timer.update():
                self.nanji_do("duck")
        elif cmd == "duck" and self.maelstrom_timer.update():
            self.nanji_do("duckpull")
        elif cmd == "duckpull":
            if x < 250:
                self.nanji.set_pos((x + 1, y))
            else:
                self.nanji_do("lift")
        elif cmd == "lift":
            if x < 280:
                self.nanji.set_pos((x + 1, y))
            else:
                self.nanji_do("liftoff")
                self.maelstrom_timer.set_interval(10)
        elif cmd == "liftoff":
            self.nanji.set_pos((x, y - 1))
            if self.maelstrom_timer.update():
                self.nanji_do("whirl")
        elif cmd == "whirl":
            img = self.nanji_fly_img.copy()
            sx, sy = img.get_size()
            img = pygame.transform.scale(
                img, (sx - self.nanji_shrink, sy - self.nanji_shrink))
            self.nanji_shrink += 1
            if sx - self.nanji_shrink < 0 or sy - self.nanji_shrink < 0:
                self.nanji_do("done")

            self.nanji_angle += 10
            if self.nanji_angle > 360:
                self.nanji_angle = self.nanji_angle - 360
            img = pygame.transform.rotate(img, self.nanji_angle)

            center = self.nanji.rect.center
            self.nanji.set_image(img)
            self.nanji.rect.center = center

            if y > 350:
                y -= 1
            if x < 350:
                x += 1
            self.nanji.set_pos((x, y))
        elif cmd == "done":
            self.nanji_do(None)
            self.closing = 1
        elif cmd == "waitquit" and self.maelstrom_timer.update():
            self.next = TheEnd()
            self.quit()

    def update_screen(self):
        self.background.blit(self.bg_image, (0, 0))

        #update and draw vortex
        self.vortex.update()
        self.background.blit(self.vortex.image, self.vortex.pos)

        #update and draw doors
        self.update_doors()

        #draw grass, building
        self.background.blit(self.top_layer, (0, 0))

        #draw nanji
        self.update_nanji()
        State.update_screen(self)
class Editor(State):
    def __init__(self):
        State.__init__(self)
        self.buttons = {}

        #tileset area
        self.tileset_area = StaticWidget((1020, 280))
        self.tileset_area.set_pos((2, 485))
        self.tileset_area.pos = (2, 485)
        ca = ClickArea(pygame.Rect([2, 485, 1024, 280]), self.choose_tiletype)
        self.widgets.append(ca)
        self.tileset_id = "ts_tileset"
        self.marked_type = None
        self.load_tileset()

        #set clan
        buttons = [
            "wood", "day", "fire", "life", "earth", "night", "metal", "water",
            "death"
        ]

        x, y = 900, 50
        for clan in buttons:
            btn = ImgButton(GLOBALS["signets"][clan][1], \
                self.set_clan, clan=clan)
            btn.set_pos((x, y))
            self.widgets.append(btn)
            self.buttons[clan] = btn
            btn.draw(self.background)
            y = y + btn.get_size()[1] + 5
        self.clan = "fire"

        #Camera
        self.camera = Camera(None)

        #load empty map
        self.filename = ""
        self.load_map(new=True)

        #map area
        self.map_area = StaticWidget((640, 480))
        self.map_area.set_pos((0, 0))
        self.map_area_rect = pygame.Rect([0, 0, 640, 480])
        self.widgets.append(ca)

        #grid overlay for map area
        w, h = self.map_area.get_size()
        self.grid = StaticWidget((w, h))
        self.grid.fill((255, 0, 255))
        self.grid.set_colorkey((255, 0, 255))
        self.grid.set_alpha(100)
        for row in xrange(h / tsize):
            for col in xrange(w / tsize):
                pygame.draw.line(self.grid, (255, 255, 255), (col * 32, 0),
                                 (col * 32, h))
                pygame.draw.line(self.grid, (255, 255, 255), (0, row * 32),
                                 (w, row * 32))
        self.grid.set_pos(self.map_area.get_pos())

        #buttons
        buttons = [(" NEW ", self.new_map), (" LOAD ", self.open_file),
                   (" SAVE AS ", self.save_file), (" SAVE ", self.save_map)]

        x, y = 650, 1
        for b in buttons:
            name, callback = b
            btn = ImgButton(TextLine(name), callback)
            btn.set_pos((x, y))
            btn.draw_border((255, 255, 255))
            self.widgets.append(btn)
            btn.draw(self.background)
            x = x + btn.get_size()[0] + 4

        #add objects
        buttons = [
            (" delete obj", "delete"),
            (" add start ", "start"),
            (" add exit ", "exit"),
            (" add enemy ", "enemy"),
            (" add dialog-trigger ", "dtrigger"),
        ]

        x, y = 650, 50
        for b in buttons:
            name, cmd = b
            btn = ImgButton(TextLine(name, fontsize=15), \
                self.select_add_object, cmd=cmd)
            btn.set_pos((x, y))
            self.widgets.append(btn)
            btn.draw(self.background)
            y = y + btn.get_size()[1] + 5
            self.buttons[cmd] = btn

        #TEST button :)
        btn = ImgButton(TextLine(" TEST ", fontsize=25), self.test)
        btn.set_pos((900, 420))
        btn.draw_border((255, 255, 255))
        self.widgets.append(btn)
        btn.draw(self.background)

        #keyboard events
        pygame.key.set_repeat(10, 20)

        #scroll map
        self.add_kbevent(KEYDOWN, K_UP, self.scroll_map, vy=-1)
        self.add_kbevent(KEYDOWN, K_DOWN, self.scroll_map, vy=1)
        self.add_kbevent(KEYDOWN, K_LEFT, self.scroll_map, vx=-1)
        self.add_kbevent(KEYDOWN, K_RIGHT, self.scroll_map, vx=1)

    def update_screen(self):
        #draw map
        self.lvl_layer.set_colorkey(None)
        self.lvl_layer.fill((255, 0, 255))
        self.lvl_layer.blit(self.lvl_img, (0, 0))
        self.lvl_layer.set_colorkey((255, 0, 255))
        self.map_area.fill((0, 0, 0))
        self.map_area.blit(self.lvl_layer, (0, 0),
                           area=[self.camera.pos, GLOBALS["screen_size"]])
        self.map_area.draw_border((255, 255, 255))

        #draw map area
        self.map_area.draw(self.background)
        self.grid.draw(self.background)

        State.update_screen(self)

    def test(self):
        self.save_map()
        if self.filename:
            self.pause()
            self.next = Level(self.filename, testing=True)
            self.quit()

    def set_clan(self, clan):
        #unmark previous selection
        self.buttons[self.clan].draw_border((0, 0, 0))
        self.buttons[self.clan].draw(self.background)
        #mark current selection
        self.clan = clan
        self.buttons[self.clan].draw_border((255, 255, 255))
        self.map["options"]["clan"] = self.clan
        self.buttons[self.clan].draw(self.background)

    def set_option(self, param):
        old_value = ""
        if self.map["options"].has_key(param):
            old_value = self.map["options"][param]

        entry = tkSimpleDialog.askstring(title="Set " + param,
                                         prompt="Enter " + param + ":",
                                         initialvalue=old_value)
        print param, ":", entry
        if entry is not None:
            self.map["options"][param] = entry

    def select_add_object(self, cmd):
        #dehighlight old button
        if self.buttons.has_key(self.marked_type):
            self.buttons[self.marked_type].draw_border((0, 0, 0))
            self.buttons[self.marked_type].draw(self.background)
        elif self.marked_type:
            self.mark_tile(None)  #deselect tile

        #highlight button
        self.buttons[cmd].draw_border((255, 255, 255))
        self.buttons[cmd].draw(self.background)
        self.marked_type = cmd

    def load_map(self, filename="", new=False):
        if not new:
            try:
                new_map = Map(filename)
            except:
                print "Could not load map"
                return
        else:
            new_map = Map()

        self.filename = filename
        pygame.display.set_caption(filename)
        self.map = new_map
        self.lvl_map = self.map["tilemap"]
        self.lvl_img, blocks = self.map.draw(editing=True)
        self.lvl_layer = pygame.Surface(self.lvl_img.get_size())
        self.camera.set_pos((0, tsize * 20))
        self.load_tileset(self.map["tset"])
        self.set_clan(self.map["options"]["clan"])

    def scroll_map(self, vx=0, vy=0):
        x, y = self.camera.pos
        self.camera.set_pos((x + vx * tsize, y + vy * tsize))

    def open_file(self):
        filename = tkFileDialog.askopenfilename(title="Open",
                                                initialfile=map_path)
        if filename:
            self.load_map(filename)

    def save_file(self):
        self.asksaveasfilename()
        if self.filename:
            self.save_map()

    def asksaveasfilename(self):
        filename = tkFileDialog.asksaveasfilename(title="Save as",
                                                  initialfile=map_path)
        if filename:
            self.filename = filename

    def save_map(self):
        if not self.filename:
            self.asksaveasfilename()
            if self.filename:
                self.map.save_map(path=self.filename)
        else:
            self.map.save_map(path=self.filename)

    def new_map(self):
        ok = tkMessageBox.askyesno(title="Just asking..",
                                   message="Really create a new map?")
        if ok:
            self.load_map(new=True)
            self.load_tileset()

    def choose_tiletype(self):
        x, y = pygame.mouse.get_pos()
        off_x, off_y = self.tileset_area.pos
        x, y = (x - off_x) / (tsize + 2), (y - off_y) / (tsize + 2)
        if GLOBALS[self.tileset_id].has_key((x, y)):
            self.mark_tile((x, y))

    def mark_tile(self, coord):
        def draw_tile_border(coord, color=(255, 255, 255)):
            x, y = coord[0] * (tsize + 2), coord[1] * (tsize + 2)
            r = pygame.Rect([x - 1, y - 1, tsize + 2, tsize + 2])
            pygame.draw.rect(self.tileset_area, color, r, 1)

        if self.marked_type:
            if GLOBALS[self.tileset_id].has_key(self.marked_type):
                draw_tile_border(self.marked_type, (0, 0, 0))
            elif self.buttons.has_key(self.marked_type):
                self.buttons[self.marked_type].draw_border((0, 0, 0))
                self.buttons[self.marked_type].draw(self.background)

        if coord:
            draw_tile_border(coord)
        self.marked_type = coord
        self.tileset_area.draw(self.background)

    def load_tileset(self, tset="tileset"):
        ts_id = "ts_" + tset
        if not GLOBALS.has_key(ts_id):
            ts_id = "ts_tileset"
        self.marked_type = None
        self.tileset_area.fill((0, 0, 0))
        self.tileset_id = ts_id
        tiles = GLOBALS[ts_id]
        keys = tiles.keys()
        keys.sort()
        for k in keys:
            x, y = k[0] * (tsize + 2), k[1] * (tsize + 2)
            self.tileset_area.blit(tiles[k], (x, y))
        self.tileset_area.draw(self.background)

    def check_collisions(self):
        #check if map was clicked -> put tiles on map
        mpos = pygame.mouse.get_pos()
        pressed = pygame.mouse.get_pressed()
        lbutton, rbutton = pressed[0], pressed[2]

        if not self.map_area_rect.collidepoint(mpos) or \
            (not rbutton and not (lbutton and self.marked_type)):
            return

        #calculate map coordinates
        off_x, off_y = self.camera.pos
        x, y = (mpos[0] + off_x) / tsize, (mpos[1] + off_y) / tsize

        #set tile info
        if rbutton and self.lvl_map.has_key((x, y)):
            self.lvl_map.pop((x, y))
        elif lbutton and GLOBALS[self.tileset_id].has_key(self.marked_type):
            #place tile
            self.lvl_map[x, y] = self.marked_type
        elif lbutton and self.buttons.has_key(self.marked_type):
            #place object
            if self.marked_type == "delete" and self.map["objects"].has_key(
                (x, y)):
                self.map["objects"].pop((x, y))
            else:
                params = None
                t = self.marked_type
                if t == "dtrigger":
                    params = tkSimpleDialog.askstring(
                        title="Set dialog id",
                        prompt="Enter dialog ID:",
                    )
                    if params is None:  #didn't want to add that trigger anyway
                        return
                    if not dialog.has_key(params):
                        print "Warning: Dialog id not found... just for your information. ^^"
                self.map["objects"][x, y] = (self.marked_type, params)

                if params:
                    self.mark_tile(None)

        self.lvl_img, blocks = self.map.draw(editing=True)
        self.lvl_layer = pygame.Surface(self.lvl_img.get_size())
    def __init__(self, new=True):
        State.__init__(self)
        self.success = False
        self.new = new  #start tutorial before showing level selection!

        self.signet_pos = {
            "wood": (83, 181),
            "day": (158, 75),
            "fire": (284, 34),
            "life": (410, 75),
            "earth": (485, 181),
            "night": (456, 307),
            "metal": (348, 368),
            "water": (220, 368),
            "death": (112, 307)
        }

        self.light_pos = {
            "wood": (239, 225),
            "day": (261, 173),
            "fire": (315, 155),
            "life": (369, 173),
            "earth": (391, 225),
            "night": (383, 271),
            "metal": (345, 307),
            "water": (285, 307),
            "death": (247, 271)
        }

        self.cur_blinking = None
        self.cur_blending = None
        self.cur_clan = None
        self.blink_timer = Timer(50)
        self.blink_count = 0
        self.blink_max = 10
        self.light = GLOBALS["ui_stuff"]["green_light"]

        r = pygame.Rect([281, 203, 78, 77])
        r.inflate(-10, -10)
        bigredbutton = ClickArea(r, self.bigred_pressed)
        self.widgets.append(bigredbutton)
        self.donotpress = pygame.Rect([267, 188, 106, 95])
        self.signets = GLOBALS["signets"]
        self.bg_image = GLOBALS["backgrounds"]["gameboard.png"].copy()
        self.ui_layer = pygame.Surface(GLOBALS["screen_size"])
        self.ui_layer.fill((255, 0, 255))
        self.ui_layer.set_colorkey((255, 0, 255))

        self.tooltip_layer = pygame.Surface(GLOBALS["screen_size"])
        self.tooltip_layer.fill((255, 0, 255))
        self.tooltip_layer.set_colorkey((255, 0, 255))
        self.tooltip = StaticWidget((80, 20))
        self.dnp_tooltip = GLOBALS["ui_stuff"]["donotpress"]

        #level selection buttons
        self.signet_buttons = []
        levels = GLOBALS["clan_levels"]
        for k in self.signet_pos.keys():
            if self.signets.has_key(k) and levels.has_key(k):
                btn = ImgButton(self.signets[k][0], self.start_level, \
                    clan=k, level=levels[k])
                btn.set_pos(self.signet_pos[k])
                btn.rect = pygame.Rect([self.signet_pos[k], btn.get_size()])
                btn.rect.inflate(-20, -20)
                btn.clan = k
                self.widgets.append(btn)
                self.signet_buttons.append(btn)

        #show savegame progress
        self.show_signet(player_data["unlocked"])

        #keyboard events
        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)

        self.background.blit(self.bg_image, (0, 0))
        self.background.blit(self.tooltip_layer, (0, 0))
        self.background.blit(self.ui_layer, (0, 0))
        self.tooltip_layer.fill((255, 0, 255))
class LevelSelection(State):
    def __init__(self, new=True):
        State.__init__(self)
        self.success = False
        self.new = new  #start tutorial before showing level selection!

        self.signet_pos = {
            "wood": (83, 181),
            "day": (158, 75),
            "fire": (284, 34),
            "life": (410, 75),
            "earth": (485, 181),
            "night": (456, 307),
            "metal": (348, 368),
            "water": (220, 368),
            "death": (112, 307)
        }

        self.light_pos = {
            "wood": (239, 225),
            "day": (261, 173),
            "fire": (315, 155),
            "life": (369, 173),
            "earth": (391, 225),
            "night": (383, 271),
            "metal": (345, 307),
            "water": (285, 307),
            "death": (247, 271)
        }

        self.cur_blinking = None
        self.cur_blending = None
        self.cur_clan = None
        self.blink_timer = Timer(50)
        self.blink_count = 0
        self.blink_max = 10
        self.light = GLOBALS["ui_stuff"]["green_light"]

        r = pygame.Rect([281, 203, 78, 77])
        r.inflate(-10, -10)
        bigredbutton = ClickArea(r, self.bigred_pressed)
        self.widgets.append(bigredbutton)
        self.donotpress = pygame.Rect([267, 188, 106, 95])
        self.signets = GLOBALS["signets"]
        self.bg_image = GLOBALS["backgrounds"]["gameboard.png"].copy()
        self.ui_layer = pygame.Surface(GLOBALS["screen_size"])
        self.ui_layer.fill((255, 0, 255))
        self.ui_layer.set_colorkey((255, 0, 255))

        self.tooltip_layer = pygame.Surface(GLOBALS["screen_size"])
        self.tooltip_layer.fill((255, 0, 255))
        self.tooltip_layer.set_colorkey((255, 0, 255))
        self.tooltip = StaticWidget((80, 20))
        self.dnp_tooltip = GLOBALS["ui_stuff"]["donotpress"]

        #level selection buttons
        self.signet_buttons = []
        levels = GLOBALS["clan_levels"]
        for k in self.signet_pos.keys():
            if self.signets.has_key(k) and levels.has_key(k):
                btn = ImgButton(self.signets[k][0], self.start_level, \
                    clan=k, level=levels[k])
                btn.set_pos(self.signet_pos[k])
                btn.rect = pygame.Rect([self.signet_pos[k], btn.get_size()])
                btn.rect.inflate(-20, -20)
                btn.clan = k
                self.widgets.append(btn)
                self.signet_buttons.append(btn)

        #show savegame progress
        self.show_signet(player_data["unlocked"])

        #keyboard events
        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)

        self.background.blit(self.bg_image, (0, 0))
        self.background.blit(self.tooltip_layer, (0, 0))
        self.background.blit(self.ui_layer, (0, 0))
        self.tooltip_layer.fill((255, 0, 255))

    def main_start(self):
        if pygame.mixer.music.get_busy():
            pygame.mixer.music.fadeout(300)

        pygame.mouse.set_visible(1)
        if self.new is True:
            self.new = "somewhere in between"
            self.cur_clan = None
            self.next = Level("tutorial.map", prev=self)
            self.pause()
            self.quit()
        elif self.new == "somewhere in between":
            self.new = False
            self.update_screen()
            self.next = ShowDialog("donotpress", self.screen)
            self.pause()
            self.quit()

    def start_level(self, clan, level):
        if clan in player_data[
                "unlocked"] or self.cur_blending or self.cur_blinking:
            #do not start finished maps and wait while blending new signet in
            return
        self.success = False
        self.cur_clan = clan
        self.next = Level(level, prev=self)
        self.pause()
        self.quit()

    def unpause(self):
        if self.success:
            if self.cur_clan:
                self.show_signet([self.cur_clan])
                player_data["unlocked"].append(self.cur_clan)  #track progress
            self.cur_clan = None
            self.autosave()  #save progress
        State.unpause(self)

    def autosave(self):
        try:
            save_object(player_data, "save.dat")
        except:
            print "Autosave failed. Uh.. guess you need to keep playing?"

    def show_signet(self, clans):
        #show recently gained signet(s)
        self.cur_blending = []
        self.cur_blinking = []
        for clan in clans:
            #signet
            signet = self.signets[clan][0]
            blend = StaticWidget(signet.get_size())
            blend.fill((255, 0, 255))
            blend.set_colorkey((255, 0, 255))
            blend.blit(signet, (0, 0))
            blend.set_pos(self.signet_pos[clan])
            blend.set_alpha(0)
            self.cur_blending.append(blend)

            #green light
            img = self.light
            blink = StaticWidget(img.get_size())
            blink.fill((255, 0, 255))
            blink.set_colorkey((255, 0, 255))
            blink.blit(img, (0, 0))
            blink.set_pos(self.light_pos[clan])
            self.cur_blinking.append(blink)
            self.blink_timer.set_interval(3)

    def update_other(self):
        if self.cur_blending:
            #fancy alpha blending effect for new signet
            alpha = self.cur_blending[0].get_alpha() + 5

            if alpha > 100:  #stop blending
                for blend in self.cur_blending:
                    blend.set_alpha(None)
                    blend.draw(self.bg_image)
                self.cur_blending = None
            else:  #keep blending
                for blend in self.cur_blending:
                    blend.set_alpha(alpha)
                    blend.draw(self.bg_image)

        elif self.cur_blinking:
            if not self.blink_timer.update():
                return

            #fancy blinking light o/
            self.blink_count += 1
            b = self.blink_count

            #simulate irregular flickering
            if b == 1:
                self.blink_timer.set_interval(2)
            elif b == 3:
                self.blink_timer.set_interval(3)
            elif b == 6:
                self.blink_timer.set_interval(1)

            #to draw or not to draw...
            if self.blink_count % 2:
                for blink in self.cur_blinking:
                    blink.draw(self.ui_layer)
            else:
                self.ui_layer.fill((255, 0, 255))

            #ok, stop flickering.
            if self.blink_count > self.blink_max:
                for blink in self.cur_blinking:
                    blink.draw(self.bg_image)
                self.ui_layer.fill((255, 0, 255))
                self.blink_count = 0
                self.cur_blinking = None
        else:
            self.check_mouseover()

    def check_mouseover(self):
        #check if mouse hovers signet and show tooltip
        mpos = pygame.mouse.get_pos()
        for b in self.signet_buttons:
            if b.rect.collidepoint(mpos):
                self.tooltip.fill((255, 255, 255))
                self.tooltip.draw_border((0, 0, 0))
                self.tooltip.blit(GLOBALS["kanji"]["clan"], (10, 3))
                self.tooltip.blit(GLOBALS["kanji"][b.clan], (60, 4))
                pos = (mpos[0] + 10, mpos[1] + 20)
                x = (b.rect.centerx - self.tooltip.get_size()[0] / 2)
                y = b.rect.top
                pos = (x, y)
                self.tooltip_layer.blit(self.tooltip, pos)
                break

        dnp = self.donotpress
        if dnp.collidepoint(mpos):
            pos = (dnp.left - 60, dnp.top - 22)
            self.tooltip_layer.blit(self.dnp_tooltip, pos)

    def bigred_pressed(self):
        if self.cur_blending or self.cur_blinking:
            return

        if len(player_data["unlocked"]) < 9:
            self.next = ShowDialog("nothinghappened", self.screen)
            self.pause()
            self.quit()
        else:
            self.next = Outro()
            self.quit()

    def update_screen(self):
        self.background.blit(self.bg_image, (0, 0))
        self.background.blit(self.tooltip_layer, (0, 0))
        self.background.blit(self.ui_layer, (0, 0))
        self.tooltip_layer.fill((255, 0, 255))
        State.update_screen(self)
class Level(State):
    def __init__(self, lvl_map="tutorial.map", testing=False, prev=None):
        State.__init__(self)
        self.fps = 60
        self.prev = prev
        tsize = GLOBALS["tile_size"]
        self.trigger = None
        self.exit_timer = Timer(50)
        self.exit_timer.deactivate()
        pygame.mixer.music.set_volume(1)
        GLOBALS["jb"].play("bgm.xm", -1)

        player_data["health"] = 9  #always full health on map start
        #player_data["lives"] = #for gameover testing

        #scrolling background - maybe later XD
        #bg_back = GLOBALS["backgrounds"]["fuji.png"]
        #bg_front = GLOBALS["backgrounds"]["trees.png"]
        #self.scroll_bg = Background(bg_back, bg_front)

        #non-scrolling background
        self.bg = GLOBALS["backgrounds"]["fuji.png"]

        #map
        self.map_filename = lvl_map
        self.map = Map(lvl_map)
        self.lvl_map = self.map["tilemap"]
        x, y = self.map["max"]
        self.lvl_img, self.blocks = self.map.draw(editing=False)
        self.lvl_layer = pygame.Surface(self.lvl_img.get_size())

        #other spritegroups
        self.bullets = pygame.sprite.Group()

        #player
        self.player = Nanji(None)
        self.player.set_pos((self.map["start"][0]*tsize, self.map["start"][1]*tsize))
        self.sprites.add(self.player)

        #camera
        self.camera = Camera(self.player)
        screen_x, screen_y = GLOBALS["screen_size"]
        mx = self.map["max"][0] * tsize - screen_x
        my = self.map["max"][1] * tsize - screen_y + 4*tsize
        self.camera.set_max(mx,my)
        self.player.camera = self.camera
        self.camera.update()

        #add enemies
        self.enemies = pygame.sprite.Group()
        clan = self.map["options"]["clan"]
        for e in self.map.enemies:
            ninjat = Ninjat(self.camera, clan)
            ninjat.set_pos((e[0]*tsize, e[1]*tsize-32))#FIXME:enemies are spawned too low..?
            self.enemies.add(ninjat)
            self.sprites.add(ninjat)

        #ui layer
        self.ui_layer = StaticWidget((GLOBALS["screen_size"][0], 30))
        self.ui_layer.fill((255,0,255))
        self.ui_layer.set_colorkey((255,0,255))
        self.ui_layer.set_pos((0,0))
        self.heart_img = GLOBALS["ui_stuff"]["heart"]
        self.heart_empty_img = GLOBALS["ui_stuff"]["heart_empty"]
        self.life_img = GLOBALS["ui_stuff"]["life"]
        self.fontholder = TextLine("", fontsize=16)
        self.update_ui()

        #keyboard events
        self.key_pressed = {
            "up": 0, "down": 0, "left": 0, "right": 0,
            "jump":0, "sprint":0, "throw": 0, "shuriken": 0,
        }

        self.add_kbevent(KEYDOWN, K_LEFT, self.set_keypress, k="left", v=1)  #move
        self.add_kbevent(KEYDOWN, K_RIGHT, self.set_keypress, k="right", v=1)
        self.add_kbevent(KEYDOWN, K_UP, self.set_keypress, k="up", v=1)
        self.add_kbevent(KEYDOWN, K_DOWN, self.set_keypress, k="down", v=1)
        self.add_kbevent(KEYDOWN, K_SPACE, self.set_keypress, k="jump", v=1)  #jump
        self.add_kbevent(KEYDOWN, K_LSHIFT, self.set_keypress, k="sprint", v=1)  #sprint
        self.add_kbevent(KEYDOWN, K_RSHIFT, self.set_keypress, k="sprint", v=1)
        self.add_kbevent(KEYDOWN, K_RCTRL, self.set_keypress, k="throw", v=1)  #throw
        self.add_kbevent(KEYDOWN, K_LCTRL, self.set_keypress, k="throw", v=1)

        self.add_kbevent(KEYUP, K_LEFT, self.set_keypress, k="left", v=0)
        self.add_kbevent(KEYUP, K_RIGHT, self.set_keypress, k="right", v=0)
        self.add_kbevent(KEYUP, K_UP, self.set_keypress, k="up", v=0)
        self.add_kbevent(KEYUP, K_DOWN, self.set_keypress, k="down", v=0)
        self.add_kbevent(KEYUP, K_SPACE, self.set_keypress, k="jump", v=0)
        self.add_kbevent(KEYUP, K_LSHIFT, self.set_keypress, k="sprint", v=0)
        self.add_kbevent(KEYUP, K_RSHIFT, self.set_keypress, k="sprint", v=0)
        self.add_kbevent(KEYUP, K_RCTRL, self.set_keypress, k="throw", v=0)
        self.add_kbevent(KEYUP, K_LCTRL, self.set_keypress, k="throw", v=0)

        if testing:
            self.add_kbevent(KEYUP, K_ESCAPE, self.quit)

    def main_start(self):
        pygame.mouse.set_visible(0)
        State.main_start(self)



    def reset_keys(self):
        self.key_pressed = {
            "up": 0, "down": 0, "left": 0, "right": 0,
            "jump":0, "sprint":0, "throw": 0, "shuriken": 0,
        }

    def update_other(self):
        if self.player.exiting:
            self.show_exit_anim()
            return

        kp = self.key_pressed
        vx = 0
        if kp["left"] and not kp["right"]:
            vx = -1
        if kp["right"] and not kp["left"]:
            vx = 1
        self.player.mod_vel(vx=vx)

        if kp["jump"]:
            self.player.jump()
        elif self.player.status==4:
            self.player.unjump()

        if kp["sprint"]:
            self.player.sprint()
            #self.scroll_bg.front_speed = 8
        elif self.player.status==2:
            self.player.unsprint()
            #self.scroll_bg.front_speed = 4

        if kp["down"]:
            self.player.duck()
        elif self.player.status==7:
            self.player.unduck()

        if kp["throw"]:
            kp["throw"] = 0
            if self.player.throw():
                self.bullets.add(Shuriken(self.player, self.camera))

    def set_keypress(self, k, v):
        self.key_pressed[k] = v

    def show_exit_anim(self):
        self.fps = 30
        self.reset_keys()
        if self.player.exiting == -1:
            self.player.set_vel((0,0))
            self.player.set_image(GLOBALS["nanji"]["idle"][0])
            if not self.exit_timer.active:
                self.exit_timer.activate()
        elif self.player.vel[1]:
            self.player.status = 5
        else:
            self.player.status = 1
            self.player.mod_vel(vx=1)

        if self.player.pos[0] > self.map["exit"][0]*tsize+10*tsize or \
            self.exit_timer.update():
            #TODO: play some funky tune / do SOMETHING on level exit
            if self.prev:
                self.prev.success = True
            self.quit()

    def show_dialog(self, dialog_id):
        self.pause()
        self.next = ShowDialog(dialog_id, self.screen)
        self.quit()

    def unpause(self):
        self.reset_keys()
        State.unpause(self)

    def check_collisions(self):
        #check bullet collisions
        b = self.bullets
        s = self.enemies
        bl = self.blocks

        #test if bullet hit player
        coll = pygame.sprite.spritecollide(self.player, self.bullets, False)
        for bullet in coll:
            if bullet.thrower is not self.player and bullet.flying and not \
                self.player.invincible:
                bullet.kill()
                self.player.get_hit()
                self.rem_health()

        #test if bullet hit wall
        dead = []
        for bullet in self.bullets:
            if bullet.rect.collidelist(bl) > -1:
                dead.append(bullet)
        for d in dead:
            if d.flying:
                d.kill()

        #test if bullet hit enemy (ninjats can't shoot each other)
        coll = pygame.sprite.groupcollide(s, b, False, False)
        for victim in coll.keys(): #my code gets weird...
            for murderer in coll[victim]:
                if murderer.thrower is self.player:
                    victim.die()
                    murderer.kill()

        #test player vs. enemy collisions
        coll = pygame.sprite.spritecollide(self.player, s, False)
        pbottom = self.player.rect.bottom
        for enemy in coll:
            if enemy.status == 8:  #enemy dead.. ignore!
                continue
            etop = enemy.rect.top
            if self.player.status==5 and pbottom >= etop:
                #enemy below player and player is falling -> enemy crushed!
                enemy.die()
                self.player.bounce()
            elif not self.player.invincible and not self.player.status==7:
                #not ducking -> get hit
                self.player.get_hit()
                self.rem_health()

    def rem_health(self):
        player_data["health"] -= 1
        GLOBALS["sfx"][sfx_hit].play()
        if player_data["health"] <= 0:
            self.player.die()
        self.update_ui()

    def update_ui(self):
        self.ui_layer.fill((255,0,255))

        #health
        x, y, add = 4, 2, self.heart_img.get_size()[0] + 2
        for i in xrange(9):
            if i < player_data["health"]:  #TODO: if i < hp
                self.ui_layer.blit(self.heart_img, (x,y))
            else:
                self.ui_layer.blit(self.heart_empty_img, (x,y))
            x += add

        #lives
        x, y, add = 595, 2, self.life_img.get_size()[0] + 2
        self.ui_layer.blit(self.life_img, (x,y))
        lives = player_data["lives"]
        life_text = self.fontholder.font.render("x"+str(lives), False, (255,255,255))
        self.ui_layer.blit(life_text, (x+add, y+10))

    def update_screen(self):
        for s in self.sprites:
            s.update_status()
            if not s.ai: #update player
                s.update()
                if not s.status==8 and not self.player.off_screen():
                    s.check_mapcollisions(self.blocks)
                    trig = s.check_trigcollisions(self.map.triggers)
                    if trig:
                        if trig.name=="exit":
                            self.player.exiting = 1
                        elif trig.name=="dtrigger":
                            self.show_dialog(trig.params)
                            if trig.params=="tut08":
                                self.player.exiting = -1
                                self.player.set_image(GLOBALS["nanji"]["idle"][0])
                else:
                        player_data["health"] = 9
                        player_data["lives"] -= 1
                        if player_data["lives"] > 0:
                            next = Level(self.map_filename, prev=self.prev)

                        else:
                            next = GameOver()
                        self.next = FadeState(self.screen, next.background, next)
                        self.quit()
            else:  #update ai
                if s.ai_update(self): #throw shuriken?
                    self.bullets.add(Shuriken(s, self.camera))

        self.bullets.update()
        self.camera.update()

        #draw bg
        #self.scroll_bg.update(self.player.vel[0])
        self.background.blit(self.bg, (0,0))

        #draw map and sprites
        self.lvl_layer.fill((255,0,255))
        self.lvl_layer.blit(self.lvl_img, self.camera.pos, [self.camera.pos, GLOBALS["screen_size"]])
        self.lvl_layer.set_colorkey((255,0,255))
        self.bullets.draw(self.lvl_layer)
        self.sprites.draw(self.lvl_layer)

        #pygame.draw.rect(self.lvl_layer, (255,255,0), self.player.colrect, 1) #draw collision rect of nanji

        if self.player.exiting:  #draw semi-black image over dojo entry while entering
            self.lvl_layer.blit(GLOBALS["objects"]["dojo_entry"], self.map.dojo_pos)

        self.background.blit(self.lvl_layer, (0,0), [self.camera.pos, GLOBALS["screen_size"]])
        self.ui_layer.draw(self.background)
        self.screen.blit(self.background, (0,0))
        pygame.display.flip()
예제 #23
0
class Game(State):
    def __init__(self,
                 mapname="level01.map",
                 folder="lvl",
                 test=False,
                 camp=False,
                 pacmode=False):
        State.__init__(self)
        self.mapname = mapname
        self.fps = 60
        self.folder = folder
        self.test = test
        self.lives = 3
        self.camp = camp
        self.start_paused = False
        if self.camp:
            self.lives = SAVE["cur"]["lives"]  #lives

        self.restart()

        #add keyboard events
        self.add_kbevent(KEYDOWN, K_ESCAPE, self.to_pause)

        if not pacmode:
            #movement
            self.add_kbevent(KEYDOWN, K_UP, self.cat_go, vel=(0, -1))
            self.add_kbevent(KEYDOWN, K_DOWN, self.cat_go, vel=(0, 1))
            self.add_kbevent(KEYDOWN, K_LEFT, self.cat_go, vel=(-1, 0))
            self.add_kbevent(KEYDOWN, K_RIGHT, self.cat_go, vel=(1, 0))

            #ghost selection
            self.add_kbevent(KEYDOWN, K_1, self.set_active, nr=0)
            self.add_kbevent(KEYDOWN, K_2, self.set_active, nr=1)
            self.add_kbevent(KEYDOWN, K_3, self.set_active, nr=2)
            self.add_kbevent(KEYDOWN, K_4, self.set_active, nr=3)
            self.add_kbevent(KEYDOWN, K_5, self.set_active, nr=4)

    def to_pause(self):
        if self.test:
            self.quit()
        else:
            self.pause()
            self.next = Pause(self.screen)
            self.quit()

    def main_start(self):
        pygame.mouse.set_visible(0)
        self.screen.blit(self.background, (0, 0))
        pygame.display.flip()
        self.started = True
        if not self.start_paused:
            self.start_pause()
        k = TMP["last_key"]
        if k and k in TMP["play_keys"]:
            ev = pygame.event.Event(KEYDOWN, {
                "key": TMP["last_key"],
                "mod": 0
            })
            pygame.event.post(ev)
        TMP["last_key"] = None

    def cat_go(self, vel):
        if self.active_cat < len(self.catlist) and \
            self.catlist[self.active_cat] is not None:
            self.ent_go(self.catlist[self.active_cat], vel)

    def ent_go(self, ent, vel):
        old_pos = ent.pos
        old_vel = ent.vel
        success = False

        ent.go(vel)
        ent.update()

        off_tile = (old_pos[0] - self.map_pos[0]) % 32 or \
            (old_pos[1] - self.map_pos[1]) % 32

        if off_tile or pygame.sprite.spritecollideany(ent, self.walls):
            ent.next_vel = vel
            ent.go((old_vel[0] / ent.speed, old_vel[1] / ent.speed))
        else:
            ent.next_vel = None
            ent.set_movedir(ent.vel2dir(vel))
            success = True
        ent.set_pos(old_pos)
        return success

    def update_other(self):
        #move cat into last requested dir if possible
        if not self.start_paused:
            self.start_pause()

        for c in self.cats:
            self.update_ent(c)

        for d in self.dogs:
            self.update_ent(d)

        #CATAWAY-mode
        if self.cataway_timer.update():
            self.cataway_timer.deactivate()
            for d in self.dogs:
                d.set_scary(0)
            for c in self.cats:
                c.set_scary(1)
            #TODO: Stop whatever else is going on when cataway mode is running

        if len(self.dogs.sprites()) == 0:
            self.show_win()
        if len(self.cats.sprites())==0 or \
            (len(self.catnip.sprites())==0  and \
            len(self.cataway.sprites())==0):
            self.show_lose()

    def show_lose(self, pacmode=False):
        if self.test or self.lost:
            self.quit()
            return

        if self.lives > 0:
            self.lives -= 1
            if self.camp:
                SAVE["cur"]["lives"] = self.lives
            self.restart()
        elif self.camp:
            self.lost = True
            self.next = GameOver(self.screen, lost=True)
            self.pause()
            self.quit()
        elif not self.camp:
            self.next = TryAgain(self.screen,
                                 self.mapname,
                                 self.folder,
                                 pacmode=pacmode)
            self.quit()

    def add_score(self, val):
        self.score = self.score - val
        self.upd = 1

    def show_win(self, pacmode=False, win=True):
        if self.test:
            self.quit()
            return

        if self.win_shown:
            self.quit()
            return

        self.win = True
        self.win_shown = True
        name = ""
        if self.camp:
            name = SAVE["cur"]["name"]
        self.pause()
        self.next = ShowWin(self.screen, self.mapname, self.score, self.custom,
                            name, pacmode, win)
        self.quit()

    def update_ai(self, ent):
        #dog-AI
        dir = None
        epos = (ent.pos[0] - self.map_pos[0], ent.pos[1] - self.map_pos[1])

        if epos[0] % 32 or epos[1] % 32:
            return

        cx = epos[0] / 32
        cy = epos[1] / 32

        vel = ent.ai.get_vel()
        if vel is None:
            vel = random.choice([(0, 1), (1, 0), (0, -1), (-1, 0)])
        self.ent_go(ent, vel)

    def update_ent(self, ent):
        epos = (ent.pos[0] - self.map_pos[0], ent.pos[1] - self.map_pos[1])
        if not epos[0] % 32 and not epos[1] % 32:
            cx = epos[0] / 32
            cy = epos[1] / 32
            ent.coord = (cx, cy)

        if ent.ai:
            self.update_ai(ent)

        if ent.next_vel:
            self.ent_go(ent, ent.next_vel)

    def set_active(self, nr=None):
        if nr is None:
            for i in xrange(len(self.catlist)):
                if self.catlist[i] is not None:
                    nr = i

        if nr is not None and nr < len(
                self.catlist) and self.catlist[nr] is not None:
            if self.catlist[self.active_cat] is not None:
                self.catlist[self.active_cat].deselect()
            self.active_cat = nr
            self.catlist[nr].select()

    def check_collisions(self):
        self.sprites.update()

        #check if cats or dogs collide with wall
        coll = pygame.sprite.groupcollide(self.sprites, self.walls, False,
                                          False)
        for s in coll.keys():
            x, y = s.pos
            n = s.speed
            v = s.vel

            if v[1] < 0:  #moving up
                s.set_pos((x, y + n))
            if v[1] > 0:  #moving down
                s.set_pos((x, y - n))
            if v[0] < 0:  #moving left
                s.set_pos((x + n, y))
            if v[0] > 0:  #moving right
                s.set_pos((x - n, y))

        #check if dogs collide with cats
        coll = pygame.sprite.groupcollide(self.dogs, self.cats, False, False)
        if self.cataway_timer.active:
            for k in coll.keys():  #in CATAWAY-mode dog kills cat
                cats = coll[k]
                for c in cats:
                    c.kill()
                    self.catlist[c.nr] = None
                    self.set_active()
        else:
            for dog in coll.keys():  #in NORMAL mode, cat kills dog
                if dog in self.doglist:
                    self.doglist.remove(dog)
                dog.kill()

        #check if dogs collide with catnip
        coll = pygame.sprite.groupcollide(self.dogs, self.catnip, False, True)
        if coll:
            self.add_score(len(coll) * CATNIP)
            for c in coll.values():
                for nip in c:
                    if nip.coord in self.map.pellets:
                        self.map.pellets.remove(nip.coord)

        #check if dogs collide with cataway
        coll = pygame.sprite.groupcollide(self.dogs, self.cataway, False, True)
        if coll:
            self.add_score(len(coll) * CATAWAY)
            self.cataway_timer.activate()

            for d in self.dogs:
                d.set_scary(1)

            for c in self.cats:
                c.set_scary(0)
            for c in coll.values():
                for nip in c:
                    if nip.coord in self.map.cataway:
                        self.map.cataway.remove(nip.coord)

    def update_screen(self):
        self.screen.blit(self.background, (0, 0))
        self.static_sprites.draw(self.screen)
        changed = self.sprites.draw(self.screen)

        if self.upd:
            self.upd = 0
            self.score_img.set_text(self.score)
            self.lives_img.draw(self.background)
            self.level_img.draw(self.background)
        self.score_img.draw(self.background)

        pygame.display.flip()

    def restart(self):
        mapname = self.mapname
        folder = self.folder
        test = self.test

        self.upd = 1
        self.fps = 50
        self.win = False
        self.lost = False
        self.win_shown = False
        self.started = False
        self.custom = not folder == "lvl"

        self.screen = pygame.display.get_surface()
        self.background = pygame.Surface(self.screen.get_size())
        pygame.mouse.set_visible(False)

        self.cataway_timer = utils.Timer(100)
        self.cataway_timer.deactivate()

        #load map
        self.map = Map(mapname, edit=False, folder=folder)
        self.map_pos = utils.center(self.map.get_size(),
                                    self.screen.get_size())
        self.background.blit(self.map, self.map_pos)
        pygame.display.flip()

        #setup blocking spritegroup
        self.walls = pygame.sprite.Group()
        block = self.map.get_blocking()
        size = (32, 32)
        for b in block:
            pos = (b[0] * 32 + self.map_pos[0], b[1] * 32 + self.map_pos[1])
            s = pygame.sprite.Sprite()
            s.rect = pygame.Rect(pos, size)
            self.walls.add(s)

        #catnip pellets
        catnip = []
        self.catnip_rects = []
        for p in self.map.pellets:
            c = CatNip(p)
            c.set_pos(
                (p[0] * 32 + self.map_pos[0], p[1] * 32 + self.map_pos[1]))
            catnip.append(c)
            self.catnip_rects.append(c.rect)
        self.catnip = pygame.sprite.Group(catnip)

        #cataway
        cataway = []
        for c in self.map.cataway:
            x = CatAway(c)
            x.set_pos(
                (c[0] * 32 + self.map_pos[0], c[1] * 32 + self.map_pos[1]))
            cataway.append(x)
        self.cataway = pygame.sprite.Group(cataway)

        #catghosts
        cats = []
        for g in self.map.ghost_start:
            c = Cat(len(cats))
            c.set_pos(
                (g[0] * 32 + self.map_pos[0], g[1] * 32 + self.map_pos[1]))
            cats.append(c)
        self.catlist = cats
        self.cats = pygame.sprite.Group(cats)
        self.active_cat = 0
        self.set_active(0)

        #pacdogs
        dogs = []
        self.doglist = []
        for p in self.map.pac_start:
            d = PacDog()
            d.set_pos(
                (p[0] * 32 + self.map_pos[0], p[1] * 32 + self.map_pos[1]))
            d.ai.setup(self.map, self.catlist)
            self.doglist.append(d)
            dogs.append(d)
        self.dogs = pygame.sprite.Group(dogs)

        #player stats
        self.score = self.map.get_score()  #score
        self.score_img = Score(self.score)

        self.lives_img = StaticWidget((60, 32))
        self.lives_img.blit(GFX["ghost"], (0, 0))
        self.lives_img.blit(TextLine("x" + str(self.lives)), (32, 10))
        self.lives_img.set_pos((800 - self.lives_img.get_size()[0], 0))

        self.level_img = TextLine(self.mapname[:-4].upper())
        x = utils.center(self.level_img.get_size(), (800, 600))[0]
        self.level_img.set_pos((x, 2))

        #setup spritegroups
        self.sprites = pygame.sprite.RenderUpdates()
        self.sprites.add(self.cats)
        self.sprites.add(self.dogs)

        self.static_sprites = pygame.sprite.Group()
        self.static_sprites.add(self.catnip)
        self.static_sprites.add(self.cataway)

        self.start_paused = False

    def start_pause(self):
        self.start_paused = True
        self.update_screen()
        self.pause()
        self.next = StartPause(self.screen)
        self.quit()
    def __init__(self, lvl_map="tutorial.map", testing=False, prev=None):
        State.__init__(self)
        self.fps = 60
        self.prev = prev
        tsize = GLOBALS["tile_size"]
        self.trigger = None
        self.exit_timer = Timer(50)
        self.exit_timer.deactivate()
        pygame.mixer.music.set_volume(1)
        GLOBALS["jb"].play("bgm.xm", -1)

        player_data["health"] = 9  #always full health on map start
        #player_data["lives"] = #for gameover testing

        #scrolling background - maybe later XD
        #bg_back = GLOBALS["backgrounds"]["fuji.png"]
        #bg_front = GLOBALS["backgrounds"]["trees.png"]
        #self.scroll_bg = Background(bg_back, bg_front)

        #non-scrolling background
        self.bg = GLOBALS["backgrounds"]["fuji.png"]

        #map
        self.map_filename = lvl_map
        self.map = Map(lvl_map)
        self.lvl_map = self.map["tilemap"]
        x, y = self.map["max"]
        self.lvl_img, self.blocks = self.map.draw(editing=False)
        self.lvl_layer = pygame.Surface(self.lvl_img.get_size())

        #other spritegroups
        self.bullets = pygame.sprite.Group()

        #player
        self.player = Nanji(None)
        self.player.set_pos((self.map["start"][0]*tsize, self.map["start"][1]*tsize))
        self.sprites.add(self.player)

        #camera
        self.camera = Camera(self.player)
        screen_x, screen_y = GLOBALS["screen_size"]
        mx = self.map["max"][0] * tsize - screen_x
        my = self.map["max"][1] * tsize - screen_y + 4*tsize
        self.camera.set_max(mx,my)
        self.player.camera = self.camera
        self.camera.update()

        #add enemies
        self.enemies = pygame.sprite.Group()
        clan = self.map["options"]["clan"]
        for e in self.map.enemies:
            ninjat = Ninjat(self.camera, clan)
            ninjat.set_pos((e[0]*tsize, e[1]*tsize-32))#FIXME:enemies are spawned too low..?
            self.enemies.add(ninjat)
            self.sprites.add(ninjat)

        #ui layer
        self.ui_layer = StaticWidget((GLOBALS["screen_size"][0], 30))
        self.ui_layer.fill((255,0,255))
        self.ui_layer.set_colorkey((255,0,255))
        self.ui_layer.set_pos((0,0))
        self.heart_img = GLOBALS["ui_stuff"]["heart"]
        self.heart_empty_img = GLOBALS["ui_stuff"]["heart_empty"]
        self.life_img = GLOBALS["ui_stuff"]["life"]
        self.fontholder = TextLine("", fontsize=16)
        self.update_ui()

        #keyboard events
        self.key_pressed = {
            "up": 0, "down": 0, "left": 0, "right": 0,
            "jump":0, "sprint":0, "throw": 0, "shuriken": 0,
        }

        self.add_kbevent(KEYDOWN, K_LEFT, self.set_keypress, k="left", v=1)  #move
        self.add_kbevent(KEYDOWN, K_RIGHT, self.set_keypress, k="right", v=1)
        self.add_kbevent(KEYDOWN, K_UP, self.set_keypress, k="up", v=1)
        self.add_kbevent(KEYDOWN, K_DOWN, self.set_keypress, k="down", v=1)
        self.add_kbevent(KEYDOWN, K_SPACE, self.set_keypress, k="jump", v=1)  #jump
        self.add_kbevent(KEYDOWN, K_LSHIFT, self.set_keypress, k="sprint", v=1)  #sprint
        self.add_kbevent(KEYDOWN, K_RSHIFT, self.set_keypress, k="sprint", v=1)
        self.add_kbevent(KEYDOWN, K_RCTRL, self.set_keypress, k="throw", v=1)  #throw
        self.add_kbevent(KEYDOWN, K_LCTRL, self.set_keypress, k="throw", v=1)

        self.add_kbevent(KEYUP, K_LEFT, self.set_keypress, k="left", v=0)
        self.add_kbevent(KEYUP, K_RIGHT, self.set_keypress, k="right", v=0)
        self.add_kbevent(KEYUP, K_UP, self.set_keypress, k="up", v=0)
        self.add_kbevent(KEYUP, K_DOWN, self.set_keypress, k="down", v=0)
        self.add_kbevent(KEYUP, K_SPACE, self.set_keypress, k="jump", v=0)
        self.add_kbevent(KEYUP, K_LSHIFT, self.set_keypress, k="sprint", v=0)
        self.add_kbevent(KEYUP, K_RSHIFT, self.set_keypress, k="sprint", v=0)
        self.add_kbevent(KEYUP, K_RCTRL, self.set_keypress, k="throw", v=0)
        self.add_kbevent(KEYUP, K_LCTRL, self.set_keypress, k="throw", v=0)

        if testing:
            self.add_kbevent(KEYUP, K_ESCAPE, self.quit)
예제 #25
0
    def restart(self):
        mapname = self.mapname
        folder = self.folder
        test = self.test

        self.upd = 1
        self.fps = 50
        self.win = False
        self.lost = False
        self.win_shown = False
        self.started = False
        self.custom = not folder == "lvl"

        self.screen = pygame.display.get_surface()
        self.background = pygame.Surface(self.screen.get_size())
        pygame.mouse.set_visible(False)

        self.cataway_timer = utils.Timer(100)
        self.cataway_timer.deactivate()

        #load map
        self.map = Map(mapname, edit=False, folder=folder)
        self.map_pos = utils.center(self.map.get_size(),
                                    self.screen.get_size())
        self.background.blit(self.map, self.map_pos)
        pygame.display.flip()

        #setup blocking spritegroup
        self.walls = pygame.sprite.Group()
        block = self.map.get_blocking()
        size = (32, 32)
        for b in block:
            pos = (b[0] * 32 + self.map_pos[0], b[1] * 32 + self.map_pos[1])
            s = pygame.sprite.Sprite()
            s.rect = pygame.Rect(pos, size)
            self.walls.add(s)

        #catnip pellets
        catnip = []
        self.catnip_rects = []
        for p in self.map.pellets:
            c = CatNip(p)
            c.set_pos(
                (p[0] * 32 + self.map_pos[0], p[1] * 32 + self.map_pos[1]))
            catnip.append(c)
            self.catnip_rects.append(c.rect)
        self.catnip = pygame.sprite.Group(catnip)

        #cataway
        cataway = []
        for c in self.map.cataway:
            x = CatAway(c)
            x.set_pos(
                (c[0] * 32 + self.map_pos[0], c[1] * 32 + self.map_pos[1]))
            cataway.append(x)
        self.cataway = pygame.sprite.Group(cataway)

        #catghosts
        cats = []
        for g in self.map.ghost_start:
            c = Cat(len(cats))
            c.set_pos(
                (g[0] * 32 + self.map_pos[0], g[1] * 32 + self.map_pos[1]))
            cats.append(c)
        self.catlist = cats
        self.cats = pygame.sprite.Group(cats)
        self.active_cat = 0
        self.set_active(0)

        #pacdogs
        dogs = []
        self.doglist = []
        for p in self.map.pac_start:
            d = PacDog()
            d.set_pos(
                (p[0] * 32 + self.map_pos[0], p[1] * 32 + self.map_pos[1]))
            d.ai.setup(self.map, self.catlist)
            self.doglist.append(d)
            dogs.append(d)
        self.dogs = pygame.sprite.Group(dogs)

        #player stats
        self.score = self.map.get_score()  #score
        self.score_img = Score(self.score)

        self.lives_img = StaticWidget((60, 32))
        self.lives_img.blit(GFX["ghost"], (0, 0))
        self.lives_img.blit(TextLine("x" + str(self.lives)), (32, 10))
        self.lives_img.set_pos((800 - self.lives_img.get_size()[0], 0))

        self.level_img = TextLine(self.mapname[:-4].upper())
        x = utils.center(self.level_img.get_size(), (800, 600))[0]
        self.level_img.set_pos((x, 2))

        #setup spritegroups
        self.sprites = pygame.sprite.RenderUpdates()
        self.sprites.add(self.cats)
        self.sprites.add(self.dogs)

        self.static_sprites = pygame.sprite.Group()
        self.static_sprites.add(self.catnip)
        self.static_sprites.add(self.cataway)

        self.start_paused = False
예제 #26
0
 def __init__(self, images, interval=40):
     StaticWidget.__init__(self, images[0].get_size())
     self.images = images
     self.cur = 0
     self.timer = utils.Timer(interval)
     self.blit(self.images[self.cur], (0, 0))
예제 #27
0
    def __init__(self, edit=True, folder="custom"):
        img = GFX["levelsel"]
        BgState.__init__(self, img)
        pygame.mouse.set_visible(1)
        self.preview = pygame.Surface((416, 320))
        self.preview_pos = (312, 105)
        self.edit = edit
        self.folder = folder
        self.stats = {
            "cats": 0,
            "dogs": 0,
            "catnip": 0,
            "cataway": 0,
            "highscore": []
        }
        self.scores = []

        #list of map filenames
        self.msg = TextLine("")
        self.maps = get_maps(self.folder)

        #buttons
        btn = ClickFlipButton(GFX["btn_up1"],
                              GFX["btn_up2"],
                              callback=self.set_page,
                              add=-1)
        btn.set_pos((56, 233))
        self.add_button("up", btn)

        btn = ClickFlipButton(GFX["btn_down1"],
                              GFX["btn_down2"],
                              callback=self.set_page,
                              add=1)
        btn.set_pos((56, 265))
        self.add_button("down", btn)

        btn = FixedTextButton((64, 32), "Cancel", callback=self.quit)
        btn.set_pos((120, 457))
        btn.draw_border()
        self.add_button("cancel", btn)

        btn = FixedTextButton((64, 32), "Load", callback=self.load)
        btn.set_pos((216, 457))
        btn.draw_border()
        self.add_button("load", btn)

        if not edit:  #hide campaign maps in editor
            btn = ImgButton(GFX["sel_camp1"].copy(),
                            callback=self.set_folder,
                            val="lvl")
            btn.set_pos((117, 41))
            self.add_button("lvl", btn)

        btn = ImgButton(GFX["sel_cus1"].copy(),
                        callback=self.set_folder,
                        val="custom")
        btn.set_pos((212, 41))
        self.add_button("custom", btn)

        #pacmode unlocked when campaign done
        if SAVE["unlock"] >= 14:
            btn = ImgButton(GFX["mode_cat"], callback=self.set_pacmode)
            btn.set_pos((674, 55))
            self.add_button("pacmode", btn)
        self.pacmode = False

        #stats/score area
        stats = StaticWidget((160, 96))
        stats.blit(GFX["ghost"], (3, 0))
        stats.blit(GFX["pacdog-img"], (3, 32))
        stats.blit(GFX["catnip"], (3, 64))
        stats.blit(GFX["cataway"], (96, 0))
        self.stat_bg = stats

        score_bg = StaticWidget((160, 96))
        self.score_bg = score_bg

        self.stat_flip = FlipImg([stats.copy(), score_bg.copy()])
        self.stat_flip.set_pos((472, 457))

        #filename buttons
        size = (160, 30)
        file_pos = (120, 106)
        x = file_pos[0]
        y = file_pos[1]
        for i in xrange(10):
            name = ""
            if i < len(self.maps):
                name = self.maps[i]
            btn = FixedTextButton(size, name, callback=self.select, nr=i)
            btn.set_pos((x, y))
            self.add_button(i, btn)
            y = y + size[1] + 2

        self.page = 0
        self.selected = 0
        self.max_page = 0
        self.set_folder(self.folder)
        self.select(0)

        self.add_kbevent(KEYDOWN, K_ESCAPE, self.quit)
예제 #28
0
    def __init__(self):
        State.__init__(self)
        self.fps = 40

        #animation checkpoints and flags
        self.opening = 0
        self.closing = 0
        self.door_timer = Timer(15)  #open slowly, then faster
        self.maelstrom_timer = Timer(30)  #open doors a bit.. then pull
        self.nanji_command = None

        #generate pseudo-map
        screen_size = GLOBALS["screen_size"]
        self.bg_image = pygame.Surface(screen_size)
        self.top_layer = pygame.Surface(screen_size)
        self.top_layer.set_colorkey((255, 0, 255))
        self.top_layer.fill((255, 0, 255))

        #draw map background
        bg = GLOBALS["backgrounds"]["fuji.png"]
        self.bg_image.blit(bg, (0, 0))

        #draw grass
        tsize = GLOBALS["tile_size"]
        grass_tile = GLOBALS["ts_tileset"][1, 0]
        x = -tsize
        y = screen_size[1] - tsize
        for i in xrange(22):
            self.top_layer.blit(grass_tile, (x, y))
            x += tsize

        #draw mysterious
        myst = GLOBALS["ui_stuff"]["mysterious.png"]

        #draw full signet board on mysterious
        board = GLOBALS["ui_stuff"]["board_filled.png"]
        x, y = 66, 197
        myst.blit(board, (x, y))

        x = 5 * tsize
        y = screen_size[1] - myst.get_size()[1] - tsize
        self.myst = StaticWidget(myst.get_size())
        self.myst.set_colorkey((255, 0, 255))
        self.myst.fill((255, 0, 255))
        self.myst.blit(myst, (0, 0))
        self.myst.set_pos((x, y))
        self.myst.pos = (x, y)
        self.myst.draw(self.top_layer)
        myst_centerx = x + myst.get_size()[0] / 2
        myst_top = y + 30

        #init doors
        self.door_speed = 1
        door_left_image = GLOBALS["ui_stuff"]["door_left.png"]
        door_right_image = GLOBALS["ui_stuff"]["door_right.png"]
        self.door_left = StaticWidget(door_left_image.get_size())
        self.door_left.blit(door_left_image, (0, 0))
        self.door_left.set_pos((self.myst.pos[0] + 99, self.myst.pos[1] + 63))
        self.door_right = StaticWidget(door_right_image.get_size())
        self.door_right.blit(door_right_image, (0, 0))
        self.door_right.set_pos(
            (self.myst.pos[0] + 177, self.myst.pos[1] + 63))

        #init whirling vortex
        self.vortex = Vortex(centerpos=(myst_centerx, myst_top))

        #init Nanji
        self.nanji = Nanji(cam=None)
        self.nanji.status = 0
        self.nanji.set_pos((205, 401))
        self.nanji_angle = 0
        self.nanji_fly_img = self.nanji.all_images["landing"][0]
        self.nanji_shrink = 1
        self.sprites.add(self.nanji)

        self.nanji_do("throw")
예제 #29
0
 def __init__(self, size, side="left"):
     StaticWidget.__init__(self, size)
     self.side = side
     self.bgcolor = (0,0,0)