Archive for the ‘cross-platform’ Category

Spaceship Destroyer on Google Play (a post-mortem)

Monday, December 1st, 2014 by Phillip Napieralski

Everything on this blog is something that I’ve put into a product, or created a prototype using. My latest adventures into haxeflixel is no exception.

Introducing Spaceship Destroyer

When I first started dabbling n haxeflixel, my goal was to be able to pet all my old flash flixel games to mobile. Today, I finally realized that goal. Check out my “studio” website at http://fantongstudios.com to get to starship destroyer.

Learning experiences

No matter how much you scope the game down to, you’ll need to scope it down even more to ship in a reasonable timeframe. I hear all the time of people that start projects and never finish them – I’ve even done that twice in the past month! I even remember reading on Reddit about a guy that spent 7 years developing a game. He kept pushing it off, doing a little bit, then pushing it off again. The problem with that is, naturally, the lack of immediate satisfaction. Another problem is that you are going to change a LOT in 7 years (or 2 years, however long it takes you to build it). By the time he finished the game, you could tell the difference between the beginning and the end of the game.

Ultimately, I went into Spaceship Destroyer thinking of having 10 different levels, many in-app purchases, in-game ads, launching on iOS and Android, and many more bosses and enemies. What I ended up with was a great game that has 5 levels, 2 in-app purchases (that are great values if you like the game), and 16 upgrades.

Integrating achievements and leaderboard

The most interesting to implement was the achievements and leaderboards. I opted to use Google Play for both, which was super easy using HaxeFlixel and Sergey’s extensions. The gist of the setup is, you get an ID from the Google Play Developer Console, plug that ID into the extension APIs when some event occurs (eg; killed 500 enemies), and watch as it just magically works! The set-up was very minimal.

Monetization

The hardest part when I was creating this game was monetization. I originally was thinking of having ads after every level you beat (which I still may do), but ultimately, it was easiest to support in-app purchases with HaxeFlixel when I originally created the game. So, I opted for 2 in-app purchases that allows you to buy coins to purchase upgrades.

How has it worked so far? Well, I’ll tell you once people start downloading it :), which brings me to my last point of monetization – marketing!

Marketing has always alluded me. I started a small, very focused, campaign on AdWords that ultimately got me <100 clicks and only a few actual installs. However, I chose cheap keywords and also chose a low budget. Perhaps if I went all in with marketing and decided to spend hundreds, it might pay off.

Conclusion

Overall, Spaceship Destroyer was a labor of love. My love for bullet hell shoot-em-up games, gradius, R-type and similar games forced me to make this game. It had some unique challenges, in terms of scope, implementation and monetization, but it was worth it in the end (though, maybe not financially)!

Don’t forget to check it out on fantongstudios.com

3 tips for working with haxelib

Wednesday, August 13th, 2014 by Phillip Napieralski

Tip 1 – Pointing haxelib library to git repository

Did you just fork flixel-addons to tweak an out-of-date control? I recently had to do this to add touch support to FlxButtonPlus – this is truly the power of open source!

Here’s what you can do:

haxelib git
> Library name : flixel-addons
> Git path : <paste git repository URL here>

Now, wait for the download to finish and confirm everything is working as expected by doing:

haxelib list 
> actuate: [1.7.5]
> firetongue: [1.0.0]
> flixel-addons: 1.1.0 git [dev:C:\HaxeToolkit\haxe\lib\flixel-addons/git]
> flixel-demos: [1.1.1]
> flixel-editors: git [dev:C:\HaxeToolkit\haxe\lib\flixel-editors/git]
...

In the output, you see that flixel-addons list two options, a stable version 1.1.0 and the actual git repository.

Tip 2 – switching between haxelib versions

Now that you have a stable 1.1.0 version and the git version, you will automatically be working using the latest and greatest in the git repository. But, what if you aren’t ready yet?

Here’s how to compile using flixel-addons version 1.1.0 – this works with all haxelibs and versions:

haxelib set flixel-addons 1.1.0

Likewise, if I wanted to downgrade/upgrade anyother library, I could via haxelib set

Tip 3 – keeping everything up-to-date

To keep everything up-to-date, there are two ways:

1. Upgrading an individual haxelib:

haxelib update <haxelib name, eg; flixel-addons>

If the library is pointing to a git repository, it will simply do a pull from the git repository (how cool is that?).

2. Upgrade all haxelibs at once

haxelib upgrade

Now wait… boom, done!

How to create a starfield in 5 lines of code (or less)

Wednesday, June 25th, 2014 by Phillip Napieralski

I recently ported my simple starfield demo over from actionscript/flixel to haxeflixel with create success and ease.

However, there’s an even easier way with the flixel addons!

Overview

Let’s see what the final result will be like – check it out:

Now that I have your attention, let’s take a quick walk through the steps to get this starfield running:

  • Install flixel addons
  • Add flixel addons to your project – one line of code
  • Add imports to your FlxState – one line of code
  • Create your starfield – 1-3 lines of code

Install flixel addons

Type this:

haxelib install flixel-addons

Afterwards, type

haxelib list

…to see what plugins you already have installed and ready for consumption.

Add flixel addson to your project

Add the following to your Project.xml file (which should be in the root directory of your project folder:

<haxelib name="flixel-addons" />

You’ll see this listed, but commented out by default, under the “libraries” section of your xml file.

Add imports

Add the following to the top of the file where your starfield will be created and used:

import flixel.addons.display.FlxStarField.FlxStarField2D;

Create the starfield!

Now that you’re all set-up, let’s create the starfield. Here’s some simple code to create the starfield and adjust it’s speed:

var starField:FlxStarField2D = new FlxStarField2D(0 /*X*/, 0 /*Y*/, FlxG.width, FlxG.height, 300);
starField.setStarSpeed(1, 80);
		
add(starField);

Put this code somewhere in your create method and feel free to modify the star speed anytime. There is also a similarly named FlxStarField3D.

Find it on github

I posted a super small sample that you can download and use with flixel addons version 1.1.0. Have fun!

Hope that helps!

How do I change the icon for my HaxeFlixel project?

Tuesday, June 24th, 2014 by Phillip Napieralski

Overview

It’s quite simple to swap out the icon for your haxeflixel project. Supposing you already have a project created, there are two main steps:
1. Create a new icon and export it as a SVG file.
2. Update your Project.xml file

Step One – Create a SVG file

An SVG file is used to save vector art – something that can, essentially, be scaled in any direction infinitely without losing it’s clarity. This is especially important for icons, that may needed in various sizes, especially on Android.

Because I love open-source technology, I chose to create my dinky Face Defender game logo using InkScape. Load it up and make your logo!

Once you’re done, save it as icon.svg and put it in your projects assets/images folder.

Step Two – Update your project.xml file

This part’s easy. Add the following to your project.xml file:

<icon path="assets/icon.svg"/>

That’s it! Build and test with “lime test Android” and see the icon difference. Haxe uses built in tools to scale the svg file appropriately and encode as a png file.

Face defender is now on Google Play

Friday, June 20th, 2014 by Phillip Napieralski

What do you do when you want to learn a new cross-platform language like Haxe? Port one of your ancient/dinky flash games to it!

On Google Play / flash version

While I have the app working on Google Play now (so you can try it on your android devices) – the real power behind haxe is the ability to be completely cross platform. So, here’s the flash version, have fun!

Porting experience

I started looking into Haxe, specifically HaxeFlixel, about two weeks ago while searching for an awesome cross-platform API. While HaxeFlixel still doesn’t support Windows 8/WP8, I’m confident someone out there is working on it.

Regardless, the experience going from Flixel in actionscript to HaxeFlixel has been great so far. Everything with HaxeFlixel seems very familiar to what I’m used.

Time spent / conclusion

I spent a weekend on porting this game. And, while there are a couple quarks and differences from the original flixel version, it’s more or less the same experience (aside from the sound effects and music, which I lost somewhere!).

So, whether it be haxeflixel or some other cross-platform toolkit, I’m sold on the idea of using cross platform tools. It’s especially nice being able to post my games on my wordpress blog as flash and also on the android marketplace with minimal overhead.

How to make a scrolling star field background with HaxeFlixel

Wednesday, June 18th, 2014 by Phillip Napieralski

A while back, when I was learning Flixel, I created a basic star field for use in my online flash game Starship Destroyer – and also just for fun.

To test out my haxe skills, and generally see how easy porting flixel to haxeflixel would be, I started by porting my basic star field to haxe. My overall conclusion is that porting from flixel to haxeflixel is VERY easy.

Check it out:

Here’s what it does

I won’t keep you waiting, here is the code.

import flixel.FlxG;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.FlxState;
import flixel.text.FlxText;
import flixel.ui.FlxButton;
import flixel.util.FlxMath;
import flixel.util.FlxPoint;
import flixel.util.FlxVector;
import flixel.group.FlxTypedGroup;

/**
 * A class for the starfield
 */
class StarField extends FlxObject {
	private static var NUM_STARS:UInt = 75;
	private var _stars:FlxTypedGroup<FlxSprite>;
	
	/**
	 * @param   ang This is the angle that the starField will be rotating (in degrees)
	 * @param   speedMultiplier
	 */
	public function new(ang:Float = 90, speedMultiplier:Float = 4):Void {          
		angle = ang;
		_stars = new FlxTypedGroup<FlxSprite>(NUM_STARS);
		 
		var radang:Float = angle * Math.PI / 180;
		var cosang:Float = Math.cos(radang);
		var sinang:Float = Math.sin(radang);
		 
		for (i in 0...NUM_STARS) {
			var str:FlxSprite = new FlxSprite(Math.random() * FlxG.width, Math.random() * FlxG.height);
			var vel:Float = Math.random() * -16 * speedMultiplier;
			 
			// change the transparency of the star based on it's velocity
			var transp:UInt = (Math.round(16 * (-vel / speedMultiplier) - 1) << 24);
			 
			str.makeGraphic(2, 2, 0x00ffffff | transp);
			str.velocity.x = cosang * vel;
			str.velocity.y = sinang * vel;
			_stars.add(str);
		}
		
		super();
	}
	
	/**
	 * Rotate the starField
	 * @param   howMuch Input the amount of rotation in degrees
	 */
	public function rotate(howMuch:Float = 1):Void {
		for (i in 0...NUM_STARS) {
			var str:FlxSprite = _stars.members[i];
			var velVector:FlxVector = new FlxVector(str.velocity.x, str.velocity.y);
			
			velVector.rotateByDegrees(howMuch);
		
			str.velocity = velVector;
		}
	}
	 
	override public function update():Void {
		_stars.update();
		 
		for (i in 0..._stars.members.length) {
			var star:FlxSprite = _stars.members[i];
			if (star.x > FlxG.width) {
				star.x = 0;
			} else if (star.x < 0) {
				star.x = FlxG.width;
			}
			if (star.y > FlxG.height) {
				star.y = 0;
			} else if (star.y < 0) {
				star.y = FlxG.height;
			}
		}
	}
	
	override public function draw():Void {
		_stars.draw();
	}
}

Then here’s an example on how to use it – note that I simply used the default state (MenuState) for this code snippet. You could easily re-used pieces of it in your own, more complex, FlxState:

/**
 * A FlxState which can be used for the game's menu.
 */
class MenuState extends FlxState
{	
	// state
	// 0 = stopped
	// 1 = rotate CW
	// -1 = rotate CCW
	private var state:UInt = 1;
	private var starField:StarField;
	/**
	 * Function that is called up when to state is created to set it up. 
	 */
	override public function create():Void
	{
		starField = new StarField(45);
		add(starField);
		
		var title = new FlxText(0, 0, FlxG.width, "HaxeFlixel");
		title.setFormat(null, 42, 0xeeeeee, "center");

		add(title);
		
		var butStop = new FlxButton(10, 10, "Stop rotation", function() { state = 0; } );
		add(butStop);
		
		var butRotateCCW = new FlxButton(10, 50, "Rotate CCW", function() { state = -1; } );
		add(butRotateCCW);
		
		var butRotateCW = new FlxButton(10, 90, "Rotate CW", function() { state = 1; } );
		add(butRotateCW);
		
		super.create();
	}
	
	/**
	 * Function that is called when this state is destroyed - you might want to 
	 * consider setting all objects this state uses to null to help garbage collection.
	 */
	override public function destroy():Void
	{
		super.destroy();
	}

	/**
	 * Function that is called once every frame.
	 */
	override public function update():Void
	{
		super.update();
		starField.rotate(cast(state,Float));
	}	
}

Or, if you’re really stuck, check it out from my github.