1 from os
.path
import exists
2 from os
import makedirs
4 from logging
import debug
, info
5 from importlib
import import_module
6 from inspect
import isclass
7 from panda3d
.core
import AmbientLight
, DirectionalLight
, Point3
, Texture
, \
8 TextPropertiesManager
, TextNode
, Spotlight
, PerspectiveLens
, BitMask32
9 from panda3d
.bullet
import BulletPlaneShape
, BulletGhostNode
10 from direct
.gui
.OnscreenImage
import OnscreenImage
11 from direct
.gui
.OnscreenText
import OnscreenText
12 from direct
.gui
.DirectGui
import DirectButton
, DirectFrame
13 from direct
.gui
.DirectGuiGlobals
import FLAT
, DISABLED
, NORMAL
14 from direct
.showbase
.DirectObject
import DirectObject
15 from pmachines
.items
.background
import Background
16 from pmachines
.gui
.sidepanel
import SidePanel
17 from ya2
.utils
.cursor
import MouseCursor
18 from ya2
.p3d
.gfx
import P3dGfxMgr
19 from ya2
.p3d
.p3d
import LibP3d
22 class Scene(DirectObject
):
24 def __init__(self
, world
, exit_cb
, auto_close_instr
, dbg_items
, reload_cb
, scenes
, pos_mgr
, testing
, mouse_coords
):
27 self
._exit
_cb
= exit_cb
28 self
._testing
= testing
29 self
._mouse
_coords
= mouse_coords
30 self
._dbg
_items
= dbg_items
31 self
._reload
_cb
= reload_cb
32 self
._pos
_mgr
= pos_mgr
35 self
._start
_evt
_time
= None
36 self
._enforce
_res
= ''
37 self
.accept('enforce_res', self
.enforce_res
)
39 self
._cursor
= MouseCursor(
40 'assets/images/buttons/arrowUpLeft.dds', (.04, 1, .04), (.5, .5, .5, 1),
45 self
._set
_mouse
_plane
()
50 self
._item
_active
= None
53 self
.__restore
_state
()
55 self
._set
_instructions
()
56 self
._bg
= Background()
57 self
._side
_panel
= SidePanel(world
, self
._mouse
_plane
_node
, (-5, 4), (-3, 1), 1, self
.items
)
58 self
._scene
_tsk
= taskMgr
.add(self
.on_frame
, 'on_frame')
70 def screenshot(self
, task
=None):
71 tex
= Texture('screenshot')
72 buffer = base
.win
.make_texture_buffer('screenshot', 512, 512, tex
, True )
73 cam
= base
.make_camera(buffer)
74 cam
.reparent_to(render
)
75 cam
.node().get_lens().set_fov(base
.camLens
.get_fov())
76 cam
.set_pos(0, -20, 0)
83 use_emission_maps
=False,
84 use_occlusion_maps
=True,
87 base
.graphicsEngine
.renderFrame()
88 base
.graphicsEngine
.renderFrame()
89 fname
= self
.__class
__.__name
__
90 if not exists('assets/images/scenes'):
91 makedirs('assets/images/scenes')
92 buffer.save_screenshot('assets/images/scenes/%s.png' % fname
)
94 # frameTexture=buffer.get_texture(), relief=FLAT,
95 # frameSize=(-.2, .2, -.2, .2))
96 return buffer.get_texture()
98 def current_bottom(self
):
100 for item
in self
.items
:
102 curr_bottom
= min(curr_bottom
, item
.get_bottom())
106 [itm
.destroy() for itm
in self
.items
]
110 self
._command
_idx
= 0
111 self
._start
_evt
_time
= None
112 if hasattr(self
, '_success_txt'):
113 self
._success
_txt
.destroy()
114 del self
._success
_txt
115 self
.__right
_btn
['state'] = NORMAL
117 def enforce_res(self
, val
):
118 self
._enforce
_res
= val
119 info('enforce res: ' + val
)
122 self
.ignore('enforce_res')
126 self
._unset
_mouse
_plane
()
127 [itm
.destroy() for itm
in self
.items
]
129 self
._side
_panel
.destroy()
130 self
._cursor
.destroy()
131 taskMgr
.remove(self
._scene
_tsk
)
132 if hasattr(self
, '_success_txt'):
133 self
._success
_txt
.destroy()
135 def _set_camera(self
):
136 base
.camera
.set_pos(0, -20, 0)
137 base
.camera
.look_at(0, 0, 0)
139 def __load_img_btn(self
, path
, col
):
140 img
= OnscreenImage('assets/images/buttons/%s.dds' % path
)
141 img
.set_transparency(True)
147 def load_images_btn(path
, col
):
150 (.6, .6, .6, 1), # ready
151 (1, 1, 1, 1), # press
152 (.8, .8, .8, 1), # rollover
158 (.4, .1, .1, .4)]}[col
]
159 return [self
.__load
_img
_btn
(path
, col
) for col
in colors
]
160 abl
, abr
= base
.a2dBottomLeft
, base
.a2dBottomRight
162 ('home', self
.on_home
, NORMAL
, abl
, 'gray'),
163 ('information', self
._set
_instructions
, NORMAL
, abl
, 'gray'),
164 ('right', self
.on_play
, NORMAL
, abr
, 'green'),
165 #('next', self.on_next, DISABLED, abr, 'gray'),
166 #('previous', self.on_prev, DISABLED, abr, 'gray'),
167 #('rewind', self.reset, NORMAL, abr, 'gray')
171 for binfo
in btn_info
:
172 imgs
= load_images_btn(binfo
[0], binfo
[4])
173 if binfo
[3] == base
.a2dBottomLeft
:
177 sign
, num
= -1, num_r
179 fcols
= (.4, .4, .4, .14), (.3, .3, .3, .05)
181 image
=imgs
, scale
=.05, pos
=(sign
* (.06 + .11 * num
), 1, .06),
182 parent
=binfo
[3], command
=binfo
[1], state
=binfo
[2], relief
=FLAT
,
183 frameColor
=fcols
[0] if binfo
[2] == NORMAL
else fcols
[1],
184 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
185 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
186 btn
.set_transparency(True)
187 self
._pos
_mgr
.register(binfo
[0], LibP3d
.wdg_pos(btn
))
189 self
.__home
_btn
, self
.__info
_btn
, self
.__right
_btn
= btns
190 # , self.__next_btn, self.__prev_btn, self.__rewind_btn
192 self
._info
_txt
= OnscreenText(
193 '', parent
=base
.a2dTopRight
, scale
=0.04,
194 pos
=(-.03, -.06), fg
=(.9, .9, .9, 1), align
=TextNode
.A_right
)
195 if self
._mouse
_coords
:
196 self
._coords
_txt
= OnscreenText(
197 '', parent
=base
.a2dTopRight
, scale
=0.04,
198 pos
=(-.03, -.12), fg
=(.9, .9, .9, 1), align
=TextNode
.A_right
)
199 def update_coords(task
):
201 for hit
in self
._get
_hits
():
202 if hit
.get_node() == self
._mouse
_plane
_node
:
203 pos
= hit
.get_hit_pos()
205 txt
= '%s %s' % (round(pos
.x
, 3),
207 self
._coords
_txt
['text'] = txt
209 self
._coords
_tsk
= taskMgr
.add(update_coords
, 'update_coords')
211 def _unset_gui(self
):
213 self
.__home
_btn
, self
.__info
_btn
, self
.__right
_btn
,
214 #self.__next_btn, self.__prev_btn, self.__rewind_btn
216 [btn
.destroy() for btn
in btns
]
218 self
._info
_txt
.destroy()
219 if self
._mouse
_coords
:
220 taskMgr
.remove(self
._coords
_tsk
)
221 self
._coords
_txt
.destroy()
223 def _set_spotlight(self
, name
, pos
, look_at
, color
, shadows
=False):
224 light
= Spotlight(name
)
226 light
.setLens(PerspectiveLens())
227 light_np
= render
.attach_new_node(light
)
228 light_np
.set_pos(pos
)
229 light_np
.look_at(look_at
)
230 light
.set_color(color
)
231 render
.set_light(light_np
)
234 def _set_lights(self
):
235 alight
= AmbientLight('alight') # for ao
236 alight
.set_color((.15, .15, .15, 1))
237 self
._alnp
= render
.attach_new_node(alight
)
238 render
.set_light(self
._alnp
)
239 self
._key
_light
= self
._set
_spotlight
(
240 'key light', (-5, -80, 5), (0, 0, 0), (2.8, 2.8, 2.8, 1))
241 self
._shadow
_light
= self
._set
_spotlight
(
242 'key light', (-5, -80, 5), (0, 0, 0), (.58, .58, .58, 1), True)
243 self
._shadow
_light
.node().set_shadow_caster(True, 2048, 2048)
244 self
._shadow
_light
.node().get_lens().set_film_size(2048, 2048)
245 self
._shadow
_light
.node().get_lens().set_near_far(1, 256)
246 self
._shadow
_light
.node().set_camera_mask(BitMask32(0x01))
248 def _unset_lights(self
):
249 for light
in [self
._alnp
, self
._key
_light
, self
._shadow
_light
]:
250 render
.clear_light(light
)
253 def _set_input(self
):
254 self
.accept('mouse1', self
.on_click_l
)
255 self
.accept('mouse1-up', self
.on_release
)
256 self
.accept('mouse3', self
.on_click_r
)
257 self
.accept('mouse3-up', self
.on_release
)
259 def _unset_input(self
):
260 for evt
in ['mouse1', 'mouse1-up', 'mouse3', 'mouse3-up']:
263 def _set_mouse_plane(self
):
264 shape
= BulletPlaneShape((0, -1, 0), 0)
265 #self._mouse_plane_node = BulletRigidBodyNode('mouse plane')
266 self
._mouse
_plane
_node
= BulletGhostNode('mouse plane')
267 self
._mouse
_plane
_node
.addShape(shape
)
268 #np = render.attachNewNode(self._mouse_plane_node)
269 #self._world.attachRigidBody(self._mouse_plane_node)
270 self
._world
.attach_ghost(self
._mouse
_plane
_node
)
272 def _unset_mouse_plane(self
):
273 self
._world
.remove_ghost(self
._mouse
_plane
_node
)
276 if not base
.mouseWatcherNode
.has_mouse(): return []
277 p_from
, p_to
= P3dGfxMgr
.world_from_to(base
.mouseWatcherNode
.get_mouse())
278 return self
._world
.ray_test_all(p_from
, p_to
).get_hits()
280 def _update_info(self
, item
):
283 txt
= '%.3f %.3f\n%.3f°' % (
284 item
._np
.get_x(), item
._np
.get_z(), item
._np
.get_r())
285 self
._info
_txt
['text'] = txt
287 def _on_click(self
, method
):
290 for hit
in self
._get
_hits
():
291 if hit
.get_node() == self
._mouse
_plane
_node
:
292 pos
= hit
.get_hit_pos()
293 for hit
in self
._get
_hits
():
294 for item
in [i
for i
in self
.items
if hit
.get_node() == i
.node
and i
.interactable
]:
295 if not self
._item
_active
:
296 self
._item
_active
= item
297 getattr(item
, method
)(pos
)
298 img
= 'move' if method
== 'on_click_l' else 'rotate'
299 if not (img
== 'rotate' and not item
._instantiated
):
300 self
._cursor
.set_image('assets/images/buttons/%s.dds' % img
)
302 def on_click_l(self
):
303 self
._on
_click
('on_click_l')
305 def on_click_r(self
):
306 self
._on
_click
('on_click_r')
308 def on_release(self
):
309 if self
._item
_active
and not self
._item
_active
._first
_command
:
310 self
._commands
= self
._commands
[:self
._command
_idx
]
311 self
._commands
+= [self
._item
_active
]
312 self
._command
_idx
+= 1
313 #self.__prev_btn['state'] = NORMAL
314 #fcols = (.4, .4, .4, .14), (.3, .3, .3, .05)
315 #self.__prev_btn['frameColor'] = fcols[0]
316 #if self._item_active._command_idx == len(self._item_active._commands) - 1:
317 # self.__next_btn['state'] = DISABLED
318 # self.__next_btn['frameColor'] = fcols[1]
319 self
._item
_active
= None
320 [item
.on_release() for item
in self
.items
]
321 self
._cursor
.set_image('assets/images/buttons/arrowUpLeft.dds')
324 for item
in self
.items
:
325 item
.repos_done
= False
326 self
.items
= sorted(self
.items
, key
=lambda itm
: itm
.__class
__.__name
__)
327 [item
.on_aspect_ratio_changed() for item
in self
.items
]
328 self
._side
_panel
.update(self
.items
)
329 max_x
= -float('inf')
330 for item
in self
.items
:
331 if not item
._instantiated
:
332 max_x
= max(item
._np
.get_x(), max_x
)
333 for item
in self
.items
:
334 if not item
._instantiated
:
337 def on_aspect_ratio_changed(self
):
340 def _win_condition(self
):
343 def _fail_condition(self
):
344 return all(itm
.fail_condition() for itm
in self
.items
) and not self
._paused
and self
._state
== 'playing'
346 def on_frame(self
, task
):
347 hits
= self
._get
_hits
()
349 for hit
in self
._get
_hits
():
350 if hit
.get_node() == self
._mouse
_plane
_node
:
351 pos
= hit
.get_hit_pos()
352 hit_nodes
= [hit
.get_node() for hit
in hits
]
353 if self
._item
_active
:
354 items_hit
= [self
._item
_active
]
356 items_hit
= [itm
for itm
in self
.items
if itm
.node
in hit_nodes
]
357 items_no_hit
= [itm
for itm
in self
.items
if itm
not in items_hit
]
358 [itm
.on_mouse_on() for itm
in items_hit
]
359 [itm
.on_mouse_off() for itm
in items_no_hit
]
360 if pos
and self
._item
_active
:
361 self
._item
_active
.on_mouse_move(pos
)
363 self
._update
_info
(items_hit
[0] if items_hit
else None)
364 if self
._win
_condition
():
365 self
._start
_evt
_time
= None
366 self
._set
_fail
() if self
._enforce
_res
== 'fail' else self
._set
_win
()
367 elif self
._state
== 'playing' and self
._fail
_condition
():
368 self
._start
_evt
_time
= None
369 self
._set
_win
() if self
._enforce
_res
== 'win' else self
._set
_fail
()
370 elif self
._testing
and self
._start
_evt
_time
and globalClock
.getFrameTime() - self
._start
_evt
_time
> 5.0:
371 self
._start
_evt
_time
= None
372 self
._set
_win
() if self
._enforce
_res
== 'win' else self
._set
_fail
()
373 if any(itm
._overlapping
for itm
in self
.items
):
374 self
._cursor
.cursor_img
.img
.set_color(.9, .1, .1, 1)
376 self
._cursor
.cursor_img
.img
.set_color(.9, .9, .9, 1)
379 def cb_inst(self
, item
):
383 self
._state
= 'playing'
384 #self.__prev_btn['state'] = DISABLED
385 #self.__next_btn['state'] = DISABLED
386 self
.__right
_btn
['state'] = DISABLED
387 [itm
.play() for itm
in self
.items
]
388 self
._start
_evt
_time
= globalClock
.getFrameTime()
391 self
._commands
[self
._command
_idx
].redo()
392 self
._command
_idx
+= 1
393 fcols
= (.4, .4, .4, .14), (.3, .3, .3, .05)
394 #self.__prev_btn['state'] = NORMAL
395 #self.__prev_btn['frameColor'] = fcols[0]
396 more_commands
= self
._command
_idx
< len(self
._commands
)
397 #self.__next_btn['state'] = NORMAL if more_commands else DISABLED
398 #self.__next_btn['frameColor'] = fcols[0] if more_commands else fcols[1]
401 self
._command
_idx
-= 1
402 self
._commands
[self
._command
_idx
].undo()
403 fcols
= (.4, .4, .4, .14), (.3, .3, .3, .05)
404 #self.__next_btn['state'] = NORMAL
405 #self.__next_btn['frameColor'] = fcols[0]
406 #self.__prev_btn['state'] = NORMAL if self._command_idx else DISABLED
407 #self.__prev_btn['frameColor'] = fcols[0] if self._command_idx else fcols[1]
412 def _set_instructions(self
):
415 mgr
= TextPropertiesManager
.get_global_ptr()
416 for name
in ['mouse_l', 'mouse_r']:
417 graphic
= OnscreenImage('assets/images/buttons/%s.dds' % name
)
418 graphic
.set_scale(.5)
419 graphic
.get_texture().set_minfilter(Texture
.FTLinearMipmapLinear
)
420 graphic
.get_texture().set_anisotropic_degree(2)
421 mgr
.set_graphic(name
, graphic
)
423 graphic
.set_transparency(True)
424 graphic
.detach_node()
425 frm
= DirectFrame(frameColor
=(.4, .4, .4, .06),
426 frameSize
=(-.6, .6, -.3, .3))
427 font
= base
.loader
.load_font('assets/fonts/Hanken-Book.ttf')
429 font
.set_pixels_per_unit(60)
430 font
.set_minfilter(Texture
.FTLinearMipmapLinear
)
431 font
.set_outline((0, 0, 0, 1), .8, .2)
432 self
._txt
= OnscreenText(
433 self
._instr
_txt
(), parent
=frm
, font
=font
, scale
=0.06,
434 fg
=(.9, .9, .9, 1), align
=TextNode
.A_left
)
435 u_l
= self
._txt
.textNode
.get_upper_left_3d()
436 l_r
= self
._txt
.textNode
.get_lower_right_3d()
437 w
, h
= l_r
[0] - u_l
[0], u_l
[2] - l_r
[2]
440 z
= h
/ 2 - font
.get_line_height() * self
._txt
['scale'][1]
441 z
+= (btn_scale
+ 2 * mar
) / 2
442 self
._txt
['pos'] = -w
/ 2, z
443 u_l
= self
._txt
.textNode
.get_upper_left_3d()
444 l_r
= self
._txt
.textNode
.get_lower_right_3d()
445 c_l_r
= l_r
[0], l_r
[1], l_r
[2] - 2 * mar
- btn_scale
446 fsz
= u_l
[0] - mar
, l_r
[0] + mar
, c_l_r
[2] - mar
, u_l
[2] + mar
447 frm
['frameSize'] = fsz
449 (.6, .6, .6, 1), # ready
450 (1, 1, 1, 1), # press
451 (.8, .8, .8, 1), # rollover
453 imgs
= [self
.__load
_img
_btn
('exitRight', col
) for col
in colors
]
455 image
=imgs
, scale
=btn_scale
,
456 pos
=(l_r
[0] - btn_scale
, 1, l_r
[2] - mar
- btn_scale
),
457 parent
=frm
, command
=self
.__on
_close
_instructions
, extraArgs
=[frm
],
458 relief
=FLAT
, frameColor
=(.6, .6, .6, .08),
459 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
460 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
461 btn
.set_transparency(True)
462 self
._pos
_mgr
.register('close_instructions', LibP3d
.wdg_pos(btn
))
465 loader
.load_sfx('assets/audio/sfx/success.ogg').play()
468 frm
= DirectFrame(frameColor
=(.4, .4, .4, .06),
469 frameSize
=(-.6, .6, -.3, .3))
470 font
= base
.loader
.load_font('assets/fonts/Hanken-Book.ttf')
472 font
.set_pixels_per_unit(60)
473 font
.set_minfilter(Texture
.FTLinearMipmapLinear
)
474 font
.set_outline((0, 0, 0, 1), .8, .2)
475 self
._txt
= OnscreenText(
478 font
=font
, scale
=0.2,
480 u_l
= self
._txt
.textNode
.get_upper_left_3d()
481 l_r
= self
._txt
.textNode
.get_lower_right_3d()
482 w
, h
= l_r
[0] - u_l
[0], u_l
[2] - l_r
[2]
485 z
= h
/ 2 - font
.get_line_height() * self
._txt
['scale'][1]
486 z
+= (btn_scale
+ 2 * mar
) / 2
487 self
._txt
['pos'] = 0, z
488 u_l
= self
._txt
.textNode
.get_upper_left_3d()
489 l_r
= self
._txt
.textNode
.get_lower_right_3d()
490 c_l_r
= l_r
[0], l_r
[1], l_r
[2] - 2 * mar
- btn_scale
491 fsz
= u_l
[0] - mar
, l_r
[0] + mar
, c_l_r
[2] - mar
, u_l
[2] + mar
492 frm
['frameSize'] = fsz
494 (.6, .6, .6, 1), # ready
495 (1, 1, 1, 1), # press
496 (.8, .8, .8, 1), # rollover
498 imgs
= [self
.__load
_img
_btn
('home', col
) for col
in colors
]
500 image
=imgs
, scale
=btn_scale
,
501 pos
=(-2.8 * btn_scale
, 1, l_r
[2] - mar
- btn_scale
),
502 parent
=frm
, command
=self
._on
_end
_home
, extraArgs
=[frm
],
503 relief
=FLAT
, frameColor
=(.6, .6, .6, .08),
504 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
505 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
506 btn
.set_transparency(True)
507 self
._pos
_mgr
.register('home_win', LibP3d
.wdg_pos(btn
))
508 imgs
= [self
.__load
_img
_btn
('rewind', col
) for col
in colors
]
510 image
=imgs
, scale
=btn_scale
,
511 pos
=(0, 1, l_r
[2] - mar
- btn_scale
),
512 parent
=frm
, command
=self
._on
_restart
, extraArgs
=[frm
],
513 relief
=FLAT
, frameColor
=(.6, .6, .6, .08),
514 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
515 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
516 self
._pos
_mgr
.register('replay', LibP3d
.wdg_pos(btn
))
517 btn
.set_transparency(True)
518 enabled
= self
._scenes
.index(self
.__class
__) < len(self
._scenes
) - 1
520 next_scene
= self
._scenes
[self
._scenes
.index(self
.__class
__) + 1]
523 imgs
= [self
.__load
_img
_btn
('right', col
) for col
in colors
]
525 image
=imgs
, scale
=btn_scale
,
526 pos
=(2.8 * btn_scale
, 1, l_r
[2] - mar
- btn_scale
),
527 parent
=frm
, command
=self
._on
_next
_scene
,
528 extraArgs
=[frm
, next_scene
], relief
=FLAT
,
529 frameColor
=(.6, .6, .6, .08),
530 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
531 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
532 btn
['state'] = NORMAL
if enabled
else DISABLED
533 self
._pos
_mgr
.register('next', LibP3d
.wdg_pos(btn
))
534 btn
.set_transparency(True)
537 loader
.load_sfx('assets/audio/sfx/success.ogg').play()
540 frm
= DirectFrame(frameColor
=(.4, .4, .4, .06),
541 frameSize
=(-.6, .6, -.3, .3))
542 font
= base
.loader
.load_font('assets/fonts/Hanken-Book.ttf')
544 font
.set_pixels_per_unit(60)
545 font
.set_minfilter(Texture
.FTLinearMipmapLinear
)
546 font
.set_outline((0, 0, 0, 1), .8, .2)
547 self
._txt
= OnscreenText(
548 _('You have failed!'),
550 font
=font
, scale
=0.2,
552 u_l
= self
._txt
.textNode
.get_upper_left_3d()
553 l_r
= self
._txt
.textNode
.get_lower_right_3d()
554 w
, h
= l_r
[0] - u_l
[0], u_l
[2] - l_r
[2]
557 z
= h
/ 2 - font
.get_line_height() * self
._txt
['scale'][1]
558 z
+= (btn_scale
+ 2 * mar
) / 2
559 self
._txt
['pos'] = 0, z
560 u_l
= self
._txt
.textNode
.get_upper_left_3d()
561 l_r
= self
._txt
.textNode
.get_lower_right_3d()
562 c_l_r
= l_r
[0], l_r
[1], l_r
[2] - 2 * mar
- btn_scale
563 fsz
= u_l
[0] - mar
, l_r
[0] + mar
, c_l_r
[2] - mar
, u_l
[2] + mar
564 frm
['frameSize'] = fsz
566 (.6, .6, .6, 1), # ready
567 (1, 1, 1, 1), # press
568 (.8, .8, .8, 1), # rollover
570 imgs
= [self
.__load
_img
_btn
('home', col
) for col
in colors
]
572 image
=imgs
, scale
=btn_scale
,
573 pos
=(-2.8 * btn_scale
, 1, l_r
[2] - mar
- btn_scale
),
574 parent
=frm
, command
=self
._on
_end
_home
, extraArgs
=[frm
],
575 relief
=FLAT
, frameColor
=(.6, .6, .6, .08),
576 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
577 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
578 self
._pos
_mgr
.register('home_win', LibP3d
.wdg_pos(btn
))
579 btn
.set_transparency(True)
580 imgs
= [self
.__load
_img
_btn
('rewind', col
) for col
in colors
]
582 image
=imgs
, scale
=btn_scale
,
583 pos
=(0, 1, l_r
[2] - mar
- btn_scale
),
584 parent
=frm
, command
=self
._on
_restart
, extraArgs
=[frm
],
585 relief
=FLAT
, frameColor
=(.6, .6, .6, .08),
586 rolloverSound
=loader
.load_sfx('assets/audio/sfx/rollover.ogg'),
587 clickSound
=loader
.load_sfx('assets/audio/sfx/click.ogg'))
588 self
._pos
_mgr
.register('replay', LibP3d
.wdg_pos(btn
))
589 btn
.set_transparency(True)
591 def _on_restart(self
, frm
):
592 self
.__on
_close
_instructions
(frm
)
595 def _on_end_home(self
, frm
):
596 self
.__on
_close
_instructions
(frm
)
599 def _on_next_scene(self
, frm
, scene
):
600 self
.__on
_close
_instructions
(frm
)
601 self
._reload
_cb
(scene
)
603 def __store_state(self
):
605 self
.__home
_btn
, self
.__info
_btn
, self
.__right
_btn
,
606 #self.__next_btn, self.__prev_btn, self.__rewind_btn
608 self
.__btn
_state
= [btn
['state'] for btn
in btns
]
610 btn
['state'] = DISABLED
611 [itm
.store_state() for itm
in self
.items
]
613 def __restore_state(self
):
615 self
.__home
_btn
, self
.__info
_btn
, self
.__right
_btn
,
616 #self.__next_btn, self.__prev_btn, self.__rewind_btn
618 for btn
, state
in zip(btns
, self
.__btn
_state
):
620 [itm
.restore_state() for itm
in self
.items
]
623 def __on_close_instructions(self
, frm
):
625 self
.__restore
_state
()