ya2 · news · projects · code · about

new scene
authorFlavio Calva <f.calva@gmail.com>
Sat, 5 Nov 2022 07:48:23 +0000 (09:48 +0200)
committerFlavio Calva <f.calva@gmail.com>
Fri, 11 Nov 2022 16:12:54 +0000 (17:12 +0100)
assets/images/buttons/plus.png [new file with mode: 0644]
pmachines/app.py
pmachines/editor/scene.py
pmachines/items/item.py
pmachines/scene.py
prj.org

diff --git a/assets/images/buttons/plus.png b/assets/images/buttons/plus.png
new file mode 100644 (file)
index 0000000..3f5cf37
Binary files /dev/null and b/assets/images/buttons/plus.png differ
index 2d8098847496218d48dc2e34eef42743dc4dadc0..095c151d1c40a8512c0762681791ac821716dbfc 100755 (executable)
@@ -33,6 +33,7 @@ class MainFsm(FSM):
     def __init__(self, pmachines):
         super().__init__('Main FSM')
         self._pmachines = pmachines
+        self.accept('new_scene', self.__on_new_scene)
 
     def enterMenu(self):
         self._pmachines.on_menu_enter()
@@ -48,6 +49,9 @@ class MainFsm(FSM):
         self._pmachines.on_scene_exit()
         self.__do_asserts()
 
+    def __on_new_scene(self):
+        self.demand('Scene', None)
+
     def __do_asserts(self):
         args = self._pmachines._args
         if not LibP3d.runtime() or args.functional_test or args.functional_ref:
index 7569113b1b30e3b0a8ae9be81e36849bfe7dee8e..e0a6a67c28ebf4bb6f326858770345c601927978 100644 (file)
@@ -24,7 +24,16 @@ class SceneEditor(DirectObject):
         super().__init__()
         self.__items = items
         self.__json = json
-        self.__json_name = json_name
+        if not json_name:
+            self.__json = json = {
+                'name': '',
+                'instructions': '',
+                'version': '',
+                'items': [],
+                'start_items': [],
+                'test_items': {
+                    'pixel_space': [],
+                    'world_space': []}}
         self.__inspector = None
         self.__context = context
         self.__add_item = add_item
@@ -44,28 +53,43 @@ class SceneEditor(DirectObject):
                 'assets/audio/sfx/rollover.ogg'),
             'clickSound': loader.load_sfx(
                 'assets/audio/sfx/click.ogg')}
-        w, h, tw, l = 1.8, .9, 30, .36
+        w, h, tw, l = 1.8, 1, 30, .36
         self._frm = DirectFrame(frameColor=(.4, .4, .4, .06),
                                 frameSize=(0, w, 0, h),
                                 parent=base.a2dBottomCenter,
                                 pos=(-w/2, 0, 0))
         OnscreenText(
-            _('Name'), pos=(l - .03, h - .1), parent=self._frm,
+            _('Filename'), pos=(l - .03, h - .1), parent=self._frm,
             font=self._common['text_font'],
             scale=self._common['scale'],
             fg=self._common['text_fg'],
             align=TextNode.A_right)
-        self.__name_entry = DirectEntry(
+        self.__filenamename_entry = DirectEntry(
             scale=self._common['scale'],
             pos=(l, 1, h - .1),
             entryFont=self._font,
             width=tw,
             frameColor=self._common['frameColor'],
+            initialText=json_name,
+            parent=self._frm,
+            text_fg=self._common['text_fg'])
+        OnscreenText(
+            _('Name'), pos=(l - .03, h - .2), parent=self._frm,
+            font=self._common['text_font'],
+            scale=self._common['scale'],
+            fg=self._common['text_fg'],
+            align=TextNode.A_right)
+        self.__name_entry = DirectEntry(
+            scale=self._common['scale'],
+            pos=(l, 1, h - .2),
+            entryFont=self._font,
+            width=tw,
+            frameColor=self._common['frameColor'],
             initialText=json['name'],
             parent=self._frm,
             text_fg=self._common['text_fg'])
         OnscreenText(
-            _('Description'), pos=(l - .03, h - .2), parent=self._frm,
+            _('Description'), pos=(l - .03, h - .3), parent=self._frm,
             font=self._common['text_font'],
             scale=self._common['scale'],
             fg=self._common['text_fg'],
@@ -77,7 +101,7 @@ class SceneEditor(DirectObject):
             entry['focus']=1
         self.__instructions_entry = DirectEntry(
             scale=self._common['scale'],
-            pos=(l, 1, h - .2),
+            pos=(l, 1, h - .3),
             entryFont=self._font,
             width=tw,
             numLines=12,
@@ -151,6 +175,13 @@ class SceneEditor(DirectObject):
             item_text_font=self._font, item_text_fg=(.9, .9, .9, 1),
             rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'),
             clickSound=loader.load_sfx('assets/audio/sfx/click.ogg'))
+        DirectButton(
+            image=load_images_btn('plus', 'gray'), scale=.05,
+            pos=(.06, 1, .58),
+            parent=self._frm, command=self.__on_new_scene, state=NORMAL, relief=FLAT,
+            frameColor=fcols[0],
+            rolloverSound=loader.load_sfx('assets/audio/sfx/rollover.ogg'),
+            clickSound=loader.load_sfx('assets/audio/sfx/click.ogg'))
         messenger.send('editor-start')
         self.accept('editor-item-click', self.__on_item_click)
         self.accept('editor-inspector-destroy', self.__on_inspector_destroy)
@@ -195,7 +226,7 @@ class SceneEditor(DirectObject):
 
     def __actually_close(self, arg):
         if arg:
-            self._frm.destroy()
+            self.destroy()
             messenger.send('editor-stop')
         self.__dialog.cleanup()
 
@@ -203,7 +234,8 @@ class SceneEditor(DirectObject):
         self.__json['name'] = self.__name_entry.get()
         self.__json['instructions'] = self.__instructions_entry.get()
         self.__json['version'] = self.__compute_hash()
-        with open('assets/scenes/%s.json' % self.__json_name, 'w') as f:
+        json_name = self.__filenamename_entry.get()
+        with open('assets/scenes/%s.json' % json_name, 'w') as f:
             f.write(dumps(self.__json, indent=2, sort_keys=True))
 
     def __on_scene_list(self):
@@ -232,3 +264,15 @@ class SceneEditor(DirectObject):
 
     def __on_inspector_destroy(self):
         self.__inspector = None
+
+    def __on_new_scene(self):
+        self.destroy()
+        messenger.send('editor-stop')
+        messenger.send('new_scene')
+
+    def destroy(self):
+        self._frm.destroy()
+        if self.__inspector:
+            self.__inspector.destroy()
+        self.ignore('editor-item-click')
+        self.ignore('editor-inspector-destroy')
index 3519801a410dde290d1a0b0d27c5510559af1684..d2b3bbd7c1f9bb35860cf054070bf7ad0541b453 100644 (file)
@@ -439,3 +439,5 @@ class Item(DirectObject):
             self._world.remove_ghost(self.node)
         else:
             self._world.remove_rigid_body(self.node)
+        self.ignore('editor-start')
+        self.ignore('editor-stop')
index 612ddde590bef390ba682db700cfca1835faa281..740a688fee5e3438faeb9ee2358363ea051bbd94 100644 (file)
@@ -89,6 +89,7 @@ class Scene(DirectObject):
 
     @classmethod
     def version(cls, scene_name):
+        if not scene_name: return ''
         if not scene_name in cls.json_files:
             with open(cls.filename(scene_name)) as f:
                 cls.json_files[scene_name] = loads(f.read())
@@ -109,6 +110,7 @@ class Scene(DirectObject):
         return bytes(string, 'utf-8').decode('unicode-escape')
 
     def _set_items(self):
+        if not self.__json_name: return
         self.items = []
         self._test_items = []
         if not self.json:
@@ -243,6 +245,7 @@ class Scene(DirectObject):
         taskMgr.remove(self._scene_tsk)
         if hasattr(self, '_success_txt'):
             self._success_txt.destroy()
+        self.ignore('editor-inspector-delete')
 
     def _set_camera(self):
         base.camera.set_pos(0, -20, 0)
@@ -497,7 +500,7 @@ class Scene(DirectObject):
             self._item_active.on_mouse_move(pos)
         if self._dbg_items:
             self._update_info(items_hit[0] if items_hit else None)
-        if self._win_condition():
+        if not self.__scene_editor and self._win_condition():
             self._start_evt_time = None
             self._set_fail() if self._enforce_res == 'fail' else self._set_win()
         elif self._state == 'playing' and self._fail_condition():
@@ -653,11 +656,15 @@ class Scene(DirectObject):
             clickSound=loader.load_sfx('assets/audio/sfx/click.ogg'))
         self._pos_mgr.register('replay', LibP3d.wdg_pos(btn))
         btn.set_transparency(True)
-        enabled = self._scenes.index(self.__json_name) < len(self._scenes) - 1
-        if enabled:
-            next_scene = self._scenes[self._scenes.index(self.__json_name) + 1]
+        if self.__json_name:
+            enabled = self._scenes.index(self.__json_name) < len(self._scenes) - 1
+            if enabled:
+                next_scene = self._scenes[self._scenes.index(self.__json_name) + 1]
+            else:
+                next_scene = None
         else:
             next_scene = None
+            enabled = False
         imgs = [self.__load_img_btn('right', col) for col in colors]
         btn = DirectButton(
             image=imgs, scale=btn_scale,
@@ -771,6 +778,7 @@ class Scene(DirectObject):
         taskMgr.doMethodLater(1.4, frame_after, 'frame after')  # after the intro sequence
 
     def _define_test_items(self):
+        if not self.__json_name: return
         if not self.__json_name in self.__class__.json_files:
             with open(self.__class__.filename(self.__json_name)) as f:
                 self.__class__.json_files[self.__json_name] = loads(f.read())
diff --git a/prj.org b/prj.org
index d2734f55c4d81c636172c6113cd1fbeb214b1388..fece1dbb85137278f55ade250b614df7a5af0193 100644 (file)
--- a/prj.org
+++ b/prj.org
@@ -28,7 +28,7 @@
   - [X] id
   - [X] strategy and strategy_args
   - [X] pop up if errors with arguments in strategy_args
-- [ ] new scene
+- [X] new scene
 - [ ] start items
 - [ ] editing of test_items in the editor for functional tests
 - [ ] define functional tests