Let’s Talk About UFOs Anyway

September 24, 2021 Posted by zachary

In my last post, I mentioned that I probably wouldn’t be writing a dedicated blog about the Chapter 7 UFO2 example from Beginning Game Programming. At the time I wrote that, I was thinking to myself that the introduction to Game Controller input would be fairly straight forward and I wouldn’t have much to talk about. But I was wrong.

Figuring Out Gamepad Controls

The first major learning experience in applying gamepad controls to our earlier UFO example was that HaxeFlixel has at least two ways that you can do it. In an earlier game I made, Manly Boy Collection, I had gamepad support. So I used it as my starting point. In that game, the code looked as follows:


		//get the most recent active controller
		_gamePad = FlxG.gamepads.lastActive;
		if (_gamePad == null)
		{
			// Make sure we don't get a crash on neko when no gamepad is active
			_gamePad = FlxG.gamepads.getByID(0);
		}
		
		//Controls!
		velocity.x = 0;				//Default velocity to zero
		if(FlxG.keys.pressed.LEFT || ( Reg.usegamepad && _gamePad.pressed.DPAD_LEFT))
		{
			velocity.x -= 30;		//If the player is pressing left, set velocity to left 100
		}
		if(FlxG.keys.pressed.RIGHT || ( Reg.usegamepad && _gamePad.pressed.DPAD_RIGHT ))	
		{
			velocity.x += 30;		//If the player is pressing right, then right 100
		}
		velocity.y = 10;				//Default velocity to zero
		if(FlxG.keys.pressed.UP || ( Reg.usegamepad && _gamePad.pressed.DPAD_UP))
		{
			velocity.y -= 40;		//If the player is pressing up, set velocity to up 100
		}
		if(FlxG.keys.pressed.DOWN || ( Reg.usegamepad && _gamePad.pressed.DPAD_DOWN))	
		{
			velocity.y += 20;		//If the player is pressing down, then down 100
		}

In this example, I was using FlxG to find the active controller, a FlxGamepad object. Then I would check for events from that controller indicating button presses. This works just fine for desktop games. However, when I tried using this method for an HTML5 game, the game could not find the controller. So I had to find a better solution.

I tried looking at the code for the Gamepad Test demo in the flixel-demos repo, but it used a similar but not quite the same method of grabbing the controller. I had trouble parsing out what exactly I needed from all the code that I didn’t (GamepadTest is a project that lets you try out a variety of different game controllers and see what their button press events look like). So I decided to try something different.

So I looked through all the demos on HaxeFlixel’s demo section looking for games that let me use a controller in the browser. That is when I found the Mode demo. This one had working controller support in the browser. So I opened up the code and found that it used a totally different method to handle controllers. It used two classes I was not familiar with, FlxAction and FlxActionManager. With these classes we are able to create watchers for the input events we want, and the classes themselves made sure that we have the controller properly identified.

		_up = new FlxActionDigital().addGamepad(DPAD_UP, PRESSED)
			.addGamepad(LEFT_STICK_DIGITAL_UP, PRESSED)
			.addKey(UP, PRESSED)
			.addKey(W, PRESSED);

		_down = new FlxActionDigital().addGamepad(DPAD_DOWN, PRESSED)
			.addGamepad(LEFT_STICK_DIGITAL_DOWN, PRESSED)
			.addKey(DOWN, PRESSED)
			.addKey(S, PRESSED);

		_left = new FlxActionDigital().addGamepad(DPAD_LEFT, PRESSED)
			.addGamepad(LEFT_STICK_DIGITAL_LEFT, PRESSED)
			.addKey(LEFT, PRESSED)
			.addKey(A, PRESSED);

		_right = new FlxActionDigital().addGamepad(DPAD_RIGHT, PRESSED)
			.addGamepad(LEFT_STICK_DIGITAL_RIGHT, PRESSED)
			.addKey(RIGHT, PRESSED)
			.addKey(D, PRESSED);

		_warp = new FlxActionDigital().addGamepad(A, JUST_PRESSED).addKey(SPACE, JUST_PRESSED);

		up = _up.triggered;
		down = _down.triggered;
		left = _left.triggered;
		right = _right.triggered;

When I found this solution, I instantly fell in love with it. It does what any good engine does, gives you a clean and easy way to define what you expect, a simple way to monitor those desired behaviors, and then handles all the messy details to do so itself.

Controller Support In Browsers

The next major learning experience was testing controller support in the web browser. While both solutions above worked fine for native desktop apps, only the second solution worked in the browser. And even then, I was only able to get it to work in Chrome. Firefox for some reason doesn’t have controller support. I wasn’t able to quickly find a reason why, and I am not going to go too deep into that right now. Thanks to another developer in the HaxeFlixel community we found the following:

  • Chrome in Ubuntu Linux: Controllers work
  • Firefox in Ubuntu Linux: Controllers don’t work
  • Firefox in Windows: Controllers don’t work
  • Firefox in Mac: Controllers don’t work
  • Chrome on Mac: Controllers work
  • Chrome on Windows: Currently untested, but based on Mac and Linux, most likely works.

Testing Multiple HTML5 Apps

While I was working with the GamePad Test and Mode demos trying to figure out controller support for browsers, I came upon an issue where apps wouldn’t build to html5. They would error out and I was left wondering why. I reached out to the HaxeFlixel community and the developer above informed me that when HaxeFlixel builds to an html5 target, it does so on the default port 3000. If you need to run multiple apps at once, you have to assign a new port number to new apps. Multiple apps can’t run on the same port number. So by default, you would run the command “lime test html5”. That uses the default port. To assign a new port, so you can run a new app along side another web app, run the following, “lime test html5 –port=3001”. You can use any number that is not currently used by another app. This was a pretty helpful thing to learn and will come in handy going forward.

A Look Back At Memory

Just to take a quick detour to the Memory game we created. I was pleased to find that the game is playable from my Android phone’s web browser. I wanted to show my wife the game and I pulled it up on my phone and HaxeFlixel awesomely translated my finger taps on the cards to mouse clicks for the game. I just though I would share that with you as it is something I think is really great about HaxeFlixel.

Where to Find The New Game

Now that we have learned a lot about controllers, you can try out the sequel to our earlier UFO example over on itch.io. You can find the source code for this game over on Github. You should also check out the many awesome code examples found over on HaxeFlixel. There is some much really cool stuff there that I haven’t touched yet.

Leave a Reply

Your email address will not be published. Required fields are marked *