package com.jonathan.survivor.hud;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton;
import com.jonathan.survivor.World;
import com.jonathan.survivor.entity.Human.Direction;
/*
* An instance of this class will display the HUD whilst in EXPLORATION mode.
*/
public class ExplorationHud extends Hud
{
/** Stores the offsets of both arrow buttons. Used to anchor the buttons to the corners of the screen. */
public static final float ARROW_BUTTON_X_OFFSET = 15f;
public static final float ARROW_BUTTON_Y_OFFSET = 10f;
/** Stores the color of the arrow buttons. */
public static final Color ARROW_BUTTON_COLOR = new Color(1, 0.1f, 0, 1);
/** Stores the left and right arrow buttons to make the player move left and right. */
private ImageButton leftArrowButton, rightArrowButton;
/** Stores the offsets of the backpack button. Used to anchor the button to the corner of the screen with a given offset. */
public static final float BACKPACK_BUTTON_X_OFFSET = 5;
public static final float BACKPACK_BUTTON_Y_OFFSET = 5;
/** Holds the scale of the backpack button's hit box. Allows for easier clicking. */
public static final float BACKPACK_HIT_BOX_SCALE = 2;
/** Stores the Backpack button. */
private Button backpackButton;
/** Stores the offset of the pause button. Used to anchor the button to the top-right corner of the screen with a given offset. */
public static final float PAUSE_BUTTON_X_OFFSET = 5;
public static final float PAUSE_BUTTON_Y_OFFSET = 5;
/** Holds the scale of the pause button's hit box. Allows for easier clicking. */
public static final float PAUSE_HIT_BOX_SCALE = 2;
/** Stores the Pause Button, used to pause the game. */
private Button pauseButton;
/** Stores the listener used to listen for events from the arrow buttons. */
private ButtonListener buttonListener;
/** Stores the buttons displaying the left and right arrows to move the player. */
private boolean leftArrowButtonDown, rightArrowButtonDown;
/** Accepts the stage where 2d widgets will be drawn and placed, and the world, which will receive information about
* button presses. */
public ExplorationHud(Stage stage, World world)
{
super(stage, world);
//Creates the left and right arrow buttons for movement.
leftArrowButton = new ImageButton(assets.leftArrowButtonStyle);
rightArrowButton = new ImageButton(assets.rightArrowButtonStyle);
//Creates the backpack button, which transitions to the backpack, and the pause button. which re-directs to the pause menu.
backpackButton = new Button(assets.backpackButtonStyle);
pauseButton = new Button(assets.pauseButtonStyle);
//Resize the arrow buttons according to the scale factor of the screen so that every atlas size creates the button with the same size in world units.
leftArrowButton.setSize(leftArrowButton.getWidth() / assets.scaleFactor, leftArrowButton.getHeight() / assets.scaleFactor);
rightArrowButton.setSize(rightArrowButton.getWidth() / assets.scaleFactor, rightArrowButton.getHeight() / assets.scaleFactor);
//Scales down the top-most buttons by the scale factor of the assets. Ensures that the sprites are scaled down if larger atlases were chosen.
backpackButton.setSize(backpackButton.getWidth() / assets.scaleFactor, backpackButton.getHeight() / assets.scaleFactor);
pauseButton.setSize(pauseButton.getWidth() / assets.scaleFactor, pauseButton.getHeight() / assets.scaleFactor);
//Scales the hit box of the backpack and pause buttons to give the user more room to click them.
scaleHitBox(backpackButton, BACKPACK_HIT_BOX_SCALE);
scaleHitBox(pauseButton, PAUSE_HIT_BOX_SCALE);
//Sets the colors of the buttons.
leftArrowButton.setColor(ARROW_BUTTON_COLOR);
rightArrowButton.setColor(ARROW_BUTTON_COLOR);
//Adds transparency to the pause button.
pauseButton.setColor(new Color(1,1,1,0.7f));
//Creates a new listener for the buttons
buttonListener = new ButtonListener();
//Adds the listeners to the buttons to know when they are pressed.
leftArrowButton.addListener(buttonListener);
rightArrowButton.addListener(buttonListener);
//Add the listeners to the top-most buttons to register button clicks.
backpackButton.addListener(buttonListener);
pauseButton.addListener(buttonListener);
}
@Override
public void draw(float deltaTime)
{
//If the right arrow button is being held down
if(rightArrowButtonDown)
{
//Make the player move right.
world.walk(world.getPlayer(), Direction.RIGHT);
}
//If the left arrow button is being held down
else if(leftArrowButtonDown)
{
//Make the player move left by changing him to his walking state.
world.walk(world.getPlayer(), Direction.LEFT);
}
//Draws the widgets to the screen.
super.draw(deltaTime);
}
class ButtonListener extends InputListener
{
/** Delegates when a button is pressed. */
@Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
//Pauses input. Ensures that no gestures or input triggers player movement while a button is pressed.
hudListener.toggleInput(false);
//If the right arrow button was pressed or its overlaying arrow image was pressed
if(event.getTarget() == rightArrowButton || event.getTarget() == rightArrowButton.getImage())
{
//The right arrow button is currently being pressed
rightArrowButtonDown = true;
}
//If the left arrow button was pressed or its overlaying arrow image was pressed
else if(event.getTarget() == leftArrowButton || event.getTarget() == leftArrowButton.getImage())
{
//The left arrow button is currently being pressed
leftArrowButtonDown = true;
}
//Returns true so the touchUp can be called when the button is released.
return true;
}
/** Delegates when a button is released. */
@Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button)
{
//Resumes input. Ensures that gestures or input can call player movement methods, since a HUD button was released.
hudListener.toggleInput(true);
//If the right arrow button was released, stop the player from moving. Note that the image on the button can also be a target.
if(event.getTarget() == rightArrowButton || event.getTarget() == rightArrowButton.getImage())
{
//The right arrow button is no longer being pressed.
rightArrowButtonDown = false;
//Stops the player from moving right once the right directional button is unpressed.
world.stopMoving(world.getPlayer());
}
//If the left arrow button was released, stop the player from moving. Note that the image on the button can also be a target.
else if(event.getTarget() == leftArrowButton || event.getTarget() == leftArrowButton.getImage())
{
//The left arrow button is no longer being pressed.
leftArrowButtonDown = false;
//Stops the player from moving left once the left directional button is unpressed.
world.stopMoving(world.getPlayer());
}
//Else, if the backpackButton was released, transition to the backpack inventory page.
else if(event.getTarget() == backpackButton)
{
//Tell the GameScreen that the BackpackButton was pressed by delegating the appropriate method call to the HudListener.
hudListener.onBackpackButton();
}
//Else, if the pause button was pressed
else if(event.getTarget() == pauseButton)
{
//Tell the GameScreen that the pause button has been pressed. Switches to the pause menu.
hudListener.onPauseButton();
}
}
}
/** Called when the stage must be reset to draw the widgets contained in this class. Used when the stage needs to be re-purposed. Also called when the
* screen is resized to re-place the widgets. */
@Override
public void reset(float guiWidth, float guiHeight)
{
//Clears the stage and all its widgets to re-purpose the stage to draw the exploration HUD.
stage.clear();
//Ensures that the right/left arrow button down booleans are set to false by default.
rightArrowButtonDown = leftArrowButtonDown = false;
//Anchor the left arrow button to the bottom left of the screen using the offset constants.
leftArrowButton.setPosition(ARROW_BUTTON_X_OFFSET, ARROW_BUTTON_Y_OFFSET);
//Anchor the right arrow button to the bottom right of the screen using the offset constants.
rightArrowButton.setPosition(stage.getWidth() - rightArrowButton.getWidth() - ARROW_BUTTON_X_OFFSET, ARROW_BUTTON_Y_OFFSET);
//Anchors the backpack button to the top left of the screen using the offset constants.
backpackButton.setPosition(BACKPACK_BUTTON_X_OFFSET, stage.getHeight() - backpackButton.getHeight() - BACKPACK_BUTTON_Y_OFFSET);
//Anchors the pause button to the top right of the screen, and offsets it according to the pre-defined constants.
pauseButton.setPosition(stage.getWidth() - pauseButton.getWidth() - PAUSE_BUTTON_X_OFFSET, stage.getHeight() - pauseButton.getHeight() - PAUSE_BUTTON_Y_OFFSET);
//Add the widgets to the stage.
stage.addActor(leftArrowButton);
stage.addActor(rightArrowButton);
//Adds the backpack button to the stage.
stage.addActor(backpackButton);
//Adds the pause button to the stage.
stage.addActor(pauseButton);
}
/** Scales the bounds of the actor by the given amount. Allows to re-scale the bounding boxes of a button. Note that the
* re-scaled bounds are centered on the actor. */
private void scaleHitBox(Actor actor, float scale)
{
//Retrieves the width and height of the actor
float width = actor.getWidth();
float height = actor.getHeight();
//Sets the origin of the actor at the correct position so that the hit box is scaled relative to the center of the button.
actor.setOrigin(((width * scale) - width)/2, ((height * scale) - height)/2);
//Scales the actor by the given scalar quantity.
actor.setScale(actor.getScaleX()*scale);
}
}