Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon

30. August 2016

 

OpenFL is the rebrand of NME, a cross platform HaXe media framework designed to implement a Flash like API for the Haxe programming langauge.  Lime is the lower level library OpenFL is built upon.  Both saw new releases this week

 

From the OpenFL release notes:

4.1.0 (08/29/2016)

  • Added new Stage3D code migrated from the (now defunct) PlayScript project
  • Added support for ENTER_FRAME, EXIT_FRAME and RENDER if not on the stage
  • Added openfl.ui.MouseCursor and Mouse.cursor support
  • Made minor changes to read-only getter properties to reduce code
  • Added to/from UInt conversion for standard enum types
  • Added duration to HTML5 NetStream onMetaData object
  • Added vector.insertAt
  • Added dictionary.exists
  • Improved stroking in graphics API
  • Improved openfl.Vector for better accuracy/performance
  • Fixed the order of ADDED and ADDED_TO_STAGE events
  • Fixed the behavior of vector.concat with no arguments
  • Fixed netStream.seek on HTML5
  • Fixed Capabilities.screenResolutionY
  • Fixed an issue with HTML5 shape positioning

 

Now from the Lime release notes:

3.1.0 (08/29/2016)

  • Switched from Ant to Gradle for Android builds
  • Added workarounds for some Haxe 3.3.0-rc1 issues
  • Added support for hidden windows on the desktop
  • Improved HTML5 mouse move by ignoring repeat events
  • Fixed issues in ArrayBuffer when values were null
  • Fixed a cross-origin issue that affected some browsers
  • Fixed support for System directories on Android
  • Fixed null fromBytes/fromImage conversion

GameDev News

12. July 2016

 

OpenFL, a Haxe library previously known as NME, just released version 4.  OpenFL is a media framework often used for creating games that is designed to give Flash developers a transitional path to Haxe development.  A major component of the OpenFL 4 release is to be more consistent with Flash APIs as well as a commitment to support the Stage3D API.  If you are interested in learning more I wrote a multipart tutorial series on using Haxe and NME before it was rebranded OpenFL.

 

From the release notes:

New OpenGL Renderer

We went to the drawing board to make a lightweight, clean, easy-to-understand OpenGL renderer in the core of OpenFL. This has resulted in a number of great benefits, not only for maintenance and development, but also this has enabled support for WebGL by default in our HTML5 builds. We have working ShaderFilter support in Bitmap, TextField,DisplayObject and Tilemap, and plan to add support to Sprite in the future.

WebGL builds will fallback to 2D canvas automatically if WebGL is not supported by a user's browser, but if you would prefer to force the use of 2D canvas when targeting HTML5, use -Dcanvas when compiling.

Greater Consistency with Flash APIs

There are many subtle little differences we are changing in order to better support the behavior you expect when using an open-source Flash library. These will not hurt ordinary projects, but can make all the difference when you port an existing ActionScript project over to use OpenFL. We are on the road to continue to remove the tiny differences that unnecessarily make some porting projects complicated.

Commitment to the Stage3D API

In the past, the Stage3D compatibility layer was developed by our friends on the Away3D project, and maintained by generous contributors through pull requests. As an API, this was not supported by the core OpenFL team, but with our new OpenGL renderer, and continuing commitment to providing the functionality you expect, we have begun the process of improving our Stage3D APIs to conform more closely with the original API. We are partnering with the developers of the Haxe Starling port to continue to make improvements to our core Stage3D implementation so that we can grow to support modern ActionScript projects using Stage3D with as little headache as possible.

Continued Graphics Improvements

OpenFL continues to improve in its support for the shape.graphics APIs, with minor edits to improve accuracy, as well as changes to our renderer to support scaled graphics and full fidelity. For projects that are designed for set pixel dimensions, OpenFL 4 is now able to automatically upscale and letterbox projects, bringing full quality graphics to projects that may have been designed only for a lower-resolution screen.

 

Along with this release there was also an update to Lime, the underlying technology on which OpenFL is built.

GameDev News

27. May 2016

 

Welcome back to our ongoing tutorial series on using the Heaps framework with the Haxe programming language.  In the first tutorial we covered the configuration and programming a simple game using Heaps.  Then we covered the basics of 2D graphics in the next tutorial.  In this tutorial we are going to look at using 2D animation in Heaps.  We are going to cover three specific ways, first using a sequence of images for each individual frame of animation, second using a single simple spritesheet image and finally we are going to look at using a texture atlas.  All of the images used in this tutorial are available here, while the project files, source, images etc. are all available to Patreon backers.

 

As always there is a HD video version of this tutorial available here and embedded below.

 

First copy the animation frames into the resource folder.  Each is named along the lines of walk01, walk02, walk03, etc like so:

image

 

Now let’s jump into the code.  The process is almost identical to the sprite handling process from the previous tutorial:

import h2d.Anim;
import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	
	var animation:Anim;
	
	override function init() {
		Res.initEmbed();
		var tiles = new Array<Tile>();
		
		tiles.push(Res.walk01.toTile());
		tiles.push(Res.walk02.toTile());
		tiles.push(Res.walk03.toTile());
		tiles.push(Res.walk04.toTile());
		tiles.push(Res.walk05.toTile());
		tiles.push(Res.walk06.toTile());
		tiles.push(Res.walk07.toTile());
		tiles.push(Res.walk08.toTile());
		tiles.push(Res.walk09.toTile());
		tiles.push(Res.walk10.toTile());
		tiles.push(Res.walk11.toTile());
		tiles.push(Res.walk12.toTile());
		tiles.push(Res.walk13.toTile());
		tiles.push(Res.walk14.toTile());
		tiles.push(Res.walk15.toTile());
		tiles.push(Res.walk16.toTile());
		
		animation = new Anim(tiles, 10, s2d);
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

Here we populate an array of type Tile with all of the images.  Remember Heaps will automatically make available any resource type with an appropriate loader.  Finally we pass this array to the constructor of Anim.  Anim is a special kind of drawable that contains several tiles that represent individual frames of animation.  Also in the constructor we pass along the frame rate to play the animation at, as well as the parent to play the animation relative to, in this case the default scene, s2d.  When you run this code you should see:

GIF

Pretty simple eh?

 

It’s also quite common to want to group all of your sprites together in a single image.  The following example does exactly that using this evenly spaced spritesheet (click for full sized image).  Just be aware, this code requires the width and height of each tile to be the same size.

animation

 

Now the code:

	override function init() {
		Res.initEmbed();
		
		var tileSrc = Res.animation.toTile();
		var tiles = tileSrc.grid(512);
		
		animation = new Anim(tiles, 10, s2d);
		animation.speed = 5;
	}

 

This code has basically the exact same end result.  Basically we load the entire spritesheet into a single tile, then split it into a number of smaller tiles using the grid() method, passing in the dimension to cut by.  Hopefully in the future this function will be updated to take both a width and a height value, removing the square requirement.  As you can see from this example, you can modify the Anim object after the fact, changing the animation speed, it’s position, rotation, scale etc.

 

One final option is to use an Atlas.  An Atlas is basically another form of spritesheet, but instead of being fixed dimensions, it comes with a text description file that says where each frame of animation within the texture is.  This allows you to more tightly store your images in a single image.  In terms of creating an atlas file, two options are LibGDX’s TexturePacker or CodeAndWeb’s TexturePacker.  Of course you could create the file by hand if you preferred.  Now some more code:

	override function init() {
		Res.initEmbed();

		var frame = Res.animationAtlasv1.get("walk01");
		
		var bmp = new Bitmap(frame, s2d);
		bmp.x = 400;
	}

 

As you can see, there is also a loader for Atlas files, so it’s simply a matter of accessing it via the Res interface.  In this particular example we are retrieving a single frame of animation that we use to populate a Bitmap and display on screen.  The Atlas loader also has the option of return an Anim object if preferred.

 

The Video

Programming

17. May 2016

 

In our previous tutorial looking at the Heaps game framework, we looked at creating an initial application.  As part of that tutorial we used s2d to draw some text on the screen.  Today we are going to look a bit closer at using 2D graphics with Heaps.  Let’s start straight off with a simple example:

import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	override function init() {
		
		// Example one, create a new Bitmap using a Tile
		Res.initEmbed();
		var logo = Res.logo.toTile();
		var bitmap = new Bitmap(logo, s2d);
		
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

When we run this example:

image

For this example to work you need to copy an jpg, gif or png file named logo to the resource directory.  Don’t forget you need to tell Haxe where this directory is using the –D resourceDir flag (see previous tutorial for more information ).  In this example we convert the resource to a Tile object, which you can think of as a rectangular region within an image (even if it encompasses the entire image).  Finally we used this tile to create a Bitmap object, which is brings together the thing to draw ( the Tile ) and where to draw it (the Sprite). More on these later.  As before to display it on screen the bitmap is parented to the s2d object, which is a Scene object that is created for us automatically.


Let’s look at another quick source example, the performs a very similar task:

import h2d.Bitmap;
import h2d.Sprite;
import h2d.Text;
import h2d.Tile;
import hxd.Res;
import hxd.res.Font;

import js.Lib;

import hxd.App;
class Main extends App {
	
	override function init() {
		
		// Example two, create a bitmap manually using BitmapData 
		and draw it to screen.
		Res.initEmbed();
		var logoBitmapData = Res.logo.toBitmap();
		var bitmap = Bitmap.create(logoBitmapData);
		s2d.addChild(bitmap);
		
		// Set the pivot point of our bitmap so it is positioned 
		relative to it's center
		bitmap.tile.dx = -Math.round(bitmap.tile.width / 2 );
		bitmap.tile.dy = -Math.round(bitmap.tile.height / 2);
		// Now center the bitmap to the screen
		bitmap.x = s2d.width / 2;
		bitmap.y = s2d.height / 2 ;
	}
	
	override function update(dt:Float) {
	}
	
	static function main() {
		new Main();
	}
	
}

 

And running this one...

image

 

Here we again create a Bitmap to be drawn on screen, but this time using a different process.  In the first example (which is that way you would do things 99% of the time) we loaded the resource as a Tile.  In this example we instead load it using the toBitmap() method.  This is VERY VERY VERY confusing, and is why I decided to show it as an example.  toBitmap() does NOT create a Bitmap object, instead it creates a BitmapData object.  This naming convention was quite poorly chosen in my opinion and leads to a great deal of confusion.  BitmapData can be thought of the raw bytes of information that go together to make all the various pixels in our bitmap.  BitmapData is stored in system memory and is extremely slow to work with.  That said, you can easily manipulate this information, so if for example you wanted to convert all of the individual pixels to grayscale, you could.

Another change here is we didn’t set the Bitmap’s parent (s2d) during construction.  Instead we manually add the newly created bitmap to our scene by calling addChild().  This function will take any Sprite derived class.  We will get back to that in a second, but it’s an important concept to understand.  This second example shows a couple other key concepts.  Notice how we set the position .x and .y?  Well these are simple pixel coordinates to represent where the image should be drawn relative to the origin of it’s parent (s2d in this case).  The origin by default is the top left corner.  In this example we set the pivot point (or origin) by specifying dx and dy.  These are delta values that tell you where drawing calls are made relative to.  In this case we will perform drawing calls on this object relative to it’s mid point.

 

That’s about all I want to cover at this point in time, but there are a few key Heaps classes we should understand before moving on.

 

Sprite

If you come from other game engines, this terminology is very confusing.  Almost universally a Sprite represents and image ( bitmap or texture in memory ) and the position to draw it at.  In heaps however, a Sprite is only about the position of the object. Sprite is the only type of object that can be added to Layer (and thus Scene) ‘s addChild() method call. 

 

Drawable

Drawable inherits from Sprite and is the parent class for things that can actually be drawn on screen.  Bitmap inherits from this class, but so to does Text which we used earlier, as does Anim and Graphics.

 

Scene

s2d is an instance of Scene which is ultimately the root of the 2D scene graph.  At it’s core, Scene is actually a Sprite itself ( via Layer ), but it also holds a special object called Stage and is capable of responding to a number of UI events, as we will see in an upcoming tutorial.

 

Tile

This is another one of those things can be a bit confusing.  A Tile is a rectangle within a texture or image, but ultimately represents a source rectangle that is going to be displayed.  For example, the tile of a bitmap could represent only a portion of the source image.  Consider the following change to our original source:

	override function init() {
		Res.initEmbed();
		var logo = Res.logo.toTile();
		var bitmap = new Bitmap(logo, s2d);
		bitmap.tile.setSize(Math.round(bitmap.tile.width / 2),	
		Math.round(bitmap.tile.height / 2));
	}

 

When this code is run we get:

image

 

The underlying image of our Bitmap is unchanged, but we are only using a quarter of it because we shrank the dimensions of the tile.  This Tile approach is handy when dealing with sprite sheets, where you have several different frames of animation in a single source texture.  We will see this process in a later tutorial.

Programming

12. May 2016

 

mínt is a renderer agnostic ui library for the Haxe language that is part of the snõwkit family of libraries.  Put more simply, it’s a Haxe based cross platform UI library.  As the headline above suggests, they just released Alpha 2.0.  The major feature of this release is the addition of a scaling factor, making high DPI monitor support easy to implement.  There is also the beginnings of a UI editor which you can try right here in your browser.

 

This release also included several minor changes including:

  • control added children_at_point for a sorted list
  • window fixed close handle being a label
  • textedit fixed/added alignment options
  • margins added fixed offset to the anchor layout
  • examples added an empty luxe testbed and an AutoCanvas helper
  • lib added focus model, allowing user/platform specified focus handling
  • textedit add/enable IME entry (+ in mint.render.luxe)
  • luxe added color options to most controls
  • slider josuigoa added invert flag
  • textedit added display_char for password type entry
  • lib fixed usage of luxe types in mint core code

 

More information about this release is available here while mint itself is available on Github.

GameDev News

Month List

Popular Comments