DanmakuJSON Bullets & Emitters

In DanmakuJSON, there are two elements that make bullet-patterns: Emitters and bullets.

An emitter defines the origin from which bullets as well as other emitters can be spawned. Usually, emitters are not visible on the screen and in many cases they don't move, but they always need a defined behaviour (otherwise they wouldn't have any purpose).

Bullets are the actual projectiles that move around the screen and can collide with other objects. They don't necessarily need a specific behaviour, if you want them to travel in a straight line with the same speed. Like emitters, bullets can spawn other bullets which makes it possible to create interesting shrapnel- or explosion-effects.

Even though bullets and emitters share a lot of properties, there still are some differences. That's why we use the term "bullet-source" if we are referring to both, emitters and bullets.

Bullet-source properties

As mentioned before, the term "bullet-source" refers to emitters as well as bullets. The following table shows the properties which can be defined inside their corresponding elements (keep reading to learn more about how they actually work):

PropertyTypeDescription
angleTermThe initial angle of the bullet-source (can be overriden by the shoot-action). (Default value: 0.0)
behaviourActionSequenceA list of actions which defines the behaviour of the bullet-source
lifetimeTermSpecifies after how much time (in seconds) the bullet-source will automatically be destroyed. (Default value: 0.0)
Note, that the bullet-source will be destroyed immediately if the value is negative or equal to zero.
propertiesStringMapCustom properties to store additional data which can be used in your application
repeatBehaviourboolSpecifies if the bullet-source will repeat its behaviour indefinitely. (Default value: false)
speedTermThe initial speed of the bullet-source (can be overriden by the shoot-action). (Default value: 0.0)

 

The root-emitter

Every bullet-pattern needs a starting point from which it originates; The root-emitter. Therefore, every DanmakuJSON-file requires a root-element to define it. Inside this element you also have to add the behaviour-property, containing a list of actions (Note, that lists are enclosed by square-brackets):

root:
{
    behaviour:
    [
        # Actions will go here...
    ]
}

Emitters have additional properties which can be defined:

PropertyTypeDescription
destroyOnFinishboolSpecifies if the emitter will be destroyed when its behaviour has finished. (Default value: true).
Note, that this property won't have any effect if repeatBehaviour is set to true.

 

Defining bullets

Bullets are defined in the optional bullets-element which contains a set of keys (the names) and the corresponding definitions:

bullets:
{
    MyBullet:
    {
        behaviour:
        [
            # Actions will go here...
        ]
    },

    AnotherBullet:
    {
        speed: 8
        # This bullet does not have a behaviour
    }
}

As you might have noticed in the previous example, defining a bullet is very similar to defining an emitter but you don't necessarily have to define a behaviour if you want a bullet to travel in a straight line with constant speed.

Note, that bullet-names are case-sensitive!

The default bullet

Because every bullet-pattern needs at least one bullet-definition (and In many cases you will only need just one, especially if you're designing simple patterns), there will always be a pre-defined bullet called "Default", which doesn't have any special behaviour. If you want to add a behaviour to the default-bullet, simply override its definition:

bullets:
{
    # This overrides the definition of the
    # pre-defined default-bullet
    Default:
    {
        behaviour:
        [
            # Actions will go here...
        ]
    }
}

Some actions (shoot, for example) accept a string-parameter containing the name of a bullet. If you omit this parameter, those actions will automatically use the bullet "Default".

More emitters

Apart from the required root-emitter, you can define additional emitters (in the optional emitters-element) which can also be spawned by the shoot-action. Defining emitters generally follows the same rules as defining bullets:

emitters:
{
    MyEmitter:
    {
        angle: 90,
        speed: 4,
        behaviour:
        [
            # Actions will go here...
        ]
    },

    AnotherEmitter:
    {
        angle: -90,
        speed: 2,
        behaviour:
        [
            # Actions will go here...
        ]
    }
}

Note, that emitter-names are case-sensitive!

Custom properties

You can add custom properties by defining a properties-element (containing a StringMap) to your bullet-sources which can be used in your code.

Note, that the DanmakuContext makes use of the property "preset" to identify bullet- and emitter-presets in your bullet libraries. If you omit the preset-property, the associated key of a bullet-source ("MyBullet" in the following example) will be used to determine the according preset.

root:
{
    behaviour:
    [
        # Root-emitter behaviour goes here...
    ]
},

bullets:
{
    # This bullet's key is "MyBullet"
    # but the preset-association is
    # overriden by the property "preset"
    MyBullet:
    {
        # These properties can be used
        # in your code...
        properties:
        {
            myProperty: "My value",

            # The property "preset" specifies,
            # which preset will be used by the
            # associated DanmakuContext
            preset: "Default"
        }
    }
}

A complete example

Here is a complete example of a bullet-pattern which shoots twenty bullets with a simple movement-behaviour (Check out the documentation about actions and procedures to learn more about how they work):

root:
{
    angle: 45,
    behaviour:
    [
        # The actions inside this repeat-block
        # will be executed twenty times.
        {repeat: {times: 20, actions:
        [
            # Shoot the bullet "Default"...
            shoot,

            # ...and wait for 0.2 seconds
            {wait: {duration: 0.2}}
        ]}}
    ]
},

bullets:
{
    Default:
    {
        speed: 5,
        properties: {myCustomProperty: "Hello World!"},
        behaviour:
        [
            # Rotate this bullet by 270 degrees (clock-wise)
            # within 1.4 seconds and wait for this action
            # to finish before continuing...
            {rotate: {angle: 270, duration: 1.4, wait: true}},

            # Rotate the bullet by 90 degrees (counter
            # clock-wise) within one second...
            {rotate: {angle: -90, duration: 1}},

            # ...wait for two seconds...
            {wait: {duration: 2}},

            # ...and destroy this bullet
            destroy
        ]
    }
}

 


Leave a comment