Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/Sort.py
diff options
context:
space:
mode:
Diffstat (limited to 'Sort.py')
-rw-r--r--Sort.py360
1 files changed, 360 insertions, 0 deletions
diff --git a/Sort.py b/Sort.py
new file mode 100644
index 0000000..3be60b6
--- /dev/null
+++ b/Sort.py
@@ -0,0 +1,360 @@
+import pygame, sys, os
+from pygame.locals import *
+from pygame.font import *
+from eduGames import *
+
+class Sort(Game):
+
+ def __init__(self, screen, uiMgr, sndMgr, screenMgr, path):
+ Game.__init__(self, screen, uiMgr, sndMgr, screenMgr, path)
+ self.binControls = [] #necessary only to place crayons
+ self.selectedCrayon = None
+ self.movingCrayon = False
+ self.solvedItems = 0
+ self.alert = ""
+ self.finished = False
+ self.hoveredOnControl = None
+ self.soundsDir = "" #This is later initialized by the Games class.
+ self.xMargin = 0
+ self.yMargin = 0
+ self.firstCrayon = None
+ self.futureFirstCrayon = None
+ self.isHelp = False
+ self.previousScreenBinControls = None
+ self.successSound = ""
+
+ def initializeGameData(self):
+ self.alert = os.path.join(self.soundsDir, "chord.ogg")
+ self.screens = self.readInfo()
+ self.currentScreenIndex = -1
+ self.moveToNextScreen = True
+ self.successSound = os.path.join(self.soundsDir, "bing.ogg")
+
+ def showCurrentScreen(self):
+ if self.screens[self.currentScreenIndex].keepState:
+ self.previousScreenBinControls = self.binControls
+ self.binControls = []
+ self.solvedItems = 0
+ self.getUiMgr().deleteGameControls(self)
+ if self.screens[self.currentScreenIndex].background != "":
+ backgroundImagePath = self.screens[self.currentScreenIndex].background
+ backgroundImageX = self.screens[self.currentScreenIndex].backgroundX
+ backgroundImageY = self.screens[self.currentScreenIndex].backgroundY
+ backgroundImageLayer = self.screens[self.currentScreenIndex].backgroundLayer
+ backgroundImage = ImageControl(self, backgroundImageX, backgroundImageY, backgroundImagePath, "", 1)
+ backgroundImage.setLayer(backgroundImageLayer)
+ self.getUiMgr().addControl(backgroundImage)
+ self.createBinObjects()
+ self.addBinObjects()
+ self.createCrayons()
+ self.moveToNextScreen= False
+ self.firstCrayon.playAnimation()
+ self.firstCrayon.stopAnimation()
+
+ def updateBinObjects(self):
+ for binControl in self.binControls:
+ binControl.setX(binControl.bin.x)
+ binControl.setY(binControl.bin.y)
+
+ def addBinObjects(self):
+ fontPath = os.path.join(self.resourcesDir, "Helvetica LT Condensed Black.ttf")
+ fontSize = 20
+ if(self.settings.has_key("fontSize")):
+ fontSize = self.settings["fontSize"]
+ font = Font(fontPath, fontSize)
+ for ctrl in self.binControls:
+ if not self.settings.has_key("showBinText") or self.settings["showBinText"] == 1:
+ txt = ctrl.bin.name
+# xText = ctrl.getX() + ctrl.getWidth()/2 - len(txt)*5
+# yText = ctrl.getY() + ctrl.getHeight()/2 - 5
+# text = Label(self, xText, yText, 20, 10, font, txt, 5)
+ text = Label(self, 0, 0, 20, 10, font, txt, 5)
+ text.acquireRenderedSize()
+ xText = ctrl.getX() + ctrl.getWidth()/2 - text.getWidth()/2
+ yText = ctrl.getY() + ctrl.getHeight()/2 - text.getHeight()/2
+ text.setX(xText)
+ text.setY(yText + 10)
+ if txt == "black":
+ text.color = (255,255,255) #TODO: maybe this should be customizable
+ else:
+ text.color = (0,0,0)
+ text.background = None
+ self.getUiMgr().addControl(text)
+ self.getUiMgr().addControl(ctrl)
+
+ def createBinObjects(self):
+ x = self.settings["leftMargin"] + self.xMargin
+ y = self.settings["yOddBins"] + self.yMargin
+
+ binImageDivisions = 6
+ if self.settings.has_key("binImageDivisions"):
+ binImageDivisions = self.settings["binImageDivisions"]
+
+ for bin in self.screens[self.currentScreenIndex].bins:
+ if bin.x < 0:
+ bin.x = x
+ bin.y = y
+ else:
+ bin.x += self.xMargin
+ bin.y += self.yMargin
+ binObj = HighlightedControl(self, bin.x, bin.y, bin.image, "", binImageDivisions)
+ binObj.bin = bin
+ binObj.type = "bin"
+ if bin.layer < 0:
+ bin.layer = 6
+ binObj.setLayer(bin.layer)
+ self.binControls.append(binObj)
+ x = x + binObj.getWidth() + self.settings["spaceBetweenBins"]
+ if y == self.settings["yOddBins"] + self.yMargin:
+ y = self.settings["yEvenBins"] + self.yMargin
+ else:
+ y = self.settings["yOddBins"] + self.yMargin
+
+ if self.screens[self.currentScreenIndex].keepState:
+ self.fillImageDivisionIndex(binObj)
+
+ def fillImageDivisionIndex(self, binControl):
+ for oldBinControl in self.previousScreenBinControls:
+ if oldBinControl.bin.name == binControl.bin.name:
+ binControl.setImageDivisionIndex(oldBinControl.getImageDivisionIndex())
+
+
+ def createCrayons(self):
+ y = self.settings["yOddCrayons"] + self.yMargin
+ fontPath = os.path.join(self.resourcesDir, "Helvetica LT Condensed Black.ttf")
+ fontSize = 20
+ if(self.settings.has_key("fontSize")):
+ fontSize = self.settings["fontSize"]
+ font = Font(fontPath, fontSize)
+ counter = 0
+ x = self.binControls[1].getX()
+ distanceBetweenCrayons = 40
+
+ firstCrayon = True
+
+ if self.settings.has_key("xFirstCrayon"):
+ x = self.settings["xFirstCrayon"]
+ if self.settings.has_key("distanceBetweenCrayons"):
+ distanceBetweenCrayons = self.settings["distanceBetweenCrayons"]
+
+ for crayon in self.screens[self.currentScreenIndex].crayons:
+ if crayon.x < 0:
+ crayon.x = x
+ crayon.y = y
+ else:
+ crayon.x += self.xMargin
+ crayon.y += self.yMargin
+ crayonObj = HighlightedControl(self, crayon.x, crayon.y, crayon.image, crayon.audio, 1)
+ if firstCrayon:
+ self.firstCrayon = GrowsAndShrinksAnimatedControl(self, crayon.x, crayon.y, crayon.image, "", 1)
+ self.firstCrayon.delay = 10
+ self.getUiMgr().addControl(self.firstCrayon)
+
+ crayonObj.type = "crayon"
+ crayonObj.crayon = crayon
+ crayonObj.setLayer(4)
+ if not self.settings.has_key("showCrayonText") or self.settings["showCrayonText"] == 1:
+ letterWidth = 14
+ if self.settings.has_key("letterWidth"):
+ letterWidth = self.settings["letterWidth"]
+ xText = crayonObj.getX()
+ if self.settings.has_key("useCenterOfCrayonForText"):
+ if self.settings["useCenterOfCrayonForText"]:
+ xText = crayonObj.getX() + crayonObj.getWidth()/2 - len(crayon.text) * (letterWidth/2)
+ text = Label(self, xText, crayonObj.getY()+crayonObj.getHeight(), 20, 10, font, crayon.text, 5)
+ text.color = (0,0,0)
+ text.background = (255,255,255)
+ crayonObj.label = text
+ self.getUiMgr().addControl(text)
+
+ if firstCrayon:
+ self.futureFirstCrayon = crayonObj
+ firstCrayon = False
+ else:
+ self.getUiMgr().addControl(crayonObj)
+ counter = counter + 1
+ #crayonObj.setAlpha(100)
+ x = x + crayonObj.getWidth() + distanceBetweenCrayons
+
+ def readInfo(self):
+ fileName = os.path.join(self.path, self.settings["infoFile"])
+ file = open(fileName, "r")
+ fileText = file.read()
+ reader = ScreensReader(self.resourcesDir, self.soundsDir)
+ file.close()
+ return reader.read(fileText)
+
+ def on_mouse_hover(self, clickedControl):
+ if clickedControl.type == "crayon" or (clickedControl.type == "bin" and not self.selectedCrayon 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.movingCrayon: return
+ if clickedControl.type == "crayon":
+ self.getSoundMgr().addSoundForPlayback(clickedControl.soundFilePath, True, True)
+ if clickedControl.crayon.secondAudio != clickedControl.crayon.audio:
+ self.getSoundMgr().addSoundForPlayback(clickedControl.crayon.secondAudio, True)
+ self.selectedCrayon = clickedControl
+ if clickedControl.type == "bin":
+ if not self.selectedCrayon is None:
+ if self.selectedCrayon.crayon.bin == clickedControl.bin:
+ target = (clickedControl.getX() + clickedControl.getWidth()/2,
+ clickedControl.getY())
+ if self.settings.has_key("useCrayonCenterAsHandle") and self.settings["useCrayonCenterAsHandle"] == 1:
+ #Specify the target so that the crayon's center will coincide with the bin's center.
+ targetX = clickedControl.getX() + clickedControl.getWidth()/2 - self.selectedCrayon.getWidth()/2
+ targetY = clickedControl.getY() + clickedControl.getHeight()/2 - self.selectedCrayon.getHeight()/2
+ target = (targetX, targetY)
+ self.selectedCrayon.startMovement(target, self.settings["speed"])
+ self.movingCrayon = True
+ self.selectedBin = clickedControl
+ self.selectedCrayon.filterOff()
+ if not self.settings.has_key("showCrayonText") or self.settings["showCrayonText"] == 1:
+ self.getUiMgr().removeControl(self.selectedCrayon.label)
+# print "ETIQUETA: " + str(self.selectedCrayon.label.getRect())
+ self.getSoundMgr().addSoundForPlayback(self.successSound, False, True)
+ self.getSoundMgr().addSoundForPlayback(self.selectedCrayon.crayon.secondAudio, True)
+ else:
+ self.triggerAlert()
+
+ def triggerAlert(self):
+ self.getSoundMgr().addSoundForPlayback(self.alert, True)
+
+ def updateState(self):
+ if not self.firstCrayon is None:
+ if not self.firstCrayon.isBeingScaled():
+ self.getUiMgr().removeControl(self.firstCrayon)
+ self.getUiMgr().addControl(self.futureFirstCrayon)
+ self.firstCrayon = None
+ if self.movingCrayon and not (self.selectedCrayon is None) and not self.selectedCrayon.isMoving():
+ self.selectedBin.increaseDivisionIndex(1)
+ self.selectedBin.filterOff()
+ self.getUiMgr().removeControl(self.selectedCrayon)
+ self.selectedCrayon = None
+ self.selectedBin = None
+ self.movingCrayon = False
+ self.solvedItems = self.solvedItems + 1
+ if self.solvedItems == len(self.screens[self.currentScreenIndex].crayons):
+ self.moveToNextScreen = True
+ else:
+ if self.moveToNextScreen:
+ self.currentScreenIndex = self.currentScreenIndex + 1
+ if self.currentScreenIndex < len(self.screens):
+ self.showCurrentScreen()
+ else:
+ self.endGame()
+ self.saveAsDone()
+
+ def endGame(self):
+ self.finished = True
+ if not self.isHelp:
+ self.saveAsDone()
+
+class ScreensReader:
+ def __init__(self, resourcesDir, soundsDir):
+ self.resourcesDir = resourcesDir
+ self.soundsDir = soundsDir
+
+ def read(self, text):
+ lines = text.splitlines()
+ self.screens = []
+ self.currentScreen = None
+ state = "screens"
+
+ for line in lines:
+ if line.strip() != "" and not line.startswith("#"):
+ if line.upper().startswith("SCREEN"):
+ self.currentScreen = Screen()
+ self.screens.append(self.currentScreen)
+ state = "screens"
+ continue
+ if line.upper().startswith("BACKGROUND"):
+ backgroundInfo = line.split(":")[1].strip()
+ splitResult = backgroundInfo.split()
+ self.currentScreen.background = os.path.join(self.resourcesDir, splitResult[0])
+ self.currentScreen.backgroundX = int(splitResult[1])
+ self.currentScreen.backgroundY = int(splitResult[2])
+ self.currentScreen.backgroundLayer = int(splitResult[3])
+ if line.upper().startswith("BINS"):
+ state = "bins"
+ if line.upper().startswith("BINS:KEEPSTATE"):
+ self.currentScreen.keepState = True
+ continue
+ if line.upper().startswith("CRAYONS"):
+ state = "crayons"
+ continue
+ if state == "bins":
+ binInfo = line.split(":")
+ binName = binInfo[0]
+ rest = binInfo[1].split()
+ binImage = rest[0]
+ bin = Bin(binName, binImage, self.resourcesDir)
+ if len(rest) > 1:
+ bin.x = int(rest[1])
+ bin.y = int(rest[2])
+ bin.layer = int(rest[3])
+ self.currentScreen.bins.append(bin)
+ if state == "crayons":
+ splitData = line.split()
+ crayonAudio = splitData[1]
+ crayonSecondAudio = crayonAudio
+
+ if "[" in crayonAudio:
+ audios = crayonAudio[1:-1].split(",")
+ crayonAudio = audios[0]
+ crayonSecondAudio = audios[1]
+
+ if len(splitData) > 4:
+ crayon = Crayon(splitData[0], crayonAudio, splitData[2], self.currentScreen.getBin(splitData[3]),
+ self.resourcesDir, self.soundsDir, int(splitData[4]), int(splitData[5]), int(splitData[6]))
+ else:
+ crayon = Crayon(splitData[0], crayonAudio, splitData[2], self.currentScreen.getBin(splitData[3]),
+ self.resourcesDir, self.soundsDir)
+ crayon.secondAudio = os.path.join(self.soundsDir, crayonSecondAudio)
+ self.currentScreen.crayons.append(crayon)
+ return self.screens
+
+class Bin:
+ def __init__(self, name, image, resourcesDir, x=-1000, y=-1000, layer=-1):
+ self.image = os.path.join(resourcesDir, image)
+ self.name = name
+ self.x = x
+ self.y = y
+ self.layer = layer
+
+class Crayon:
+ def __init__(self, image, audio, text, bin, resourceDir, soundsDir, x=-1000, y=-1000, layer=-1):
+ self.image = os.path.join(resourceDir,image)
+ self.audio = os.path.join(soundsDir,audio)
+ self.text = text.replace("*", " ")
+ self.bin = bin
+ self.x = x
+ self.y = y
+ self.layer = layer
+ self.secondAudio = self.audio
+
+class Screen:
+ def __init__(self):
+ self.bins = []
+ self.crayons = []
+ self.background = ""
+ self.backgroundX = 0
+ self.backgroundY = 0
+ self.backgroundLayer = 0
+ self.keepState = False
+
+ def getBin(self, name):
+ for bin in self.bins:
+ if bin.name == name:
+ return bin
+
+
+