root/Alpha/story.py @ 136

Revision 136, 14.1 KB (checked in by kvigue, 2 years ago)

-Fixed the cursor not showing during gameplay

Line 
1"""
2Story mode. Contains the different classes that form the hierarchy of
3story mode.
4"""
5
6import pygame
7from random import randint
8from gameobject import *
9from constants import BBUILDER
10import globalVars
11
12class Story:
13    """Story is the highest level class in the story. Keep track of
14        levels and changes between them."""
15    def __init__(self, difficulty=0):
16        """initializes a Story"""
17        self.score = 0
18        self.rank = 0
19        self.difficulty = difficulty
20        self.levelDict = {}
21        self.maxLevel = 3
22        for levelNum in range(self.maxLevel):
23            background = 'background'+str(levelNum)
24            level = Level(self.difficulty, levelNum, background)
25            self.levelDict[levelNum] = level
26        self.currentLevel = 0
27        self.exit = False #Exit flag
28
29    def update(self, valueChange):
30        """update function for Story. Calls currentLevel's update
31            and moves appropriately."""
32        if self.exit:
33            return self.score
34       
35        levelStatus = self.levelDict[self.currentLevel].update(valueChange)
36        if levelStatus == "UpdateScore":
37            self.score += 1000*(self.currentLevel+1)
38        elif levelStatus == "IncrementLevel":
39            self.currentLevel += 1
40            if self.currentLevel >= self.maxLevel:
41                return self.score
42        return -1 #Recognized by EventHandler as incomplete Story
43
44    def draw(self):
45        """draw function for story."""
46        globalVars.graphics.drawImage(BBUILDER.STORY_BG_LIST[self.levelDict
47                                    [self.currentLevel].background], (0,0))
48        globalVars.graphics.drawText("Level: "+str(int(self.currentLevel)),
49                                     775, 10, 30, pygame.Color("black"), "right")
50        globalVars.graphics.drawText("Score: "+str(int(self.score)),
51                                     775, 35, 30, pygame.Color("black"),
52                                     "right")
53        self.levelDict[self.currentLevel].draw()
54       
55class Level:
56    """Levels are the next level down from Story. Levels contain puzzles."""
57    def __init__(self, difficulty, levelNum, background):
58        """initializes a Level"""
59        self.time = 60000
60        self.puzzlesCompleted = 0
61        self.difficulty = difficulty
62        self.levelNum = levelNum
63        self.currentPuzzle = self.generatePuzzle()
64        self.clock = pygame.time.Clock()
65        self.background = background
66
67    def generatePuzzle(self):
68        """generates a puzzle based on parameters."""
69        return Puzzle(randint(1,BBUILDER.MAXPUZZLESIZE[self.difficulty]), BBUILDER.INTRO, "cursor0.png",
70                      True, self.levelNum, self.puzzlesCompleted, difficulty=self.difficulty)
71        #second number is maximum supported puzzle value
72        #randint(0,2)+(1+2*self.puzzlesCompleted)
73
74    def update(self, valueChange):
75        """updates a Level"""
76        if self.currentPuzzle.mode == BBUILDER.PUZZLE:
77            self.time += -self.clock.tick()
78            if self.time < 0:
79                self.time = 0
80        puzzleComplete = self.currentPuzzle.update(valueChange)
81       
82        if puzzleComplete == "Next":
83            if self.puzzlesCompleted >= 3:
84                return "IncrementLevel"
85            self.currentPuzzle = self.generatePuzzle()
86           
87        if puzzleComplete == "Score++":
88            self.puzzlesCompleted += 1
89            return "UpdateScore"
90       
91        return "None"
92   
93    def draw(self):
94        """draws a Level"""
95        self.currentPuzzle.draw()
96
97class Puzzle:
98    """Puzzle is a class that falls below Level. It contains individual
99        puzzles"""
100    def __init__(self, goalNumber, mode, cursor, showVicScreen = False,
101                 levelNum = -1, puzzleNum = -1, difficulty=0):
102        """initializes a Puzzle"""
103        self.goalNumber = goalNumber
104        self.currentCount = 0
105        if difficulty == 0:
106            self.toggleList = [Toggle(BBUILDER.TOGGLE_0, 4, (250, 550), (65,65)),
107                               Toggle(BBUILDER.TOGGLE_0, 2, (400, 550), (65,65)),
108                               Toggle(BBUILDER.TOGGLE_0, 1, (550, 550), (65,65))]
109        elif difficulty == 1:
110            self.toggleList = [Toggle(BBUILDER.TOGGLE_0, 32, (150, 550), (65,65)),
111                               Toggle(BBUILDER.TOGGLE_0, 16, (250, 550), (65,65)),
112                               Toggle(BBUILDER.TOGGLE_0, 8, (350, 550), (65,65)),
113                               Toggle(BBUILDER.TOGGLE_0, 4, (450, 550), (65,65)),
114                               Toggle(BBUILDER.TOGGLE_0, 2, (550, 550), (65,65)),
115                               Toggle(BBUILDER.TOGGLE_0, 1, (650, 550), (65,65))]
116       
117        self.exitButton = GameButton(BBUILDER.BUTTON_0,
118                                     (105,30), (200,50), "Quit")
119        self.selectedToggle = 0
120        self.puzzleGoal = self.generatePuzzleGoal()
121        self.selectedMenuButton = 0 #Cursor starts on button
122        self.cursor = "cursor0.png"
123       
124        self.mode = mode
125        self.showVicScreen = showVicScreen #Flag for showing the victory screen
126        self.introText = None
127        self.endText = None
128        if ((levelNum != -1) and (puzzleNum != -1)): #If they were set
129            self.introText = BBUILDER.INTROTEXT[levelNum][puzzleNum]
130            self.endText = BBUILDER.ENDTEXT[levelNum][puzzleNum]
131            self.introButtons = [GameButton(BBUILDER.BUTTON_0, (600,500),
132                                            (200,50), "Continue")]
133            self.endButtons = [GameButton(BBUILDER.BUTTON_0, (600,500),
134                                            (200,50), "Next Puzzle...")]
135
136        if self.mode == BBUILDER.INTRO and self.introText == None:
137            self.mode = BBUILDER.PUZZLE
138
139        if self.showVicScreen:
140            self.victoryButtons = [GameButton(BBUILDER.BUTTON_0, (650,365),
141                                            (200,50), "Continue")]
142
143    def generatePuzzleGoal(self):
144        """generates a PuzzleGoal object"""
145        puzzleNum = randint(0, BBUILDER.PUZZLETYPECOUNT-1)
146        puzzleType = BBUILDER.PUZZLETYPES[puzzleNum]
147        for sizeIndex in range(len(BBUILDER.MAXPUZZLESIZE)):
148            if self.goalNumber <= BBUILDER.MAXPUZZLESIZE[sizeIndex]:
149                break #Lowest sizeIndex that fits
150        blockCords = BBUILDER.PUZZLECORDS[puzzleNum][sizeIndex]
151        puzzlePos = BBUILDER.PUZZLEPOS[puzzleNum]
152        return PuzzleGoal(puzzlePos, puzzleType, self.goalNumber, blockCords)
153
154    def update(self, valueChange):
155        """updates a Puzzle"""
156        if valueChange == "Continue": #Mode is Intro, Victory, or End
157            if self.mode == BBUILDER.INTRO:
158                self.mode = BBUILDER.PUZZLE
159            elif self.mode == BBUILDER.VICTORY:
160                self.mode = BBUILDER.END
161            else: #self.mode == BBUILDER.END
162                return "Next"
163        elif type(valueChange) == int: #mode is Puzzle
164            self.currentCount += valueChange
165            if (self.currentCount == self.goalNumber):
166                if self.showVicScreen:
167                    self.mode = BBUILDER.VICTORY
168                else:
169                    self.mode = BBUILDER.END
170                return "Score++"
171        if self.mode == BBUILDER.END and self.endText == None:
172            return "Next"
173
174    def selectTogglePrev(self):
175        """changes location of cursor. Called by EventHandler."""
176        if self.selectedToggle != None:
177            if self.selectedToggle != 0:
178                self.selectedToggle += -1
179            else: self.selectedToggle = len(self.toggleList) - 1
180        else:
181            self.selectedToggle = 0
182
183    def selectToggleNext(self):
184        """changes location of cursor. Called by EventHandler."""
185        if self.selectedToggle != None:
186            if self.selectedToggle != len(self.toggleList) - 1:
187                self.selectedToggle += 1
188            else: self.selectedToggle = 0
189        else:
190            self.selectedToggle = 0
191
192    def draw(self):
193        """draws a Puzzle by calling the appropriate function"""
194        if self.mode == BBUILDER.INTRO:
195            self.drawIntro()
196        elif self.mode == BBUILDER.END:
197            self.drawEnd()
198        else:
199            self.drawPuzzle()
200
201    def drawIntro(self):
202        """draws a Puzzle when in Intro mode"""
203        globalVars.graphics.drawImage("textBG.jpg", (100,134))
204        if self.introText != None:
205            globalVars.graphics.drawText(self.introText, 150, 180, 30,
206                                         pygame.Color("black"))
207        for button in self.introButtons:
208            button.draw()
209            globalVars.graphics.drawImage(self.cursor,(button.x-50, button.y))
210
211    def drawEnd(self):
212        """draws a Puzzle when in End mode"""
213        globalVars.graphics.drawImage("textBG.jpg", (100,134))
214        if self.endText != None:
215            globalVars.graphics.drawText(self.endText, 150, 180, 30,
216                                         pygame.Color("black"))
217        for button in self.endButtons:
218            button.draw()
219            globalVars.graphics.drawImage(self.cursor,(button.x-50, button.y))
220
221    def drawPuzzle(self):
222        """draws a Puzzle when in Puzzle mode or Victory Mode"""
223        for toggleNum in range(len(self.toggleList)):
224            currentToggle = toggleNum - len(self.toggleList)
225            toggle = self.toggleList[currentToggle]
226            toggle.draw()
227            if toggle.active:
228                globalVars.graphics.drawImage(BBUILDER.ACTIVE_TOGGLE_PIC[currentToggle], 
229                                     (toggle.pos[0]-BBUILDER.TOGGLE_PIC_SIZE[
230                                             currentToggle][0]/2,
231                                     toggle.pos[1]-100-BBUILDER.TOGGLE_PIC_SIZE[
232                                             currentToggle][1]/2 + toggle.activeDropValue))
233            else:
234                globalVars.graphics.drawImage(BBUILDER.INACTIVE_TOGGLE_PIC[currentToggle], 
235                                     (toggle.pos[0]-BBUILDER.TOGGLE_PIC_SIZE[
236                                             currentToggle][0]/2,
237                                     toggle.pos[1]-100-BBUILDER.TOGGLE_PIC_SIZE[
238                                             currentToggle][1]/2))
239            if toggleNum == self.selectedToggle and self.mode != BBUILDER.VICTORY:
240                globalVars.graphics.drawImage("cursor0.png",
241                                              (toggle.x-60, toggle.y)) #Magic!
242        self.exitButton.draw()
243        globalVars.graphics.drawText("Goal: " + str(self.goalNumber),
244                                     400, 110, 120, pygame.Color("black"),
245                                     "center")
246        globalVars.graphics.drawText("Current: "+str(self.currentCount),
247                                     725, 225, 30, pygame.Color("black"),
248                                     "right")
249        globalVars.graphics.drawText("Remaining: "+str(
250                                     self.goalNumber-self.currentCount),
251                                     725, 250, 30, pygame.Color("black"),
252                                     "right")
253        if self.currentCount > self.goalNumber:
254            globalVars.graphics.drawText("Too many blocks!", 50, 210, 36, pygame.Color("red"))
255
256        if self.mode == BBUILDER.VICTORY: #Victory mode PuzzleGoal
257            self.puzzleGoal.complete()
258            for button in self.victoryButtons:
259                button.draw()
260                globalVars.graphics.drawImage(self.cursor,(button.x-50, button.y))
261        else:
262            self.puzzleGoal.draw(self.currentCount)
263
264class Toggle(GameObject):
265    """used by Puzzle. Represents toggle buttons with values"""
266    def __init__(self, image, value, pos, size):
267        """initializes a Toggle"""
268        GameObject.__init__(self, image, pos, size) #How I super?
269        self.active = False
270        self.value = value
271        self.pos = pos
272       
273        # activeDropValue is the amount by which the Toggle Blocks (not buttons)
274        # are lowered (y axis) when active.
275        self.activeDropValue = -20
276
277    def draw(self):
278        """draws a Toggle"""
279        if self.active:
280            text = pygame.font.Font(None, 40).render(
281                '1', 1, pygame.Color("white")) #Woo magic
282        else:
283            text = pygame.font.Font(None, 40).render('0', 1, pygame.Color("black"))
284        globalVars.graphics.drawObject(self, text)
285
286class GameButton(GameObject):
287    """game button from a puzzle."""
288    def __init__(self, image, pos, size, text):
289        """initializes a GameButton"""
290        GameObject.__init__(self, image, pos, size) #How I super?
291        self.active = False
292        self.text = text
293        self.textSize = 25 #Magic!
294        self.textColor = pygame.Color("black") #Double magic!
295
296    def draw(self):
297        """draws a GameButton"""
298        text = pygame.font.Font(None, self.textSize).render(self.text, 1,
299                                                            self.textColor)
300        globalVars.graphics.drawObject(self, text)
301
302class PuzzleGoal:
303    """used by Puzzle. Represents the object being created by the player"""
304    def __init__(self, pos, objType, value, cords):
305        """initializes a puzzleGoal"""
306        self.pos = pos
307        self.type = objType
308        self.value = value
309        self.cords = cords
310
311    def draw(self, currentCount):
312        """draws a puzzleGoal"""
313        try:
314            for i in range(self.value):
315                if i < currentCount:
316                    image = "activeGoalBlock.png"
317                else:
318                    image = "inactiveGoalBlock.png"
319                pos = (self.pos[0]+self.cords[i][0], self.pos[1]+self.cords[i][1])
320                globalVars.graphics.drawImage(image, pos)
321        except:
322            print "Error: Puzzle value too large for PuzzleGoal"
323
324    def complete(self):
325        """draws a PuzzleGoal in VictoryMode"""
326        globalVars.graphics.drawImage("puzzleComplete.png", (75,185))
327        globalVars.graphics.drawImage(self.type+".png", self.pos)
Note: See TracBrowser for help on using the browser.