Documentation.
authorJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 17 Mar 2010 09:47:51 +0000 (02:47 -0700)
committerJoe Wreschnig <joe.wreschnig@gmail.com>
Wed, 17 Mar 2010 09:47:51 +0000 (02:47 -0700)
bulletml/__init__.py
bulletml/impl.py
bulletml/parser.py

index 1e0fcdf..f06d086 100644 (file)
@@ -1,10 +1,35 @@
 """BulletML parser.
 
 """BulletML parser.
 
-http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html
+This module parses and runs BulletML scripts. BulletML is a markup
+language for describing complex bullet patterns in shooting games.
+More information is available at the BulletML homepage,
+http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html.
+
+Basic Usage:
+
+    from bulletml import Bullet, BulletML
+    doc = Bulletml.BulletML.FromDocument(open("test.xml", "rU"))
+    rank = 0.5    # Player difficulty, 0 to 1
+    params = []   # Initial variable settings, usually empty
+    actions = [a(params, rank) for a in doc.top]
+    bullet = Bullet(x, y, target=player, actions=actions, rank=rank)
+    bullets = [bullet]
+    ...
+    for bullet in bullets:
+        bullets.extend(bullet.step())
+
+    ...
+
+For drawing, you're on your own, but Bullet has a number of
+attributes that can be used to influence it.
+
 """
 
 from bulletml.parser import BulletML
 """
 
 from bulletml.parser import BulletML
-from bulletml.impl import Bullet, Action
+from bulletml.impl import Bullet
 
 VERSION = (1, 0)
 VERSION_STRING = ".".join(map(str, VERSION))
 
 VERSION = (1, 0)
 VERSION_STRING = ".".join(map(str, VERSION))
+
+__all__ = ["VERSION", "VERSION_STRING", "Bullet", "BulletML"]
+
index 98b0ef7..3326cec 100644 (file)
@@ -14,6 +14,8 @@ from bulletml import parser
 
 PI_2 = math.pi * 2
 
 
 PI_2 = math.pi * 2
 
+__all__ = ["Action", "Bullet"]
+
 class Action(object):
     """Running action implementation."""
 
 class Action(object):
     """Running action implementation."""
 
@@ -227,7 +229,24 @@ class Action(object):
         return created
 
 class Bullet(object):
         return created
 
 class Bullet(object):
-    """Simple bullet implementation."""
+    """Simple bullet implementation.
+
+    Attributes:
+    x, y - current X/Y position
+    px, py - X/Y position prior to the last step
+    mx, my - X/Y axis-oriented speed modifier ("acceleration")
+    direction - direction of movement, in radians
+    speed - speed of movement, in units per frame
+    target - object with .x and .y fields for "aim" directions
+    vanished - set to true by a <vanish> action
+
+    Contructor Arguments:
+    x, y, direction, speed, target - same as the attributes
+    actions - internal action list
+    parent - parent of actions, None for manually-created bullets
+    rank - game difficulty, 0 to 1
+
+    """
 
     def __init__(self, x=0, y=0, direction=0, speed=0, target=None,
                  actions=(), parent=None, rank=None):
 
     def __init__(self, x=0, y=0, direction=0, speed=0, target=None,
                  actions=(), parent=None, rank=None):
@@ -254,7 +273,7 @@ class Bullet(object):
 
     @property
     def aim(self):
 
     @property
     def aim(self):
-        """Angle to the target."""
+        """Angle to the target, in radians."""
         if self.target is None:
             return self.direction
         else:
         if self.target is None:
             return self.direction
         else:
@@ -264,6 +283,9 @@ class Bullet(object):
     def finished(self):
         """Check if this bullet is finished running.
 
     def finished(self):
         """Check if this bullet is finished running.
 
+        A bullet is finished when it has vanished, and all its
+        actions have finished.
+
         If this is true, the bullet should be removed from the screen.
         (You will probably want to cull it under other circumstances
         as well).
         If this is true, the bullet should be removed from the screen.
         (You will probably want to cull it under other circumstances
         as well).
@@ -283,7 +305,10 @@ class Bullet(object):
         self._actions = []
 
     def replace(self, old, new):
         self._actions = []
 
     def replace(self, old, new):
-        """Replace an active action with another."""
+        """Replace an active action with another.
+
+        This is mostly used by actions internally to queue children.
+        """
         try:
             idx = self._actions.index(old)
         except ValueError:
         try:
             idx = self._actions.index(old)
         except ValueError:
@@ -294,8 +319,10 @@ class Bullet(object):
     def step(self):
         """Advance by one frame.
 
     def step(self):
         """Advance by one frame.
 
-        This updates the direction, speed, x, y, px, and py members,
-        and may set the vanished flag.
+        This updates the position and velocity, and may also set the
+        vanished flag.
+
+        It returns any new bullets this bullet spawned during this step.
         """
         created = []
 
         """
         created = []
 
index edb9d29..62f00d4 100644 (file)
@@ -1,6 +1,10 @@
 """BulletML parser.
 
 """BulletML parser.
 
-http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/index_e.html
+This is based on the format described at
+http://www.asahi-net.or.jp/~cs8k-cyu/bulletml/bulletml_ref_e.html.
+
+Unless you are adding support for new tags, the only class you should
+care about in here is BulletML.
 """
 
 from __future__ import division
 """
 
 from __future__ import division
@@ -31,7 +35,7 @@ def realtag(element):
 class ParamList(object):
     """List of parameter definitions."""
 
 class ParamList(object):
     """List of parameter definitions."""
 
-    def __init__(self, params=[]):
+    def __init__(self, params=()):
         self.params = list(params)
 
     @classmethod
         self.params = list(params)
 
     @classmethod
@@ -312,7 +316,13 @@ class BulletRef(object):
             type(self).__name__, self.params, self.bullet)
 
 class ActionDef(object):
             type(self).__name__, self.params, self.bullet)
 
 class ActionDef(object):
-    """Action definition."""
+    """Action definition.
+
+    To support parsing new actions, add tags to
+    ActionDef.CONSTRUCTORS. It maps tag names to classes with a
+    FromElement classmethod, which take the BulletML instance and
+    ElementTree element as arguments.
+    """
 
     # This is self-referential, so it's filled in later.
     CONSTRUCTORS = dict()
 
     # This is self-referential, so it's filled in later.
     CONSTRUCTORS = dict()
@@ -435,6 +445,12 @@ class BulletML(object):
 
     A BulletML document is a collection of bullets, actions, and
     firings, as well as a base game type.
 
     A BulletML document is a collection of bullets, actions, and
     firings, as well as a base game type.
+
+    You can add tags to the BulletML.CONSTRUCTORS dictionary to extend
+    its parsing. It maps tag names to classes with a FromElement
+    classmethod, which take the BulletML instance and ElementTree
+    element as arguments.
+    
     """
 
     CONSTRUCTORS = dict(
     """
 
     CONSTRUCTORS = dict(
@@ -443,14 +459,15 @@ class BulletML(object):
         fire=FireDef,
         )
 
         fire=FireDef,
         )
 
-    def __init__(self, type="none", bullets={}, fires={}, actions={}):
+    def __init__(self, type="none", bullets=None, fires=None, actions=None):
         self.type = type
         self.type = type
-        self.bullets = {}
-        self.actions = {}
-        self.fires = {}
+        self.bullets = {} if bullets is None else bullets
+        self.actions = {} if actions is None else actions
+        self.fires = {} if fires is None else fires
 
     @classmethod
     def FromDocument(cls, source):
 
     @classmethod
     def FromDocument(cls, source):
+        """Return a BulletML instance based on a string or file-like."""
         if isinstance(source, (str, unicode)):
             source = StringIO(source)
 
         if isinstance(source, (str, unicode)):
             source = StringIO(source)