~ml-launchpad/ubuntu/natty/gcompris/fix-for-777349

« back to all changes in this revision

Viewing changes to src/penalty-activity/penalty.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Gariepy, Marc Gariepy, Stephane Graber
  • Date: 2010-01-04 17:42:49 UTC
  • mfrom: (1.1.14 upstream)
  • Revision ID: james.westby@ubuntu.com-20100104174249-7bupatd9dtxyhvs4
Tags: 9.0-0ubuntu1
[Marc Gariepy]
* New upstream release (9.0).
* Remove cache.c from POTFILES to avoid FTBFS
* Remove unneeded rm in debian/rules (file no longer exists upstream)

[Stephane Graber]
* Bump Debian standards to 3.8.3
* Add patch system (dpatch)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#  gcompris - penalty
 
2
#
 
3
# Copyright (C) 2008 Bruno Coudoin
 
4
#
 
5
#   This program is free software; you can redistribute it and/or modify
 
6
#   it under the terms of the GNU General Public License as published by
 
7
#   the Free Software Foundation; either version 3 of the License, or
 
8
#   (at your option) any later version.
 
9
#
 
10
#   This program is distributed in the hope that it will be useful,
 
11
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
13
#   GNU General Public License for more details.
 
14
#
 
15
#   You should have received a copy of the GNU General Public License
 
16
#   along with this program; if not, see <http://www.gnu.org/licenses/>.
 
17
#
 
18
 
 
19
import gobject
 
20
import goocanvas
 
21
import cairo
 
22
import gcompris
 
23
import gcompris.utils
 
24
import gcompris.skin
 
25
import gcompris.bonus
 
26
import gcompris.sound
 
27
import gtk
 
28
import gtk.gdk
 
29
import rsvg
 
30
from gcompris import gcompris_gettext as _
 
31
 
 
32
# ----------------------------------------
 
33
# Double click in a timely fashion to goal against Tux
 
34
 
 
35
class Gcompris_penalty:
 
36
  """double click goal"""
 
37
 
 
38
 
 
39
  def __init__(self, gcomprisBoard):
 
40
    self.gcomprisBoard = gcomprisBoard
 
41
 
 
42
    self.gcomprisBoard.disable_im_context = True
 
43
 
 
44
    # These are used to let us restart only after the bonus is displayed.
 
45
    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
 
46
    self.board_paused  = 0
 
47
    self.gamewon       = 0
 
48
    self.timer_indic   = 0
 
49
    self.timerinc      = 10
 
50
 
 
51
  def start(self):
 
52
    self.gcomprisBoard.level=1
 
53
    self.gcomprisBoard.maxlevel=9
 
54
    self.gcomprisBoard.sublevel=1
 
55
    self.gcomprisBoard.number_of_sublevel=1
 
56
    gcompris.bar_set(gcompris.BAR_LEVEL)
 
57
    gcompris.bar_location(5, -1, 0.8)
 
58
 
 
59
    gcompris.bar_set_level(self.gcomprisBoard)
 
60
 
 
61
 
 
62
    self.ballinc = 20        # Event loop timer for the ball move
 
63
 
 
64
    # Create our rootitem. We put each canvas item in it so at the end we
 
65
    # only have to kill it. The canvas deletes all the items it contains automaticaly.
 
66
    self.rootitem = \
 
67
        goocanvas.Group(parent =  self.gcomprisBoard.canvas.get_root_item())
 
68
 
 
69
 
 
70
    svghandle = gcompris.utils.load_svg("penalty/penalty_bg.svgz")
 
71
    goocanvas.Svg(
 
72
      parent = self.rootitem,
 
73
      svg_handle = svghandle,
 
74
      svg_id = "#BACKGROUND",
 
75
      pointer_events = goocanvas.EVENTS_NONE
 
76
      )
 
77
 
 
78
    # Help
 
79
    self.help_item = goocanvas.Text(
 
80
      parent = self.rootitem,
 
81
      font = gcompris.skin.get_font("gcompris/board/medium"),
 
82
      x = gcompris.BOARD_WIDTH / 2,
 
83
      y = gcompris.BOARD_HEIGHT - 170,
 
84
      anchor=gtk.ANCHOR_CENTER,
 
85
      fill_color = "white"
 
86
      )
 
87
    self.help_item.props.visibility = goocanvas.ITEM_INVISIBLE
 
88
 
 
89
    # Tux
 
90
    item = goocanvas.Svg(
 
91
      parent = self.rootitem,
 
92
      svg_handle = svghandle,
 
93
      svg_id = "#TUX"
 
94
      )
 
95
    item.connect("button_press_event", self.help)
 
96
 
 
97
    # The activity help
 
98
    item = goocanvas.Svg(
 
99
      parent = self.rootitem,
 
100
      svg_handle = svghandle,
 
101
      svg_id = "#HELP"
 
102
      )
 
103
    item.connect("button_press_event", self.help)
 
104
    # This item is clickeable and it must be seen
 
105
    gcompris.utils.item_focus_init(item, None)
 
106
 
 
107
    # The click indicator
 
108
    indicator_h = 30
 
109
    indicator_w = 10
 
110
    y_ref = 107
 
111
 
 
112
    self.indicator = []
 
113
    self.indicator.append(
 
114
      Indicator(self.rootitem,
 
115
                gcompris.BOARD_WIDTH/2 - 350,
 
116
                y_ref,
 
117
                indicator_w,
 
118
                indicator_h,
 
119
                0,
 
120
                200)
 
121
      )
 
122
    self.indicator.append(
 
123
      Indicator(self.rootitem,
 
124
                gcompris.BOARD_WIDTH/2,
 
125
                y_ref - 80,
 
126
                indicator_h,
 
127
                indicator_w,
 
128
                1,
 
129
                100)
 
130
      )
 
131
    self.indicator.append(
 
132
      Indicator(self.rootitem,
 
133
                gcompris.BOARD_WIDTH/2 + 350,
 
134
                y_ref,
 
135
                indicator_w,
 
136
                indicator_h,
 
137
                2,
 
138
                200)
 
139
      )
 
140
 
 
141
    self.balloon = Balloon(self, svghandle, 10, 10)
 
142
    self.balloon.item.connect("button_press_event",
 
143
                              self.shoot_item_event)
 
144
 
 
145
    self.next_level()
 
146
 
 
147
 
 
148
  def end(self):
 
149
 
 
150
    self.balloon.reset()
 
151
 
 
152
    if self.timer_indic:
 
153
      gobject.source_remove(self.timer_indic)
 
154
    self.timer_indic = 0
 
155
 
 
156
    # Remove the root item removes all the others inside it
 
157
    self.rootitem.remove()
 
158
 
 
159
  def ok(self):
 
160
    pass
 
161
 
 
162
 
 
163
  def repeat(self):
 
164
    pass
 
165
 
 
166
 
 
167
  def config(self):
 
168
    pass
 
169
 
 
170
 
 
171
  def key_press(self, keyval, commit_str, preedit_str):
 
172
    return False
 
173
 
 
174
  # Called by gcompris core
 
175
  def pause(self, pause):
 
176
 
 
177
    self.board_paused = pause
 
178
 
 
179
    # When the bonus is displayed, it call us first with pause(1) and then with pause(0)
 
180
    # the game is won
 
181
    if(pause == 0):
 
182
      self.next_level()
 
183
      self.gamewon = 0
 
184
 
 
185
    return
 
186
 
 
187
 
 
188
  # Called by gcompris when the user click on the level icon
 
189
  def set_level(self, level):
 
190
    self.gcomprisBoard.level=level
 
191
    self.gcomprisBoard.sublevel=1
 
192
    self.next_level()
 
193
 
 
194
  # End of Initialisation
 
195
  # ---------------------
 
196
 
 
197
  def next_level(self):
 
198
 
 
199
    # Set the level in the control bar
 
200
    gcompris.bar_set_level(self.gcomprisBoard);
 
201
    self.balloon.reset()
 
202
 
 
203
    if self.timer_indic:
 
204
      gobject.source_remove(self.timer_indic)
 
205
    self.timer_indic = 0
 
206
 
 
207
    if(self.gcomprisBoard.level == 1):
 
208
      winlimit = 1000
 
209
    elif(self.gcomprisBoard.level == 2):
 
210
      winlimit = 800
 
211
    elif(self.gcomprisBoard.level == 3):
 
212
      winlimit = 600
 
213
    elif(self.gcomprisBoard.level == 4):
 
214
      winlimit = 400
 
215
    elif(self.gcomprisBoard.level == 5):
 
216
      winlimit = 250
 
217
    elif(self.gcomprisBoard.level == 6):
 
218
      winlimit = 200
 
219
    elif(self.gcomprisBoard.level == 7):
 
220
      winlimit = 180
 
221
    elif(self.gcomprisBoard.level == 8):
 
222
      winlimit = 170
 
223
    elif(self.gcomprisBoard.level == 9):
 
224
      winlimit = 160
 
225
 
 
226
    self.counter = [0, 0, 0]
 
227
    for i in self.indicator:
 
228
      i.reset()
 
229
      i.winlimit = winlimit
 
230
 
 
231
 
 
232
  # Code that increments the sublevel and level
 
233
  # And bail out if no more levels are available
 
234
  # return 1 if continue, 0 if bail out
 
235
  def increment_level(self):
 
236
    self.gcomprisBoard.sublevel += 1
 
237
 
 
238
    if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
 
239
      # Try the next level
 
240
      self.gcomprisBoard.sublevel=1
 
241
      self.gcomprisBoard.level += 1
 
242
      if(self.gcomprisBoard.level>self.gcomprisBoard.maxlevel):
 
243
        self.gcomprisBoard.level = self.gcomprisBoard.maxlevel
 
244
 
 
245
    return 1
 
246
 
 
247
  # Update the counter and return true if click action
 
248
  # is compteted
 
249
  def update_counter(self, button, time):
 
250
 
 
251
    if self.counter[button] == 0:
 
252
      # FIRST CLICK
 
253
      # Check we are not already running
 
254
      for i in range(3):
 
255
        if self.counter[i] != 0:
 
256
          return False
 
257
 
 
258
      self.counter[button] = time
 
259
      self.indicator[button].start()
 
260
      self.timer_indic  = gobject.timeout_add(self.timerinc,
 
261
                                              self.indicator[button].refresh,
 
262
                                              self.timerinc)
 
263
      gcompris.sound.play_ogg("sounds/flip.wav")
 
264
      return False
 
265
    elif self.counter[button] != 0:
 
266
      # SECOND CLICK
 
267
      self.counter[button] = abs(self.counter[button] - time)
 
268
      self.counter[button] = 0
 
269
      self.balloon.move_to(self.indicator[button].stop())
 
270
      return True
 
271
 
 
272
  def shoot_item_event(self, widget, target, event=None):
 
273
    if event.type == gtk.gdk.BUTTON_PRESS:
 
274
      if event.button <= 3:
 
275
        if self.balloon.need_reset:
 
276
          self.balloon.reset()
 
277
          for i in range(3):
 
278
            self.counter[i] = 0
 
279
            self.indicator[i].reset()
 
280
        else:
 
281
          self.update_counter(event.button - 1,
 
282
                              event.time)
 
283
 
 
284
    return False
 
285
 
 
286
  #
 
287
  # Display an info string when the user clicks
 
288
  # on the wrong item
 
289
  def help(self, widget, target, event=None):
 
290
    if event.type == gtk.gdk.BUTTON_PRESS:
 
291
      if self.balloon.need_reset:
 
292
        text=_("Click on the balloon to place it again.")
 
293
      else:
 
294
        text=_("Click twice on the balloon to shoot it.")
 
295
 
 
296
      self.help_item.set_properties(text = text)
 
297
      self.help_item.props.visibility = goocanvas.ITEM_VISIBLE
 
298
 
 
299
    return False
 
300
 
 
301
class Indicator:
 
302
  winlimit = 0
 
303
  color_init = 0x1212CCC0
 
304
  color_done = 0x000012C0
 
305
  item = 0
 
306
  orientation = 0
 
307
  counter = 0
 
308
  stopped = True
 
309
  # orientation = 0 : horizontal, left assigned
 
310
  #             = 1 : vertical, top assigned
 
311
  #             = 2 : horizontal, right assigned
 
312
  #
 
313
  def __init__(self, rootitem, x, y, w, h,
 
314
               orientation, max):
 
315
    self.x = x
 
316
    self.y = y
 
317
    self.w = w
 
318
    self.h = h
 
319
    self.max = max
 
320
    self.orientation = orientation
 
321
 
 
322
    self.item = \
 
323
        goocanvas.Rect(
 
324
      parent = rootitem,
 
325
      stroke_color_rgba = 0xFFFFFFFFL,
 
326
      line_width = 1)
 
327
    self.reset()
 
328
 
 
329
  def reset(self):
 
330
    self.item.set_properties(
 
331
      x = self.x,
 
332
      y = self.y,
 
333
      width = self.w,
 
334
      height = self.h,
 
335
      fill_color_rgba = self.color_init)
 
336
    self.stopped = True
 
337
 
 
338
  #
 
339
  # Return the calculated coordinate of the balloon
 
340
  # return: (win, X, Y) with win = True or False
 
341
  #
 
342
  def stop(self):
 
343
    self.stopped = True
 
344
 
 
345
    return (self.counter <= self.winlimit,
 
346
            self.target_x,
 
347
            self.target_y)
 
348
 
 
349
 
 
350
  def start(self):
 
351
    self.stopped = False
 
352
    self.counter = 0
 
353
 
 
354
  def refresh(self, timerinc):
 
355
    self.counter += timerinc
 
356
    self.update(self.counter)
 
357
 
 
358
    if self.stopped:
 
359
      return False
 
360
    return True
 
361
 
 
362
  def update(self, counter):
 
363
    length = min( (counter * self.max) / self.winlimit,
 
364
                  self.max)
 
365
 
 
366
    if self.orientation == 0:
 
367
      x2 = self.x + length
 
368
      self.item.set_properties(width = length)
 
369
      self.target_x = x2
 
370
      self.target_y = self.y
 
371
    elif self.orientation == 1:
 
372
      y2 = self.y + length
 
373
      self.item.set_properties(width = length)
 
374
      self.target_x = self.x
 
375
      self.target_y = y2
 
376
    elif self.orientation == 2:
 
377
      x1 = (self.x + self.w) - length
 
378
      self.item.set_properties(x = x1,
 
379
                               width = length)
 
380
      self.target_x = x1
 
381
      self.target_y = self.y
 
382
 
 
383
    # Calc a proportional red and green color
 
384
    color = 0L
 
385
    if counter <= self.winlimit:
 
386
      cg = 0xFF - min( 0xFF,
 
387
                       (counter * 0xFF) / self.winlimit)
 
388
      cg = max(cg, 0x50)
 
389
      cr = 0x12
 
390
    else:
 
391
      cg = 0x12
 
392
      cr = min( 0xFF,
 
393
                ((counter - self.winlimit) * 0xFF) / self.winlimit)
 
394
      cr += 0x90
 
395
      cr = min(0xFF, cr)
 
396
 
 
397
    color = self.color_done | (cg<<16) | (cr<<24)
 
398
 
 
399
    self.item.set_properties(fill_color_rgba = color)
 
400
 
 
401
#
 
402
# The balloon display and it's motion
 
403
#
 
404
class Balloon:
 
405
  x = 0
 
406
  y = 0
 
407
  size = 0
 
408
  stopped = True
 
409
  item = 0
 
410
  timerinc = 20
 
411
  timer = 0
 
412
  need_reset = False
 
413
 
 
414
  def __init__(self, penalty, svghandle, x, y):
 
415
 
 
416
    self.penalty = penalty
 
417
    self.rootitem = penalty.rootitem
 
418
    self.x = x
 
419
    self.y = y
 
420
 
 
421
    # Balloon shadow
 
422
    self.shadow = goocanvas.Svg(
 
423
      parent = self.rootitem,
 
424
      svg_handle = svghandle,
 
425
      svg_id = "#BALLOON_SHADOW"
 
426
      )
 
427
 
 
428
    # Balloon
 
429
    self.item = goocanvas.Svg(
 
430
      parent = self.rootitem,
 
431
      svg_handle = svghandle,
 
432
      svg_id = "#BALLOON"
 
433
      )
 
434
 
 
435
    bounds = self.item.get_bounds()
 
436
    self.size = bounds.y2 - bounds.y1
 
437
 
 
438
    # Save the original position of the balloon
 
439
    self.item_bounds = self.item.get_bounds()
 
440
 
 
441
 
 
442
  def reset(self):
 
443
    self.need_reset = False
 
444
    self.x = gcompris.BOARD_WIDTH/2
 
445
    self.y = gcompris.BOARD_HEIGHT - 115
 
446
 
 
447
    self.item.translate(self.item_bounds.x1 - self.item.get_bounds().x1,
 
448
                        self.item_bounds.y1 - self.item.get_bounds().y1)
 
449
 
 
450
    gcompris.utils.item_focus_init(self.item, None)
 
451
    self.shadow.props.visibility = goocanvas.ITEM_VISIBLE
 
452
 
 
453
    if self.timer:
 
454
      gobject.source_remove(self.timer)
 
455
    self.timer = 0
 
456
 
 
457
 
 
458
  def move_step(self):
 
459
    self.x -= self.dx
 
460
    self.y -= self.dy
 
461
    self.item.translate(self.dx * -1,
 
462
                        self.dy * -1)
 
463
    self.step -= 1
 
464
 
 
465
    if self.step == 0:
 
466
      if self.win:
 
467
        gcompris.sound.play_ogg("sounds/bonus.wav")
 
468
        self.penalty.increment_level()
 
469
        self.penalty.next_level()
 
470
      else:
 
471
        gcompris.sound.play_ogg("sounds/tuxok.wav")
 
472
 
 
473
      return False
 
474
 
 
475
    return True
 
476
 
 
477
 
 
478
  # target: (win, X, Y) with win = True or False
 
479
  def move_to(self, target):
 
480
    if self.timer != 0:
 
481
      return
 
482
 
 
483
    self.shadow.props.visibility = goocanvas.ITEM_INVISIBLE
 
484
    gcompris.utils.item_focus_remove(self.item, None)
 
485
 
 
486
    self.need_reset = True
 
487
    gcompris.sound.play_ogg("sounds/brick.wav")
 
488
 
 
489
    self.win = target[0]
 
490
    target_x = target[1]
 
491
    target_y = target[2]
 
492
    if target[0] == False:
 
493
      target_x = gcompris.BOARD_WIDTH / 2
 
494
      target_y = 260
 
495
 
 
496
    self.step = 100.0
 
497
    self.dx = (self.x - target_x) / self.step
 
498
    self.dy = (self.y - target_y) / self.step
 
499
 
 
500
    self.timer  = gobject.timeout_add(self.timerinc,
 
501
                                      self.move_step)
 
502