1. schlangen
  2. gallox

Commits

schlangen  committed 64088f1

- added "params" tab to SpriteEditor and Sprite.parameters

  • Participants
  • Parent commits 146ec09
  • Branches default

Comments (0)

Files changed (4)

File gallox/editor/editor.py

View file
  • Ignore whitespace
         tree = ET.parse(os.path.join(path, "level.xml"))
         root = tree.getroot()
         general = root.find("about")
-#        imgs = root.find("images")
         sprites = root.find("sprites")
         size = root.find("size")
         if general:

File gallox/editor/widgets.py

View file
  • Ignore whitespace
     
     def dummy_callback(self, **kw):
         print "no callback defined for <IconButton '%s'>" % self.name
+        
+#! add to gui.widgets?
+
+class ToggleText(gui.Text):
+    highlight = True
+    def __init__(self, parent, size, pos, texts, align="left", **kwargs):
+        gui.Text.__init__(self, parent, size, pos, texts[0], align=align, **kwargs)
+        self.texts = texts
+        self.index = 0
+        
+    def handle_mouse_down(self, button, **kw):
+        ind = self.index
+        if button == 1:
+            self.index += 1
+        elif button == 3:
+            self.index += len(self.texts) - 1
+        self.index %= len(self.texts)
+        if ind != self.index:
+            self._send_event("toggled", index=self.index, 
+                             text=self.texts[self.index])
+        self.text = self.texts[self.index]
+        
+    def toggle(self):
+        self.handle_mouse_down(1)
 
 class PanelSwitch(gui.Layer):
     style_class_name = "panelswitch"
     def deactivate(self):
         self.active = False
         self.panel.hide()
-#        print "deactivated"
         
     def get_suffix(self, style_name):
         suff = gui.Layer.get_suffix(self, style_name)
         self.widgets = []
         self.switches = {}
         pos = [0, 0]
-#        print "--"
         for panel in self.panels:
-#            print "new ps", panel.name, "at", pos
             p = PanelSwitch(self, self.tabsize, pos, panel,
                             style=self.style)
             p.listen("mouse_down", self.handle_ps_clicked)
     
 MAX_FILENAME_LENGTH = 18
     
+#! make more generic and add to gui.widgets
+
 class FileBrowser(gui.Window):
     style_class_name = "window"
     image_exts = [".png", ".gif", ".jpg", ".jpeg", ".bmp", ".tiff"]
     def handle_callback(self, widget, **kw):
         if self.filter == "level":
             path = os.path.join(self.path, widget.full_text, "level.xml")
-#        elif self.filter == "dir":
-#            path = os.path.join(self.path, widget.full_text)
         elif self.filter == "image":
             path = os.path.join(self.path, widget.full_text)
         self.delete()
         if self.init:
             self.build_dir_info()
     
+BOOL = 1
+INT = 2
+FLOAT = 3
+
+CONVERT_FUNCTIONS = [None, bool, int, float]
+    
 DEFAULT_ATTRS = {"fix_no":False, "turnable":False, "resizable":False}
 SPRITES = {
         "plattform":{"resizable":True},
         "gun":{"turnable":True},
         "ship":{"fix_no":True, "turnable":True},
            }
+SPRITE_PARAMS = {
+        "plattform":[
+               { "name": "refuel",
+                 "repr_name": "refuel",
+                 "type": BOOL,
+                 "default": True,
+                 "args": {}
+                },
+                    ],
+        "gun":[
+               {"name": "actionScope",
+                "repr_name": "action scope",
+                "type": INT,
+                "default":60,
+                "args": {"max_val":361,
+                         "min_val":0}
+                },
+                {"name": "autoAim",
+                 "repr_name": "auto aim",
+                 "type": BOOL,
+                 "default": False,
+                 "args": {}
+                },
+                {"name":"rotSpeed",
+                "repr_name":"rotary speed [deg/s]",
+                "type":FLOAT,
+                "default": 4,
+                "args":{"max_val":100,
+                        "min_val":0}
+                },
+                {"name":"shotFreq",
+                "repr_name":"shot frequency [px/s]",
+                "type":FLOAT,
+                "default": -5,
+                "args":{"max_val":100,
+                        "min_val":1}
+                },
+               ],
+        "ship":[],
+           }
 HIGHLIGHT_COLOR = (255,0, 200)
                                              
 class Sprite(gui.Widget):
         self.name = name
         #self.can_turn = SPRITES[name].get("can_turn", False)
         self.degrees = degrees
+        # what a sprite of this type can do 
         self.attributes = dict(DEFAULT_ATTRS)
         self.attributes.update(SPRITES[name])
         
+        # individual parameters for this single sprite object
+        # first, get names and default values
+        self.parameters = dict([(d["name"], d["default"]) 
+                                for d in SPRITE_PARAMS[self.name]])
+        
+            
+        
         if self._is("fix_no"):
             if self.name in self.counters:
                 raise ValueError, "number of %s sprites limited to 1" % self.name
                 self.counters[self.name] += 1
                 count = self.counters[self.name]
             self.repr = u"%s %i" % (name, count)
-#        print "created", self
         
         self._id2obj_dict[self.repr] = self        
         
         gui.Widget.__init__(self, parent, size, pos, **kwargs)
         
         
-        
-        
     def __str__(self):
         return "%s" % str(self.repr)
     
     
     @classmethod
     def get(cls, name):
-#        print cls._id2obj_dict.items()
         try:
             return cls._id2obj_dict[str(name)]
         except KeyError:
         rotate the sprite by scrolling (if allowed)
         """
         if self._is("turnable"):
-#            print "turn"
             if button == 4:
                 self.degrees += 10
             elif button == 5:
             
     def blit_widget(self, styles):
         if "image" in styles and styles["image"]:
-            #image = pygame.transform.rotate(styles["image"], self.degrees)
             image = pygame.transform.rotozoom(styles["image"], self.degrees, 1)
-#            self.resize(image.get_size(), anchor="center")
             rect = self.image.get_rect()
             image_rect = image.get_rect(center=rect.center)
             self.image.blit(image, image_rect)
     style_class_name = "map"
     def __init__(self, parent, size=None, pos=(0,0), **kw):
         gui.ScrolledLayer.__init__(self, parent, size, pos=pos, **kw)
-#        self.scroll_size = self.size
         self.init = False
         self.scrollbars_x = [gui.Scrollbar(self, ("100%", 15), (0, 0), orient="x", 
                       anchor="topleft", style={"borderwidth": (15, 4)}),
                       anchor="topleft", style={"borderwidth": (4, 15)}),
                       gui.Scrollbar(self, (15, "100%"), ("100%", 0), orient="y", 
                       anchor="topright", style={"borderwidth": (4, 15)})]
-#        self.line_rect = None
         self.auto_dragging = False
         self.init = True
        
         styles["highlight_item"] = self.highlight_item
         return styles
 
+
+class SpriteParamEditor(gui.Layer):
+    def __init__(self, parent, size, pos, **kwargs):
+        gui.Layer.__init__(self, parent, size, pos, **kwargs)
+        self._sprite = None
+    
+    def get_sprite(self):
+        return self._sprite
+        
+    def set_sprite(self, sprite):
+        self._sprite = sprite
+        self.rebuild()
+        
+    sprite = property(get_sprite, set_sprite)
+    
+    def rebuild(self):
+        """
+        build interface
+        """
+        # remove old stuff
+        self.widgets = []
+        self.dirty = True
+        # if not sprite is selected, there is nothing to show
+        if self.sprite is None:
+            return
+        y = 0
+        for param in SPRITE_PARAMS[self.sprite.name]:
+            if param["type"] == BOOL:
+                texts = ["no", "yes"]
+                # value = no/0/False
+                widget = ToggleText(self, "auto", (0, y), texts, 
+                                    template="%s: %%s" % param["repr_name"])
+                # toggle if value is yes/1/True
+                if self.sprite.parameters[param["name"]]:
+                    widget.toggle()
+                widget.listen("toggled", self.handle_toggled)
+                
+            elif param["type"] in [INT, FLOAT]:
+                if param["type"] == INT:
+                    cf = int
+                else:
+                    cf = float
+                widget = gui.NumberInput(self, "auto", (0,y), 
+                               text=str(self.sprite.parameters[param["name"]]),
+                               template="%s: %%s" % param["repr_name"], 
+                               align="left", convert_func=cf, **param["args"])
+                widget.listen("number_changed", self.handle_new_num_val)
+                self.sprite.parameters[param["name"]] = widget.get_number()
+            else:
+                continue
+            widget.param_name = param["name"]
+            y += widget.size[1]
+        
+        
+    #! maybe update sprite and add some visual hint for new param?
+    
+    def handle_new_num_val(self, widget, new, **kw):
+        self.sprite.parameters[widget.param_name] = new
+        
+    def handle_toggled(self, widget, index, **kw):
+        self.sprite.parameters[widget.param_name] = bool(index)
+        
+        
+        
+        
+        
     
 class SpriteEditor(gui.Layer):
     def __init__(self, parent, size, pos, **kwargs):
                                 events=[("post_mouse_down", self.handle_sprite_select)],
                                 item_kwargs={"highlight":True},
                                 style=self.style)
-                                
-                                
 
         self.panels.add_panel(self.sprite_list, "sprites")
+
         
         self.obj_list = List(self, sidebar_size, sidebar_pos,
                                 items=self.map.sprites,
                                        ("move", ("mouse_stopped_dragging", self.handle_obj_moved)),
                                        ("preferences", self.handle_obj_prefs),
                                        ("remove", self.handle_obj_remove)],
-                                events=[("post_mouse_down", self.handle_sprite_select)],
+                                events=[("post_mouse_down", self.handle_obj_select)],
 #                                item_kwargs={"highlight":True}
                                 style=self.style
                                 )
 
         self.panels.add_panel(self.obj_list, "objects")
+
+        
+        self.param_editor = SpriteParamEditor(self, sidebar_size, sidebar_pos, style=self.style)
+        
+        self.panels.add_panel(self.param_editor, "params")
+        
         
         #! specify list (update_list(listX))
         self.map.listen("widget_added", self.update_lists)
         
     def handle_sprite_select(self, item, **kw):
         # update self.obj_list.
+        # set filter (item.name)
         # self.panels.activate(self.obj_list)
         print "show %ss" % item
         
         
         
     def handle_obj_select(self, item, **kw):
+        #! highlight in list too
         self.get_gui().set_focus(Sprite.get(item))
     
     def handle_obj_move(self, item, widget, **kw):
         
     def handle_obj_prefs(self, item, **kw):
         print "obj prefs"
+        self.param_editor.sprite = Sprite.get(item)
+        self.panels.activate(self.param_editor.name)
         
     def handle_obj_remove(self, item, **kw):
         # remove item from map
         
         
         
+        
+        
     def load(self, sprite_tree, size_tree):
         """
         :type tree: Element
                 s = Sprite(self.map, name, size=size, pos=pos, degrees=degrees)
                 if name == "ship":
                     has_ship = True
-            #self.sprites.append(s)
+                for param in SPRITE_PARAMS[name]:
+                    #! improve
+                    cf = CONVERT_FUNCTIONS[param["type"]]
+                    val = se.findtext(param["name"])
+                    if val:
+                        s.parameters[param["name"]] = cf(val)
         if not has_ship:
             Sprite(self.map, "ship")
         self.map.dirty = True
+        # may still refference to an old sprite
+        self.param_editor.sprite = None
         self.update_lists()
                     
     def save(self, parent):
                 se.attrib["degrees"] = str(sprite.degrees)
             SubElement(se, "position", x=str(sprite.local_pos[0]), y=str(sprite.local_pos[1]))
             SubElement(se, "size", w=str(sprite.size[0]), h=str(sprite.size[1]))
+            for p_name, p_val in sprite.parameters.iteritems():
+                SubElement(se, p_name).text = str(p_val)
             
     def reset(self, size):
         self.map.clear()

File gallox/main.py

View file
  • Ignore whitespace
                 
         # "menu" or "game" or "editor"
         self.state = "menu"
-#        self.fade_to(self.menu)
-        self.start_game("testlevel")
+        self.fade_to(self.menu)
+#        self.start_game("testlevel")
 #        self.start_editor()
         self.photo_sound = load_sound("photo.wav")
         self.c = 0

File testlevel/level.xml

View file
  • Ignore whitespace
       <name>peter</name>
     </author>
   </about>
-   <size>
+  <size>
     <width>1000</width>
     <height>800</height>
   </size>
   <sprites>
-    <sprite degrees="-360" type="gun">
-      <position x="784" y="497" />
+    <sprite degrees="80" type="gun">
+      <position x="292" y="167" />
       <size h="34" w="39" />
-    </sprite>
-    <sprite degrees="-490" type="gun">
-      <position x="168" y="401" />
-      <size h="34" w="39" />
-    </sprite>
-    <sprite type="plattform">
-      <position x="775" y="616" />
-      <size h="18" w="113" />
-    </sprite>
-    <sprite degrees="80" type="gun">
-      <position x="291" y="138" />
-      <size h="34" w="39" />
+      <rotSpeed>4.0</rotSpeed>
+      <actionScope>20</actionScope>
+      <autoAim>True</autoAim>
+      <shotFreq>1.0</shotFreq>
     </sprite>
     <sprite degrees="-130" type="ship">
       <position x="239" y="184" />
       <size h="25" w="25" />
     </sprite>
     <sprite type="plattform">
-      <position x="414" y="282" />
-      <size h="18" w="99" />
+      <position x="214" y="283" />
+      <size h="22" w="75" />
+      <refuel>True</refuel>
     </sprite>
     <sprite type="plattform">
-      <position x="241" y="277" />
-      <size h="17" w="57" />
+      <position x="498" y="344" />
+      <size h="13" w="73" />
+      <refuel>True</refuel>
+    </sprite>
+    <sprite degrees="10" type="gun">
+      <position x="789" y="490" />
+      <size h="34" w="39" />
+      <rotSpeed>4</rotSpeed>
+      <actionScope>60</actionScope>
+      <autoAim>False</autoAim>
+      <shotFreq>-5</shotFreq>
+    </sprite>
+    <sprite type="plattform">
+      <position x="818" y="611" />
+      <size h="7" w="60" />
+      <refuel>True</refuel>
+    </sprite>
+    <sprite type="plattform">
+      <position x="144" y="474" />
+      <size h="11" w="47" />
+      <refuel>True</refuel>
+    </sprite>
+    <sprite type="plattform">
+      <position x="895" y="729" />
+      <size h="32" w="44" />
+      <refuel>True</refuel>
+    </sprite>
+    <sprite degrees="-160" type="gun">
+      <position x="342" y="552" />
+      <size h="34" w="39" />
+      <rotSpeed>4</rotSpeed>
+      <actionScope>60</actionScope>
+      <autoAim>False</autoAim>
+      <shotFreq>-5</shotFreq>
     </sprite>
   </sprites>
 </level>