示例#1
0
class Game():

    QUIT_GAME = -2
    QUIT_TO_MENU = -1
    NORMAL = 0 #All other modes count as paused!
    POP_UP_MENU = 1
    POP_UP_QUIT = 2
    
    def __init__(self, scr, toLoad):
        self.state = Game.NORMAL
        self.quitState = Game.NORMAL
        self.screen = scr
        self.windowX = self.screen.get_width()
        self.windowY = self.screen.get_height()
        self.fillerFont = pygame.font.Font(None, 24)
        self.filler16 = pygame.font.Font(None, 16)
        self.gameBG = pygame.image.load("img/game_bg.png")
        self.gameBGTile = pygame.image.load("img/game_bg_tile.png")
        self.gameBGTileRect = self.gameBGTile.get_rect()
        self.botPanel = Object("img/ui/bottom_panel.png",512,self.windowY-64,1024,128)
        self.topLeft = Object("img/ui/top_left.png", 256,64,512,128)
        self.topLeftRect1 = pygame.Rect(0,0,128,128)
        self.topLeftRect2 = pygame.Rect(128,0,512-128,64)
        #Some UI Buttons
        self.saveButton = ClickableButton("img/buttons/save80x32.png",self.windowX - 96, self.windowY - 64,80,32)
        self.moveButton = ClickableButton("img/buttons/move_here80x32.png",352, self.windowY - 32,80,32)
        #Menu Panel
        self.menuPanel = Object("img/ui/menu.png",self.windowX/2, self.windowY/2, 212,274)
        self.closeButton = ClickableButton("img/buttons/close.png", self.menuPanel.rect.right-13, self.menuPanel.rect.top+13,17,17)
        self.menuSaveButton = ClickableButton("img/buttons/save_game.png", self.menuPanel.x, self.menuPanel.rect.top+88,192,64)
        self.menuMenuButton = ClickableButton("img/buttons/quit_menu.png", self.menuPanel.x, self.menuPanel.rect.top+160,192,64)
        self.menuQuitButton = ClickableButton("img/buttons/quit_desktop.png", self.menuPanel.x, self.menuPanel.rect.top+232,192,64)
        #Quit Dialog Panel
        self.quitPanel = Object("img/ui/quit_menu.png",self.windowX/2, self.windowY/2, 212,274)
        self.saveButton = ClickableButton("img/buttons/save80x32.png",self.windowX - 96, self.windowY - 64,80,32)
        #Use the same close button
        self.saveQuitButton = ClickableButton("img/buttons/save_quit.png", self.menuPanel.x, self.menuPanel.rect.top+88,192,64)
        self.quitWOSaveButton = ClickableButton("img/buttons/quit_wo_save.png", self.menuPanel.x, self.menuPanel.rect.top+160,192,64)
        self.cancelButton = ClickableButton("img/buttons/cancel.png", self.menuPanel.x, self.menuPanel.rect.top+232,192,64)
        #More variables
        self.timeRatio = 60
        self.actionQueue = []
        #Guess what? It's a map, bitch
        self.cmapRect = pygame.Rect(0,0,1080,540)
        self.cmapRect.center = (self.windowX/2, self.windowY/2-32)
        self.cmap = CMap(9,9,self.cmapRect)
        #Load or New is important here
        if toLoad != None:
            self.loadGame(toLoad)
            self.saveName = toLoad
        else:
            self.newGame()
            self.saveName = "save.txt"
    
    #More Map code
    def swap(self,setSpecial,x):
        if x > 0: #change start
            self.startBlock.state = 0
            self.startBlock = setSpecial
        if x < 0: #change end
            self.endBlock.state = 0
            self.endBlock = setSpecial
    
    def newGame(self):
        #Set up the time
        self.startTime = datetime.datetime.now()
        self.currTime = self.startTime
        self.player = Player("Chap", (0,1), self.cmap)
        #Add test actions
        #self.actionQueue.append( Action("testType", "Poopalooping", self.startTime, datetime.timedelta(minutes=30), None) )
        #self.actionQueue.append( Action("testType", "Infecting Zombies", self.startTime, datetime.timedelta(hours=4), None) )
        #self.actionQueue.append( Action("testType", "Reticulating Splines", self.startTime, datetime.timedelta(days=7), None) )
    
    def loadGame(self, toLoad):
        #print "Loading game from %s..."%toLoad
        f = open(toLoad, 'r')
        prevGameTimeLine = f.readline()
        if prevGameTimeLine == '':
            print "No File Found!"
            self.newGame()
            f.close()
            return
        prevSaveTimeLine = f.readline()
        #Maybe more error checking here?
        #Now convert to datetimes!
        prevGameTime = self.textToDateTime(prevGameTimeLine)
        prevSaveTime = self.textToDateTime(prevSaveTimeLine)
        #Calculate the new game time!
        saveTimeDiff = datetime.datetime.now() - prevSaveTime
        gameTimeDiff = saveTimeDiff * self.timeRatio
        self.currTime = prevGameTime #+ gameTimeDiff #Disabling time passing while offline, gameplay decision
        #Now load up the player!
        playerLine = f.readline().rstrip().split('^')
        self.player = Player(playerLine[0], (int(playerLine[1]),int(playerLine[2])), self.cmap)
        #Load Actions/Fulfill based on time passed
        aLine = f.readline()
        if aLine != "actions:\n":
            print "ERROR!"
            pygame.quit()
            sys.exit()
        aLine = f.readline()
        while aLine != "endActions\n":
            #Code goes here to check if an action completed while away from the game
            anAction = self.textToAction(aLine)
            if anAction.isDone(self.currTime) == False:
                self.actionQueue.append(anAction)
                self.player.action = anAction
            aLine = f.readline()
        #At this point, aLine == "endActions\n"

        #End File Stuff
        f.close()
        #print "Load complete!"
        
    def saveGame(self, saveDest):
        #print "Saving game to %s..."%saveDest
        f = open(saveDest, 'w')
        #Time stuff
        f.write("gametime,%s\n"%self.dateTimeToText(self.currTime))
        irlTime = datetime.datetime.now()
        f.write("savetime,%s\n"%self.dateTimeToText(irlTime))
        #Player
        f.write("%s^%i^%i\n"%(self.player.name, self.player.pos[0], self.player.pos[1]))
        #Actions
        f.write("actions:\n")
        for act in self.actionQueue:
            f.write(self.actionToText(act))
        f.write("endActions\n")
        #End File Stuff
        f.close()
        #print "Save complete!"
    
    def mouseCollideWithUI(self, pt):
        return self.botPanel.rect.collidepoint(pt) or self.topLeftRect1.collidepoint(pt) or self.topLeftRect2.collidepoint(pt)
    
    def handle_events(self):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.state = Game.POP_UP_QUIT
                self.quitState = Game.QUIT_GAME
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.toggle_menu()
                if event.key == pygame.K_F5:
                    self.saveGame(self.saveName)
            #Mouse Events
            elif self.state == Game.NORMAL and(event.type == pygame.MOUSEBUTTONUP or event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.MOUSEMOTION):
                toSave = self.saveButton.mouse_event(event)
                if toSave:
                    self.saveGame(self.saveName)
                #Deal with the movement button
                if self.cmap.selectedPos != None:
                    toMove = self.moveButton.mouse_event(event)
                    if toMove:
                        self.move_player_to_selected()
            #Dialog Menu
            elif self.state == Game.POP_UP_MENU and(event.type == pygame.MOUSEBUTTONUP or event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.MOUSEMOTION):
                toClose = self.closeButton.mouse_event(event)
                if toClose:
                    self.toggle_menu()
                #Save
                toSave = self.menuSaveButton.mouse_event(event)
                if toSave:
                    self.saveGame(self.saveName)
                    self.toggle_menu()
                #Main Menu
                toMenu = self.menuMenuButton.mouse_event(event)
                if toMenu:
                    self.quitState = Game.QUIT_TO_MENU
                    self.state = Game.POP_UP_QUIT
                #Quit Game
                toQuit = self.menuQuitButton.mouse_event(event)
                if toQuit:
                    self.quitState = Game.QUIT_GAME
                    self.state = Game.POP_UP_QUIT
            #Quit Dialog
            elif self.state == Game.POP_UP_QUIT and(event.type == pygame.MOUSEBUTTONUP or event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.MOUSEMOTION):
                toClose = self.closeButton.mouse_event(event)
                toCancel = self.cancelButton.mouse_event(event)
                if toClose or toCancel:
                    self.toggle_menu()
                #Save & Quit
                toSave = self.saveQuitButton.mouse_event(event)
                if toSave:
                    self.saveGame(self.saveName)
                    self.state = self.quitState
                #Quit w/o Save
                toQuit = self.quitWOSaveButton.mouse_event(event)
                if toQuit:
                    self.state = self.quitState
            #Map stuff (from test.py)
            if self.state == Game.NORMAL and (event.type == pygame.MOUSEBUTTONUP or event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.MOUSEMOTION):
                if not(self.mouseCollideWithUI(event.pos)):
                    self.cmap.handle_event(event)
                elif self.cmap.lastHighlight != None:
                    self.cmap.lastHighlight.state = GridIcon.NORMAL
    
    def toggle_menu(self):
        """Activates a menu pop-up for saving/quitting"""
        #If the pop up is already on, deactivate
        if self.state == Game.POP_UP_MENU or self.state == Game.POP_UP_QUIT:
            self.state = Game.NORMAL
        else:
            self.state = Game.POP_UP_MENU
    
    def move_player_to_selected(self):
        """Moves the player to the currently selected grid square"""
        #Check for no selection
        if self.cmap.selectedPos == None:
            print "Ruh Roh!"
            return
        #Create a movement action for this movement
        someParams = [self.cmap.path_find(self.player.pos, self.cmap.selectedPos), "walking"]
        moveAct = Action("movement", "Moving to (%i, %i)"%(self.cmap.selectedPos[0], self.cmap.selectedPos[1]), self.currTime, None, someParams)
        #Remove any previous movement actions
        for act in self.actionQueue:
            if act.type == "movement":
                self.actionQueue.remove(act)
        self.actionQueue.append(moveAct)
        self.player.action = moveAct
        
    def update(self, msPassed):
        #Do something with the time (only if unpaused):
        if self.state == Game.NORMAL:
            timeDiff = datetime.timedelta(microseconds = self.timeRatio * msPassed * 1000)
            self.currTime = self.currTime + timeDiff
            #Check if any actions have finished
            for act in self.actionQueue:
                if act.isDone(self.currTime):
                    self.actionQueue.remove(act)
        #Map stuff
        self.cmap.update(msPassed)
        #Player
        self.player.update(msPassed, self.currTime)
    
    def draw(self):
        #self.screen.blit(self.gameBG, pygame.Rect(0, 0, self.windowX, self.windowY))
        for x in range(self.windowX/self.gameBGTileRect.width + self.gameBGTileRect.width):
            for y in range(self.windowY/self.gameBGTileRect.height + self.gameBGTileRect.height):
                self.screen.blit(self.gameBGTile, pygame.Rect(x*self.gameBGTileRect.width, y*self.gameBGTileRect.height, self.gameBGTileRect.width, self.gameBGTileRect.height))
        #Whattup, it's a map!
        self.cmap.draw(self.screen)
        #Player
        self.player.draw(self.screen)
        #UI
        self.botPanel.draw(self.screen)
        self.topLeft.draw(self.screen)
        self.saveButton.draw(self.screen)
        if self.cmap.selectedPos != None:
            self.moveButton.draw(self.screen)
        #Some code to display the time and date
        timeStr = self.getTimeStr(self.currTime)
        timeText1 = self.fillerFont.render(timeStr, 1, (0, 0, 0))
        timeText2 = self.fillerFont.render("%i/%i/%i"%(self.currTime.month, self.currTime.day, self.currTime.year), 1, (0, 0, 0))
        timeRect1 = timeText1.get_rect()
        timeRect2 = timeText2.get_rect()
        timeRect1.center = (32, self.windowY - 96)
        timeRect2.center = (128, self.windowY - 96)
        self.screen.blit(timeText1, timeRect1)
        self.screen.blit(timeText2, timeRect2)
        #A quick display for the actions we have (active ones only)
        counter = 0
        for index, act in enumerate(self.actionQueue):
            if counter >= 3:
                break
            if act.isStarted(self.currTime) == False:
                continue
            actStr = "%s : %s to go"%(act.desc, self.getDeltaStr(act.timeRemaining(self.currTime)))
            txtSurf = self.filler16.render(actStr, 0, (0, 0, 0))
            txtRect = txtSurf.get_rect()
            txtRect.center = (self.windowX - 352, self.windowY - 96 + 32*counter)
            self.screen.blit(txtSurf, txtRect)
            counter += 1
        #Display Player Name
        nameStr = self.fillerFont.render(self.player.name, 1, (0, 0, 0))
        nameRect = nameStr.get_rect()
        nameRect.center = (64,64)
        self.screen.blit(nameStr, nameRect)
        #Display info about the selected tile
        if self.cmap.selectedPos == None:
            selStr = "No Tile Selected! :("
        else:
            selStr = "(%i, %i) Selected"%(self.cmap.selectedPos[0], self.cmap.selectedPos[1])
        selSurf = self.fillerFont.render(selStr, 1, (0, 0, 0))
        selRect = selSurf.get_rect()
        selRect.center = (352, self.windowY - 96)
        self.screen.blit(selSurf, selRect)
        #Pop-Up Menu
        if self.state == Game.POP_UP_MENU:
            #draw some menu stuff
            self.menuPanel.draw(self.screen)
            self.closeButton.draw(self.screen)
            self.menuSaveButton.draw(self.screen)
            self.menuMenuButton.draw(self.screen)
            self.menuQuitButton.draw(self.screen)
        #Quit Dialog
        if self.state == Game.POP_UP_QUIT:
            #draw some menu stuff
            self.quitPanel.draw(self.screen)
            self.closeButton.draw(self.screen)
            self.saveQuitButton.draw(self.screen)
            self.quitWOSaveButton.draw(self.screen)
            self.cancelButton.draw(self.screen)
    
    #Copied from main.py D:
    def exit_game(self):
        """Exits the game completely"""
        self.state = Game.QUIT_GAME
    
    #Here Lie the Helper Functions:
    def getTimeStr(self, aTime):
        leStr = ""
        hours = aTime.hour
        if hours < 10:
            leStr += "0%i"%hours
        else:
            leStr += "%i"%hours
        leStr += ":"
        mins = aTime.minute
        if mins < 10:
            leStr += "0%i"%mins
        else:
            leStr += "%i"%mins
        return leStr
        
    def getDeltaStr(self, dt):
        leStr = ""
        if dt.days > 0:
            leStr += "%i day(s), "%dt.days
        #print "dt.seconds/3600 = " + str(dt.seconds/3600) + " dt.seconds/60 = " + str(dt.seconds/60)
        if dt.seconds/3600 > 0:
            leStr += "%i:"%(dt.seconds/3600)
        else:
            leStr += "0:"
        if (dt.seconds/60)%60 >= 10:
            leStr += "%i"%((dt.seconds/60)%60)
        elif (dt.seconds/60)%60 > 0:
            leStr += "0%i"%((dt.seconds/60)%60)
        else:
            leStr += "00"
        #Seconds
        if dt.seconds%60 >= 10:
            leStr += ":%i"%(dt.seconds%60)
        elif dt.seconds%60 > 0:
            leStr += ":0%i"%(dt.seconds%60)
        else:
            leStr += ":00"
        return leStr
    
    def textToDateTime(self, text): #For loading datetimes
        aList = text.rstrip().split(',')
        return datetime.datetime(int(aList[1]), int(aList[2]), int(aList[3]), int(aList[4]), int(aList[5]), int(aList[6]))
    
    def dateTimeToText(self, dt): #For saving datetimes
        return "%i,%i,%i,%i,%i,%i"%(dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
    
    def textToDelta(self, text): #For loading deltas
        aList = text.rstrip().split(',')
        return datetime.timedelta(int(aList[1]), int(aList[2]), int(aList[3]))
    
    def deltaToText(self, dlt): #For saving deltas
        #print "dlt.days = %i, dlt.seconds = %i"%(dlt.days, dlt.seconds)
        return "%i,%i,%i"%(dlt.days, dlt.seconds, dlt.microseconds)
    
    def actionToText(self, act): #For saving actions
        aStr = "%s^%s^actStart,%s^actDuration,%s^"%(act.type, act.desc, self.dateTimeToText(act.startTime), self.deltaToText(act.duration))
        #Now deal with params
        if act.type == "testType":
            aStr += "None"
        elif act.type == "movement":
            pathStr = ""
            for tile in act.path:
                pathStr += "*%i %i"%(tile[0], tile[1])
            pathStr+="*"
            aStr += "%s&%s"%(pathStr, act.method)
        elif act.type == "scavenge":
            aStr += "None"
        elif act.type == "fortify":
            aStr += "None"
        elif act.type == "sweep":
            aStr += "None"
        return aStr+"\n"
        
    def textToAction(self, text): #For loading actions
        aList = text.rstrip().split('^')
        #Before making our Action, deal with params
        paramarams = None
        if aList[0] == "testType":
            pass
        elif aList[0] == "movement":
            paramarams = []
            paramList = aList[4].split('&')
            #First, append the path
            thePathList = paramList[0].split('*')
            thePath = []
            for tile in thePathList:
                if tile != "":
                    coords = tile.split(' ')
                    thePath.append((int(coords[0]), int(coords[1])))
            paramarams.append(thePath)
            #Then, append the method
            paramarams.append(paramList[1])
        elif aList[0] == "scavenge":
            pass
        elif aList[0] == "fortify":
            pass
        elif aList[0] == "sweep":
            pass
        return Action(aList[0], aList[1], self.textToDateTime(aList[2]), self.textToDelta(aList[3]), paramarams)
示例#2
0
 def draw(self, screen):
     screenRect = pygame.Rect(0, 0, 1024, 768)
     if self.rect.colliderect(screenRect):
         self.subrect.left = self.selected * self.rect.width
         ClickableButton.draw(self, screen)
示例#3
0
class Main():
    """Driver Class/Main Menu"""
    
    #Possible screens we're at:
    NONE = 0
    MAIN_MENU = 1
    INTRO = 2
    IN_GAME = 3
    #Add more as we add them (though these screens may have subscreens)
    
    def __init__(self):
        """Setup the window, etc"""
        self.windowX = 1024
        self.windowY = 768
        self.windowName = "Bacon Poutine"
        self.state = Main.NONE
        pygame.init()
        self.clock = pygame.time.Clock()
        self.msPassed = 0
        #Get the screen going
        self.screen = pygame.display.set_mode((self.windowX, self.windowY))
        pygame.display.set_caption(self.windowName)
        self.iconImg = pygame.image.load("img/icon.png").convert_alpha()
        pygame.display.set_icon(self.iconImg)
        pygame.mouse.set_visible(True)
        #Main Menu Stuff
        self.dudeObj = Object("img/dude.png",200,200,64,128)
        self.newButtonObj = ClickableButton("img/buttons/new_game.png",self.windowX/2, self.windowY/2+200,192,64)
        self.loadButtonObj = ClickableButton("img/buttons/load_game.png",self.windowX/2, self.windowY/2+272,192,64)
        self.menuBG = pygame.image.load("img/menu_bg.png").convert()
        self.intro = None
        self.game = None
    
    def run(self):
        """Runs the game"""
        self.state = Main.MAIN_MENU
        self.clock.tick()
        while True:
            if self.state == Main.MAIN_MENU:
                #Do our menu stuff
                self.handle_events()
                self.update()
                self.draw()
                pygame.display.flip()
            elif self.state == Main.INTRO and self.intro != None:
                self.handle_events()
                self.intro.update(self.msPassed)
                self.intro.draw()
                pygame.display.flip()
                if self.intro.doneYet:
                    self.state = Main.IN_GAME
                    self.game = Game(self.screen, None)
            elif self.state == Main.IN_GAME and self.game != None:
                self.game.handle_events()
                self.game.update(self.msPassed)
                self.game.draw()
                pygame.display.flip()
                #Check Game's state
                if self.game.state == Game.QUIT_GAME:
                    self.exit_game()
                if self.game.state == Game.QUIT_TO_MENU:
                    self.state = Main.MAIN_MENU
            else:
                #Quit!
                self.exit_game()
            #Tick the clock forward
            self.msPassed = self.clock.tick(60)
    
    def handle_events(self):
        """Handles all of the input (for main menu)"""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                self.exit_game() #If close button clicked in top right
            elif event.type == pygame.KEYDOWN:
                if event.key == pygame.K_ESCAPE:
                    self.exit_game()
            #Mouse Events
            elif event.type == pygame.MOUSEBUTTONUP or event.type == pygame.MOUSEBUTTONDOWN or event.type == pygame.MOUSEMOTION:
                newGame = self.newButtonObj.mouse_event(event)
                if newGame:
                    self.state = Main.INTRO
                    self.intro = IntroSeq(self.screen)
                loadGame = self.loadButtonObj.mouse_event(event)
                if loadGame:
                    self.state = Main.IN_GAME
                    self.game = Game(self.screen, "save.txt")
            
    def update(self):
        """Updates the menu every frame"""
        pass
        
    def draw(self):
        """Deals with drawing the menu stuff every frame"""
        self.screen.blit(self.menuBG, pygame.Rect(0, 0, self.windowX, self.windowY))
        #Buttons
        self.newButtonObj.draw(self.screen)
        self.loadButtonObj.draw(self.screen)
        self.screen.blit(self.dudeObj.img,self.dudeObj.rect)
    
    def exit_game(self):
        """Exits the game completely"""
        pygame.quit()
        sys.exit()