Rocket Racer Released

Rocket Racer has been released, you can get it here: broken-shotgun.itch.io/rocket-racer

Story

The Universe is being plagued by a virus that is able to spread through space and infect a planet in seconds! You are the AI of a nuke on a mission from your home world to nuke infected planets, but there are other worlds looking to take credit for saving the universe. Race and battle against other nukes to be the world that gets credit for saving the Universe!

Features

  • Battle rockets in space!
  • Nuke planets and other rockets
  • Strike, kill, and destroy to become the #1 hero of the universe

Also earned my first dollar:
dollar

Which also means I’ve completed the October Challenge!  Woo!

I’m Back!

I’m back to working on games full time!  Actually I have been since the beginning of September and I’ve already finished 2 prototypes, an entry for Ludum Dare 33 (Face Puncher) and an entry for Mini Ludum Dare 62 (Rainbow Dragon Slayer).  I’m also currently working on a third one, a Rocket Racing game (untitled at the moment), for the October Challenge 2015.

I’ve switched to using Unity and wow has it made the difference; so many headaches of programming things from scratch with LibGDX are just taken care of for you.  Plus the ability to prototype quickly and modify variables on the fly means you get to spend time on the more important stuff rather than number bumping and recompiling.  I’m also hoping to play around with Game Maker Studio and Unreal Engine sometime this year.

A main focus of mine with this attempt at full-time game development is visibility.  I really want to get the stuff I make in front of people as soon as possible.  I’m trying not to be a ghost, so I’ll try to post or at least Tweet about progress or when I start a new project.  Also I am going to get a Twitch stream up of my development, too.  I’ll post a stream schedule and link when that is all good and ready.

That’s it now, you’ll here from me soon kids!  Til then, keep it interesting.

Throw the Moon

Throw the Moon development is done… for now!  I want to fix a visual bug that blocks out the neat moon fall animation I had when you clear a stage that only seems to happen in the release build, but other than that I am moving onto a new project!  I need to update the source page and maybe document my experience a little more, so stay tuned for that!

UPDATE (5/9): Visual bug fixed!  Turns out it was an issue that was covered up by the debug renderer in LibGDX Stage drawDebug enabling blend instead of me having to set it for the screen fade effect to happen.

Let me know what you think!  It isn’t the most polished thing ever and gameplay is kind of janky, but still something I am proud of.

[LibGDX] Control Scene2D Buttons With A Controller

LibGDX provides a great way to setup a UI, but it only works with touch or mouse and keyboard.  I really wanted to control the main menu of my game with my controller, so I made a wrapper to simulate mouse movement with the D-pad and mouse click with the A button.

Note: this only supports buttons in a single row or column, I will probably being adding support for selecting buttons in a table grid when I add my in game menu. Also, I may add support for controlling buttons through the keyboard arrow keys.

Hopefully this helps someone else!

public class MenuControllerListener implements ControllerListener {

private final Group buttonGroup;

private int currentButtonIndex = 0;

public MenuControllerListener(Group buttonGroup) {
this.buttonGroup = buttonGroup;
}

@Override public void connected(Controller controller) { }
@Override public void disconnected(Controller controller) { }

@Override
public boolean buttonDown(Controller controller, int buttonCode) {
if(buttonGroup.getChildren().size == 0) return false;
if(controller.getName().toLowerCase().contains("xbox") &&
controller.getName().contains("360")){
switch(buttonCode) {
case Xbox360Pad.BUTTON_A:
Actor currentButton = buttonGroup.getChildren().get(currentButtonIndex);
return clickButton(currentButton);
}
}
return false;
}

@Override
public boolean buttonUp(Controller controller, int buttonCode) {
if(buttonGroup.getChildren().size == 0) return false;
if(controller.getName().toLowerCase().contains("xbox") &&
controller.getName().contains("360")){
switch(buttonCode) {
case Xbox360Pad.BUTTON_A:
Actor currentButton = buttonGroup.getChildren().get(currentButtonIndex);
return releaseButton(currentButton);
}
}
return false;
}

/**
* Simulate button click down.
* @param button
* @return
*/
private boolean clickButton(Actor button) {
InputEvent event = Pools.obtain(InputEvent.class);
event.setType(Type.touchDown);
event.setButton(Input.Buttons.LEFT);

button.fire(event);
boolean handled = event.isHandled();
Pools.free(event);
return handled;
}

/**
* Simulate button click release.
* @param button
* @return
*/
private boolean releaseButton(Actor button) {
InputEvent event = Pools.obtain(InputEvent.class);
event.setType(Type.touchUp);
event.setButton(Input.Buttons.LEFT);

button.fire(event);
boolean handled = event.isHandled();
Pools.free(event);
return handled;
}

@Override
public boolean axisMoved(Controller controller, int axisCode, float value) { return false; }

@Override
public boolean povMoved(Controller controller, int povCode, PovDirection value) {
if(buttonGroup.getChildren().size == 0) return false;
if(controller.getName().toLowerCase().contains("xbox") &&
controller.getName().contains("360")){

unselectButton(buttonGroup.getChildren().get(currentButtonIndex));

switch(value) {
case north:
case west:
currentButtonIndex--;
break;
case south:
case east:
currentButtonIndex++;
break;
default:
break;
}

currentButtonIndex = currentButtonIndex % buttonGroup.getChildren().size;
if(currentButtonIndex < 0) currentButtonIndex = buttonGroup.getChildren().size - 1;

return selectButton(buttonGroup.getChildren().get(currentButtonIndex));
}

return false;
}

/**
* Simulate mousing over a button.
* @param button
* @return
*/
private boolean selectButton(Actor button) {
InputEvent event = Pools.obtain(InputEvent.class);
event.setType(Type.enter);

button.fire(event);
boolean handled = event.isHandled();
Pools.free(event);
return handled;
}

/**
* Simulate mousing off of a button.
* @param button
* @return
*/
private boolean unselectButton(Actor button) {
InputEvent event = Pools.obtain(InputEvent.class);
event.setType(Type.exit);

button.fire(event);
boolean handled = event.isHandled();
Pools.free(event);
return handled;
}

@Override public boolean xSliderMoved(Controller controller, int sliderCode, boolean value) { return false; }
@Override public boolean ySliderMoved(Controller controller, int sliderCode, boolean value) { return false; }
@Override public boolean accelerometerMoved(Controller controller, int accelerometerCode, Vector3 value) { return false; }
}

Example usage:

TextButton.TextButtonStyle buttonStyle = new TextButton.TextButtonStyle();
buttonStyle.font = new BitmapFont();
buttonStyle.font.scale(2f);
buttonStyle.fontColor = Color.WHITE;
buttonStyle.overFontColor = Color.LIGHT_GRAY;
buttonStyle.downFontColor = Color.GRAY;

newGameButton = new TextButton("New Game", buttonStyle);
continueButton = new TextButton("Continue", buttonStyle);
optionsButton = new TextButton("Options", buttonStyle);
exitButton = new TextButton("Exit", buttonStyle);

Table buttonGroup = new Table();
buttonGroup.setFillParent(true);
buttonGroup.align(Align.center);
buttonGroup.add(newGameButton);
buttonGroup.row();
buttonGroup.add(continueButton);
buttonGroup.row();
buttonGroup.add(optionsButton);
buttonGroup.row();
buttonGroup.add(exitButton);

stage.addActor(buttonGroup);

Controllers.addListener(new MenuControllerListener(buttonWrapper));