Subscribe to GameFromScratch on YouTube Support GameFromScratch on Patreon


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

blog comments powered by Disqus

Month List

Popular Comments