class GameTouillette(GameBasic): """ classe qui gère tout le jeu. """ def __init__(self, surfaceDest, gravityDir=DOWN, tutorialScheduler=None, xyFirstTouillette=(2, 5)): """ constructeur. (thx captain obvious) entrée : surfaceDest : Surface principale de l'écran, sur laquelle s'affiche le jeu. """ self.initCommonStuff(surfaceDest, gravityDir, tutorialScheduler) self.nbTouilletteToRemove = 2 self.mustDisplayRemoving = False self.arena = ArenaTouillette(surfaceDest, self.posPixelArena, ARENA_SIZE, 2, LIST_CHIP_GENERATION) self.selectorPlayerOne = Selector(self.arena, 0) self.populateArena() self.arena.addBigObject(Touillette, pyRectTuple(xyFirstTouillette)) self.arena.draw() pygame.display.flip() def periodicAction(self): """ à overrider """ # À priori, ce genre de truc n'a rien à foutre dans une "periodicAction". # On n'a besoin de le tester uniquement quand une touillette # est arrivée en bas de l'écran. if self.mustDisplayRemoving: securedPrint(u"blorp") nbTouRemoved = self.arena.nbTouilletteRemoved nbTouToRem = self.nbTouilletteToRemove self.mustDisplayRemoving = False if nbTouRemoved == nbTouToRem: listTextWin = language.LIST_TEXTS_WIN[language.languageCurrent] self.console.addListTextAndDisplay(listTextWin, COLOR_WIN) else: strBla = u"%d/%d" % (nbTouRemoved, nbTouToRem) textTouy = language.TEXT_TOUY[language.languageCurrent] self.console.addListTextAndDisplay((textTouy, strBla)) def handleGravity(self): securedPrint(u"handleGravity") if self.arena.removeBottomTouillette(): touilletteRemoved = True self.mustDisplayRemoving = True else: touilletteRemoved = False self.applyGravity() if self.needStabilization() or touilletteRemoved or self.arena.hasTouilletteInBottom(): securedPrint(u"there is still gravity.") self.gravityCounter = DELAY_GRAVITY else: securedPrint(u"lock set to false.") self.selectorPlayerOne.setStimuliLock(False)
class GameAspirin(GameBasic): """ classe qui gère tout le jeu. """ def __init__(self, surfaceDest, gravityDir=DOWN, tutorialScheduler=None): """ constructeur. (thx captain obvious) entrée : surfaceDest : Surface principale de l'écran, sur laquelle s'affiche le jeu. """ self.initCommonStuff(surfaceDest, gravityDir, tutorialScheduler) self.arena = ArenaAspirin(surfaceDest, self.posPixelArena, ARENA_SIZE, 2) self.selectorPlayerOne = Selector(self.arena, 0) self.crawlerGravRift = ArenaCrawler(ARENA_SIZE) self.crawlerGravRift.config(RIGHT, DOWN) self.gravityMovementsRift = GravityMovements(LEFT, False, False) self.crawlerRegenRift = ArenaCrawler(ARENA_SIZE) self.crawlerRegenRift.config(LEFT, UP) self.crawlerGravRiftApply = ArenaCrawler(ARENA_SIZE) self.crawlerGravRiftApply.config(UP, RIGHT) self.nbAspirinTaken = 0 self.blinker = Blinker(self.arena) self.populateArena() self.arena.draw() pygame.display.flip() def populateArena(self): """ overriden """ for (coordX, coordY) in LIST_COORD_ASPRO_HALF_LEFT: tileToHardDefine = self.arena.getTile(pyRect(coordX, coordY)) tileToHardDefine.chip = ChipAsproHalfLeft() for (coordX, coordY) in LIST_COORD_ASPRO_HALF_RIGHT: tileToHardDefine = self.arena.getTile(pyRect(coordX, coordY)) tileToHardDefine.chip = ChipAsproHalfRight() def applyGravity(self): """ zonc """ securedPrint(u" applyGravity") #TRODO : une fonction/propriété, au lieu de ce len de merte. if len(self.gravityMovements.dicMovement) > 0: param = (self.crawlerGrav, self.gravityMovements, None) self.arena.applyGravity(*param) elif len(self.gravityMovementsRift.dicMovement) > 0: param = (self.crawlerGravRiftApply, self.gravityMovementsRift, self.crawlerRegenRift) self.arena.applyGravity(*param) self.arena.regenerateAllChipsAfterOneGravity(self.crawlerRegenRift) else: self.arena.removeHalfAsproBottom() def _determineAnyGravity(self): param = (self.crawlerGrav, self.gravityMovements) self.gravityMovements = self.arena.determineGravity(*param) #pas besoin de controler None ? gravNormalToDo = (self.gravityMovements is not None and len(self.gravityMovements.dicMovement) > 0) if gravNormalToDo: return True param = (self.crawlerGravRift, self.gravityMovementsRift) self.gravityMovementsRift = self.arena.determineGravityFullSegment(*param) gravColumnToDo = (self.gravityMovementsRift is not None and len(self.gravityMovementsRift.dicMovement) > 0) if gravColumnToDo: return True return False def needStabilization(self): """ overriden """ securedPrint(u"needStabilization") anyGravToDo = self._determineAnyGravity(); if anyGravToDo: securedPrint(u"needStabilization TRUE") return True if self.arena.hasAnyHalfAsproInBottom(): securedPrint(u"needStabilization true") return True securedPrint(u"needStabilization false") return False def handleGravity(self): securedPrint(u"handleGravity aspro") self.applyGravity() # Morceaux copié-collé exactement de GameBasic.handleGravity if self.needStabilization(): self.gravityCounter = DELAY_GRAVITY else: #arrache un peu no ? Réponse : oui. double-arrache. if (self.tutorialScheduler is None or not self.tutorialScheduler.mustLockGameStimuli() ): self.selectorPlayerOne.setStimuliLock(False) def gameStimuliInteractiveTouch(self): """ overriden """ #self.blinker.startBlink((pyRect(2, 2), pyRect(3, 2), pyRect(4, 2))) if self.arena.getAndResetTakenAsproFull(): self.nbAspirinTaken += 1 if self.nbAspirinTaken == NB_ASPIRIN_TO_TAKE: listTextWin = language.LIST_TEXTS_WIN[language.languageCurrent] self.console.addListTextAndDisplay(listTextWin, COLOR_WIN) else: textYeah = language.TEXT_YEAH[language.languageCurrent] self.console.addListTextAndDisplay((textYeah, )) if self.tutorialScheduler is None: strBla = u"%d/%d" % (self.nbAspirinTaken, NB_ASPIRIN_TO_TAKE) self.console.addListTextAndDisplay((strBla, ))
class GameBasic(): """ classe qui gère tout le jeu. """ def __init__(self, surfaceDest, gravityDir=DOWN, tutorialScheduler=None): """ constructeur. (thx captain obvious) entrée : surfaceDest : Surface principale de l'écran, sur laquelle s'affiche le jeu. """ self.initCommonStuff(surfaceDest, gravityDir, tutorialScheduler) self.arena = ArenaBasic(surfaceDest, self.posPixelArena, ARENA_SIZE, 2) self.selectorPlayerOne = Selector(self.arena, 0) self.populateArena() self.arena.draw() pygame.display.flip() def populateArena(self): """ à overrider. On initialise l'arena avec les chips que l'on veut, si on veut. """ pass def execStimTutoNext(self): securedPrint(u"next tutorialization") # TRODO : un tutorial qui ne fait rien ? Ce qui permettrait d'éviter # ces tests de is None à chaque fois ? if self.tutorialScheduler is None: return if self.tutorialScheduler.takeStimTutoNext(): self.showCurrentTutoStep() if self.tutorialScheduler.getCurrentTellObjective(): zapValidatorDescrip = self.zapValidatorBase.getListStrDescription() param = (zapValidatorDescrip, COLOR_ZAP_OBJECTIVE) self.console.addListTextAndDisplay(*param) else: # re-blink, si le tuto n'avance pas, et que y'a des trucs à blinker. # comme ça le joueur revoit les blinks si il a pas eu le temps de les voir. # ATTENTION : code ajouté à l'arrache suite à reprise du projet à l'arrache. listPosBlink = self.tutorialScheduler.getCurrentBlink() if len(listPosBlink) and self.blinker is not None: self.blinker.startBlink(listPosBlink) def initCommonStuff(self, surfaceDest, gravityDir, tutorialScheduler=None): """ zob TRODO : c'est un peu le bordel d'avoir foutu ça là. Du coup, quand on regarde dans l'init, on se rend pas compte que y'a toutes ces variables membres. donc, c'est mal de faire ça. """ self.surfaceDest = surfaceDest self.blinker = None self.tutorialScheduler = tutorialScheduler self.console = Console(self.surfaceDest, pyRect(400, 10, 235, 460), nbCharMax=25) self.console.addText(language.TEXT_HELLO[language.languageCurrent]) self.console.refresh() self.console.display() self.manual = ManualInGame( self.surfaceDest, pyRect(10, 340, 400, 130), self.tutorialScheduler) self.manual.refresh() self.manual.display() self.posPixelArena = pyRect(10, 10) param = (self.posPixelArena, ARENA_SIZE, TILE_PIXEL_SIZE) self.stimuliStocker = StimuliStockerForGame(*param) #Ca c'est le putain d'objet qui permet de maîtriser le temps !!! #Talaaaa, je suis le maître du temps. et des frames par secondes aussi. self.clock = pygame.time.Clock() if gravityDir is None: self.crawlerGrav = None self.gravityMovements = None self.crawlerRegen = None else: (gravPrimDir, gravSecDir, primCoordIsX, gravIncsCoord, regenPrimDir, regenSecDir) = DICT_GRAVITY_CONFIG[gravityDir] self.crawlerGrav = ArenaCrawler(ARENA_SIZE) self.crawlerGrav.config(gravPrimDir, gravSecDir) param = (gravityDir, primCoordIsX, gravIncsCoord) self.gravityMovements = GravityMovements(*param) self.crawlerRegen = ArenaCrawler(ARENA_SIZE) self.crawlerRegen.config(regenPrimDir, regenSecDir) #print "self.crawlerRegen.secMove :", self.crawlerRegen.secMove def respawnZapValidator(self): """ redéfinit self.zapValidatorBase (qui n'est pas bien nommé, au passage) """ param = (self.arena, random.randrange(7, 23), random.randrange(3)) self.zapValidatorBase = ZapValidatorBase(*param) def tryToZap(self): """ zob """ selPath = self.selectorPlayerOne.selPath selSuppl = self.selectorPlayerOne.selSuppl if self.zapValidatorBase.validateZap(selPath, selSuppl, []): # gestion du tutorial, si y'en a un. if self.tutorialScheduler is not None: param = (selPath, selSuppl) if self.tutorialScheduler.takeStimTileSelected(*param): self.showCurrentTutoStep() if self.tutorialScheduler.totallyFailed: listTextFail = self.tutorialScheduler.getFailText() self.console.addListTextAndDisplay(listTextFail) self.zapWin() self.respawnZapValidator() self.arena.zapSelection(selPath, selSuppl) self.selectorPlayerOne.cancelAllSelection() if self.needStabilization(): self.gravityCounter = DELAY_GRAVITY self.selectorPlayerOne.setStimuliLock(True) if ((self.tutorialScheduler is None) or (self.tutorialScheduler.getCurrentTellObjective())): zapValidatorDescrip = self.zapValidatorBase.getListStrDescription() self.console.addListTextAndDisplay(zapValidatorDescrip, COLOR_ZAP_OBJECTIVE) else: lastTryDescrip = self.zapValidatorBase.getListStrLastTry() textFail = language.TEXT_FAIL[language.languageCurrent] self.console.addListTextAndDisplay(lastTryDescrip + (textFail, )) def zapWin(self): """ à overrider """ textYeah = language.TEXT_YEAH[language.languageCurrent] self.console.addListTextAndDisplay((textYeah, )) def periodicAction(self): """ à overrider """ pass def applyGravity(self): """ zonc """ param = (self.crawlerGrav, self.gravityMovements, self.crawlerRegen) self.arena.applyGravity(*param) self.arena.regenerateAllChipsAfterOneGravity(self.crawlerRegen) def needStabilization(self): """ zob """ param = (self.crawlerGrav, self.gravityMovements) self.gravityMovements = self.arena.determineGravity(*param) if (self.gravityMovements is not None and len(self.gravityMovements.dicMovement) > 0 ): return True if self.arena.hasChipToRegenerate(self.crawlerRegen): return True return False def handleGravity(self): self.applyGravity() if self.needStabilization(): self.gravityCounter = DELAY_GRAVITY else: #arrache un peu no ? Réponse : oui. double-arrache. if (self.tutorialScheduler is None or not self.tutorialScheduler.mustLockGameStimuli() ): self.selectorPlayerOne.setStimuliLock(False) def gameStimuliInteractiveTouch(self): """ à overrider """ pass # debug à l'arrache if False: if hasattr(self.arena, "listBigObj"): for bigObject in self.arena.listBigObj: securedPrint(u"bigobj : %s" % unicode(bigObject.posTopLeft)) securedPrint(u" listPosArena : %s" % bigObject.listPosArena) for line in self.arena.matrixTile: for tile in line: if tile.chip.getBrouzouf() == 10: print "10 ", elif tile.chip.getBrouzouf() > 0: print " " + str(tile.chip.getBrouzouf()) + " ", elif tile.chip.getSugar() > 0: print " S ", elif tile.chip.getChipType() == 4: print " B ", elif tile.chip.getChipType() == 1: print " 0 ", else: print "?" + str(tile.chip.getChipType()) + " ", print "" def showCurrentTutoStep(self): """ """ if self.tutorialScheduler is None: return listTextDescrip = self.tutorialScheduler.getCurrentText() if len(listTextDescrip): securedPrint(unicode(listTextDescrip)) param = (listTextDescrip, COLOR_TUTORIAL) self.console.addListTextAndDisplay(*param) # sound soundTuto = self.tutorialScheduler.getCurrentSound() if soundTuto is not None: pygame.mixer.stop() soundTuto.play() #blink listPosBlink = self.tutorialScheduler.getCurrentBlink() if len(listPosBlink) and self.blinker is not None: self.blinker.startBlink(listPosBlink) #lock if self.tutorialScheduler.mustLockGameStimuli(): securedPrint("locked !!!") self.selectorPlayerOne.setStimuliLock(True) else: # Euh... Faut délocker ou rien faire ? Bonne question. self.selectorPlayerOne.setStimuliLock(False) def playOneGame(self): """ zob """ # TRODO : pourquoi y'a du code d'init ici ? self.gravityCounter = 0 self.respawnZapValidator() self.showCurrentTutoStep() if ((self.tutorialScheduler is None) or (self.tutorialScheduler.getCurrentTellObjective())): zapValidatorDescrip = self.zapValidatorBase.getListStrDescription() self.console.addListTextAndDisplay(zapValidatorDescrip, COLOR_ZAP_OBJECTIVE) while True: #ça, c'est la classe, déjà pour commencer. #Le jeu va s'auto-ralentir pour atteindre le nombre de FPS spécifié self.clock.tick(FRAME_PER_SECOND) self.stimuliStocker.resetStimuli() self.stimuliStocker.takeEventsFromMouseAndKeyboard() #TRODO : une sorte de mapping ? if self.stimuliStocker.stimuliQuitGame: return if self.stimuliStocker.mustStandBy: self.selectorPlayerOne.takeStimuliStandBy() for posSelected in self.stimuliStocker.listPosArenaToActivate: securedPrint(unicode(posSelected)) self.selectorPlayerOne.takeStimuliActivateTile(posSelected) if self.stimuliStocker.stimuliTryZap: # TRODO condition foutue à l'arrache. # Faut rendre le stimuliStocker configurable. On y locke/délocke des trucs if (self.tutorialScheduler is None or not self.tutorialScheduler.mustLockGameStimuli()): self.tryToZap() if self.stimuliStocker.stimuliEmptySelection: self.selectorPlayerOne.cancelAllSelection() if self.stimuliStocker.stimuliChangeZapConstraint: self.respawnZapValidator() zapValidatorDescrip = self.zapValidatorBase.getListStrDescription() self.console.addListTextAndDisplay(zapValidatorDescrip, COLOR_ZAP_OBJECTIVE) if self.stimuliStocker.stimuliConsoleScrollUp: self.console.moveCursorText(-1) self.console.refresh() self.console.display() if self.stimuliStocker.stimuliConsoleScrollDown: self.console.moveCursorText(+1) self.console.refresh() self.console.display() if self.stimuliStocker.stimTutoNext: self.execStimTutoNext() if self.stimuliStocker.stimReblink: # TODO : il aurait vraiment fallu un tutorialScheduler par # défaut, bidon, qui ne fait rien. Là on s'en sort pas à le # tester à chaque fois si il existe. if self.tutorialScheduler is not None: listPosBlink = self.tutorialScheduler.getCurrentBlink() else: listPosBlink = [] if len(listPosBlink) and self.blinker is not None: self.blinker.startBlink(listPosBlink) # Je ne sais plus pourquoi je raconte ça ici, ni ce que ça veut dire. # #si stand by : stand by #si activate. on chope la coord. # si coord none. : stan by. Et previous = None # sinon : # si previous = None. On active et c'est tout. # sinon : on active tout le chemin entre previous et actuel # previous = actuel posInteract = self.stimuliStocker.posArenaToInteractTouch if posInteract is not None: # ça faut le foutre dans la fonction qu'on override. # C'est peut être mieux non ? if self.arena.stimuliInteractiveTouch(posInteract): self.selectorPlayerOne.cancelAllSelection() if self.needStabilization(): self.selectorPlayerOne.setStimuliLock(True) self.gravityCounter = DELAY_GRAVITY if (self.tutorialScheduler is not None and self.tutorialScheduler.takeStimInteractiveTouch()): self.showCurrentTutoStep() # c'est de cette fonction là que je parle. self.gameStimuliInteractiveTouch() #TRODO : faudra une 'tite classe pour les compteurs. if self.gravityCounter: self.gravityCounter -= 1 if not self.gravityCounter: self.handleGravity() self.periodicAction() if self.blinker is not None: self.blinker.advanceTimerAndHandle() #TRODO : optimiser ça. Pas de refresh géant à chaque frame. self.arena.draw() pygame.display.flip()