Nuclear Throne style weapon movement #LibGDX #Gamedev

I have published 11 tutorials on making a game from scratch, while the game was intended to be a rougue-like it has evolved away from the genre. I aim to add interesting features which might help others. While this may never be a fun to play or complete game it hopefully will aid others in producing their own games.

If you are interested in checking out the changes to the Chunk management and also the loading and saving methods then check out this pull request (I will create posts about these changes in the future.):

https://github.com/tyler6699/evoscape/pull/7

This tutorial will add a weapon to the Hero that points toward the mouse cursor position. The gun points right or left and swaps hands depending on the mouse position.

gun_anim

Full source code on Github

Entity Class
New variables are added to Entity that will allow rotation and horizontal flipping of
a texture, this means we only need one image for the weapon, also we will add an active flag and an array of guns called weapons. The active flag can be used later to determine if the gun or weapon has been drawn. The array will allow multiple weapons in a future tutorial.

The drawRotated method uses spriteBatch draw that will allow the angle and rotation point of our entity.

// New Variables
public float angle;
public Boolean flipX = false;
public Boolean flipY = false;
public boolean active;
public ArrayList weapons;

// New draw function which we will over ride
public void drawRotated(SpriteBatch batch){
  if(texture != null) batch.draw(texture, pos.x, pos.y, 0, 0, width, height,1, 1, angle, 0, 0, (int)width, (int)height, flipX, flipY);
}

All of the available parameters for the draw method we are calling.

x the x-coordinate in screen space
y the y-coordinate in screen space
originX the x-coordinate of the scaling and rotation origin relative to the screen space coordinates
originY the y-coordinate of the scaling and rotation origin relative to the screen space coordinates
width the width in pixels
height the height in pixels
scaleX the scale of the rectangle around originX/originY in x
scaleY the scale of the rectangle around originX/originY in y
rotation the angle of counter clockwise rotation of the rectangle around originX/originY
srcX the x-coordinate in texel space
srcY the y-coordinate in texel space
srcWidth the source with in texels
srcHeight the source height in texels
flipX whether to flip the sprite horizontally
flipY whether to flip the sprite vertically

Gun Class

At the moment the gun class is a basic entity that only draws to the screen, I will look at shooting in the next tutorial. What we care about is the position of the mouse retaliative to the hero, is it to the left or right side and at what angle.

The Gun class has x and y offsets for the origin and also the x position, these values allow us to move the gun into the hand of the hero. The gun can be set to the Hero’s x position by default and moved left or right accordingly, knowing the size of the gun and hero we can work out how far to move it so it appears in the correct position.

package uk.co.carelesslabs.weapons;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import uk.co.carelesslabs.Media;
import uk.co.carelesslabs.entity.Entity;

public class Gun extends Entity {
	float originXOffset; // OriginX Offset
	float originYOffset; // OriginY Offset
	float xPos;          // X offset for gun position
	float xMinPos;       // X Position offset facing left
	float xMaxPos;       // X Position offset facing right

	public Gun(float originXOffset, float xMinRight, float xMaxRight){
		texture = Media.gun;
		width = texture.getWidth();
		height = texture.getHeight();
		active = true;
		originYOffset = height/2;
		this.originXOffset = originXOffset;
		this.xMinPos = xMinRight;
		this.xMaxPos = xMaxRight;
	}

    public void drawRotated(SpriteBatch batch){
    	if(angle > 90 && angle < 270){ // 6 to 12 Clockwise or LEFT
    		xPos = xMinPos;
    		flipY = true;
    	} else { // 12 to 6 clockwise or RIGHT
    		xPos = xMaxPos;
    		flipY = false;
    	}
        // When the gun is to the right of the hero we move
        // the it by xMaxPos (7) and when
        // its to the left we move it byxMinPos (-1)
        if(texture != null) batch.draw(texture, pos.x + xPos, pos.y, originXOffset, originYOffset, width, height, 1, 1, angle, 0, 0, (int)width, (int)height, flipX, flipY);
    }
}

Hero Class

There is a new Vector3 added to the hero class, previously the hero was not aligned to the centre of the screen, this new variable will be updated to the hero position but half of the hero width +/- from the x value so that the hero appears centred.

A new ArrayList of ‘Gun’ called weapons is setup and initiated, we add a Gun to the list, the origin X Offset is set to 1 and the min and max x offsets set the -1 and 7. This sets up the rotation point and the left/right positions relative to the hero.

public Hero(Vector3 pos, Box2DWorld box2d){
  super();
  cameraPos = new Vector3(); // new variable
  type = EntityType.HERO;
  width = 8;
  height = 8;
  texture = Media.hero;
  speed = 30;
  inventory = new Inventory();
  reset(box2d, pos);

  // Weapon
  weapons = new ArrayList();
  weapons.add(new Gun(1, -1, 7));
}

Draw function

The Hero draw function now loops through the weapon array and will call drawRotated for any active gun.

The cameraPos variable is also updated in this draw method, it is set to the same as the hero position and then the x value has half of the Hero width added on.

@Override
public void draw(SpriteBatch batch){
  if(shadow != null) batch.draw(shadow, pos.x, pos.y, width, height);
  if(texture != null) batch.draw(texture, pos.x, pos.y, width, height);
// Loop all weapons and draw the active ones
  for(Gun g : weapons){
      if(g.active){
        g.drawRotated(batch);
      }
   }

...
     // Update Camera Position
     cameraPos.set(pos);
     cameraPos.x += width / 2;
}

Gun position
The gun by default is positioned at Hero.pos.x, it it was not moved using the x offset this is how it would look:
001_gun_hero_pos

Once it is in game and rotating you can see if flips but stay in the right hand of the Hero:gun_no_x_offset

The small yellow cross shows the point at which the entity rotates around, placing it here makes the movement seem more real than if it was centred.

When the gun needs to face right flip is set to false and it is rendered hero x + 7. When the gun is facing left the texture is flipped and moved left by 1. The texture flips from the x point so the flip alone moves the texture left by the width. If you change the origin X value you can see how it affects the rotation (Not all weapons would have the same rotation point)

 

Hero update

When the Hero update is called we should update all active weapons so they move with the Hero, we also update the angle, I found that the mouse angle from the centre of the screen did not match the draw function, taking 90 degrees away made these match.

public void update(Control control) {
  ....
  // Update weapons
  for(Gun g : weapons){
  	if(g.active){
            g.updatePos(pos.x, pos.y);
      	    g.angle = control.angle - 90;
  	}
  }

ENUMS

If you wanted a Hero that faced the mouse (8 directions) we can implement a mouse angle to compass position, while this is not used in the tutorial it may be useful to someone and we can use it in the future. Here are the ENUM values, the order of these is important.

/**
 * Compass directions
 */
public enum Compass {
    S,
    SE,
    E,
    NE,
    N,
    NW,
    W,
    SW
}

Control Class

The new angle and facing variables will be set/updated within the the Control class.  On mouseMoved we have the x and y values for the current mouse position which can be used to calculate the angle between the screen centre and the cursor:
angle = (float) Math.toDegrees(Math.atan2(screenX – (screenWidth/2), screenY – (screenHeight/2)));

if the angle is negative then we add 360:
angle = angle < 0 ? angle += 360: angle;

To turn this angle into a compass direction:
direction = (int) Math.floor((angle / 45) + 0.5) & 7;

This will produce 0 to 7 as a result, we can then pick N ENUM from the list, 0 is S 1 is SE and so on:
facing = Compass.values()[direction];

  // ACTIONS
  public boolean interact;
  public float   angle;
  public int     direction;
  public Compass facing;

  @Override
  public boolean mouseMoved(int screenX, int screenY) {
      float flippedY = screenHeight - screenY;
      mousePos.set(screenX, flippedY);

      // Set angle of mouse
      angle = (float) Math.toDegrees(Math.atan2(screenX - (screenWidth/2), screenY - (screenHeight/2)));
      angle = angle  0){
            Rumble.tick(Gdx.graphics.getDeltaTime());
            camera.translate(Rumble.getPos());
        } else {
            camera.position.lerp(hero.cameraPos, .2f); // use new Vector3 variable<span id="mce_SELREST_start" style="overflow:hidden;line-height:0;"></span>
        }

Hopefully there are a few useful snippets of code in the tutorial, remember there are always other ways to achieve a goal and often more efficient methods.

Next time I will add bullets and firing, thanks for reading!

Advertisements

Making a LibGDX Roguelike Survival Game Part 11 – Custom menu / buttons #gamedev

Welcome to the 11th part in this game from scratch series, in this tutorial we look at changing the projection of our sprite batch to allow us to render a heads up display / menu and also create the classes which will allow us to generate interactive menus. The full source code is available on Github.

menu_tutorial

New Images

  • core/assets/gui/main_background.png
  • core/assets/gui/pink_button.png
  • core/assets/gui/square_menu.png
  • core/assets/gui/icons/build.png
  • core/assets/gui/icons/close_menu.png
  • core/assets/gui/icons/resources.png
  • core/assets/gui/icons/settings.png
  • core/assets/gui/selector.png

New classes

  • core/src/uk/co/carelesslabs/ui/BuildMenu.java
  • core/src/uk/co/carelesslabs/ui/Button.java
  • core/src/uk/co/carelesslabs/ui/Menu.java
  • core/src/uk/co/carelesslabs/ui/OnClickListener.java
  • core/src/uk/co/carelesslabs/ui/SquareMenu.java

Updated

  • core/src/uk/co/carelesslabs/Media.java
  • core/src/uk/co/carelesslabs/gameclass.java
  • core/src/uk/co/carelesslabs/Enums.java
  • core/src/uk/co/carelesslabs/Control.java

Custom menu

In this tutorial we will look at creating a custom menu for our game, this eventually will
allow the player to access/view build, settings and inventory. There are libraries available to handle all sorts of inputs (buttons, text boxes etc) such as Scene2D, but when the menu is basic and for learning LibGDX its interesting and sometimes simpler to create your own.

Rendering the menu

Whereas the main game camera moves around the map and can zoom / shake etc the menu view will need to be fixed.

The projection set for game screen is not fit for displaying the menu. Initially I created a new spriteBatch for the HUD (Heads Up Display) which was created using the screen size, this seemed less efficient than having just one spriteBatch, to use only one we will need to update the Matrix of the spriteBatch before rendering the HUD.

We can achieve this by updating the projection of the spriteBatch prior to rendering.

gameclass.java

// new class variable
Matrix4 screenMatrix;

@Override
public void create() {
    ...
    // Setup Matrix4 for HUD
    screenMatrix = new Matrix4(batch.getProjectionMatrix().setToOrtho2D(0, 0, control.screenWidth, control.screenHeight));

...

@Override
public void render () {
  ...
  // GUI
  batch.setProjectionMatrix(screenMatrix);

The screenMatrix will allow us to change to spriteBatch back to a view the size of the screen, co-ordinates 0,0 will be the bottom left of the screen. With the view being the same size as the screen it will be easy to position menu items as we can access the screen width and height.

Menu

Menu.java

The new menu class has a texture which is the background for the menu, a postiion, width and height used when rendering, a Rectanlge (hitbox)
and an array of buttons.

package uk.co.carelesslabs.ui;

import java.util.ArrayList;
import uk.co.carelesslabs.Enums;
import uk.co.carelesslabs.Enums.MenuState;
import uk.co.carelesslabs.entity.Entity;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;

public class Menu {
    public String name;
    public Vector2 pos;
    public Texture texture;
    public float width;
    public float height;
    public float scale;
    public MenuState state;
    public float time;
    public float coolDown;
    public Rectangle hitbox;
    public ArrayList<Button> buttons;

    public Menu(float x, float y, float scale, Texture texture){
        pos = new Vector2(x,y);
        this.texture = texture;
        width = texture.getWidth() * scale;
        height = texture.getHeight() * scale;
        buttons = new ArrayList<Button>();
        hitbox = new Rectangle(x,y,width,height);
        setActive();
    }

    // Render the texture and all of the button textures
    public void draw(SpriteBatch batch){
          if(texture != null) batch.draw(texture, pos.x, pos.y, width, height);
          for(Button b : buttons){
              b.draw(batch);
          }
    }

    // If the player has clicked the mouse then processedClick will be true
    // We check if the mouse position is contained within any of the button Rectangles
    public boolean checkClick(Vector2 pos, boolean processedClick){
        boolean processed = false;
        if(!processedClick){
            if(hitbox.contains(pos)){
                System.out.println("Hit: " + name);
            }

            // Check if a button has been clicked
            for(Button b : buttons){
                if(b.hitbox.contains(pos)){
                    if (b.listener != null) b.listener.onClick(b);
                    processed = true;
                    break;
                }
            }
        } else {
            return processedClick;
        }

        return processed;
    }

    // If the mouse is inside of the menu then check if its also inside of a button
    // When the mouse is inside a button then set its state to hovering
    // Else set all buttons to idle
    public void checkHover(Vector2 pos){
        if(hitbox.contains(pos)){
            // Check if a button is being hovered over
            for(Button b : buttons){
                if(b.hitbox.contains(pos)){
                    b.state = Enums.EnityState.HOVERING;
                } else {
                    b.state = Enums.EnityState.IDLE;
                }
            }
        } else {
            for(Button b : buttons){
              b.state = Enums.EnityState.IDLE;
            }
        }
    }

    // A function to add multiply buttons to our menu
    // It is possible to add any size grid of buttons with a certain sized padding
    public void addButtons(float offset, int columns, int rows, Texture texture, Texture select, int scale) {
        for(int i = 0; i < columns; i++){
            for(int j = 0; j < rows; j++){
                float bx = pos.x + (offset + ((i+1)*offset) + (i * texture.getWidth())) * 2;
                float by = pos.y + (offset + ((j+1)*offset) + (j * texture.getHeight())) * 2;
                float width = texture.getWidth() * 2;
                float height = texture.getHeight() * 2;

                Entity selector = new Entity();
                selector.texture = select;
                selector.width = selector.texture.getWidth() * scale;
                selector.height = selector.texture.getHeight() * scale;
                selector.pos.x = bx - ((selector.width - width) / 2);
                selector.pos.y = by - ((selector.height - height) / 2);

                buttons.add(new Button(bx, by, width, height, texture, selector));
            }
        }
    }

    // Check if the menu is active
    public boolean isActive(){
        return state == Enums.MenuState.ACTIVE;
    }

    // Set meny to active
    public void setActive(){
        state = Enums.MenuState.ACTIVE;
    }

    // Set menu to inactive
    public void setInactive(){
        state = Enums.MenuState.DISABLED;
    }

    // Toggle active state
    public void toggleActive() {
        if(isActive()){
            setInactive();
        } else {
            setActive();
        }
    }
}

Button.java

The Button class extends Entity, it adds an OnClickListener, a hitbox, an icon texture and a selector entity. The OnClickListener defines
what to do when the button is clicked, the hitbox allows us to test if the mouse position when a click occurs should interact with
button, the selector is a texture that is drawn when the button is being hovered over and the icon is a texture to help identify what
the button does.

package uk.co.carelesslabs.ui;

import uk.co.carelesslabs.Enums;
import uk.co.carelesslabs.entity.Entity;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;

public class Button extends Entity {
    public OnClickListener listener;
    public Rectangle hitbox;
    public Texture icon;
    public Entity selector;

    public Button(float x, float y, float width, float height, Texture texture, Entity selector) {
        super();
        this.texture = texture;
        this.selector = selector;
        this.pos.x = x;
        this.pos.y = y;
        this.width = width;
        this.height = height;
        hitbox = new Rectangle(pos.x, pos.y, width, height);
    }

    public void setOnClickListener(OnClickListener listener){
        this.listener = listener;
    }

    @Override
    public void draw(SpriteBatch batch){
        if(texture != null) batch.draw(texture, pos.x, pos.y, width, height);
        if(icon != null) batch.draw(icon, pos.x, pos.y, width, height);
        if(isHovered() && selector != null){
            selector.draw(batch);
        }
    }

    // Is button currently being hovered over by the mouse
    private boolean isHovered(){
        return state == Enums.EnityState.HOVERING;
    }

    // Updates the position and size of the hitbox (Rectangle)
    public void updateHitbox() {
        hitbox.set(pos.x, pos.y, width, height);
    }
}

OnClickListener.java

We can create an instance of this interface for each button and use it to create an over ride of the onClick function, within this function
we can write custom code that will run when onClick is called.

package uk.co.carelesslabs.ui;

public interface OnClickListener {
    public void onClick(Button b);
}

An example of setting the onClick function for a button

// Setting the onClick function for a button called button
// We can put any code here
btn.setOnClickListener(
        new OnClickListener(){
            @Override
            public void onClick(Button b) {
                // Declare code to run here
                System.out.println("This button was clicked.");
            }
        });

SquareMenu.java

The SquareMenu is the bottom left square shapped main menu, it has 3 icons at the moment, one for inventory/resources, a build menu and also an icon for settings.

This class extends menu, we set the position and background texture using super (calls the constructor for the extended class ‘Meny’), 4 buttons are added in a 2×2 grid.
The icons and onClick for each button is set, currently we set up only 3 of the buttons.

A new type of menu ‘Build’ is also added, this menu will be hidden by default and only shown when the build icon/button is clicked.

package uk.co.carelesslabs.ui;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector2;
import uk.co.carelesslabs.Media;
import uk.co.carelesslabs.gameclass;

public class SquareMenu extends Menu {
    public BuildMenu build;

    public SquareMenu(final gameclass game){
        super(0, 0, 2, Media.squareMenu);

        int scale = 2;
        addButtons(3, 2, 2, Media.pinkButton, Media.selector, scale);

        Button btn = buttons.get(0);
        btn.setOnClickListener(
                new OnClickListener(){
                    @Override
                    public void onClick(Button b) {

                    }
                });

        btn = buttons.get(1);
        btn.icon = Media.iconSettings;
        btn.setOnClickListener(
                new OnClickListener(){
                    @Override
                    public void onClick(Button b) {
                        System.out.println("Settings.");
                    }
                });

        btn = buttons.get(2);
        btn.icon = Media.iconResources;
        btn.setOnClickListener(
                new OnClickListener(){
                    @Override
                    public void onClick(Button b) {
                        game.control.inventory = true;
                    }
                });

        btn = buttons.get(3);
        btn.icon = Media.iconBuild;
        buttons.get(3).setOnClickListener(
                new OnClickListener(){
                    @Override
                    public void onClick(Button b) {
                        build.toggleActive();
                    }
                });

        // BUILDING
        build = new BuildMenu(pos.x + width, 0, 2, Media.mainBack);
    }

    // Draw the extended menu and also the build menu.
    @Override
    public void draw(SpriteBatch batch){
        super.draw(batch);
        build.draw(batch);
    }

    // Check if the menu / build menu buttons are being hovered over.
    @Override
    public void checkHover(Vector2 pos) {
        super.checkHover(pos);
        build.checkHover(pos);
    }

}

BuildMenu.java

This class is another extended Menu class which is shown when the build menu button has been pressed. It has 14 columns and 2 rows which will be used
to add building options in another tutorial. Clicking these will allow items to be built/placed onto the map.

This class also adds another button which will call toggleActive(), basically this is a close menu button. The main build menu button will also close
menu when it is clicked and the build menu is currently active.

package uk.co.carelesslabs.ui;

import uk.co.carelesslabs.Media;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class BuildMenu extends Menu {

    public BuildMenu(float x, int y, int scale, Texture mainBack){
        super(x, y, 2, Media.mainBack);
        addButtons(3, 14, 2, Media.pinkButton, Media.selector, 2);
        setInactive();

        // Add a close button
        Button close = new Button(0, 0, Media.close_menu.getWidth() * scale, Media.close_menu.getHeight() * scale, Media.close_menu, null);
        close.pos.x = x + width - (Media.close_menu.getWidth() * scale) - (6 * scale);
        close.pos.y = height - (Media.close_menu.getHeight() * scale) - (6 * scale);
        close.updateHitbox();
        close.setOnClickListener(
                new OnClickListener(){
                    @Override
                    public void onClick(Button b) {
                        toggleActive();
                    }
                });
        buttons.add(close);
    }

    // Only draw when the menu is active.
    public void draw(SpriteBatch batch){
        if(isActive()){
            super.draw(batch);
        }
    }
}

Enum.java

New ENUM list for menu/button states.

...
public enum MenuState {
    ACTIVE,
    DISABLED,
    HOVEROVER,
    CLICKED
}

Control.java

New Vector for the mouse position which is updated on mouseMoved.

...
public Vector2  mousePos = new Vector2();

...
@Override
public boolean mouseMoved(int screenX, int screenY) {
    mousePos.set(screenX, screenHeight - screenY);
    return false;
}

The menus are not yet complete but this gives us a decent foundation for completing / progressing our HUD.

LibGDX Simple Slides

Currently working on a game for Wing Wing Shoot Bag using Java with LibGDX. While trying to learn Pixel/Game art I produced a few animated GIFS, one of which would be perfect for the main screen.

Being a little lazy I thought of loading in the individual images and looping through them rather than create one large image and cut it up programmatically for an animation. This worked, I had created a sort of slide player.

After pressing start within the game menu I wanted the current frame to pause and fade out, then the intro of the game would play. The intro follows the movie to which the game is based, several images would fade in, hold then fade out.

Fading in and out
First off I needed to find a way to fade an image in or out, there is a library available to do this: https://code.google.com/p/java-universal-tween-engine/

I followed the guide and setup a Sprite Accessor class: Class source

Slide Manager
Next I created a slide manager class, this would hold an array of slides which could have some simple attributes:

  • sprite;              // The image
  • fade_duration  // Time to fade in or out
  • hold_duration  // Time to hold slide on screen after fade in
  • total_duration  // time for fade in, hold and fade out
  • gap_duration   // time between slides

Classes: Slide ClassSlide Manager

Creating and using the Slide manager
Basically you initiate the new class then add to the array of images with some settings. During the render loop you tell the class to update and it will play your images in order; fading them in and out.

// Declare a new var
SlideManager slide_manager;

// Slides
slide_manager = new SlideManager();

// Add slides that fade in for 4 seconds, holds for 1 seconds
// After fade out leaves a gap of 1 seconds before next slide

slide_manager.add_slide(new Slide(“intro/screens/russian.png”, 4, 1, 1));
slide_manager.add_slide(new Slide(“intro/screens/spy.png”, 4, 1, 1));

// Add a slide with an overlay animation
// Passes animation width, speed and position
slide_manager.add_slide(new Slide(“bck.png”, 2, 0, 1, “frames.png”, 70, 0.1f, 45, 25));

I started playing about with a few variations of slides, would probably move the extras such as animations into an array and create a new animation class to pass with the slide.

This is a render loop for the intro screen, when the slides are done it just loads the next screen:

public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
slide_manager.tick(delta);

// DRAW
batch.begin();
if (!slide_manager.finished){
slide_manager.draw(batch);
}
batch.end();

if (slide_manager.finished){
game.setScreen(game.level_one);
}
}

This is a very quick prototype which only allows simple fading in and out and overlaying of one animation. It requires a library to be imported even though setting the colour(Alpha) of a sprite over time is very simple I could go on to use many more of the libs features.

This class will allows me to quickly create simple comic book style cuts scenes between levels while prototyping.

 

Pixel Art and new project

I have been busy lately with all sorts of things, time off work, ran a marathon but I did start learning pixel art recently so thought I would blog about it.

There many types of artists, sadly I fall into the category of a coder with a zero game budget who has to make all his own art or will have no game. After making the two Jam games I felt it was time to return to my main game “Endure” but while wasting some time on FaceBook I saw a message on a group I follow saying they were celebrating their 10 Year anniversary:

Wing Wing Shoot Bag Facebook group

Anyway, I offered to make the group a game based on a feature length movie they made some 6 years ago about a transgender cop called “Susan Balaka”, they also make short comedy sketches but this had a full story which would be awesome to make into a game.

Oh yes Pixel Art,the game would require lots of animated scenes and pixel style art, so I started having a go:

First Attempt at Balaka

This was a bit shoddy and the guns look like socks! Next I found some forums and asked for help, you may find these useful:


Forums
Final Boss Blues
Way of the Pixel
Pixel Joint
Reddit – pixelart

With some help and reading tutorials I broke a whole new set of pixel art rules and came up with these:

Two main characters (Line from the movie)

One rule I broke early on was using far to many colours, the advise I received most often referred to colour palette and contrast between colours. A useful site for checking how many colours your using:
http://wouterpleizier.nl/pj/index.php?input=http://snag.gy/FngMY.jpg

After some help from Final Boss Blues I started adding some shading to the characters faces, as you progress you look back at your earlier work and realise you will need to redo them over.

Trying to add detail

There will be all sorts of assets in the Balaka game, I had a go at making an arcade machine to test the use of isometric angles with pixel art, I am far from good at this but you can see what it is and its not too ugly?

After making several static images that I tried my hand at animation, I have made simple animations for other games but I always seem to make some sort of mistake, here the flash from the screen is not really pixel art as such and the feet/body position is all wrong.

So there you have it, I am now learning pixel art while making a game. I would suggest finding some good pixel artists and following their work, realise that you will make mistakes, when asking for help do not take criticisms to heart and say thanks when people take the time out to give help.

“His head looks like a potato” – I could have tried to defend this comment but its true and made me laugh.

Happy Pixeling!

 

Humble indie dev’s game jam adventure

So I decided to take part in a few game jams to see what they were all about, I have mixed feelings about them and will take you through my highs and lows during two recent jams.

What is a Jam?
Within a set period of time you have to produce a game to some theme or basic specification. The rules are usually basic.

Why Jam
Having clear goals and a deadline really gets you working! I was making pixel art and thinking of how it would work in the game, basically multitasking like a beast. You learn new things rapidly and learn to actually finish tasks so there are lots of pro’s to taking part in a jam. For many this will be the first project this see through to publishing.

My Journey
After seeing the Flappy Bird game do so well I though why not make something simple like this to see project from start to finish in a few days, then I found Flappy Jam!

http://itch.io/jam/flappyjam

Flappy Jam main image

Clicky Pixel
I got to work right away on the basic game and had a square dodging blocks before long and it ran well on all mobiles! WIN! Then I made my first big mistake, instead of adding graphics and submitting I decided to add levels, HP and character unlocks.

As a solo hobby developer I have little time and no resources and a wife who likes to see me every now and again, I basically locked myself in my study night after night polishing the game and trying to do far too much.

note: Samsung mobile with battery save mode enabled = poor fps!

My Entry

My First Itch.io game

Only 4 votes! I submitted at some stupid time in the morning then posted a bit about the game and slept the next evening at 7pm, I was tired and still have a busy day job to do! oh and I am training for a marathon and have 30+ miles to run a week.

Once the game was in the list I lost all interest and had to get my sleep pattern back to normal and try to make it up to the wife.

Feedback
Feedback

I did get a little bit of feedback, Okeedoke Studios comment is priceless, imagine that a Flappy Game being a bit grindy! This really made my day and also 556 views and 199 downloads was great.

I promised the wife I would wait a while before the next jam and get back to my main game Endure and take it easy, so I waited a few days then saw CyberPunkJam and thought I am doing that!


Cyber Punk Jam
With Clicky Pixel finished and shelved I was no longer a jam virgin and ready for more, this time I would be even more focused and learn from my mistakes, so I decided on an even more complicated game that would require much more art, more code and this time Id go for mobile, Windows, Mac and HTML!

CYPERPUNK Jam main image

So make a game based on the image of some punks jumping off a building, first thought was base jumping, too simple I thought, before I could even research it someone had posted their game and yes it was a sky diving game.

I decided I would do something a little different and after some time decided to remake an old Amiga classic “Walker”.

Using LibGDX and some ripped sprites of the origin game I quickly mocked up a walking bot: View the Sprites here

I was not intending to keep these sprites in the demo I submitted, but I had little time to work on the game. I produced some punks to use as enemies and played about with pixels for a few evenings:

Some sprites for the game
I also changed my screen saver and bought a new t-shirt! Making animated sprites is a slow process for a coder, I had to keep Googling for examples to help me get ideas, the game could have done with many more enemies but there was no game yet and I was running out of time. I made two types of punks, a helicopter and an Akira style biker, I am really happy with them overall.
Final Day

I only actually submitted this game as the jam had a 48 hour extension, I came home from work late, sat at my computer with very little complete; a robot that moved and shot bullets, a few enemies that had no AI and just ran across the screen, at this point there were no sounds and no background.

I made a background and 3 shops that would give the impression you were moving forward between waves, this took about an hour. Next I had to produce an algorithm to produce wave attacks, I got this so wrong, the first waves were fine but if you got to around round 6 you were completed overwhelmed, but I had run out of time. I think it was around 4am when I uploaded the .jar and HTML versions of the game, “Mech Stroller”PLAY HERE

Mech Stroller Wave 0

The game was full of bugs and lacked:

  • Power Ups
  • Decent AI
  • Up / Down movement
  • Balanced Waves 
  • Parachutes!

I spent an hour over my lunch break and put better waves into place and made the enemies a little more random with their movement, once this was published I saw a tweet saying I may have broken some rules in updating the game after the cut off point! If the game had been pulled I would have been annoyed but seems I got away with this.

Twitter, Forums & Reddit
So this time I understood it was important to get people playing the game and getting more feedback than with Clicky P. I posted to twitter every so often, posted in some of the Java forums I use and also hit Reddit for the first time.

Those people at Reddit must deal with a lot of spam and general time wasters, if you delete a post they make you wait forever to repost, I almost gave up on it, had to make a second account just to post, it is just not a nice interface to use:

It was worth using Reddit though as it brought some traffic to the game page, overall the game had around 500 views and maybe 70 downloads of the .Jar file. This just shows if you are producing a real game you need a solid


Voting
If you want to place in the Jam you are going to have to spend time convincing others who submitted games to play and vote on your game, some 268 people contributed to the jam in total, you are going to want a decent number of votes or a least a few that score you highly.

I played other games for hours and hours adding comments and trying to vote fairly, I must have voted on about 150 of the games, each time if possible tweeting to the dev asking them to check out my game in return.

I had 34 votes from other devs:

I am pretty happy with this score, considering I probably only spent half the available time on the game and put more effort into learning pixel art its a miracle there was any game at all. I find it strange how people will comment on whats missing from the game, the jam was around 10/12 days long and I am one person with a full time job, collaborating might be a better idea for more adventurous ideas.

Conclusions

I have learned a lot about myself, game making and a small faction of the Indie Game Scene during the last month or so. There are a lot of kind people out there on Twitter willing to help, give feedback and motivate you, this is great and really helped me stick at it.

Before you dive into coding or drawing try to come up with a simple idea that is possible in complete in the given time. Make a list of the assets you need for the game, if the list is getting to big you are aiming too high, try to truncate the list as much as possible. If you know others who might like to team up then work this out before the jam, I would have loved to team up with an artist for this so I could concentrate on the code.

I did enjoy talking to other developers after the jam ended but I did feel a bit of an anti-climax, the fun for me was making the game even though I didn’t have enough time to really get it to a point I was happy with.

Use the Jams to make you fast prototype an idea and get some feedback but I would not suggest taking the comments on your game too personally, not everyone will like what you have done and this was made in no time at all.


Most of all try to have fun and interact with the Indie community as much as possible! I hope you enjoyed reading, please check out my games and throw any questions to me on Twitter @carelesslabs

Careless releases Android game

Download the game here: http://itch.io/jam/flappyjam/rate/2989

After seeing all the Flappy Clones being published on the Play store I thought it would be fun to attempt a similar game, a few days after I started the #FlappyJam started so I had a deadline!

I quickly got the basic mechanics up and running, a score, randomly placed blockers and a character that moved up and down. Not totally convinced with the movement I put a trail in place which I thought looked neat and it made it into the final game.

To make this game stand apart from Flappy Bird I decided to add levels, each time you play your score adds to a total percentage and upon reaching that the next level is unlocked.

Then just to add another dimension to the game I added a bank, character selection and hearts (HP). All of your points go into your bank total, hearts allow you to get hit in game and the new characters get smaller so its easier to avoid the blockers.
Working on a smaller game has been a lot of fun, the level design was quite rewarding, the way in which its coded means you can just drop in a new folder with the correct graphics; change one variable number_of_levels and its instantly in game.
I will try to add a more detailed write up on actual code soon, please check out the game at:

LibGDX and Parse.com

To have a break from fish this evening decided to set up a highscore board as a test case for JSON and online storage for Endure.

Full Source Code

Signed up for Parse.com a very neat data-store for mobiles and web applications, they provide example projects for JavaScript, Unity, Android and other platforms.

The best thing is the price… free!

Features

  • Requests: 1 million/month
  • Pushes: 1 million/month
  • Burst Limit: 20/second

 Scores Table

 I did try out the Android sample project but without your app being Andriod as expected there was no way to use the .Jar libraries that Parse provide, but they do offer a great Restful method to POST and GET your data.

Custom Parse Class

I wrote a very simple Java class and imported Java’s own Net and IO libraries did not take long to get some scores in and out of the service.

LibGDX has its own Net library so I also gave this a go as my code looked messy, have some speed tests to run yet but happy to be able to push and pull data for free and with no real hassle.

I will not go through my code put post the class for you to see, the important lines here are:

httpPost.setHeader(“X-Parse-Application-Id”, app_id);
httpPost.setHeader(“X-Parse-REST-API-Key”, app_key);

conn.setRequestProperty(“X-Parse-Application-Id”, app_id);
conn.setRequestProperty(“X-Parse-REST-API-Key”, app_key);

While looking how others use Parse with Java I saw a lot of complaints about unauthorized errors, Parse provides many different keys and you have to set and use the right ones. 

Full Source Code

Code adding hard coded score and retrieving all scores

Lots of testing left to do with this and of course will need to ask the user their name (@twitter_tag) when they start the game, will use this for the upcoming fishing competition and keep a track of all the fish caught.

Also will need to use a JSON library to properly generate the string that is post and also parse the results into objects.

Thanks for reading.