Version User Scope of changes
Jul 24 2009, 5:30 PM EDT (current) dale.beermann 27 words added
Apr 14 2008, 10:33 AM EDT sharendipity

Changes

Key:  Additions   Deletions
NOTE: This tutorial was built in the old version of our editor. It is left here as it still provides a guide for creating a full application.

Bloomshine is a Sharendipity-based version of Boomshine, a popular Flash-based casual game. The player is tasked with starting a chain reaction in an attempt to explode as many dots as needed to pass each of it's increasingly difficult levels. The original Boomshine's levels have been attempted more than 30,000,000 times by hundreds of thousands of players.

Because of it's straight-forward rules and collision-based gameplay, Boomshine is a perfect example of the type of game that can be easily created within Sharendipity.

Elements of Gameplay


Bloomshine uses a flower-theme when describing it's gameplay:

  • A number of colorful ''seeds''are randomly placed in the world. Each is given a random direction and speed. Seeds bounce off of each other as well as the edges of the world.
  • The player clicks anywhere within the world to initiate the blooming process. Blooms grow to a specific size and then wilt away - disappearing from the world.
  • Any seed that comes in contact with a bloom begins to bloom itself. On any given level, the player's goal is to get a certain number of seeds to bloom off of their initial bloom. Each bloom counts toward the player's total score.
  • If the player succeeds in blooming a minimum number of seeds, they move on to the next level where the number of seeds and difficulty increases. Otherwise, they must repeat the current level.

Despite what the the length of this document suggests, Bloomshine is pretty simple. Before we can start on the main game logic, we need to prepare a couple of objects.

Objects

Seed

The Seed is the small circle which briefly transform into colorful blooms and then wilt away. We'll create the those behaviors later - for now it makes World configuration easier if the Seed is created and waiting in the gallery.

Draw out a single circle and open it's properties dialog. Name it "seed" and then configure it's properties in the following way:

Custom Properties
  • WILTING ("boolean") indicates that the seed has entered the wilting state and will be used later by the seed's behaviors. It defaults to false.

Appearance
  • DRAW_BORDER and DRAW_CIRCLE_AXIS are unchecked.
  • FILL_COLOR is set to "1, 1, 1, 1" which is pure white.
  • FILLED is checked.
  • LINE_COLOR does not matter because the DRAW_BORDER is disabled.
  • TEXT_COLOR is set to "1, 1, 1, 0.5" which is pure white.
  • VISIBLE is true.

Physics
  • ELASTICITY is "1.0" which ensures perfect bounce after each collision.
  • FRICTION is "0.0" ensuring that the seed will not slow down during a collision.
  • PINNED is unchecked.

Geometry
RADIUS is 0.6.

Interaction
GRABBABLE is unchecked. (This disables mouse interaction with the seed during play ensuring it does not interfere with the player's click to create an initial bloom.)

Once the seed's properties have been configured, it should be put in the gallery. Because it is no longer GRABBABLE, you need to press the control key while clicking on it to bring up it's menu. Then choose "Add to Gallery" to save the seed for use later.

Announcement

The ANNOUNCEMENT object is responsible for displaying messags to the user. It is created by dragging out a PINNED BOX in the center of the world. It's properties are configured in the following way:

Appearance
  • DRAW_BORDER and FILLED are unchecked.
  • TEXT_COLOR is "1,1,1,1" which is pure white.

Text
  • FONT is set to "defaultEntity,32" which is an unfortunately complicated way of saying use the default font in 32-point size.
  • TEXT defaults to "Welcome to Bloomshine" which is the message it will display when the game starts.
  • WRAP_TEXT is unchecked.

Physics
  • IGNORE_COLLISIONS is checked to ensure that nothing inadvertently collides with the message.
  • PINNED is checked.

Geometry
The height and width of the box is "6.0" and "54.0" respectively.

Position
  • ORIENTATION is "0.0"
  • POSITION is "0.0, 0.0" ensuring that the box is perfectly centered on the screen.

Interaction
GRABBABLE is unchecked. Once we've configured it's properties, we don't want to inadvertently grab and move the announcement.

Score

The player's score is displayed on a PINNED box in the upper-right corner called SCORE. Like ANNOUNCEMENT, it is configured to be ignored by the physics engine and useful in displaying the player's score.

Appearance
  • DRAW_BORDER and FILLED are unchecked.
  • TEXT_COLOR is "1,1,1,1" which is pure white.

Text
  • FONT is "defaultEntity,18,bold" which, again, is an unfortunately complicated way of specifying the default font in bold and an 18-point size.
  • TEXT defaults to "0" which is the player's score at the beginning of the game.
  • WRAP_TEXT is unchecked.

Physics
  • IGNORE_COLLISIONS and PINNED are checked.

Geometry
The height and width of the box is "3.0" and "9.0" respectively.

Interaction
GRABBABLE is unchecked. Once we've configured it's properties, we don't want to inadvertently grab and move the announcement.

The "Press Space to Continue" Prompt

The final object needed by Bloomshine comes from the community. The "Press Space to Continue" object can be found by searching for it. This is a simple object that flashes a message until the user presses the space bar. Drag it from the search results into the world and then add it to your gallery by (since it isn't grabbable) holding CONTROL while you click on it

The World

Properties

The WORLD plays an important role in Bloomshine. It is responsible for managing the current state (such as the player's current score, the total number of blooms needed in the current chain reaction to complete the level, etc.) and when appropriate, handles the transition to the next level or announces the end of the game.

Appearance
BACKGROUND COLOR is set to "63, 63, 48, 255" - this is a dark gray that will help the colorful blooms stand out during gameplay.

Geometry

The WIDTH and HEIGHT of the world are set to "64.6" and "56.5", respectively. (The dimensions of the Sharendipity application are actually 646 x 565 pixels - so using these measurements ensure that the world exactly matches the size and aspect ratio of the applet.)

World Boundaries
  • BOUNDRY MODE defaults to"Bounce" which is perfect because we don't want the randomly moving seeds to fall off the edges of the world.
  • VISIBLE is unchecked.
  • FRICTION is set to "0.0" so that when objects bounce off the walls, they do not slow down.
  • ELASTICITY is set to "1.0" which is also necessary to ensure a perfect bounce.

Physics
APPLY GRAVITY is unchecked.

Custom Properties
The world has a number of custom properties that manage the game's state at all times. These properties are:

  • BLOOMS (''integer'') will be used to keep track of the number of seeds that are currently blooming. Each time a seed begins the blooming process, this value is incremented. When the bloom "pops", the value is decremented. At any given moment, it reflects the number of active blooms in the world.
  • BLOOMS_MAX (''integer'') will count the total number of blooms resulting from the player's chain reaction. Like BLOOMS, each time a seed starts blooming, this value will be incremented. Unlike BLOOMS, however, this value does not decrement when a bloom pops. The player completes a level when, after all blooms have popped, the BLOOMS_MAX value is greater than or equal to the BLOOMS_MIN value.
  • BLOOMS_MIN (''integer'') holds the minimum number of blooms required to pass the level. For the first level, this defaults to "2". As the levels progress, this value will be calculated based on the current DIFFICULTY value multiplied by SEEDS_MAX.
  • DIFFICULTY (''float'') represents the percentage of seeds that must be bloomed in this level. It defaults to 30% ("0.3") and each time the player advances a level, it is increased by 10% ("0.1").
  • IN_PLAY (''boolean'') indicates whether or not the current level is in-play. When "False" the world is poised to begin a new level. When "True" the game is waiting for the player to start the chain reaction or for it to die off.
  • LEVEL (''integer'') represents the current level number. The default value is "1" because the game begins on the first level. Each time the player completes a level, this value will be incremented.
  • SCORE (''integer'') represents the player's total score for each level the player has successfully beaten during this game. The player earns score each time they pass a level. Their score is incremented by the total number of blooms they created during that level.
  • SEEDS (''integer'') tracks the number of seeds that will be released at the beginning of the level. For the first level, this defaults to "5". This will be incremented each time the player advances a level.

Here's a screenshot showing what the world's custom properties look like at the beginning of the game:

Bloomshine World's Custom Properties

Behaviors

The world is responsible for initializing each new level, spawing the seeds that bounce randomly around the world and, upon the final bloom popping, determining whether or not the player has succeeded.

Beginning the Level
This behavior responds to the spacebar being pressed and either starts a new level or restarts the current one (if the player was unable to pass it previously). To that end, we setup a new KEY EVENT FILTER:

When Space is pressed

Here's some pseudo code to illustrate the overall behavior:

When the player presses the Space bar...
If the World is not already IN_PLAY...
Set the World's state to IN_PLAY
Randomly create new seeds
Reset the number of total number of blooms
Notify the player of the current goal

Here are the step-by-step instructions for building the behavior:

  1. The first step is to verify that the World is not in the IN_PLAY state. Pressing the Space bar should have no effect while the game is playing. If it is not IN_PLAY then immediately change the state.

    If the world is not IN_PLAY...
  2. The next step is to create the requisite number of seeds for the current level. Each will be given a random position, color and direction.

    Seed Creation Loop

    These steps will be repeated for as many SEEDs are required on this level. Each pass through this loop a new SEED is created. It's POSITION, FILL_COLOR and ORIENTATION are set randomly. Then it is given an initial SPEED which sets the SEED in motion along it's ORIENTATION. Because the World's borders are enabled, these SEEDs automatically bounce when they hit the edges.

  3. Lastly, the counter which keeps track of the number of blooms created by the player during the level (BLOOMS_MAX) is reset to zero and a message is created which tells the player which level they are on and the number of blooms they need to create.

The completed behavior looks like this:

When Space is Pressed

When the Player Clicks
These actions define how the world behaves when the player clicks somewhere. Assuming the world is IN_PLAY, the player's click creates the bloom that will hopefully cause a chain reaction large enough to complete the level. To achieve this, we create a new MOUSE EVENT FILTER:

When mouse is pressed on World

Here's the pseudo code for this behavior:

When the mouse is pressed anywhere in the World...
If the game is IN_PLAY and no other blooms exist...
Create the first bloom at the mouse position

Here are the step-by-step instructions for building this behavior:

  1. The first thing the action needs to do is verify that the game is in a state to accept the mouse click. Once the player has clicked, they can not click again. This is achieved by verifying that the world is IN_PLAY and that there are no BLOOMS already in existence.

  2. Next the total number of BLOOMS is set to one. This represents the player's initial bloom but does not count toward their score.

  3. Lastly, a SEED is created and it's POSITION is set to the MOUSE POSITION. By setting it's PINNED flag is set to true which is necessary for it to begin blooming.

The completed behavior looks like this:

When mouse is pressed on World

When the Number of Blooms Changes
The World's last behavior is one that is invoked each time the number of blooms in the world changes. Of primary interest is when the last bloom disappears and the number of BLOOMS returns to zero. When this happens, the world is no longer IN_PLAY, all remaining SEEDS are destroyed and the results are displayed to the user. To achieve this, we start with an OBJECT MODIFIED FILTER:

When World's BLOOMS is modified

Here's the pseudo code for this behavior:

When the number of BLOOMS in the World changes...
If the World is in the IN_PLAY state and there are no remaining BLOOMS...
Change out of the IN_PLAY state.
Destroy all remaining SEEDs
If the required number of blooms was created...
Advance to the next level
Increment the player's score
Notify the player that the level is complete
Otherwise
Encourage the player to try again
Save the player's score to the server
Ask the player to press Space to continue

Here are the step-by-step instructions for building this behavior:

  1. The first step is to verify that the world is both IN_PLAY and that there are no remaining blooms. (This event is processed each time the number of BLOOMS changes and we're only interested in the case where the last bloom has wilted away.) If this is the case, it resets the state back to not IN_PLAY.

  2. Next, each of the remaining SEEDs (those that were not bloomed by the player's chain reaction will still be bouncing around the world) are destroyed.

    On each SEED, destroy ACTIVE OBJECT

    The EXECUTE ACTIONS ON EACH control runs a set of child actions on each of the objects of that type in the world. Each pass through the loop, ACTIVE OBJECT is set to the next object of that type. That's why we destroy the ACTIVE OBJECT rather than a SEED.

  3. Next, we'll check to see if the player has passed the level. If the total number of blooms created (BLOOMS_MAX) is greater than or equal to the number required to pass the level (BLOOMS_MIN) then the player has won the level.

    Bloomshine's level-completed test

    Advancing to the next level involves several steps. First, the World's LEVEL is incremented. Second, the number of SEEDS is incremented by "5" ensuring the next level has more seeds than the previous one. DIFFICULTY is also updated as long as it never goes above 90%. Lastly, the minimum number of blooms needed to pass the next level (BLOOMS_MIN) is calculated by taking the number of SEEDS and multiplying it by the DIFFICULTY.

    Since the player just completed a level, the final step is to add the number of blooms they created (BLOOMS_MAX) to their total SCORE.

    If the player did not pass the level, they are encouraged to try again.

  4. Lastly, regardless of whether or not the player has won the level, their current score is sent to the server. Since Bloomshine does not have an end, by sending the score during each level, the number of plays count will reflect the number of levels that have been attempted.

    Afterwards a "Continue" object is created which will prompt the user to press the Space key to continue.

The complete behavior looks like this:

When World's BLOOMS is modified...

Seed Behaviors


While the World plays an important role in managing the game's overall state, the individual SEED objects need to manage their own blooming and wilting effects. These behaviors are added to the SEED instance in Bloomshine's gallery.

When a Seed Collides with a Bloom

This behavior is triggered when a SEED collides with another SEED that is in the blooming state. The blooming state is signified by a SEED that has been PINNED. This COLLISION EVENT trigger will enable the chain reaction we desire.

When Active Object collides with SEED

The pseudo-code for this action is:

When a SEED collides with another SEED...
If one of the SEEDs is PINNED...
Pin the appropriate SEED
Increment the number of active bloomsIncrement the total number of blooms achievedNumber the SEED visually

Here are the step-by-step instructions for building this behavior:

  1. The first step is to determine if an free-floating SEED has collided with a PINNED SEED. PINNED SEEDs will never generate collision events so this action only tests to see if the second collision body's PINNED flag is true and for sanity verifies that the ACTIVE OBJECT is not already PINNED. Otherwise, the event is ignored.

  2. Now the number of active blooms and the total number involved in the chain reaction are incremented. When the bloom eventually wilts, the number of active blooms is decremented.

  3. As a courtesy to the user, the final step positions the newly blooming SEED on the highest layer and set's it's TEXT to the bloom count giving the player a hint on their progress through the level.

The complete behavior logic looks like this:

When Active Object collides with SEED

Blooming Behavior

Once any seed has been PINNED, it starts blooming. When it reaches a certain size, it immediately and rapidly wilts. This behavior is controlled by an EVERY N-STEPS filter:

Every step

The pseudo-code for this behavior is:

Every frame...
If this seed is WILTING...
Decrement the seed's RADIUS
If the seed is too small to see...
Decrement the number of remaining blooms
Destroy this seed.
Otherwise if the seed is PINNED
Increment the seed's radius
If the seed's RADIUS has reached it's maximum size....
Begin WILTING

Here are the step-by-step instructions for assembling this behavior:

  1. First we need to see if this SEED is WILTING. This is accomplished by testing if the SEED's WILTING property is set to true. The wilting process involves reducing the SEED's RADIUS by a large amount. Once the SEED reaches a specific size, the number of active blooms is decremented and the SEED is destroyed.

    Seed wilting logic

  2. Otherwise, if the SEED has been PINNED (set in the previous behavior as a result of colliding with another blooming SEED) it's RADIUS is increased. If it reaches a maximum size, WILTING begins by setting the custom property to "True"

    Seed blooming logic

    Because fonts render strangely and jump around when the object they're on becomes too small, the text of the SEED (which was set when it started to bloom) is cleared as wilting begins.

The complete behavior pieces these two sections together:

Bloomshine's blooming and wilting behavior


Next Steps


Building Bloomshine is a great way to get started in Sharendipity. You've seen how custom properties can be used to track game state and created a variety of behaviors that each handle a different aspect of of the game's play. Try loading Bloomshine from the community search, choose Edit from the Professor menu and you can start exploring the properties and behaviors discussed in this article. What's really exciting is the enhancement possibilities that Bloomshine offers.

Difficulty

Bloomshine's difficulty is derived from several simple components. It's fun to change one or more of these aspects and immediately see the imact on gameplay. Small tweaks can make Bloomshine much easier or much harder!

  1. In the World's "When Space is pressed" behavior, the initial SPEED given to new SEEDs seems to have a big impact on the average number of blooms a player will achieve on any given level. The faster the seeds, the more likely that they'll reach the chain reaction area before it wilts.

  2. In the Seed's "Every 1 step(s)" behavior, the maximum RADIUS of the SEED's bloom also has a big impact on how easy it is to complete a level. Larger blooms fill the screen with color and make the levels easier. It doesn't take a big adjustment to the maximum radius to have a big effect.

  3. Also in the Seed's "Every 1 step(s)" behavior, the speed at which the SEED blooms (or wilts) has interesting results. Slow the blooming or wilting process down and the levels get a lot easier.

  4. The World's DIFFICULTY property controls the percentage of seeds that need to be bloomed during each level. Modifying it's default value can make the first few levels much easier to harder.

Try experimenting with these values and see how it affects game play. Since Sharendipity is a live environment, your changes take effect each time a level begins - so it's easy to fine tune gameplay.

Another consideration would be to incorporate behaviors that modify these parameters over time. Perhaps the maximum bloom size should shrink as the levels get harder or the seeds get random speeds when the level starts.

Graphics & Sound

While it's bright colors are attractive, Bloomshine lacks for graphics and sound. It's easy to add media to a Sharendipity application so try adding some nice tones or ringing when blooms are created. Or put a nice texture on the actual bloom.

To see an example of how Bloomshine's look and feel can be upgraded, check out Bloomshine 2 which takes the garden theme to a whole new level.