comparison frontends/src/wix/quiz_game.py @ 362:208107419b17

Quiz game: buzzer, timer, answer management
author Goffi <goffi@goffi.org>
date Sun, 12 Jun 2011 22:34:15 +0200
parents 141eeb7cd9e6
children d9499d27f884
comparison
equal deleted inserted replaced
361:141eeb7cd9e6 362:208107419b17
69 self.loadImages("images/quiz/") 69 self.loadImages("images/quiz/")
70 70
71 def loadImages(self, dir): 71 def loadImages(self, dir):
72 """Load all the images needed for the game 72 """Load all the images needed for the game
73 @param dir: directory where the PNG files are""" 73 @param dir: directory where the PNG files are"""
74 x_player = 24
74 for name, sub_dir, filename, x, y, zindex, transparent in [("background", "backgrounds", "blue_background.png", 0, 0, 0, False), 75 for name, sub_dir, filename, x, y, zindex, transparent in [("background", "backgrounds", "blue_background.png", 0, 0, 0, False),
75 ("joueur0", "characters/zombie", "zombie.png", 24, 170, 5, True), 76 ("joueur0", "characters/zombie", "zombie.png", x_player+0*184, 170, 5, True),
76 ("joueur1", "characters/nerd", "nerd2.png", 209, 170, 5, True), 77 ("joueur1", "characters/nerd", "nerd2.png", x_player+1*184, 170, 5, True),
77 ("joueur2", "characters/zombie", "zombie.png", 392, 170, 5, True), 78 ("joueur2", "characters/zombie", "zombie.png", x_player+2*184, 170, 5, True),
78 ("joueur3", "characters/zombie", "zombie.png", 578, 170, 5, True), 79 ("joueur3", "characters/zombie", "zombie.png", x_player+3*184, 170, 5, True),
79 ("foreground", "foreground", "foreground.png", 0, 0, 10, True)]: 80 ("foreground", "foreground", "foreground.png", 0, 0, 10, True)]:
80 self.graphic_elts[name] = GraphicElement(os.path.join(dir, sub_dir, filename), x = x, y = y, zindex=zindex, transparent=transparent) 81 self.graphic_elts[name] = GraphicElement(os.path.join(dir, sub_dir, filename), x = x, y = y, zindex=zindex, transparent=transparent)
82
83 self.right_image = wx.Image(os.path.join(dir, "right.png")).ConvertToBitmap()
84 self.wrong_image = wx.Image(os.path.join(dir, "wrong.png")).ConvertToBitmap()
81 85
82 def fullPaint(self, device_context): 86 def fullPaint(self, device_context):
83 """Paint all the game on the given dc 87 """Paint all the game on the given dc
84 @param device_context: wx.DC""" 88 @param device_context: wx.DC"""
85 elements = self.graphic_elts.values() 89 elements = self.graphic_elts.values()
86 elements.sort() 90 elements.sort()
87 for elem in elements: 91 for elem in elements:
88 elem.draw(device_context) 92 elem.draw(device_context)
89 #device_context.DrawArc(39,127, 39, 127,
90 93
91 _font = wx.Font(65, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL) 94 _font = wx.Font(65, wx.FONTFAMILY_TELETYPE, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
92 device_context.SetFont(_font) 95 device_context.SetFont(_font)
93 device_context.SetTextForeground(wx.BLACK) 96 device_context.SetTextForeground(wx.BLACK)
94 97
95 x = 100 98 for i in range(4):
96 for score in [0,1,4,9]: 99 answer = self.parent.players_data[i]["answer"]
97 device_context.DrawText("%d" % score, x, 355) 100 score = self.parent.players_data[i]["score"]
98 x+=184 101 if answer == None:
102 device_context.DrawText("%d" % score, 100 + i*184, 355)
103 else:
104 device_context.DrawBitmap(self.right_image if answer else self.wrong_image, 39+i*184, 348, True)
99 105
100 106
101 if self.parent.time_origin: 107 if self.parent.time_origin:
102 device_context.SetPen(wx.BLACK_PEN) 108 device_context.SetPen(wx.BLACK_PEN)
103 radius = 20 109 radius = 20
104 center_x = 760 110 center_x = 760
105 center_y = 147 111 center_y = 147
106 origin = self.parent.time_origin 112 origin = self.parent.time_origin
107 current = time() 113 current = self.parent.time_pause or time()
108 limit = self.parent.time_limit 114 limit = self.parent.time_limit
109 print "limit:", limit
110 total = limit - origin 115 total = limit - origin
111 left = self.parent.time_left = max(0,limit - current) 116 left = self.parent.time_left = max(0,limit - current)
112 device_context.SetBrush(wx.RED_BRUSH if left/total < 1/4.0 else wx.WHITE_BRUSH) 117 device_context.SetBrush(wx.RED_BRUSH if left/total < 1/4.0 else wx.WHITE_BRUSH)
113 print "left:",left
114 if left: 118 if left:
115 #we now draw the timer 119 #we now draw the timer
116 print "total - left:", total - left
117 angle = ((-2*pi)*((total-left)/total) + (pi/2)) 120 angle = ((-2*pi)*((total-left)/total) + (pi/2))
118 print "angle:", angle*57.3
119 x = center_x + radius * cos(angle) 121 x = center_x + radius * cos(angle)
120 y = center_y - radius * sin(angle) 122 y = center_y - radius * sin(angle)
121 print "x: %s, y:%s" % (x, y)
122 device_context.DrawArc(center_x, center_y-radius, x, y, center_x, center_y) 123 device_context.DrawArc(center_x, center_y-radius, x, y, center_x, center_y)
123
124
125 124
126 def onPaint(self, event): 125 def onPaint(self, event):
127 dc = wx.PaintDC(self) 126 dc = wx.PaintDC(self)
128 self.fullPaint(dc) 127 self.fullPaint(dc)
129 128
132 class QuizPanel(wx.Panel): 131 class QuizPanel(wx.Panel):
133 """This class is used to display the quiz game""" 132 """This class is used to display the quiz game"""
134 133
135 def __init__(self, parent, referee, players, player_nick): 134 def __init__(self, parent, referee, players, player_nick):
136 wx.Panel.__init__(self, parent) 135 wx.Panel.__init__(self, parent)
136 self.referee = referee
137 self.player_nick = player_nick
138 self.players = players
137 self.time_origin = None #set to unix time when the timer start 139 self.time_origin = None #set to unix time when the timer start
138 self.time_limit = None 140 self.time_limit = None
139 self.time_left = None 141 self.time_left = None
142 self.time_pause = None
143 self.last_answer = None
140 self.parent = parent 144 self.parent = parent
141 self.SetMinSize(wx.Size(WIDTH, HEIGHT)) 145 self.SetMinSize(wx.Size(WIDTH, HEIGHT))
142 self.SetSize(wx.Size(WIDTH, HEIGHT)) 146 self.SetSize(wx.Size(WIDTH, HEIGHT))
143 self.base = BaseWindow(self) 147 self.base = BaseWindow(self)
144 self.question = wx.TextCtrl(self.base, -1, "", pos=(168,17), size=(613, 94), style=wx.TE_MULTILINE | wx.TE_READONLY) 148 self.question = wx.TextCtrl(self, -1, pos=(168,17), size=(613, 94), style=wx.TE_MULTILINE | wx.TE_READONLY)
145 self.reponse = wx.TextCtrl(self.base, -1, pos=(410,569), size=(342, 21), style=wx.TE_PROCESS_ENTER) 149 self.answer = wx.TextCtrl(self, -1, pos=(410,569), size=(342, 21), style=wx.TE_PROCESS_ENTER)
150 self.players_data = [{}, {}, {}, {}]
151 for i in range(4):
152 self.players_data[i]['bubble'] = wx.TextCtrl(self, -1, pos=(39+i*184, 120), size=(180, 56), style=wx.TE_MULTILINE | wx.TE_READONLY)
153 self.players_data[i]['bubble'].Hide()
154 self.players_data[i]['answer'] = None #True if the player gave a good answer
155 self.players_data[i]['score'] = 0
156 self.answer.Bind(wx.EVT_TEXT_ENTER, self.answered)
146 self.parent.host.bridge.quizGameReady(player_nick, referee, profile_key = self.parent.host.profile) 157 self.parent.host.bridge.quizGameReady(player_nick, referee, profile_key = self.parent.host.profile)
147 self.state = None 158 self.state = None
159
160 def answered(self, event):
161 """Called when the player gave an answer in the box"""
162 self.last_answer = self.answer.GetValue()
163 self.answer.Clear()
164 if self.last_answer:
165 self.parent.host.bridge.quizGameAnswer(self.player_nick, self.referee, self.last_answer, profile_key = self.parent.host.profile)
166
167 def quizGameTimerExpired(self):
168 """Called when nobody answered the question in time"""
169 self.question.SetValue(_(u"Quel dommage, personne n'a trouvé la réponse\n\nAttention, la prochaine question arrive..."))
170
171 def quizGameTimerRestarted(self, time_left):
172 """Called when nobody answered the question in time"""
173 timer_orig = self.time_limit - self.time_origin
174 self.time_left = time_left
175 self.time_limit = time() + time_left
176 self.time_origin = self.time_limit - timer_orig
177 self.time_pause = None
178 self.__timer_refresh()
148 179
149 def startTimer(self, timer=60): 180 def startTimer(self, timer=60):
150 """Start the timer to answer the question""" 181 """Start the timer to answer the question"""
151 def _refresh():
152 self.Refresh()
153 if self.time_left:
154 wx.CallLater(1000, _refresh)
155 self.time_left = timer 182 self.time_left = timer
156 self.time_origin = time() 183 self.time_origin = time()
157 self.time_limit = self.time_origin + timer 184 self.time_limit = self.time_origin + timer
158 _refresh() 185 self.time_pause = None
186 self.__timer_refresh()
187
188 def __timer_refresh(self):
189 self.Refresh()
190 if self.time_left:
191 wx.CallLater(1000, self.__timer_refresh)
159 192
160 def quizGameNew(self, data): 193 def quizGameNew(self, data):
161 """Start a new game, with given hand""" 194 """Start a new game, with given hand"""
162 if data.has_key('instructions'): 195 if data.has_key('instructions'):
163 self.question.ChangeValue(data['instructions']) 196 self.question.ChangeValue(data['instructions'])
166 def quizGameQuestion(self, question_id, question, timer): 199 def quizGameQuestion(self, question_id, question, timer):
167 """Called when a new question is available 200 """Called when a new question is available
168 @param question: question to ask""" 201 @param question: question to ask"""
169 self.question.ChangeValue(question) 202 self.question.ChangeValue(question)
170 self.startTimer(timer) 203 self.startTimer(timer)
171 204 self.last_answer = None
205 self.answer.Clear()
206
207 def quizGamePlayerBuzzed(self, player, pause):
208 """Called when the player pushed the buzzer
209 @param player: player who pushed the buzzer
210 @param pause: should we stop the timer ?"""
211 if pause:
212 self.time_pause = time()
213
214 def quizGamePlayerSays(self, player, text, delay):
215 """Called when the player says something
216 @param player: who is talking
217 @param text: what the player says"""
218 if player != self.player_nick and self.last_answer:
219 #if we are not the player talking, and we have an answer, that mean that our answer has not been validated
220 #we can put it again in the answering box
221 self.answer.SetValue(self.last_answer)
222 idx = self.players.index(player)
223 bubble = self.players_data[idx]['bubble']
224 bubble.SetValue(text)
225 bubble.Show()
226 self.Refresh()
227 wx.CallLater(delay * 1000, bubble.Hide)
228
229 def quizGameAnswerResult(self, player, good_answer, score):
230 """Result of the just given answer
231 @param player: who gave the answer
232 @good_answer: True if the answer is right
233 @score: dict of score"""
234 player_idx = self.players.index(player)
235 self.players_data[player_idx]['answer'] = good_answer
236 for _player in score:
237 _idx = self.players.index(_player)
238 self.players_data[_idx]['score'] = score[_player]
239 def removeAnswer():
240 self.players_data[player_idx]['answer'] = None
241 self.Refresh()
242 wx.CallLater(2000, removeAnswer)
243 self.Refresh()