from eduGames import * from pygame.font import * import os if os.name != "nt": try: import olpcgames except: pass from GamesHelpers import * import Sort import Paint import Match import DragnDrop import MultipleChoice import Concentrate import ColorPaint import Help class Games(StandaloneGame): def makePath(self, fileName): resourcesDir = self.settings["resourcesDir"] return os.path.join(resourcesDir, fileName) def __init__(self, settings): if os.name == "nt": horizontalRes = 1200 verticalRes = 900 else: horizontalRes = 1200 verticalRes = 900 StandaloneGame.__init__(self, settings["fps"], horizontalRes, verticalRes, settings["gameTitle"]) self.xMargin = (horizontalRes - settings["screenWidth"])/2 self.yMargin = (verticalRes - settings["screenHeight"])/2 self.settings = settings self.root = None self.currentGame = None self.background = ImageControl(self, 0, 0, self.makePath("background1.png"), "") self.background.setLayer(10) self.getUiMgr().addControl(self.background) self.level2MenuItems = 0 self.level3MenuItems = 0 self.level4MenuItems = 0 self.level2MenuItemsForHelp = 0 self.level3MenuItemsForHelp = 0 self.level4MenuItemsForHelp = 0 self.filter = ColorFilterControl(self, 0, 0, self.settings["screenWidth"], self.settings["screenHeight"], (0,0,0), 3, 100) self.getUiMgr().addControl(self.filter) self.progressBar = ProgressBar(self, 84, 713, 276, 14) self.progressBar.filledColor = (255, 0, 0) self.progressBar.setLayer(4) self.currentNode = None self.quitButton = ImageControl(self, self.settings["quitButtonX"], self.settings["quitButtonY"], self.makePath("btn_quit.png"), "", 2) self.helpButton = ImageControl(self, self.settings["helpButtonX"], self.settings["helpButtonY"], self.makePath("btn_help.png"), "", 2) self.previousButton = ImageControl(self, self.settings["previousButtonX"], self.settings["previousButtonY"], self.makePath("btn_previous.png"), "", 2) self.nextButton = ImageControl(self, self.previousButton.getX() + 80, self.previousButton.getY(), self.makePath("btn_next.png"), "", 2) self.barraBase = ImageControl(self, 75, 705, self.makePath("Barra_base.png"), "") self.marcoBarraBase = ImageControl(self, 75, 705, self.makePath("MarcoBarra_base.png"), "") self.logo = ImageControl(self, self.settings["logoX"], self.settings["logoY"], self.makePath("logo.png"), "", 1) self.actTypeName = None self.nextButton.setLayer(4) self.quitButton.setLayer(5) self.helpButton.setLayer(5) self.previousButton.setLayer(5) self.barraBase.setLayer(5) self.marcoBarraBase.setLayer(3) self.hoveredOnControl = None self.pausedGame = None self.messageWindow = MessageWindow(self) self.congratsAnimation = None self.frameCounter = 0 self.loadXOCursor() self.headUpDisplay = HeadUpDisplay(self) self.congratsWindow = CongratsWindow(self) self.welcomeWindow = WelcomeWindow(self) self.exitPopup = ImageControl(self, self.settings["exitPopupX"], self.settings["exitPopupY"], self.makePath("EFF_credits.png"), "", 1) self.helpIsPlaying = False def initializeGameData(self): self.filebox = Archiver(self, self.settings["rootIconX"], self.settings["rootIconY"]) self.buildTree() self.menu = self.buildMenu(self.root) self.menu.setLayer(0) self.filebox.setLayer(1) self.getUiMgr().addControl(self.progressBar) self.progressBar.maxValue = self.root.getNumberOfActivities() if self.settings["resetScoreOnStart"]: self.resetScore() self.progressBar.setCurValue(self.root.getNumberOfFinishedActivities()) self.getUiMgr().addControl(self.quitButton) self.getUiMgr().addControl(self.helpButton) self.getUiMgr().addControl(self.barraBase) self.getUiMgr().addControl(self.marcoBarraBase) self.getUiMgr().addControl(self.logo) for c in self.getUiMgr().controls: c.setX(c.getX() + self.xMargin) c.setY(c.getY() + self.yMargin) self.getUiMgr().addControl(self.exitPopup) self.exitPopup.makeInvisible() self.menu.open() self.filter.filterOn() self.playWelcomeAnimation() def resetScore(self): try: self.root.resetScore() except: pass def loadXOCursor(self): if not os.name == "nt": mouseImage = self.makePath("arrow.xbm") mouseMask = self.makePath("arrow-mask.xbm") a, b, c, d = pygame.cursors.load_xbm(mouseImage, mouseMask) pygame.mouse.set_cursor(a, b, c, d) def on_mouse_button_down(self, clickedControl): if self.exitPopup.isVisible(): pygame.quit() sys.exit() if not self.messageWindow.isOpen() and not self.congratsWindow.isOpen() and not self.welcomeWindow.isOpen(): if clickedControl.type == "menu": if len(clickedControl.submenus) > 0: clickedControl.click() if clickedControl.isOpen() and clickedControl.parent is None: self.filter.filterOn() if not self.currentNode is None: if self.currentNode.getActivityTypeName() == "Paint" or self.currentNode.getActivityTypeName() == "ColorPaint": self.currentGame.pause() self.currentGame.isPaused = True if clickedControl.isClosed() and clickedControl.parent is None: self.filter.filterOff() if not self.currentNode is None: if self.currentNode.getActivityTypeName() == "Paint" or self.currentNode.getActivityTypeName() == "ColorPaint": self.currentGame.unPause() self.currentGame.isPaused = False elif clickedControl.item.level == 4: self.menu.close() self.filter.filterOff() self.currentNode = clickedControl.item self.startGameFromNode(self.currentNode) elif clickedControl is self.nextButton: self.moveToNextActivity() elif clickedControl is self.previousButton: self.moveToPreviousActivity() elif clickedControl is self.quitButton: self.filter.filterOn() self.exitPopup.makeVisible() elif clickedControl is self.helpButton: self.openHelp() else: if not self.currentGame is None: self.currentGame.on_mouse_button_down(clickedControl) elif self.messageWindow.isOpen(): if clickedControl is self.messageWindow.exitButton: if not self.pausedGame is None: self.closeHelp() elif self.congratsWindow.isOpen(): if clickedControl is self.congratsWindow.nextButton: self.congratsWindow.close() if not self.congratsAnimation is None: self.congratsAnimation.stop() self.getUiMgr().removeControl(self.congratsAnimation) self.moveToNextActivity() elif self.welcomeWindow.isOpen(): if clickedControl is self.welcomeWindow.okButton: self.welcomeWindow.close() if not self.welcomeAnimation is None: self.welcomeAnimation.stop() self.getUiMgr().removeControl(self.welcomeAnimation) def moveToNextActivity(self): if not self.currentNode is None: nextNode = self.currentNode.getNextActivity() if not nextNode is None: self.currentNode = nextNode self.startGameFromNode(self.currentNode) def moveToPreviousActivity(self): if not self.currentNode is None: previousNode = self.currentNode.getPreviousActivity() if not previousNode is None: self.currentNode = previousNode self.startGameFromNode(self.currentNode) def openHelp(self): x = self.settings["screenWidth"]/2 + self.xMargin - 680/2 y = self.settings["screenHeight"]/2 + self.yMargin - 460/2 if not self.currentGame is None: helpDir = os.path.join("Help", self.currentGame.settings["helpDir"]) game = self.getGameEngineObject(self.currentNode.getGameEngineName(), helpDir) self.pausedGame = self.currentGame self.pausedGame.isPaused = True if self.currentNode.getActivityTypeName() == "Paint" or self.currentNode.getActivityTypeName() == "ColorPaint": self.pausedGame.pause() self.messageWindow.open(Rect(x, y, 680, 460), exitButton = True) self.currentGame = Help.DemoPlayer(helpDir, game) self.currentGame.gameEngine.isHelp = True self.currentGame.gameEngine.resourcesDir = self.pausedGame.resourcesDir #can be overriden by the resourcesDir setting of the help. self.currentGame.gameEngine.soundsDir = self.pausedGame.soundsDir self.currentGame.gameEngine.xMargin = self.xMargin self.currentGame.gameEngine.yMargin = self.yMargin self.currentGame.gameEngine.masterResourcesDir = self.settings["resourcesDir"] self.currentGame.initializeGameData() else: # pass self.level2MenuItemsForHelp = 0 self.level3MenuItemsForHelp = 0 self.level4MenuItemsForHelp = 0 mainHelp = Help.MainHelp(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(), os.path.join("Help", "MainHelp")) self.messageWindow.open(Rect(x, y, 680, 460), exitButton = True) dir = os.path.join("Help", "MainHelp") self.pausedGame = self self.currentGame = Help.DemoPlayer(dir, mainHelp) self.currentGame.gameEngine.resourcesDir = self.settings["resourcesDir"] self.currentGame.gameEngine.xMargin = self.xMargin self.currentGame.gameEngine.yMargin = self.yMargin self.currentGame.gameEngine.masterResourcesDir = self.settings["resourcesDir"] self.currentGame.gameEngine.realGame = self self.currentGame.initializeGameData() self.helpIsPlaying = True def closeHelp(self): if not self.pausedGame is self: if "endGame" in dir(self.currentGame.gameEngine): self.currentGame.gameEngine.endGame() self.currentGame.mousePointer.persistent = False self.getUiMgr().deleteGameControls(self.currentGame.gameEngine) self.currentGame = self.pausedGame if self.currentNode.getActivityTypeName() == "Paint" or self.currentNode.getActivityTypeName() == "ColorPaint": self.pausedGame.unPause() self.pausedGame.isPaused = False self.pausedGame = None self.messageWindow.close() else: # pass self.pausedGame = None self.currentGame.mousePointer.persistent = False self.getUiMgr().deleteGameControls(self.currentGame.gameEngine) self.currentGame = None self.messageWindow.close() self.helpIsPlaying = False def closeCurrentGame(self): if not self.currentGame is None: self.getUiMgr().deleteGameControls(self.currentGame) self.getSoundMgr().clearSounds() try: self.getUiMgr().removeControl(self.previousButton) except: pass #This should happen only the first time. try: self.getUiMgr().removeControl(self.nextButton) except: pass self.headUpDisplay.hide() def startGameFromNode(self, node): pygame.mouse.set_visible(True) self.closeCurrentGame() self.currentGame = self.getGameEngineObject(node.getGameEngineName(), node.path) self.currentGame.xMargin = self.xMargin self.currentGame.yMargin = self.yMargin self.currentGame.dataFilePath = node.getDataFilePath() self.currentGame.soundsDir = os.path.join(node.parent.path, "sounds") self.currentGame.masterResourcesDir = os.path.abspath(self.settings["resourcesDir"]) if os.name != "nt": try: folder = olpcgames.util.get_activity_root() (levelNumber, unitNumber, activityNumber) = self.getCurrentGameLevelUnitActivityNumbers() fileName = "data" + str(levelNumber) + "-" + str(unitNumber) + "-" + str(activityNumber) + ".txt" self.currentGame.dataFilePath = os.path.join(folder, fileName) except: pass (levelNumber, unitNumber, activityNumber) = self.getCurrentGameLevelUnitActivityNumbers() self.showForwardAndBackButtons(levelNumber, unitNumber, activityNumber) self.showActivityInfo(levelNumber, unitNumber, activityNumber) self.currentGame.initializeGameData() if self.currentNode.isFirstActivityOfUnit(): unitSoundPath = os.path.join(self.currentGame.soundsDir, "unitSound.ogg") self.getSoundMgr().addSoundForPlayback(unitSoundPath, False, True, True) def showForwardAndBackButtons(self, levelNumber, unitNumber, activityNumber): if levelNumber > 1 or unitNumber > 1 or activityNumber > 1: self.getUiMgr().addControl(self.previousButton) if levelNumber < 3 or unitNumber < 4 or activityNumber < 9: self.getUiMgr().addControl(self.nextButton) def getCurrentGameLevelUnitActivityNumbers(self): unit = self.currentNode.parent level = unit.parent activityNumber = unit.children.index(self.currentNode) + 1 unitNumber = level.children.index(unit) + 1 levelNumber = self.root.children.index(level) + 1 return (levelNumber, unitNumber, activityNumber) def showActivityInfo(self, levelNumber, unitNumber, activityNumber): self.changeBackground(levelNumber, unitNumber); unitName = self.getUnitName() activityTypeName = self.currentNode.getActivityTypeName() self.headUpDisplay.show(levelNumber, unitName, activityTypeName) def getUnitName(self): return self.currentNode.parent.name[1:] def changeBackground(self, levelNumber, unitNumber): totalUnitNumber = unitNumber + (levelNumber - 1)*4 backgroundFileName = "background" + str(totalUnitNumber) + ".png" self.getUiMgr().removeControl(self.background) self.background = ImageControl(self, self.xMargin, self.yMargin, self.makePath(backgroundFileName), "") self.background.setLayer(10) self.getUiMgr().addControl(self.background) def getGameEngineObject(self, engineName, settingsFilePath): #print engineName if engineName == "Sort": return Sort.Sort(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(), settingsFilePath) if engineName == "Paint": return Paint.Paint(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(),settingsFilePath) if engineName == "ColorPaint": return ColorPaint.ColorPaint(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(),settingsFilePath) if engineName == "Match": return Match.Match(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(),settingsFilePath) if engineName == "Dragndrop" or engineName == "DragnDrop" or engineName == "Drag": return DragnDrop.DragnDrop(self.getScreen(), self.getUiMgr(), self.getSoundMgr(),self.getScreenMgr(), settingsFilePath) if engineName == "MultipleC" or engineName == "Yes and No": return MultipleChoice.MultipleChoice(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(),settingsFilePath) if engineName == "Concentrate" or engineName == "Concentration": return Concentrate.Concentrate(self.getScreen(), self.getUiMgr(), self.getSoundMgr(), self.getScreenMgr(),settingsFilePath) def on_mouse_hover(self, clickedControl): if not self.messageWindow.isOpen() and not self.congratsWindow.isOpen() and not self.welcomeWindow.isOpen(): if clickedControl is self.menu: if not self.filebox.isOpen(): #this condition improves performance by avoiding useless executions of the hover method. self.filebox.hover() elif clickedControl.type == "menu": if not self.hoveredOnControl is None: self.hoveredOnControl.turnHoverOff() if not clickedControl.isOpen(): self.hoveredOnControl = clickedControl self.hoveredOnControl.turnHoverOn() elif clickedControl == self.quitButton: self.quitButton.setImageDivisionIndex(1) elif clickedControl == self.helpButton: self.helpButton.setImageDivisionIndex(1) elif clickedControl == self.nextButton: self.nextButton.setImageDivisionIndex(1) elif clickedControl == self.previousButton: self.previousButton.setImageDivisionIndex(1) else: if not self.filebox.isOpen(): self.filebox.closeCompletely() self.quitButton.setImageDivisionIndex(0) self.helpButton.setImageDivisionIndex(0) self.nextButton.setImageDivisionIndex(0) self.previousButton.setImageDivisionIndex(0) if not self.currentGame is None: self.currentGame.on_mouse_hover(clickedControl) elif self.messageWindow.isOpen(): if clickedControl == self.messageWindow.exitButton: clickedControl.setImageDivisionIndex(1) else: if not self.messageWindow.exitButton is None: self.messageWindow.exitButton.setImageDivisionIndex(0) elif self.congratsWindow.isOpen(): if clickedControl == self.congratsWindow.nextButton: clickedControl.setImageDivisionIndex(1) else: if not self.congratsWindow.nextButton is None: self.congratsWindow.nextButton.setImageDivisionIndex(0) elif self.welcomeWindow.isOpen(): if clickedControl == self.welcomeWindow.okButton: clickedControl.setImageDivisionIndex(1) else: if not self.welcomeWindow.okButton is None: self.welcomeWindow.okButton.setImageDivisionIndex(0) def on_mouse_button_up(self, clickedControl): if not self.currentGame is None: self.currentGame.on_mouse_button_up(clickedControl) def updateState(self): if not self.helpIsPlaying: self.frameCounter += 1 if self.frameCounter == 25: self.addDirtyRectangle(Rect(0,0,1200,100)) self.addDirtyRectangle(Rect(0,700,1200,200)) self.addDirtyRectangle(Rect(0,100,100,800)) self.addDirtyRectangle(Rect(1100,0,100,800)) self.setScreenAsChanged() self.frameCounter = 0 if not self.currentGame is None: self.currentGame.updateState() if self.currentGame.finished: self.getUiMgr().deleteGameControls(self.currentGame) self.currentGame = None self.progressBar.setCurValue(self.root.getNumberOfFinishedActivities()) if not self.currentNode is None: self.playCongratsAnimation() self.currentNode.menu.mainControl.markAsDone() self.headUpDisplay.hide() def playCongratsAnimation(self): self.congratsWindow.open() animation = MultipleFileAnimation(self, self.settings["jumpingGuyX"] + self.xMargin, self.settings["jumpingGuyY"] + self.yMargin, os.path.join(self.settings["resourcesDir"], "CongratsAnim")) self.getUiMgr().addControl(animation) animation.playAnimation(0) self.congratsAnimation = animation self.getSoundMgr().addSoundForPlayback(self.makePath("success.ogg")) soundFile = self.makePath(self.congratsWindow.currentCongratsMessage()[0:-1] + ".ogg") self.getSoundMgr().addSoundForPlayback(soundFile) def playWelcomeAnimation(self): self.welcomeWindow.open() animation = MultipleFileAnimation(self, self.settings["welcomeGuyX"] + self.xMargin, self.settings["welcomeGuyY"] + self.yMargin, os.path.join(self.settings["resourcesDir"], "kid_welcome")) self.getUiMgr().addControl(animation) animation.playAnimation(0) self.welcomeAnimation = animation self.getSoundMgr().addSoundForPlayback(self.makePath("welcome.ogg"), False, False, True) def buildTree(self): self.root = DirectoryTreeNode(self.settings["rootActivitiesDir"]) def buildMenu(self, node, diffX = 0, diffY = 0, help = None): (mainControl,backgroundControl) = self.getMenuControls(node, diffX, diffY) if help is None: menu = Menu(self, mainControl, backgroundControl) else: menu = Menu(help, mainControl, backgroundControl) menu.item = node node.menu = menu self.getUiMgr().addControl(menu) for child in node.children: if child.level < 5 and child.isDir: submenu = self.buildMenu(child, diffX, diffY) menu.addSubmenu(submenu) submenu.parent = menu return menu def getMenuControls(self, node, diffX = 0, diffY = 0): forHelp = diffX != 0 parent = self if forHelp: parent = self.currentGame.gameEngine if node.level == 1: mainControl = self.filebox backgroundControl = ImageControl(parent, self.settings["menuBaseX"] + self.xMargin + diffX, self.settings["menuBaseY"] + self.yMargin + diffY, self.makePath("menu_fdo_lvl.png"), "", 1) backgroundControl.setLayer(2) if node.level == 2: mainControl = MenuLevelItem(parent, self.makePath("btn_lvl.png"), os.path.join(node.path, "ico.png")) mainControl.setX(53 + self.settings["menuBaseX"] + self.xMargin + diffX) if not forHelp: itemsCounter = self.level2MenuItems else: itemsCounter = self.level2MenuItemsForHelp mainControl.setY(30 + self.settings["menuBaseY"]+ self.yMargin + diffY + itemsCounter * (mainControl.getHeight()+10)) mainControl.textColor = (0,0,0) #mainControl.text = "LEVEL " + str(self.level2MenuItems + 1) mainControl.text = "Level " + str(itemsCounter + 1) backgroundControlPath = os.path.join(self.makePath("menu_fdo_unit.png")) backgroundControl = ImageControl(parent, 221 + self.settings["menuBaseX"] + self.xMargin + diffX, 14 + self.settings["menuBaseY"] + self.yMargin + diffY, backgroundControlPath, "", 1) backgroundControl.setLayer(2) backgroundControl.name = "bkg2" + str(itemsCounter) if not forHelp: self.level2MenuItems += 1 else: self.level2MenuItemsForHelp += 1 if node.level == 3: iconPosition = (-5,-5) mainControl = MenuLevelItem(parent, os.path.join(node.parent.path, "btn_unit.png"), os.path.join(node.path, "ico.png"), iconPosition) mainControl.setX(240 + self.settings["menuBaseX"] + self.xMargin + diffX) if not forHelp: mainControl.setY(30 + self.settings["menuBaseY"] + self.yMargin + diffY + self.level3MenuItems * (mainControl.getHeight()+10)) else: mainControl.setY(30 + self.settings["menuBaseY"] + self.yMargin + diffY + self.level3MenuItemsForHelp * (mainControl.getHeight()+10)) mainControl.textColor = (0,0,0) #This wasn't here before #mainControl.text = node.name.upper()[1:] mainControl.text = node.name[1:] backgroundControlPath = os.path.join(node.parent.path, "menu_fdo_act.png") backgroundControl = ImageControl(parent, 414 + self.settings["menuBaseX"] + self.xMargin, 14 + self.settings["menuBaseY"] + self.yMargin, backgroundControlPath, "", 1) backgroundControl.setLayer(2) if not forHelp: mainControl.text = str(self.level3MenuItems + 1) + " " + mainControl.text self.level3MenuItems = (self.level3MenuItems + 1) % 4 else: mainControl.text = str(self.level3MenuItemsForHelp + 1) + " " + mainControl.text self.level3MenuItemsForHelp = (self.level3MenuItemsForHelp + 1) % 4 if node.level == 4: iconPosition = (-5,-5) mainControl = MenuLevelItem(parent, os.path.join(node.parent.path, "btn_act.png"), os.path.join(node.path, "ico.png"), iconPosition) if self.level4MenuItems < 5: mainControl.setX(415 + self.settings["menuBaseX"] + self.xMargin + diffX) mainControl.setY(25 + self.settings["menuBaseY"] + self.yMargin + diffY + self.level4MenuItems * (mainControl.getHeight()+10)) else: mainControl.setX(575 + self.settings["menuBaseX"] + self.xMargin + diffX) mainControl.setY(55 + self.settings["menuBaseY"] + self.yMargin + diffY + (self.level4MenuItems-5) * (mainControl.getHeight()+10)) #mainControl.text = node.getActivityTypeName().upper() mainControl.text = node.getActivityTypeName() mainControl.text = str(self.level4MenuItems + 1) + " " + mainControl.text mainControl.textColor = (0,0,0) backgroundControlPath = os.path.join(node.parent.path, "menu_fdo_act.png") backgroundControl = None if not forHelp: self.level4MenuItems = (self.level4MenuItems + 1) % 9 else: self.level4MenuItemsForItems = (self.level4MenuItemsForHelp + 1)%9 return (mainControl, backgroundControl) def playIntro(): if os.name == "nt": import introPlayerWin introPlayerWin.playIntro() def main(): settings = readDataFile("settings.txt") if not settings["skipIntro"]: playIntro() game = Games(settings) game.execute() if __name__ == '__main__': main()