3
# Copyright (C) 2008 Bruno Coudoin
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.
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.
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/>.
30
from gcompris import gcompris_gettext as _
32
# ----------------------------------------
33
# Double click in a timely fashion to goal against Tux
35
class Gcompris_penalty:
36
"""double click goal"""
39
def __init__(self, gcomprisBoard):
40
self.gcomprisBoard = gcomprisBoard
42
self.gcomprisBoard.disable_im_context = True
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)
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)
59
gcompris.bar_set_level(self.gcomprisBoard)
62
self.ballinc = 20 # Event loop timer for the ball move
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.
67
goocanvas.Group(parent = self.gcomprisBoard.canvas.get_root_item())
70
svghandle = gcompris.utils.load_svg("penalty/penalty_bg.svgz")
72
parent = self.rootitem,
73
svg_handle = svghandle,
74
svg_id = "#BACKGROUND",
75
pointer_events = goocanvas.EVENTS_NONE
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,
87
self.help_item.props.visibility = goocanvas.ITEM_INVISIBLE
91
parent = self.rootitem,
92
svg_handle = svghandle,
95
item.connect("button_press_event", self.help)
99
parent = self.rootitem,
100
svg_handle = svghandle,
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)
107
# The click indicator
113
self.indicator.append(
114
Indicator(self.rootitem,
115
gcompris.BOARD_WIDTH/2 - 350,
122
self.indicator.append(
123
Indicator(self.rootitem,
124
gcompris.BOARD_WIDTH/2,
131
self.indicator.append(
132
Indicator(self.rootitem,
133
gcompris.BOARD_WIDTH/2 + 350,
141
self.balloon = Balloon(self, svghandle, 10, 10)
142
self.balloon.item.connect("button_press_event",
143
self.shoot_item_event)
153
gobject.source_remove(self.timer_indic)
156
# Remove the root item removes all the others inside it
157
self.rootitem.remove()
171
def key_press(self, keyval, commit_str, preedit_str):
174
# Called by gcompris core
175
def pause(self, pause):
177
self.board_paused = pause
179
# When the bonus is displayed, it call us first with pause(1) and then with pause(0)
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
194
# End of Initialisation
195
# ---------------------
197
def next_level(self):
199
# Set the level in the control bar
200
gcompris.bar_set_level(self.gcomprisBoard);
204
gobject.source_remove(self.timer_indic)
207
if(self.gcomprisBoard.level == 1):
209
elif(self.gcomprisBoard.level == 2):
211
elif(self.gcomprisBoard.level == 3):
213
elif(self.gcomprisBoard.level == 4):
215
elif(self.gcomprisBoard.level == 5):
217
elif(self.gcomprisBoard.level == 6):
219
elif(self.gcomprisBoard.level == 7):
221
elif(self.gcomprisBoard.level == 8):
223
elif(self.gcomprisBoard.level == 9):
226
self.counter = [0, 0, 0]
227
for i in self.indicator:
229
i.winlimit = winlimit
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
238
if(self.gcomprisBoard.sublevel>self.gcomprisBoard.number_of_sublevel):
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
247
# Update the counter and return true if click action
249
def update_counter(self, button, time):
251
if self.counter[button] == 0:
253
# Check we are not already running
255
if self.counter[i] != 0:
258
self.counter[button] = time
259
self.indicator[button].start()
260
self.timer_indic = gobject.timeout_add(self.timerinc,
261
self.indicator[button].refresh,
263
gcompris.sound.play_ogg("sounds/flip.wav")
265
elif self.counter[button] != 0:
267
self.counter[button] = abs(self.counter[button] - time)
268
self.counter[button] = 0
269
self.balloon.move_to(self.indicator[button].stop())
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:
279
self.indicator[i].reset()
281
self.update_counter(event.button - 1,
287
# Display an info string when the user clicks
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.")
294
text=_("Click twice on the balloon to shoot it.")
296
self.help_item.set_properties(text = text)
297
self.help_item.props.visibility = goocanvas.ITEM_VISIBLE
303
color_init = 0x1212CCC0
304
color_done = 0x000012C0
309
# orientation = 0 : horizontal, left assigned
310
# = 1 : vertical, top assigned
311
# = 2 : horizontal, right assigned
313
def __init__(self, rootitem, x, y, w, h,
320
self.orientation = orientation
325
stroke_color_rgba = 0xFFFFFFFFL,
330
self.item.set_properties(
335
fill_color_rgba = self.color_init)
339
# Return the calculated coordinate of the balloon
340
# return: (win, X, Y) with win = True or False
345
return (self.counter <= self.winlimit,
354
def refresh(self, timerinc):
355
self.counter += timerinc
356
self.update(self.counter)
362
def update(self, counter):
363
length = min( (counter * self.max) / self.winlimit,
366
if self.orientation == 0:
368
self.item.set_properties(width = length)
370
self.target_y = self.y
371
elif self.orientation == 1:
373
self.item.set_properties(width = length)
374
self.target_x = self.x
376
elif self.orientation == 2:
377
x1 = (self.x + self.w) - length
378
self.item.set_properties(x = x1,
381
self.target_y = self.y
383
# Calc a proportional red and green color
385
if counter <= self.winlimit:
386
cg = 0xFF - min( 0xFF,
387
(counter * 0xFF) / self.winlimit)
393
((counter - self.winlimit) * 0xFF) / self.winlimit)
397
color = self.color_done | (cg<<16) | (cr<<24)
399
self.item.set_properties(fill_color_rgba = color)
402
# The balloon display and it's motion
414
def __init__(self, penalty, svghandle, x, y):
416
self.penalty = penalty
417
self.rootitem = penalty.rootitem
422
self.shadow = goocanvas.Svg(
423
parent = self.rootitem,
424
svg_handle = svghandle,
425
svg_id = "#BALLOON_SHADOW"
429
self.item = goocanvas.Svg(
430
parent = self.rootitem,
431
svg_handle = svghandle,
435
bounds = self.item.get_bounds()
436
self.size = bounds.y2 - bounds.y1
438
# Save the original position of the balloon
439
self.item_bounds = self.item.get_bounds()
443
self.need_reset = False
444
self.x = gcompris.BOARD_WIDTH/2
445
self.y = gcompris.BOARD_HEIGHT - 115
447
self.item.translate(self.item_bounds.x1 - self.item.get_bounds().x1,
448
self.item_bounds.y1 - self.item.get_bounds().y1)
450
gcompris.utils.item_focus_init(self.item, None)
451
self.shadow.props.visibility = goocanvas.ITEM_VISIBLE
454
gobject.source_remove(self.timer)
461
self.item.translate(self.dx * -1,
467
gcompris.sound.play_ogg("sounds/bonus.wav")
468
self.penalty.increment_level()
469
self.penalty.next_level()
471
gcompris.sound.play_ogg("sounds/tuxok.wav")
478
# target: (win, X, Y) with win = True or False
479
def move_to(self, target):
483
self.shadow.props.visibility = goocanvas.ITEM_INVISIBLE
484
gcompris.utils.item_focus_remove(self.item, None)
486
self.need_reset = True
487
gcompris.sound.play_ogg("sounds/brick.wav")
492
if target[0] == False:
493
target_x = gcompris.BOARD_WIDTH / 2
497
self.dx = (self.x - target_x) / self.step
498
self.dy = (self.y - target_y) / self.step
500
self.timer = gobject.timeout_add(self.timerinc,