Added game over & victory condition & round system.

This commit is contained in:
Jeasonfire 2015-05-17 01:10:51 +03:00
parent c5ad241dd3
commit 94d9606963
18 changed files with 352 additions and 72 deletions

View File

@ -8,6 +8,7 @@ import com.badlogic.gdx.Gdx;
import com.saltosion.gladiator.gui.GUIManager;
import com.saltosion.gladiator.input.InputHandler;
import com.saltosion.gladiator.level.EntityFactory;
import com.saltosion.gladiator.level.LevelFactory;
import com.saltosion.gladiator.state.BaseState;
import com.saltosion.gladiator.state.MainMenuState;
import com.saltosion.gladiator.systems.AISystem;
@ -22,6 +23,7 @@ public class GladiatorBrawler extends ApplicationAdapter {
private Engine engine;
private EntityFactory entityFactory;
private LevelFactory levelFactory;
private GUIManager guiManager;
private InputHandler inputHandler;
@ -40,6 +42,10 @@ public class GladiatorBrawler extends ApplicationAdapter {
entityFactory = new EntityFactory();
AppUtil.entityFactory = entityFactory;
// Initialize the LevelFactory
levelFactory = new LevelFactory();
AppUtil.levelFactory = levelFactory;
// Initialize GUI
guiManager = new GUIManager();
AppUtil.guiManager = this.guiManager;

View File

@ -3,6 +3,7 @@ package com.saltosion.gladiator.components;
import com.badlogic.ashley.core.Component;
import com.badlogic.gdx.math.Vector2;
import com.saltosion.gladiator.listeners.CollisionListener;
import com.saltosion.gladiator.util.Direction;
public class CPhysics extends Component {
@ -120,6 +121,16 @@ public class CPhysics extends Component {
return this;
}
public CPhysics setDirection(Direction dir) {
if (dir == Direction.RIGHT) {
this.movedLeftLast = false;
}
if (dir == Direction.LEFT) {
this.movedLeftLast = true;
}
return this;
}
public Vector2 getPosition() {
return this.position;
}

View File

@ -0,0 +1,45 @@
package com.saltosion.gladiator.gui.creators;
import com.saltosion.gladiator.gui.nodes.ButtonNode;
import com.saltosion.gladiator.gui.nodes.TextNode;
import com.saltosion.gladiator.util.AppUtil;
import com.saltosion.gladiator.util.Name;
import com.saltosion.gladiator.util.SpriteLoader;
public class GameOverGUICreator implements GUICreator {
private boolean shouldReturn = false;
@Override
public void create() {
TextNode titleText = new TextNode("Game Title", "Gladiator Brawler Game Thing!");
titleText.setPosition(0.23f, 0.8f);
AppUtil.guiManager.getRootNode().addChild(titleText);
TextNode gameOverText = new TextNode("Game Over", "Game over");
gameOverText.setPosition(0.415f, 0.6f);
AppUtil.guiManager.getRootNode().addChild(gameOverText);
ButtonNode playButton = new ButtonNode("Return Button", SpriteLoader.loadSprite(Name.BUTTON_BIG),
SpriteLoader.loadSprite(Name.BUTTON_BIG_HOVER)) {
@Override
public void pressed(int x, int y, int mouseButton) {
}
@Override
public void released(int x, int y, int mouseButton) {
shouldReturn = true;
}
};
playButton.setPosition(0.5f, 0.4f);
TextNode playButtonText = new TextNode("Return Button Text", "Main Menu");
playButtonText.setPosition(-0.09f, 0.0175f);
playButton.addChild(playButtonText);
AppUtil.guiManager.getRootNode().addChild(playButton);
}
public boolean shouldReturn() {
return shouldReturn;
}
}

View File

@ -0,0 +1,45 @@
package com.saltosion.gladiator.gui.creators;
import com.saltosion.gladiator.gui.nodes.ButtonNode;
import com.saltosion.gladiator.gui.nodes.TextNode;
import com.saltosion.gladiator.util.AppUtil;
import com.saltosion.gladiator.util.Name;
import com.saltosion.gladiator.util.SpriteLoader;
public class WinGUICreator implements GUICreator {
private boolean shouldReturn = false;
@Override
public void create() {
TextNode titleText = new TextNode("Game Title", "Gladiator Brawler Game Thing!");
titleText.setPosition(0.23f, 0.8f);
AppUtil.guiManager.getRootNode().addChild(titleText);
TextNode gameOverText = new TextNode("Win", "You win!");
gameOverText.setPosition(0.415f, 0.6f);
AppUtil.guiManager.getRootNode().addChild(gameOverText);
ButtonNode playButton = new ButtonNode("Return Button", SpriteLoader.loadSprite(Name.BUTTON_BIG),
SpriteLoader.loadSprite(Name.BUTTON_BIG_HOVER)) {
@Override
public void pressed(int x, int y, int mouseButton) {
}
@Override
public void released(int x, int y, int mouseButton) {
shouldReturn = true;
}
};
playButton.setPosition(0.5f, 0.4f);
TextNode playButtonText = new TextNode("Return Button Text", "Main Menu");
playButtonText.setPosition(-0.09f, 0.0175f);
playButton.addChild(playButtonText);
AppUtil.guiManager.getRootNode().addChild(playButton);
}
public boolean shouldReturn() {
return shouldReturn;
}
}

View File

@ -7,10 +7,11 @@ import com.saltosion.gladiator.components.CAI;
import com.saltosion.gladiator.components.CCombat;
import com.saltosion.gladiator.components.CPhysics;
import com.saltosion.gladiator.components.CRenderedObject;
import com.saltosion.gladiator.listeners.CombatListener;
import com.saltosion.gladiator.listeners.BasicDeathListener;
import com.saltosion.gladiator.listeners.ai.DummyAI;
import com.saltosion.gladiator.util.AppUtil;
import com.saltosion.gladiator.util.Direction;
import com.saltosion.gladiator.util.Global;
import com.saltosion.gladiator.util.Name;
import com.saltosion.gladiator.util.SpriteLoader;
import com.saltosion.gladiator.util.SpriteSequence;
@ -19,48 +20,52 @@ public class EntityFactory {
private final static int IDLE_ANIMATION_SPEED = 1, RUN_ANIMATION_SPEED = 15, SWING_ANIMATION_SPEED = 10;
public void createPlayer(Vector2 pos) {
public Entity createPlayer(Vector2 pos) {
return createPlayer(pos, Direction.RIGHT);
}
public Entity createPlayer(Vector2 pos, Direction initialDirection) {
Entity player = new Entity();
player.flags |= Global.FLAG_ALIVE;
// Graphics
player.add(createPlayerRenderedObject());
// Physics
player.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y));
player.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y).setDirection(initialDirection));
// Combat
player.add(new CCombat().setBaseDamage(100).setHealth(1000));
player.add(new CCombat().setBaseDamage(100).setHealth(1000)
.setCombatListener(new BasicDeathListener()));
AppUtil.engine.addEntity(player);
AppUtil.player = player;
return player;
}
public void createDummy(Vector2 pos) {
public Entity createDummy(Vector2 pos) {
return createDummy(pos, Direction.RIGHT);
}
public Entity createDummy(Vector2 pos, Direction initialDirection) {
Entity dummy = new Entity();
dummy.flags |= Global.FLAG_ALIVE;
// Graphics
dummy.add(createPlayerRenderedObject());
// Physics
dummy.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y));
dummy.add(new CPhysics().setSize(1.5f, 3.299f).setPosition(pos.x, pos.y).setDirection(initialDirection));
// Combat
dummy.add(new CCombat().setBaseDamage(100).setHealth(1000).setSwingCD(.5f).setCombatListener(
new CombatListener() {
@Override
public void died(Entity source, int damageTaken) {
System.out.println("Nooooo! I died! I will revenge this!");
}
@Override
public void damageTaken(Entity source, int damageTaken) {
System.out.println(String.format("I took %d damage! Damnit!", damageTaken));
}
}));
dummy.add(new CCombat().setBaseDamage(100).setHealth(1000).setSwingCD(.5f)
.setCombatListener(new BasicDeathListener()));
dummy.add(new CAI().setReactDistance(5).setAIListener(new DummyAI()));
AppUtil.engine.addEntity(dummy);
return dummy;
}
private CRenderedObject createPlayerRenderedObject() {

View File

@ -4,6 +4,10 @@ public interface Level {
public String getLevelName();
public boolean levelCleared();
public boolean levelFailed();
public void generate();
}

View File

@ -1,5 +1,6 @@
package com.saltosion.gladiator.level;
import com.badlogic.ashley.core.ComponentMapper;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Vector2;
@ -12,16 +13,18 @@ import com.saltosion.gladiator.util.Name;
import com.saltosion.gladiator.util.SpriteLoader;
import com.saltosion.gladiator.util.SpriteSequence;
public class TestLevel implements Level {
public class LevelFactory {
@Override
public String getLevelName() {
return "Test level";
private static final ComponentMapper<CPhysics> pm = ComponentMapper.getFor(CPhysics.class);
public void createLevelBase() {
createAudience();
createWall();
CPhysics groundPO = pm.get(createGround());
createBorders(groundPO);
}
@Override
public void generate() {
// Audience
public Entity createAudience() {
Entity audience = new Entity();
Sprite audienceSprite0 = SpriteLoader.loadSprite(Name.AUDIENCEIMG, 0, 0, 768, 576);
Sprite audienceSprite1 = SpriteLoader.loadSprite(Name.AUDIENCEIMG, 1, 0, 768, 576);
@ -37,7 +40,10 @@ public class TestLevel implements Level {
audience.add(audiencePO);
AppUtil.engine.addEntity(audience);
// Wall
return audience;
}
public Entity createWall() {
Entity wall = new Entity();
Sprite wallSprite = SpriteLoader.loadSprite(Name.WALLIMG);
CRenderedObject wallRO = new CRenderedObject(wallSprite);
@ -49,7 +55,10 @@ public class TestLevel implements Level {
wall.add(wallPO);
AppUtil.engine.addEntity(wall);
// Ground
return wall;
}
public Entity createGround() {
Entity ground = new Entity();
Sprite groundSprite = SpriteLoader.loadSprite(Name.GROUNDIMG);
CRenderedObject groundRO = new CRenderedObject(groundSprite);
@ -61,8 +70,11 @@ public class TestLevel implements Level {
ground.add(groundPO);
AppUtil.engine.addEntity(ground);
// Level borders
float xClamp = groundPO.getSize().x / 2f;
return ground;
}
public void createBorders(CPhysics ground) {
float xClamp = ground.getSize().x / 2f;
AppUtil.engine.getSystem(RenderingSystem.class).setXMin(-xClamp).setXMax(xClamp);
Entity borderLeft = new Entity();
@ -77,10 +89,6 @@ public class TestLevel implements Level {
borderRightPhysics.setPosition(xClamp + borderRightPhysics.getSize().x, 0);
borderRight.add(borderRightPhysics);
AppUtil.engine.addEntity(borderRight);
// Generate entities
AppUtil.entityFactory.createPlayer(new Vector2(0, 5));
AppUtil.entityFactory.createDummy(new Vector2(-6, 5));
}
}

View File

@ -0,0 +1,43 @@
package com.saltosion.gladiator.level.premade;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.math.Vector2;
import com.saltosion.gladiator.level.Level;
import com.saltosion.gladiator.util.AppUtil;
import com.saltosion.gladiator.util.Direction;
import com.saltosion.gladiator.util.Global;
import java.util.ArrayList;
public class Round1Level implements Level {
public Entity player;
public ArrayList<Entity> enemies = new ArrayList<Entity>();
@Override
public String getLevelName() {
return "Round 1";
}
@Override
public boolean levelCleared() {
for (Entity enemy : enemies) {
if ((enemy.flags & Global.FLAG_ALIVE) == Global.FLAG_ALIVE) {
return false;
}
}
return true;
}
@Override
public boolean levelFailed() {
return (player.flags & Global.FLAG_ALIVE) == 0;
}
@Override
public void generate() {
AppUtil.levelFactory.createLevelBase();
player = AppUtil.entityFactory.createPlayer(new Vector2(-10, 2), Direction.RIGHT);
enemies.add(AppUtil.entityFactory.createDummy(new Vector2(10, 2), Direction.LEFT));
}
}

View File

@ -0,0 +1,17 @@
package com.saltosion.gladiator.listeners;
import com.badlogic.ashley.core.Entity;
import com.saltosion.gladiator.util.Global;
public class BasicDeathListener implements CombatListener {
@Override
public void died(Entity source, Entity target, int damageTaken) {
target.flags &= ~Global.FLAG_ALIVE;
}
@Override
public void damageTaken(Entity source, Entity target, int damageTaken) {
}
}

View File

@ -3,18 +3,23 @@ package com.saltosion.gladiator.listeners;
import com.badlogic.ashley.core.Entity;
public interface CombatListener {
/**
* This is called when the entity dies.
* @param source The Entity that dealt the damage. Null if called without source.
*
* @param source The Entity that dealt the damage. Null if called without
* source.
* @param target The target of the damage. Should never be null.
* @param damageTaken The damage dealt, that killed the entity.
*/
public void died(Entity source, int damageTaken);
public void died(Entity source, Entity target, int damageTaken);
/**
* This is called when the entity takes damage.
*
* @param source Source of the damage. Null if called without source.
* @param target The target of the damage. Should never be null.
* @param damageTaken Amout of damage taken.
*/
public void damageTaken(Entity source, int damageTaken);
public void damageTaken(Entity source, Entity target, int damageTaken);
}

View File

@ -16,7 +16,7 @@ public abstract class BaseState {
public abstract void destroy();
public void changeState(BaseState newState) {
public void setState(BaseState newState) {
mainClass.setState(newState);
}

View File

@ -0,0 +1,32 @@
package com.saltosion.gladiator.state;
import com.saltosion.gladiator.gui.creators.GameOverGUICreator;
import com.saltosion.gladiator.util.AppUtil;
public class GameOverState extends BaseState {
private GameOverGUICreator guiCreator;
@Override
public void create() {
// Start from a clean slate
AppUtil.guiManager.clearGUI();
guiCreator = new GameOverGUICreator();
guiCreator.create();
}
@Override
public void update(float deltaTime) {
if (guiCreator.shouldReturn()) {
setState(new MainMenuState());
}
}
@Override
public void destroy() {
// Clear GUI so there's nothing leftover for the next state
AppUtil.guiManager.clearGUI();
}
}

View File

@ -1,16 +1,18 @@
package com.saltosion.gladiator.state;
import com.saltosion.gladiator.gui.creators.GUICreator;
import com.saltosion.gladiator.gui.creators.InGameGUICreator;
import com.saltosion.gladiator.level.Level;
import com.saltosion.gladiator.level.TestLevel;
import com.saltosion.gladiator.level.premade.Round1Level;
import com.saltosion.gladiator.util.AppUtil;
public class InGameState extends BaseState {
private static final Level[] levels = {new Round1Level()};
private Level level;
private InGameGUICreator guiCreator;
private int currentLevel = 0;
private float timeSinceLevelChange;
private final float levelChangeTextDelay = 2;
private boolean levelChangeTextChanged = false;
@ -21,7 +23,7 @@ public class InGameState extends BaseState {
AppUtil.engine.removeAllEntities();
AppUtil.guiManager.clearGUI();
level = new TestLevel();
level = levels[currentLevel];
level.generate();
timeSinceLevelChange = 0;
@ -42,6 +44,19 @@ public class InGameState extends BaseState {
guiCreator.getLevelChangeText().setVisible(false);
levelChangeTextChanged = false;
}
if (level.levelCleared()) {
currentLevel++;
if (currentLevel >= levels.length) {
setState(new WinState());
} else {
changeLevel(levels[currentLevel]);
}
}
if (level.levelFailed()) {
setState(new GameOverState());
}
}
public void changeLevel(Level level) {

View File

@ -19,7 +19,7 @@ public class MainMenuState extends BaseState {
@Override
public void update(float deltaTime) {
if (guiCreator.shouldPlay()) {
changeState(new InGameState());
setState(new InGameState());
}
}

View File

@ -0,0 +1,32 @@
package com.saltosion.gladiator.state;
import com.saltosion.gladiator.gui.creators.WinGUICreator;
import com.saltosion.gladiator.util.AppUtil;
public class WinState extends BaseState {
private WinGUICreator guiCreator;
@Override
public void create() {
// Start from a clean slate
AppUtil.guiManager.clearGUI();
guiCreator = new WinGUICreator();
guiCreator.create();
}
@Override
public void update(float deltaTime) {
if (guiCreator.shouldReturn()) {
setState(new MainMenuState());
}
}
@Override
public void destroy() {
// Clear GUI so there's nothing leftover for the next state
AppUtil.guiManager.clearGUI();
}
}

View File

@ -21,58 +21,63 @@ import com.saltosion.gladiator.util.SpriteLoader;
public class CombatSystem extends EntitySystem {
private ComponentMapper<CCombat> cm = ComponentMapper.getFor(CCombat.class);
private ComponentMapper<CPhysics> pm = ComponentMapper.getFor(CPhysics.class);
private final ComponentMapper<CCombat> cm = ComponentMapper.getFor(CCombat.class);
private final ComponentMapper<CPhysics> pm = ComponentMapper.getFor(CPhysics.class);
private ImmutableArray<Entity> entities;
@Override
public void addedToEngine(Engine engine) {
updateEntities(engine);
}
@Override
public void update(float deltaTime) {
for (int i=0; i<entities.size(); i++) {
for (int i = 0; i < entities.size(); i++) {
Entity e = entities.get(i);
CCombat combat = cm.get(e);
CPhysics obj = pm.get(e);
if (combat.swingCdCounter > 0) {
combat.swingCdCounter -= deltaTime;
} if (combat.swingCdCounter > 0) { continue; }
}
if (combat.swingCdCounter > 0) {
continue;
}
// Ready to swing !
combat.getSwing().setZero();
if (combat.inputs.get(Direction.LEFT)) {
combat.getSwing().add(-1, 0);
} if (combat.inputs.get(Direction.RIGHT)) {
}
if (combat.inputs.get(Direction.RIGHT)) {
combat.getSwing().add(1, 0);
} if (combat.inputs.get(Direction.UP)) {
}
if (combat.inputs.get(Direction.UP)) {
combat.getSwing().add(0, 1);
} if (combat.inputs.get(Direction.DOWN)) {
}
if (combat.inputs.get(Direction.DOWN)) {
combat.getSwing().add(0, -1);
}
if (!combat.getSwing().isZero() && combat.swingCdCounter <= 0) {
Vector2 pos = obj.getPosition().cpy();
if (combat.getSwingDirection() == Direction.LEFT) {
pos.add(-combat.getSwingSize().x/2, 0);
pos.add(-combat.getSwingSize().x / 2, 0);
} else if (combat.getSwingDirection() == Direction.RIGHT) {
pos.add(combat.getSwingSize().x/2, 0);
pos.add(combat.getSwingSize().x / 2, 0);
} else if (combat.getSwingDirection() == Direction.UP) {
pos.add(0, combat.getSwingSize().y/3*2);
pos.add(0, combat.getSwingSize().y / 3 * 2);
} else if (combat.getSwingDirection() == Direction.DOWN) {
pos.add(0, -combat.getSwingSize().y/3*2);
pos.add(0, -combat.getSwingSize().y / 3 * 2);
}
createSwingHitbox(e, pos);
combat.swingCdCounter = combat.getSwingDuration();
}
}
}
public void createSwingHitbox(Entity source, Vector2 position) {
Entity e = new Entity();
CCombat combat = cm.get(source);
@ -81,17 +86,19 @@ public class CombatSystem extends EntitySystem {
e.add(new CPhysics().setGhost(true).setGravityApplied(false).setMovable(false)
.setSize(combat.getSwingSize()));
e.getComponent(CPhysics.class).setPosition(position).setCollisionListener(new SwingHitboxListener(source));
e.add(new CDestructive(combat.getSwingDuration()/2));
e.add(new CDestructive(combat.getSwingDuration() / 2));
AppUtil.engine.addEntity(e);
}
public void updateEntities(Engine engine) {
entities = engine.getEntitiesFor(Family.getFor(CCombat.class));
}
/**
* Deal <b>damage</b> to <b>target</b>. Source is optional, leave null if none.
* Deal <b>damage</b> to <b>target</b>. Source is optional, leave null if
* none.
*
* @param source Source of the <b>damage</b>.
* @param target Target to kill.
* @param damage Damage taken, that was dealth to the <b>target</b>.
@ -100,16 +107,17 @@ public class CombatSystem extends EntitySystem {
CCombat combat = target.getComponent(CCombat.class);
CombatListener listener = combat.getCombatListener();
if (listener != null) {
listener.damageTaken(source, damage);
listener.damageTaken(source, target, damage);
}
combat.health -= damage;
if (combat.health <= 0) {
killEntity(source, target, damage);
}
}
/**
* Straight off kill the <b>target</b>.
*
* @param source Source of the <b/>damage</b>.
* @param target Target to kill.
* @param damage Damage taken, that killed <b>target</b>.
@ -118,9 +126,9 @@ public class CombatSystem extends EntitySystem {
CCombat combat = target.getComponent(CCombat.class);
CombatListener listener = combat.getCombatListener();
if (listener != null) {
listener.died(source, damage);
listener.died(source, target, damage);
}
AppUtil.engine.removeEntity(target);
AppUtil.engine.removeEntity(target);
}
}

View File

@ -5,12 +5,14 @@ import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.math.Vector2;
import com.saltosion.gladiator.gui.GUIManager;
import com.saltosion.gladiator.level.EntityFactory;
import com.saltosion.gladiator.level.LevelFactory;
public class AppUtil {
public static Entity player;
public static Engine engine;
public static EntityFactory entityFactory;
public static LevelFactory levelFactory;
public static GUIManager guiManager;
public static final int VPHEIGHT_CONST = 24;

View File

@ -9,6 +9,8 @@ public class Global {
public static final float SPRITE_SCALE = 1 / 16f;
public static final int FLAG_ALIVE = 1;
/**
* Higher font scale = smaller text
*/