import pygame, sys, os from pygame.locals import * from eduGames import * import random class Match(Game): def __init__(self, screen, uiMgr, sndMgr, screenMgr, path): Game.__init__(self, screen, uiMgr, sndMgr, screenMgr, path) self.selectedLeftImage = None self.controlMoving = None self.controlMovingTarget = (0,0) self.ignoreCommands = False self.solvedPuzzleElements = 0 self.currentPuzzleIndex = -1 self.moveToNextPuzzle = True self.finished = False self.mustRandom = self.settings["random"] self.soundsDir = "" #This is set by the Games class afterwards. self.wrongChoiceSoundPath = "" self.hoveredOnControl = None self.xMargin = 0 self.yMargin = 0 self.firstElement = None self.futureFirstElement = None self.isHelp = False def readInfo(self): fileName = os.path.join(self.path, self.settings["infoFile"]) puzzleFile = open(fileName, "r") fileText = puzzleFile.read() puzzleFileReader = PuzzlesReader(self.resourcesDir, self.mustRandom, self.soundsDir) puzzleFile.close() return puzzleFileReader.read(fileText) def initializeGameData(self): self.wrongChoiceSoundPath = os.path.join(self.soundsDir,"chord.ogg") self.puzzles = self.readInfo() def on_mouse_hover(self, clickedControl): if clickedControl.type == "leftImage" or (clickedControl.type == "rightImage" and not self.selectedLeftImage is None): if not clickedControl.isMoving(): if not self.hoveredOnControl is None: self.hoveredOnControl.filterOff() self.hoveredOnControl = clickedControl self.hoveredOnControl.filterOn() else: if not self.hoveredOnControl is None: self.hoveredOnControl.filterOff() def on_mouse_button_down(self, clickedControl): if self.ignoreCommands: return if clickedControl.type == "leftImage": self.changeLeftImageSelection(clickedControl) elif clickedControl.type == "rightImage": self.matchAttempt(clickedControl) def changeLeftImageSelection(self, control): previousSelectedLeftImage = self.selectedLeftImage self.getSoundMgr().addSoundForPlayback(control.puzzleElement.soundPath, True) self.selectedLeftImage = control def matchAttempt(self, selectedControl): if self.selectedLeftImage is None: return matchOk = (self.selectedLeftImage.puzzleElement.solution == selectedControl.puzzleElement.rightImagePath) if not matchOk: self.getSoundMgr().addSoundForPlayback(self.wrongChoiceSoundPath, False) else: self.solvedPuzzleElements += 1 yCenterLeftImage = self.selectedLeftImage.getY() + self.selectedLeftImage.getHeight()/2 yDestination = yCenterLeftImage - selectedControl.getWidth()/2 destination = (self.selectedLeftImage.getX() + self.selectedLeftImage.getWidth(), yDestination) selectedControl.setLayer(0) selectedControl.filterOff() selectedControl.startMovement(destination, self.settings["speed"]) self.controlMoving = selectedControl self.controlMovingTarget = destination self.ignoreCommands = True self.getSoundMgr().addSoundForPlayback(os.path.join(self.soundsDir, "bing.ogg"), False, True) self.getSoundMgr().addSoundForPlayback(self.selectedLeftImage.puzzleElement.secondAudio, True, False) def updateState(self): if not self.firstElement is None: if not self.firstElement.isBeingScaled(): self.getUiMgr().removeControl(self.firstElement) self.getUiMgr().addControl(self.futureFirstElement) self.firstElement = None if not (self.controlMoving is None): if not self.controlMoving.isMoving(): self.ignoreCommands = False self.controlMoving.setLayer(1) self.controlMoving.type = "" self.controlMoving = None if self.solvedPuzzleElements == len(self.puzzles[self.currentPuzzleIndex]): self.moveToNextPuzzle = True if self.moveToNextPuzzle: self.currentPuzzleIndex += 1 if self.currentPuzzleIndex < len(self.puzzles): self.buildCurrentPuzzle() self.moveToNextPuzzle = False self.firstElement.playAnimation() self.firstElement.stopAnimation() else: if(not self.getSoundMgr().thereAreSoundsPlaying()): self.finished = True if not self.isHelp: self.saveAsDone() def buildCurrentPuzzle(self): self.solvedPuzzleElements = 0 self.selectedLeftImage = None self.getUiMgr().deleteGameControls(self) totalImagesHeight = 0 firstElement = True y = self.settings["topMargin"] + self.yMargin + 10 for currentElement in self.puzzles[self.currentPuzzleIndex]: xLeftImage = self.settings["leftMargin"] + self.xMargin leftImageControl = HighlightedControl(self, xLeftImage, y, currentElement.leftImagePath, currentElement.soundPath, 1) leftImageControl.type = "leftImage" leftImageControl.puzzleElement = currentElement #this adds the "puzzleElement" attribute to the object. leftImageControl.setLayer(4) leftImageControl.setColorKey((255,255,255)) if firstElement: self.firstElement = GrowsAndShrinksAnimatedControl(self, xLeftImage, y, currentElement.leftImagePath, "", 1) self.firstElement.delay = 10 self.getUiMgr().addControl(self.firstElement) self.futureFirstElement = leftImageControl firstElement = False else: self.getUiMgr().addControl(leftImageControl) deltaY = leftImageControl.getHeight() + self.settings["verticalSpaceBetweenImages"] xRightImage = xLeftImage + self.settings["spaceBetweenImages"] + leftImageControl.getWidth() rightImageControl = HighlightedControl(self, xRightImage, y, currentElement.rightImagePath, "", 1) rightImageControl.type = "rightImage" rightImageControl.puzzleElement = currentElement rightImageControl.setLayer(4) rightImageControl.setColorKey((255,255,255)) self.getUiMgr().addControl(rightImageControl) y = y + deltaY class PuzzlesReader(): def __init__(self, resourcesDir, mustRandom, soundsDir): self.puzzles = [] self.resourcesDir = resourcesDir self.soundsDir = soundsDir self.mustRandom = mustRandom if self.mustRandom: random.seed() def read(self, puzzlesDefinition): lines = puzzlesDefinition.splitlines() thisPuzzle = [] correspondingImages = [] for line in lines: if line <> "": ln = line.split() audio = ln[1] if "[" in audio: audios = audio[1:-1].split(",") audio = audios[0] secondAudio = os.path.join(self.soundsDir,audios[1]) else: secondAudio = os.path.join(self.soundsDir, audio) puzzleElement = PuzzleElement(ln[0], audio, ln[2], self.resourcesDir, self.soundsDir) puzzleElement.secondAudio = secondAudio thisPuzzle.append(puzzleElement) correspondingImages.append(ln[2]) else: random.shuffle(correspondingImages) counter = 0 for pe in thisPuzzle: pe.setRightImagePath(correspondingImages[counter]) counter = counter + 1 self.puzzles.append(thisPuzzle) thisPuzzle = [] correspondingImages = [] if self.mustRandom: random.shuffle(correspondingImages) else: correspondingImages.reverse() counter = 0 for pe in thisPuzzle: pe.setRightImagePath(correspondingImages[counter]) counter = counter + 1 self.puzzles.append(thisPuzzle) thisPuzzle = [] correspondingImages = [] return self.puzzles class PuzzleElement(): def __init__(self, leftImage, soundFile, correspondingLeftImage, resourcesDir, soundsDir): self.resourcesDir = resourcesDir self.leftImagePath = os.path.join(resourcesDir,leftImage) self.soundPath = os.path.join(soundsDir, soundFile) self.solution = os.path.join(resourcesDir,correspondingLeftImage) self.rightImagePath = "" self.secondAudio = self.soundPath def setRightImagePath(self, rightImagePath): self.rightImagePath = os.path.join(self.resourcesDir, rightImagePath)