root/src/bonus.py @ 267

Revision 267, 13.0 KB (checked in by andefodahl, 23 months ago)

Hopefully revamped hover system

Line 
1""" creates the bonus level where kids have to turn a binary number into a
2normal number"""
3
4import pygame
5import random
6from constants import BBUILDER
7import globalVars
8from gameobject import *
9from bubbles import *
10from math import sin, radians
11from graphics import AnimatedObject
12
13class Bonus():
14    """highest level class in the Bonus mode. Contains Puzzles."""
15    def __init__(self, difficulty, background, score):
16        """initializes a Bonus game"""
17        self.score = score
18        self.difficulty = difficulty
19        self.multiplier = 1
20        self.puzzleMistake = False
21        self.time = 30000
22        self.clock = pygame.time.Clock()
23        self.puzzlesCompleted = 0
24        self.puzzleState = BBUILDER.BONUS_INTRO
25        self.background = BubbleBackground(globalVars.screen)
26        self.currentPuzzle = BonusPuzzle(self.puzzleState)
27        self.timeColor = BBUILDER.SALMON_COLOR
28        self.exit = False #Exit flag
29        self.introButtons = [GameButton(BBUILDER.BUTTON_0, (360,415), (200,50), "continue")]
30        self.cursorTimer = 0
31        self.cursor = "cursor0.png"
32        self.multiplierChange = 0
33        self.multiplierAni = AnimatedObject()
34
35       
36        # Messages to be displayed
37        self.lastFrame = 30000
38        self.message = "Correct!!!"
39        self.messageDisplay = False
40        self.messageColor = BBUILDER.SALMON_COLOR
41
42    def update(self, valueChange):
43        """updates a Bonus game"""
44        if valueChange == "Continue":
45            if self.puzzleState == BBUILDER.BONUS_INTRO:
46                self.puzzleState = BBUILDER.BONUS
47                self.currentPuzzle.puzzleState = BBUILDER.BONUS
48        if self.exit:
49            return (self.score, self.puzzlesCompleted)
50
51        else:
52            puzzleStatus = self.currentPuzzle.update(valueChange)
53            if (puzzleStatus == "Score++"):
54                self.score += 1000*self.multiplier*(1+self.difficulty)
55                self.puzzlesCompleted += 1
56                if not self.puzzleMistake and self.multiplier < 8:
57                    self.multiplier = self.multiplier*2
58                    self.multiplierChange = self.multiplier
59                    self.multiplierAni.play = True
60               
61                self.lastFrame = self.time
62                self.message = "Correct!!"
63                self.messageDisplay = True
64                self.messageColor = "green"
65               
66                self.puzzleMistake = False
67                if self.puzzlesCompleted <= 5:
68                    self.currentPuzzle = BonusPuzzle(self.puzzleState, self.difficulty)
69                elif self.puzzlesCompleted >= 5:
70                    return "IncrementLevel"
71                return ("UpdateScore", self.score)
72
73               
74            elif (puzzleStatus == False):
75               
76                self.lastFrame = self.time
77                self.message = "Wrong Answer"
78                self.messageDisplay = True
79                self.messageColor = "red"
80                 
81                self.multiplier = 1
82                if self.puzzlesCompleted <= 5:
83                    self.currentPuzzle = BonusPuzzle(self.puzzleState, self.difficulty)
84                elif self.puzzlesCompleted >= 5:
85                    return "IncrementLevel"
86
87            if self.lastFrame - self.time >= 2000:
88                self.messageDisplay = False
89               
90            timeChange = self.clock.tick()
91            self.time += -timeChange
92            if self.time <= 10000:
93                self.timeColor = pygame.Color("red")
94            if self.time <= 0:
95                return "IncrementLevel"
96            return "None"
97           
98
99    def draw(self):
100        """draws Survival related data including current Puzzle"""
101        self.background.update()
102        if self.puzzleState == BBUILDER.BONUS_INTRO:
103            globalVars.graphics.drawImage("dialog.png", (100,134))
104            globalVars.graphics.drawText(BBUILDER.BONUSTEXT, 130, 180, 30,
105                             pygame.Color("black"), "left")
106            for button in self.introButtons:
107                button.draw()
108                cursorOffset = 7*sin(radians(self.cursorTimer))
109                globalVars.graphics.drawRotatedImage(self.cursor,
110                (button.x-20-cursorOffset, button.y), -90)
111                globalVars.graphics.drawRotatedImage(self.cursor,
112                (button.x+button.size[0]+20-46+cursorOffset, button.y), 90)
113                # NOTE: 46 in the second equation is an offset for the width
114                # of the rotated triangle. It needs to be changed if the cursor
115                # size is changed
116
117                self.cursorTimer += 10
118                self.cursorTimer = self.cursorTimer % 360
119        else:
120            if self.multiplierChange:
121                globalVars.graphics.drawAnimation(120, 60, str(self.multiplierChange)+"xEffect.png",
122                                            (710, 65), self.multiplierAni)
123                if not self.multiplierAni.play:
124                    self.multiplierChange = 0
125            else:
126                globalVars.graphics.drawText(str(self.multiplier)+"x", 760, 85, 18,
127                                    BBUILDER.SALMON_COLOR, "left")
128            self.currentPuzzle.draw()       
129            globalVars.graphics.drawText("Score: "+str(int(self.score)),
130                                         675, 35, 18, BBUILDER.SALMON_COLOR,
131                                         "left")
132            globalVars.graphics.drawText("Multiplier: ",
133                                         675, 85, 18, BBUILDER.SALMON_COLOR,
134                                         "left")
135            globalVars.graphics.drawText("Bonus: "+str(int(self.puzzlesCompleted)+1)+"/6",
136                                         675, 10, 18, BBUILDER.SALMON_COLOR,
137                                         "left")
138            globalVars.graphics.drawText("Time: "+str(round(self.time/1000.0,1)),
139                                         675, 60, 18, self.timeColor, "left")
140       
141        if self.messageDisplay == True:
142            globalVars.graphics.drawText(self.message, 50, 400, 36, pygame.Color(self.messageColor))
143
144       
145class BonusPuzzle:
146    """Puzzle is a class that falls below Level. It contains individual
147        puzzles"""
148    def __init__(self, mode, difficulty=0):
149        """initializes a Puzzle"""
150        self.goalNumber = 0
151        self.selectedNumber = 0
152        self.difficulty = difficulty
153        self.correctIndex = 0
154        self.selectedToggle = 3
155        self.choiceList = []
156               
157        self.position = [(175, 250), (500, 250), (175, 450), (500, 450)]
158                             
159        self.exitButton = GameButton(BBUILDER.BUTTON_0,
160                                     (733,565), (200,50), "quit")
161        self.puzzleState = mode
162
163        self.cursor = "cursor0.png"
164        self.cursorTimer = 0
165                                           
166        self.generateBonus()
167        self.choiceList[self.selectedToggle].hover = True
168        self.choiceList[self.selectedToggle].play = True
169                                           
170    def generateBonus(self):
171        """generates a Puzzle based on parameters"""
172        if self.difficulty == 0 :
173            difficultyRange = range(1,8)
174        elif self.difficulty == 1 :
175            difficultyRange = range(8, 32)
176        else :
177            difficultyRange = range(32, 64)
178
179        #  generates four random numbers in the range
180        self.choiceList = [0,0,0,0]
181        for i in range(len(self.choiceList)) :
182            x = random.choice(difficultyRange)
183            while x in self.choiceList :
184                x = random.choice(difficultyRange)
185            self.choiceList[i] = x
186
187        correctIndex = random.randrange(0,4) 
188        self.goalNumber = self.choiceList[correctIndex]
189       
190        for i in range(4):
191            toggle = BonusToggle(self.choiceList[i], self.position[i], (160, 160)) #Idk about the index, revisit
192            self.choiceList[i] = toggle
193           
194
195    def update(self, valueChange):
196        """updates a Puzzle"""   
197        for toggle in range(len(self.choiceList)):
198            if toggle == self.selectedToggle:
199                self.choiceList[self.selectedToggle].hover = True
200                self.choiceList[self.selectedToggle].play = True
201            else:
202                self.choiceList[self.selectedToggle].hover = False
203                self.choiceList[self.selectedToggle].play = False             
204        if type(valueChange) == int: #mode is Puzzle
205            if (valueChange == self.goalNumber):
206                for toggle in self.choiceList:
207                    toggle.locked = True
208                return "Score++"
209            else:
210                return False
211
212    def selectTogglePrev(self):
213        """changes location of cursor. Called by EventHandler."""
214        if self.selectedToggle != None:
215            if self.selectedToggle != 0:
216                self.selectedToggle += -1
217            else: 
218                self.selectedToggle = len(self.choiceList) - 1
219        else:
220            self.selectedToggle = 0
221
222    def selectToggleNext(self):
223        """changes location of cursor. Called by EventHandler."""
224        if self.selectedToggle != None:
225            if self.selectedToggle != len(self.choiceList) - 1:
226                self.selectedToggle += 1
227            else: 
228                self.selectedToggle = 0
229        else:
230            self.selectedToggle = 0
231
232    def draw(self):
233        """draws a Puzzle by calling the appropriate function"""
234        self.drawPuzzle()
235
236    def drawPuzzle(self):
237        """draws a Puzzle when in Puzzle mode or Victory Mode"""
238        for toggleNum in range(4):
239            toggle = self.choiceList[toggleNum]
240            toggle.draw()
241           
242            if toggleNum == self.selectedToggle:
243                selectedToggle = self.choiceList[self.selectedToggle]
244                cursorOffset = 7*sin(radians(self.cursorTimer))
245                globalVars.graphics.drawRotatedImage(self.cursor,
246                (selectedToggle.x-50-cursorOffset, selectedToggle.y + 60),
247                                                     -90)
248                globalVars.graphics.drawRotatedImage(self.cursor,
249                (selectedToggle.x+selectedToggle.size[0]+50-46+cursorOffset,
250                 selectedToggle.y + 60), 90)
251                # NOTE: 46 in the second equation is an offset for the width
252                # of the rotated triangle. It needs to be changed if the cursor
253                # size is changed
254
255                self.cursorTimer += 10
256                self.cursorTimer = self.cursorTimer % 360
257       
258        globalVars.graphics.drawText("Goal: " + self.getBinaryNumber(),
259                                     333, 110, 90, BBUILDER.SALMON_COLOR, "center")
260                                     
261        self.exitButton.draw()                     
262
263    def getBinaryNumber(self):
264        strBinaryNum = ""
265        n = self.goalNumber
266        while n > 0:
267            strBinaryNum = str(n % 2) + strBinaryNum
268            n = n >> 1
269        return strBinaryNum
270
271class BonusToggle(GameObject):
272    """used by Puzzle. Represents toggle buttons with values"""
273    def __init__(self, value, pos, size):
274        """initializes a Toggle"""
275        image = BBUILDER.BONUS_BUTTON
276        GameObject.__init__(self, image , pos, size) #How I super?
277        self.active = False
278        self.value = value
279        self.index = 8
280        self.rectList = [self.imageRect]
281        self.locked = False
282        self.hover = False
283        self.pos = pos
284
285    def draw(self):
286        """draws a Toggle"""
287        if self.active:
288            text = pygame.font.Font(None, 40).render(
289                str(self.value), 1, pygame.Color("white")) #Woo magic
290        else:
291            text = pygame.font.Font(None, 40).render(str(self.value), 1, pygame.Color("gray"))
292           
293        globalVars.graphics.drawObject(self)
294        globalVars.graphics.drawText(str(self.value), self.pos[0], self.pos[1], 80, color=pygame.Color("white"), drawpos="center")
295       
296
297
298class GameButton(GameObject):
299    """game button from a puzzle."""
300    def __init__(self, image, pos, size, text):
301        """initializes a GameButton"""
302        GameObject.__init__(self, image, pos, size) #How I super?
303        self.active = False
304        self.text = text
305        self.textSize = 25 #Magic!
306        self.textColor = pygame.Color("white") #Double magic!
307        self.hover = False
308       
309        self.inactive_hover_anim = text+"_hover.png"
310        self.active_hover_anim = text+"_hover.png"
311        self.hover_anim_frames = 16
312        self.hover_anim_size = (1920, 80)
313        self.hover_xoffset = (self.imageRect.width - self.hover_anim_size[0]/self.hover_anim_frames)/2
314        self.hover_yoffset = (self.imageRect.height - self.hover_anim_size[1])/2
315
316    def draw(self):
317        """draws a GameButton"""
318        globalVars.graphics.drawObject(self, source="anim")
Note: See TracBrowser for help on using the browser.