DartGameDevs

Bleeding edge tutorials and news for game developers working with Dart

Game Development Library Updates

There has been lots of activity going on in the Dart game development library community. Below is a list of libraries and important changes:

spectre

  • Don Olmstead added support for compressed textures.
  • Bounds checking on camera angle was added so the camera cannot “wig out”.
  • Initial work on spectre_renderer started.

game_loop

  • Touch event support was added.
  • Renamed Timer to GameLoopTimer to avoid conflicting with dart:async.
  • Renamed GamePad to GameLoopGamePad to avoid conflicting with dart:html.

asset_pack

  • Removal of property_map accessors. Asset access is done using operator[] now.
  • Support for reloading assets has been added.
  • Loaders now work when compiled to dart2js and run under Firefox.
  • Don Olmstead fleshed out support for programmatically created assets.
  • Status string update logic fixes.
  • Landed MapLoader for meta-assets.
  • NoopImporter, useful for assets which are good once loaded.
  • More tests!
  • Update to support latest SDK.

vector_math

  • Generated code was refactored to support better compilation via dart2js.
  • Update to support latest SDK.
  • Typo fixed in quaternion code.
  • v0.9.7 released.

simple_audio

  • David Bernard added support for sfxr file format.

Juggler: bringing Flash animations to Dart

A basic building block in game development is a framework to move things around on the screen. The Juggler is a framework built right into dartflash and it provides animation capabilities and much more. If you are not familiar with the basics of the dartflash library, please read the Introducing dartflash article first.

Early Egyptian Juggling

Let’s get started with a simple example. In the previous article you have learned about the Stage and the RenderLoop. The RenderLoop manages the continuous update of the screen and he also keeps track of the time that passes while the game is running. The current time is important for the Juggler because animations are functions over time. Therefore the RenderLoop also provides an instance of the Juggler.

var canvas = html.query('#stage');
var stage = new Stage('myStage', canvas);
var renderLoop = new RenderLoop();
var juggler = renderLoop.juggler;

Tween

Now that we have an instance of the Juggler we can start to animate things. The simplest animation is to move an object from its current position to another position. The current position is know, you only have to provide the time (duration) and the target position. This kind of animation is often referred as tweening.

tweening: Short for in-betweening, the process of generating intermediate frames between two states to give the appearance that the first state evolves smoothly into the second state. Tweening is a key process in all types of animation.

var spaceship = new Spaceship();
spaceship.x = 100;
spaceship.y = 100;
addChild(spaceShip);

var tween = new Tween(spaceship, 2.0, TransitionFunction.linear);
tween.animate("x", 500);
tween.animate("y", 500);
juggler.add(tween);

This example creates a spaceship and sets the current position. A Tween is created for the spaceship, the animation should last for 2.0 seconds and the transition should be linear over time. Most importantly the tween should animate the “x” and “y” properties of the spaceship to the desired values. Last but not least the tween if added to the juggler who will take care that the spaceship moves from its current position to the target position. When the tween is finished it is automatically removed from the juggler.

The Tween class does not only animate the position of display objects, it also animates all other properties like alpha, scale or rotation. To keep track of the progress of the animation you can set callbacks for start, update and complete. The delay property enables the deferred start of the animation.

var tween = new Tween(spaceship, 2.0, TransitionFunction.linear);
tween.animate("x", 500);
tween.animate("y", 500);
tween.onStart = () => print('tween start');
tween.onComplete = () => print('tween complete');
tween.delay = 1.0;

Of course you can create multiple tweens with different parameters for the same or different display objects at the same time. One tween could animate the position while another tween could animate the alpha property.

Transition Functions

A transition function defines the progress of the animation over time. The simplest transition is linear, where the progress of the animation is linear in relationship to time. Often animations look more natural when the transition accelerates or decelerates. Those transition functions are often called easing functions.

The example for the Tween class already showed how to use a transition function. You can choose between many different functions which are provided by the dartflash library. There is an overview for all transition functions on the dartflash homepage, the image below just shows some of the common functions.

http://www.dartflash.com/docs/transitions.html

Transition Functions

If none of the provided transition functions fulfills your needs you can simply build one of your own. The example below shows a custom transition function called “sawtooth”.

// A transition function looks like this:
// num transition(num ratio)
// ratio is the relative time of the transition (between 0.0 and 1.0)
// returns the relative progress of the transition (between 0.0 and 1.0)

var sawtooth = (ratio) => (ratio * 4.0).remainder(1.0);
var tween = new Tween(spaceship, 2.0, sawtooth);

Animatables

The example above showed how you add a Tween to the Juggler. In fact the Juggler not only takes Tween classes but all classes that implement the Animatable class. Therefore you can create your own classes and add it to the Juggler as long as it implements the Animatable class.

The Animatable class is very simple. It only has one method called ‘advanceTime’ which takes a time and returns a bool. This method is called by the Juggler on every frame for all Animatables added to the Juggler. The time parameter is the time that has passed since the last call. The boolean return value indicates if the Animatable is still active. If ‘false’ is returned, the Animatable will be automatically removed from the Juggler and therefore it will no longer be called.

abstract class Animatable {
  bool advanceTime(num time);
}

A simple example is the performance demo on the dartflash homepage. Here we are using a class called FlyingFlag which extends the Bitmap class and implements the Animatable class. The Juggler manages the motion of all flags by calling the ‘advanceTime’ method of all FlyingFlags.

http://www.dartflash.com/demos/performance.html

class FlyingFlag extends Bitmap implements Animatable {

    // velocity of the flag
    num vx, vy;

    FlyingFlag(BitmapData bitmapData, this.vx, this.vy):super(bitmapData) {
      this.pivotX = bitmapData.width / 2;
      this.pivotY = bitmapData.height / 2;
    }

    bool advanceTime(num time) {
      var tx = x + vx * time;
      var ty = y + vy * time;
      if (tx > 910 || tx < 30) vx = -vx; else x = tx;
      if (ty > 470 || ty < 30) vy = -vy; else y = ty;
      return true;
    }
}

Delayed Call

One of the Animatables provided by the dartflash library is the DelayedCall class. This class is not directly related to animations, but is very useful to control the flow of your game. The purpose of this class is obviously to delay the call to a function.

var action = () => print("Action!");

// Call action after 5.0 seconds
var delayedAction = new DelayedCall(action, 5.0);
juggler.add(delayedAction);

// Call action 10 times every 1.0 seconds.
var repeatAction = new DelayedCall(action, 1.0);
repeatAction.repeatCount = 10;
juggler.add(repeatAction);

Of course you can do similar things with the Timer class included in dart:async, but the advantage here is that the calls are synchronized with all the other animations and time related things happening in your game.

Transition

The Transition class also implements the Animatable class. This Animatable is closely related to the Transition Functions shown above and allows you to animate any arbitrary value. As example you could fade the volume of a sound or count up the score in your game.

// count from 1000 to 2000 within 5.0 seconds.
var transition = new Transition(1000, 2000, 5.0, TransitionFunction.linear);
transition.roundToInt = true;
transition.onUpdate = (num value) => print(value);
juggler.add(transition);

Juggler

The Juggler class itself implements the Animatable class. This allows better control of the time in your game. As example you can add a button to pause the game, therefore you have to pause all animations and accordingly you have to pause the time. You can achieve this by creating your own juggler instance and add all animations to this juggler. Now you only have to add or remove this juggler to the juggler from the RenderLoop and you are done!

var juggler = new Juggler();
juggler.add(tween1);
juggler.add(tween2);
juggler.add(delayedCall);
...

_pauseGame() {
  renderLoop.juggler.remove(juggler);
}

_continueGame() {
  renderLoop.juggler.add(juggler);
}

Another possible use case is a time lapse juggler. You can implement a TimeLapseJuggler by extending the Juggler class and by overriding the ‘advanceTime’ method like this:

class TimeLapseJuggler extends Juggler {
  num speed = 0.5;
  bool advanceTime(num time) {
    super.advanceTime(time * speed);
  }
}

Convenience methods

For some of the simple use cases the Juggler class provides convenience methods.

// delay the call the 'action' by 5.0 seconds.
juggler.delayCall(action, 5.0);

// a linear transition for a value from 0.0 to 100.0 within 5.0 seconds.
juggler.startTransition(0.0, 100.0, 5.0,
  TransitionFunction.linear, (num value) => print(value));

// remove all tweens on the 'spaceship' display object.
juggler.removeTweens(spaceship);

Credits

The Juggler framework was originally developed by my friend Daniel Sperl for ActionScript 3. Daniel is also the creator of the famous Sparrow and Starling frameworks. If you are not familiar with these frameworks and you are interested in iOS or Stage3D game development you should definitely visit his homepage: www.gamua.com.

Get in contact

The dartflash library is open source and available on github. If you have a questions or want to provide feedback, you can use the issue tracker on github or send an email to support@dartflash.com.

Slides from Talk on Dart SIMD

Last night I had a great time speaking at SFHTML5 about the new SIMD numeric types and operations I’ve added to Dart. Check out my slides here. I’ll post when the video is released.

-Cutch

Introducing dartflash

I’m excited to have Bernhard Pichler contributing articles for DartGameDevs. Bernhard has been hard at work on the dartflash library, which makes migrating from ActionScript to Dart easy.

The following article is a first in a series that helping Flash game developers migrate to Dart.

In the past and even today, most games on the Web are developed with Adobe Flash and ActionScript 3. With the rise of HTML5 and the lack of support for Flash on mobile devices, developers need an easy migration path. The Dart language is very similar to ActionScript 3 and the dartflash library itself provides the easy to use API of Flash to build games and other graphically rich content. Although dartflash is targeted to existing Flash developers, the API should be appealing to all other game developers too.

Flash Logo

This article explains the basic building blocks of the dartflash library and should get you started. You can also visit the dartflash homepage to look at some games, demos and code snippets.

Display List

The rendering model of dartflash relies on the Display List concept. The display list is a hierarchy that contains all objects that should be visible on the screen. To build this hierarchy, three basic types of objects are available.

The stage

The stage is the root of the display list hierarchy and is a wrapper over the HTML5 canvas element. Typically your game has one stage, only in a more advanced scenario you may use two stages on top of each other.

Display object container

As the name suggests, the display object container is a container of display objects. The stage itself is a display object container. You can add child display objects to the container and thereby build the hierarchy of the display list. If you move, scale or rotate the container, all children will behave accordingly. If you remove the container from the display list, all children will be removed aswell and consequently disappear from the screen.

Display object

The display object is a visual element on the screen. The most basic display object is the Bitmap. A Bitmap contains pixel art.

The hierarchy of the display list is also responsible for the depth management of your display objects. Child display objects are always in front of their predecessor.

The Display List in action

The easiest way to understand the Display List is to look at some code. You can find this example and more advanced examples on the dartflash github page. The first example shows the construction of a custom display object container called ‘Painting’.

The painting consists of a rectangluar background and four colorful boxes. The example introduces the BitmapData and Bitmap types. The BitmapData type contains pixels - either by creating a new BitmapData object filled with a flat color (as in our example), or by loading an image from the server. To make those pixels visible, you have to create a Bitmap display object and add it to the display object container (Painting). Please pay attention to the order of the boxes - the boxes added first are in the background, the boxes added later are in the foreground. The example also shows how to set the position of the Bitmap relative to its parent.

Modern Art Painting

class Painting extends DisplayObjectContainer {
  final List<int> colors = [Color.Red, Color.Green, Color.Blue, Color.Brown];

Painting() {
    var background = new BitmapData(400, 300, false, Color.BlanchedAlmond);
    var backgroundBitmap = new Bitmap(background);
    addChild(backgroundBitmap);

    for(var i = 0; i < colors.length; i++) {
      var box = new BitmapData(100, 100, false, colors[i]);
      var boxBitmap = new Bitmap(box);
      boxBitmap.x = 80 + i * 50;
      boxBitmap.y = 60 + i * 30;
      addChild(boxBitmap);
    }
  }
}

Now that we have created the Painting, we need to add the Painting itself to the display list to make it visible. As explained earlier, the root of the display list is the Stage. Therefore we create the Stage from a canvas element which is part of the HTML document. At the same time we have to take a look at the RenderLoop class. The render loop (also known as game loop) provides a constant stream of events that updates your game logic and draws the display list to the screen. Our painting example looks pretty static, but in fact it is updated 60 times per second - if the positions of the boxes would change over time, you would see a smooth animation.

import 'dart:html' as html;
import 'package:dartflash/dartflash.dart'; 

void main() {
  var canvas = html.query('#stage');
  var stage = new Stage('myStage', canvas);
  var renderLoop = new RenderLoop();
  renderLoop.addStage(stage);

  var painting = new Painting();
  painting.x = 40;
  painting.y = 40;
  stage.addChild(painting);
}

Interactive objects and events

All display objects are so called event dispatchers. This means that you can dispatch events or listen to events on each single display object. This is particularly useful for mouse or touch events, this way the objects in your game can individually react to user input. Another common and useful event is dispatched by the render loop whenever a new frame is entered. The following example shows a clock where the time is updated “onEnterFrame” and the color of the time is changed “onMouseClick”. The example introduces another display object called TextField, which is used to display text on the screen.

Running Clock

class Clock extends DisplayObjectContainer {
  List _colors = [Color.Black, Color.Blue, Color.Red, Color.Green];
  int _colorIndex = 0;
  TextField _textField;

  Clock() {
    _textField = new TextField();
    _textField.defaultTextFormat = new TextFormat("Verdana", 14, Color.Black);
    _textField.width = 200;
    _textField.height = 20;
    _textField.background = true;
    _textField.backgroundColor = Color.Yellow;
    _textField.text = new DateTime.now().toString();
    addChild(_textField);

    this.onEnterFrame.listen(_onEnterFrame);
    this.onMouseClick.listen(_onMouseClick);
  }

  _onEnterFrame(EnterFrameEvent e) {
    _textField.text = new DateTime.now().toString();
  }

  _onMouseClick(MouseEvent e) {
    _colorIndex = (_colorIndex + 1) % _colors.length;
    _textField.textColor = _colors[_colorIndex];
  }
}

The enterFrame event could be used to animate display objects over time (as example you could change the “x” and “y” property of a display object). Please note that the dartflash library provides a dedicated framework with easing functions for this use case, therefore we do not recommend using the enterFrame for animations. Please visit the dartflash homepage for more details.

Resource manager

A game consists of many different resources (or assets) like images and sounds. You can load all of those resources one by one, or use the resource manager to do the job. Using the resource manager is as easy as creating a new instance, adding all your resources (name and URL) and calling a single load method.

The example below adds three images to the resource manager. Each image is tagged with a unique name and the URL to the image is provided too. When the resource manager has finished loading all images, the load-future completes and you can access the BitmapDatas by the given unique name.

World

import 'dart:async';
import 'dart:html' as html;
import 'package:dartflash/dartflash.dart';

void main() {
  var canvas = html.query('#stage');
  var stage = new Stage('myStage', canvas);
  var renderLoop = new RenderLoop();
  renderLoop.addStage(stage);

  var resourceManager = new ResourceManager()
    ..addBitmapData("house", "../common/images/House.png")
    ..addBitmapData("sun", "../common/images/Sun.png")
    ..addBitmapData("tree", "../common/images/Tree.png");

  resourceManager.load().then((_) {
    var sun = new Bitmap(resourceManager.getBitmapData("sun"));
    var tree = new Bitmap(resourceManager.getBitmapData("tree"));
    var house = new Bitmap(resourceManager.getBitmapData("house"));

    // Not shown: set x and y properties of sun, tree, house

    stage.addChild(sun);
    stage.addChild(tree);
    stage.addChild(house);
  });
}

Advanced features

This introduction to dartfash covers only the basic concepts of the display list to get you started. You can find more advanced samples and demos on the dartflash homepage and in the github repository. Stay tuned for future articles, covering some advanced features:

Sound

The dartflash library does not only cover the display list, but also the Sound APIs of Flash. The easy to use Sound API hides the implementation details and provides cross browser compatibility.

Juggler animation framework

The juggler animation framework is a powerful tool to bring your game objects to life. You can use built in tools like Tweens and easing functions, or you can implement the Animatable interface in your own classes. Later you can add “animatable” objects to the Juggler who keeps track of all your animations.

Masks and Filters

Masks are used to limit the available display area of display objects. Masks can have any arbitrary shape, but most commonly they have a rectangular shape. Only the content within the mask is visible, all pixels outside of the mask are not drawn. Filters provide visual effects like drop shadow, glow or blur to BitmapDatas.

Runtimes

The darflash library also contains runtimes for popular third party tools. This is a list of current and future runtimes supported by dartflash out of the box.

Get and contact

The dartflash library is open source and available on github. If you have a questions or want to provide feedback, please can use the issue tracker on github or send an email to support@dartflash.com.

game_loop 0.7 with M3 support

New release with M3 support

Last week’s M3 release of Dart broke the game_loop library. Today version 0.7.0 of game_loop was published on pub.

Changes: 1. Support for M3 version of Dart. 2. Removal of GameLoop prefix from classes, if you have a conflict use a prefixed import.

Pub and Import

If you’re using pub, just run pub update and you’ll be good. If you aren’t using pub, start!

1
2
dependencies:
  game_loop: any
1
import 'package:game_loop/game_loop.dart'

Be sure to checkout the GitHub project and read the docs here.

New game_loop Release

Today I released a new release of Dart’s game_loop library. Version: 0.6.0. Since January some bug fixes have landed and some important breaking changes have been added to the library. Read on for details.

Super Mario

Split of game logic update and game drawing

The correct usage of game_loop requires you to decouple your drawing code from your game update code:

1
2
3
gameLoop.onUpdate = ((gameLoop) {
    // Game update logic here.
});
1
2
3
gameLoop.onRender = ((gameLoop) {
    // Game drawing here.
});

The library will do the right thing and call onUpdate when it’s time to update the game world and onRender when it’s time to draw it. game_loop calls these functions at the right time letting you focus on your game and not the browser.

Controlling how frequently your game logic updates

How frequently onUpdate is called can be controlled with the updateTimeStep member variable. By default it is 15 milliseconds.

Time source

Absolute Time

There are a two sources of absolute time in game_loop. The first is time which gives you the current time of the computer. For game logic time see gameTime which is kept in sync with any game_loop timers. In case it’s not obvious, you should be using gameTime almost all the time.

Delta Time

There are two sources of delta time in game_loop. The first is dt which is always the same as updateTimeStep, that is, the logical game time change since the last call to update. There is also requestAnimationFrameTime which is the delta between requestAnimationFrame callbacks from the browser. Again, you should almost always be using dt which is linked to gameTime.

Pub and Import

If you’re using pub, just run pub update and you’ll be good. If you aren’t using pub, start!

1
2
dependencies:
  game_loop: any
1
import 'package:game_loop/game_loop.dart'

Be sure to checkout the GitHub project and read the docs here.

New vector_math Release

Today I released a roll up release of Dart’s vector_math library. Version: 0.9.3. This release includes important fixes to matrix constructors, mixed vector / scalar GLSL style constructors. All existing users should upgrade.

cross_product

For existing users, there is a breaking change in the package import line. Previous versions of vector_math had a library split between console and HTML applications. This is no longer the case and a single import line is all that’s needed:

1
import 'package:vector_math/vector_math.dart';

If you’re using pub, just run pub update and you’ll be good. If you aren’t using pub, start!

1
2
dependencies:
  vector_math: any

Be sure to checkout the GitHub project and read the docs here.

A big thank you to all users who filed issues and provided bug fixes. You’re awesome!

Introducing Game Loop

Over the break I wrote a couple of game development libraries. In today’s post I will introcuce the first, game_loop, a library for managing your main loop. The game main loop is responsible for processing inputs, fullscreen, pointerlock, and, finally, executing the game code once per frame. Read on to learn how how easy and powerful game_loop is.

Mario Loves game_loop

Initializing the game_loop library is really simple:

1
2
CanvasElement canvasElement = query('#frontBuffer');
GameLoop gameLoop = new GameLoop(canvasElement);

First you get a reference to the element your game will be displaying from. Second, you construct a new instance of GameLoop passing the element in. At this point you can start the game loop by:

1
gameLoop.start();

But, wait, you haven’t specified your frame update function. GameLoop has the following callbacks hook points that you can set:

1
2
3
4
5
6
7
8
/** Called once per frame. */
GameLoopUpdateFunction onUpdate;

/** Called when element is resized. */
GameLoopResizeFunction onResize;

/** Called when element moves between fullscreen and non-fullscreen mode. */
GameLoopFullscreenChangeFunction onFullscreenChange;

So, let’s hook in an onUpdate function before calling start:

1
2
3
4
gameLoop.onUpdate = ((gameLoop) {
  print('${gameLoop.frame}: ${gameLoop.frameTime} [dt = ${gameLoop.dt}].');
});
gameLoop.start();

Now, each frame we will print out the frame number, frame time, and the time delta. Quick tip: You can safely change the onUpdate (and other) callback anytime.

Want to get started with GameLoop now?

1. Add the following to your project’s pubspec.yaml and run pub install.

1
2
3
dependencies:
  game_loop:
    git: https://github.com/johnmccutchan/game_loop.git

2. Add the correct import for your project.

1
import 'package:game_loop/game_loop.dart';

3. Check out the API docs

The game_loop library includes powerful support for keyboard and mouse inputs. Stay tuned to DartGameDevs for the next post on game_loop!

submit to reddit

Vote on HN