Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Paint.py
diff options
context:
space:
mode:
Diffstat (limited to 'Paint.py')
-rw-r--r--Paint.py363
1 files changed, 363 insertions, 0 deletions
diff --git a/Paint.py b/Paint.py
new file mode 100644
index 0000000..40cf97a
--- /dev/null
+++ b/Paint.py
@@ -0,0 +1,363 @@
+import pygame, sys, os
+from pygame.locals import *
+from eduGames import *
+import random
+
+class Paint(Game):
+ (INITIAL, WAITING, BAD_CHOICE, GOOD_CHOICE, WAITING_PAINT, PAINTING, END) = (0,1,2,3,4,5, 6)
+
+ def __init__(self, screen, uiMgr, sndMgr, screenMgr, path):
+ Game.__init__(self, screen, uiMgr, sndMgr, screenMgr, path)
+ self.finished = False
+ self.puzzleElements = None
+ self.paintBoxes = None
+ self.currentElementIndex = 0
+ self.state = Paint.INITIAL
+ self.puzzleElementControls = None
+ self.selectedColor = ""
+ self.soundIcon = None
+ self.soundsDir = "" #set later by the Games class
+ self.xMargin = 0
+ self.yMargin = 0
+ self.masterResourcesDir = None
+ self.brush = None
+ self.fakeMouse = None
+ self.isHelp = False
+ self.onNavigationPortion = False
+ self.xStartBrushZone = 0
+ self.yStartBrushZone = 0
+ self.xEndBrushZone = 1030 + self.xMargin
+ self.yEndBrushZone = 0
+
+
+ def getCurrentPuzzleElement(self):
+ return self.puzzleElements[self.currentElementIndex]
+
+ def getCurrentPuzzleElementControl(self):
+ return self.puzzleElements[self.currentElementIndex].control
+
+ def pause(self):
+ self.getUiMgr().removeControl(self.brush)
+ pygame.mouse.set_visible(True)
+
+ def unPause(self):
+ self.getUiMgr().addControl(self.brush)
+ pygame.mouse.set_visible(False)
+
+ def initializeGameData(self):
+ self.brush = Brush(self, "")
+ self.alert = os.path.join(self.soundsDir, "chord.ogg")
+ self.ding = os.path.join(self.soundsDir, "ding.ogg")
+ (self.puzzleElements, self.paintBoxes, backgroundPath, backgroundX, backgroundY) = self.readInfo()
+ self.showElements()
+ self.showPaintBoxes()
+ if backgroundPath != "":
+ self.showBackgroundImage(backgroundPath, backgroundX, backgroundY)
+ fakeMouse = [c for c in self.getUiMgr().controls if c.type == "fakeMouse"]
+ self.fakeMouse = None
+ if not len(fakeMouse) == 0:
+ self.fakeMouse = fakeMouse[0]
+ self.brush.trackControl(self.fakeMouse)
+ self.fakeMouse.setLayer(20)
+ self.getUiMgr().addControl(self.brush)
+ if not self.isHelp:
+ pygame.mouse.set_visible(False)
+
+ def showBackgroundImage(self, backgroundPath, x, y):
+ path = os.path.join(self.resourcesDir, backgroundPath)
+ ic = ImageControl(self, x, y, path, "", 1)
+ ic.setLayer(9)
+ self.getUiMgr().addControl(ic)
+
+
+ def getShuffledElements(self):
+ shuffledElements = []
+ for element in self.puzzleElements:
+ shuffledElements.append(element)
+ random.shuffle(shuffledElements)
+ return shuffledElements
+
+ def showElements(self):
+ shuffledElements = self.getShuffledElements()
+ x = self.settings["xFirstElement"] + self.xMargin
+ y = self.settings["yFirstElement"] + self.yMargin
+ distanceBetweenElements = -1
+ if self.settings.has_key("distanceBetweenElements"):
+ distanceBetweenElements = self.settings["distanceBetweenElements"]
+ self.puzzleElementControls = []
+ counter = 1
+
+ for element in shuffledElements:
+ if counter > self.settings["elementsPerRow"] and counter % self.settings["elementsPerRow"] == 1:
+ xLastRow = self.settings["xFirstElementLastRow"] + self.xMargin
+ x = xLastRow
+ y = y + self.settings["spaceBetweenRows"]
+
+ if element.x > -1:
+ x = element.x
+ y = element.y
+
+ ic = ImageControl(self, x, y, os.path.join(self.resourcesDir, element.image),
+ "", element.getNumberOfStates())
+ ic.setLayer(6)
+ ic.type = "drawing"
+ ic.setAsUnclickable()
+ element.control = ic
+ if distanceBetweenElements > -1:
+ x += distanceBetweenElements
+ else:
+ x += ic.getWidth()
+ self.getUiMgr().addControl(ic)
+ self.puzzleElementControls.append(ic)
+
+ counter += 1
+
+ def showPaintBoxes(self):
+ x = self.settings["paintBoxesX"] + self.xMargin
+ y = self.settings["paintBoxesY"] + self.yMargin
+ watercolor = ImageControl(self, x, y, os.path.join(self.masterResourcesDir, "_acuarelas.png"))
+ watercolor.setLayer(5)
+ self.soundIcon = GrowsAndShrinksAnimatedControl(self, self.settings["soundIconX"] + self.xMargin, self.settings["soundIconY"] + self.yMargin, os.path.join(self.masterResourcesDir, "sound.png"), "", 2)
+ self.soundIcon.setLayer(5)
+ self.soundIcon.type = "soundIcon"
+ self.getUiMgr().addControl(watercolor)
+ self.getUiMgr().addControl(self.soundIcon)
+ x = self.settings["paintBoxesX"] + self.xMargin + 75
+ y = self.settings["paintBoxesY"] + self.yMargin + 25
+
+ for element in self.paintBoxes:
+ ic = Control(self, x, y, 50, 50)
+ ic.color = element
+ ic.setLayer(4)
+ ic.type = "paint"
+ x += 7 + ic.getWidth()
+ self.getUiMgr().addControl(ic)
+
+ self.yEndBrushZone = watercolor.getY() + watercolor.getHeight()
+
+ def readInfo(self):
+ fileName = os.path.join(self.path, self.settings["infoFile"])
+ file = open(fileName, "r")
+ fileText = file.read()
+ reader = ScreensReader()
+ file.close()
+ return reader.read(fileText)
+
+ def on_mouse_hover(self, clickedControl):
+ if clickedControl == self.soundIcon:
+ self.soundIcon.setImageDivisionIndex(1)
+ self.onNavigationPortion = True
+ else:
+ if self.soundIcon.getImageDivisionIndex() == 1: #might improve performance.
+ self.soundIcon.setImageDivisionIndex(0)
+ mousePos = pygame.mouse.get_pos()
+ mousePosX = mousePos[0]
+ mousePosY = mousePos[1]
+
+ if mousePosX < self.xStartBrushZone or mousePosY < self.yStartBrushZone or mousePosX > self.xEndBrushZone or mousePosY > self.yEndBrushZone:
+ self.onNavigationPortion = True
+ else:
+ self.onNavigationPortion = False
+ try:
+ if self.onNavigationPortion:
+ if self.brush.isVisible():
+ self.brush.makeInvisible()
+ else:
+ if not self.brush.isVisible():
+ self.brush.makeVisible()
+ except:
+ pass
+
+ def on_mouse_button_down(self, clickedControl):
+ if self.state == Paint.WAITING:
+ if clickedControl.type == "paint":
+ self.selectedColor = clickedControl.color
+ elif clickedControl == self.soundIcon:
+ self.state = Paint.INITIAL
+ if self.state == Paint.WAITING_PAINT:
+ if clickedControl.type == "drawing" and clickedControl is self.getCurrentPuzzleElementControl():
+ self.state = Paint.PAINTING
+ self.playSoundSequentially(self.ding)
+ else:
+ self.playSound(self.alert)
+
+ def paintCurrentElement(self):
+ self.getCurrentPuzzleElementControl().setImageDivisionIndex(self.getCurrentPuzzleElement().getCurrentIndex()+1)
+
+ def playSoundSequentially(self, sound):
+ self.getSoundMgr().addSoundForPlayback(sound, False, True)
+
+ def playSound(self, sound):
+ self.getSoundMgr().addSoundForPlayback(sound)
+
+ def updateState(self):
+ mouseVisible = self.isHelp or self.isPaused or self.onNavigationPortion
+ pygame.mouse.set_visible(mouseVisible)
+
+ if self.state == Paint.INITIAL:
+ soundPath = os.path.join(self.soundsDir, self.getCurrentPuzzleElement().currentAudio())
+ self.getSoundMgr().addSoundForPlayback(soundPath)
+ self.soundIcon.delay = 15
+ self.soundIcon.playAnimation()
+ self.soundIcon.stopAnimation()
+ self.state = Paint.WAITING
+ currentControl = self.getCurrentPuzzleElementControl()
+ currentControl.setAsClickable()
+ return
+ if self.state == Paint.WAITING: #Actually two states: with and without a selected color.
+ if self.selectedColor != "":
+ if self.selectedColor == self.getCurrentPuzzleElement().currentColor():
+ self.state = Paint.GOOD_CHOICE
+ self.getUiMgr().removeControl(self.brush)
+ self.brush = Brush(self, self.selectedColor, self.fakeMouse)
+ self.getUiMgr().addControl(self.brush)
+ else:
+ self.state = Paint.BAD_CHOICE
+ self.selectedColor = ""
+ return
+ if self.state == Paint.BAD_CHOICE:
+ self.playSound(self.alert)
+ self.state = Paint.WAITING
+ return
+ if self.state == Paint.GOOD_CHOICE:
+ self.playSound(self.ding)
+ self.state = Paint.WAITING_PAINT
+ return
+ if self.state == Paint.PAINTING:
+ self.paintCurrentElement()
+ self.getCurrentPuzzleElement().moveOn()
+ self.getUiMgr().removeControl(self.brush)
+ self.brush = Brush(self)
+ self.brush.trackControl(self.fakeMouse)
+ self.getUiMgr().addControl(self.brush)
+ self.state = Paint.INITIAL
+ if self.getCurrentPuzzleElement().solved():
+ self.getCurrentPuzzleElementControl().setAsUnclickable()
+ self.currentElementIndex += 1
+ if self.currentElementIndex >= len(self.puzzleElements):
+ self.state = Paint.END
+ return
+ if self.state == Paint.END:
+ self.finished = True
+ if not self.fakeMouse:
+ pygame.mouse.set_visible(True)
+ if not self.isHelp:
+ self.saveAsDone()
+ return
+
+ def endGame(self):
+ self.finished = True
+ if not self.fakeMouse:
+ pygame.mouse.set_visible(True)
+
+class ScreensReader:
+
+ def read(self, text):
+ lines = text.splitlines()
+ self.elements = []
+ self.paintCollection = []
+ self.backgroundPath = ""
+ self.backgroundX = 0
+ self.backgroundY = 0
+ state = "initial"
+
+ for line in lines:
+ if line.strip() != "" and not line.startswith("#"):
+ if line.strip() == "paint:":
+ state = "paint"
+ continue
+ if line.strip() == "elements:":
+ state = "elements"
+ continue
+ if line.strip().startswith("background"):
+ state = "background"
+ info = line.split(":")[1].strip()
+ infoPieces = info.split()
+ self.backgroundPath = infoPieces[0]
+ self.backgroundX = int(infoPieces[1])
+ self.backgroundY = int(infoPieces[2])
+ if state == "paint":
+ self.paintCollection.append(line.strip())
+ if state == "elements":
+ elemData = line.split()
+ element = PaintPuzzleItem(elemData[0])
+ counter = 1
+ while(counter < len(elemData)):
+ if not elemData[counter].isdigit():
+ part = PaintPuzzlePart(elemData[counter], elemData[counter+1])
+ element.parts.append(part)
+ else:
+ element.x = int(elemData[counter])
+ element.y = int(elemData[counter+1])
+ counter = counter + 2
+ self.elements.append(element)
+ return (self.elements, self.paintCollection, self.backgroundPath, self.backgroundX, self.backgroundY)
+
+class PaintPuzzleItem:
+ def __init__(self, image):
+ self.image = image
+ self.parts = []
+ self.__currentIndex = 0
+ self.x = -1
+ self.y = -1
+
+ def getNumberOfStates(self):
+ return len(self.parts) + 1
+
+ def getCurrentIndex(self):
+ return self.__currentIndex
+
+ def moveOn(self):
+ self.__currentIndex = self.__currentIndex + 1
+
+ def solved(self):
+ return self.__currentIndex == len(self.parts)
+
+ def currentAudio(self):
+ return self.parts[self.__currentIndex].audio
+
+ def currentColor(self):
+ return self.parts[self.__currentIndex].color
+
+class PaintPuzzlePart:
+ def __init__(self, audio, color):
+ self.audio = audio
+ self.color = color
+
+
+class Brush(ImageControl):
+ def __init__(self, game, color="", controlToTrack=None):
+ if color == "":
+ imageFilePath = os.path.join(game.masterResourcesDir, "pincel.png")
+ else:
+ imageFilePath = os.path.join(game.masterResourcesDir, "pincel_" + color + ".png")
+ if controlToTrack is None:
+ (mouseX, mouseY) = pygame.mouse.get_pos()
+ else:
+ (mouseX, mouseY) = (controlToTrack.getX(), controlToTrack.getY())
+ ImageControl.__init__(self, game, mouseX, mouseY, imageFilePath, "", 1)
+ self.__controlToTrack = controlToTrack
+
+ def update(self):
+ if self.getLayer() != 0:
+ self.setLayer(0)
+ ImageControl.update(self)
+ if not self.__controlToTrack:
+ (mouseX, mouseY) = pygame.mouse.get_pos()
+ else:
+ mouseX = self.__controlToTrack.getX()
+ mouseY = self.__controlToTrack.getY()
+ self.setX(mouseX)
+ self.setY(mouseY)
+
+ def isClickable(self):
+ return False
+
+ def trackControl(self, controlToTrack):
+ self.__controlToTrack = controlToTrack
+
+ def stopTrackingControl(self):
+ self.__controlToTrack = None
+
+
+