|
@@ -1,549 +0,0 @@
|
|
-package squidpony.gdx.examples;
|
|
|
|
-
|
|
|
|
-import com.badlogic.gdx.ApplicationAdapter;
|
|
|
|
-import com.badlogic.gdx.Gdx;
|
|
|
|
-import com.badlogic.gdx.graphics.Color;
|
|
|
|
-import com.badlogic.gdx.graphics.GL20;
|
|
|
|
-import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
|
|
|
-import com.badlogic.gdx.scenes.scene2d.Stage;
|
|
|
|
-import com.badlogic.gdx.utils.Array;
|
|
|
|
-import com.badlogic.gdx.utils.IntArray;
|
|
|
|
-import com.badlogic.gdx.utils.viewport.ScreenViewport;
|
|
|
|
-import squidpony.squidai.*;
|
|
|
|
-import squidpony.squidgrid.FOVCache;
|
|
|
|
-import squidpony.squidgrid.LOS;
|
|
|
|
-import squidpony.squidgrid.Radius;
|
|
|
|
-import squidpony.squidgrid.gui.gdx.*;
|
|
|
|
-import squidpony.squidgrid.mapping.DungeonGenerator;
|
|
|
|
-import squidpony.squidgrid.mapping.DungeonUtility;
|
|
|
|
-import squidpony.squidgrid.mapping.styled.TilesetType;
|
|
|
|
-import squidpony.squidmath.*;
|
|
|
|
-
|
|
|
|
-import java.util.ArrayList;
|
|
|
|
-import java.util.Map;
|
|
|
|
-import java.util.Set;
|
|
|
|
-
|
|
|
|
-public class SquidAIDemo extends ApplicationAdapter {
|
|
|
|
- private enum Phase {MOVE_ANIM, ATTACK_ANIM}
|
|
|
|
- SpriteBatch batch;
|
|
|
|
-
|
|
|
|
- private Phase phase = Phase.ATTACK_ANIM;
|
|
|
|
- private RNG rng;
|
|
|
|
- private LightRNG lrng;
|
|
|
|
- private SquidLayers display;
|
|
|
|
- private DungeonGenerator dungeonGen;
|
|
|
|
- private char[][] bareDungeon, lineDungeon;
|
|
|
|
- private double[][] res;
|
|
|
|
- private int[][] colors, bgColors, lights;
|
|
|
|
- private LOS los;
|
|
|
|
- private int width, height;
|
|
|
|
- private int cellWidth, cellHeight;
|
|
|
|
- private int numMonsters = 16;
|
|
|
|
-
|
|
|
|
- private SquidInput input;
|
|
|
|
- private static final Color bgColor = SColor.DARK_SLATE_GRAY;
|
|
|
|
- private Array<AnimatedEntity> teamRed, teamBlue;
|
|
|
|
- private IntArray redHealth, blueHealth;
|
|
|
|
- //private OrderedMap<AnimatedEntity, Integer> teamRed, teamBlue;
|
|
|
|
- private OrderedSet<Coord> redPlaces, bluePlaces;
|
|
|
|
- private Technique redCone, redCloud, blueBlast, blueBeam;
|
|
|
|
- private DijkstraMap getToRed, getToBlue;
|
|
|
|
- private Stage stage;
|
|
|
|
- private int framesWithoutAnimation = 0, moveLength = 5;
|
|
|
|
- private ArrayList<Coord> awaitedMoves;
|
|
|
|
- private int redIdx = 0, blueIdx = 0;
|
|
|
|
- private boolean blueTurn = false;
|
|
|
|
-
|
|
|
|
- private FOVCache cache;
|
|
|
|
- @Override
|
|
|
|
- public void create () {
|
|
|
|
- batch = new SpriteBatch();
|
|
|
|
- width = 40;
|
|
|
|
- height = 40;
|
|
|
|
- cellWidth = 6;
|
|
|
|
- cellHeight = 12;
|
|
|
|
- display = new SquidLayers(width * 2, height, cellWidth, cellHeight, DefaultResources.narrowName);
|
|
|
|
- display.setAnimationDuration(0.35f);
|
|
|
|
- stage = new Stage(new ScreenViewport(), batch);
|
|
|
|
-
|
|
|
|
- lrng = new LightRNG(0x1337BEEF);
|
|
|
|
- rng = new RNG(lrng);
|
|
|
|
-
|
|
|
|
- dungeonGen = new DungeonGenerator(width, height, rng);
|
|
|
|
-// dungeonGen.addWater(10);
|
|
|
|
- //dungeonGen.addDoors(15, true);
|
|
|
|
-
|
|
|
|
- // change the TilesetType to lots of different choices to see what dungeon works best.
|
|
|
|
- bareDungeon = dungeonGen.generate(TilesetType.ROUND_ROOMS_DIAGONAL_CORRIDORS);
|
|
|
|
- cache = new FOVCache(bareDungeon, 9, Radius.CIRCLE);
|
|
|
|
- bareDungeon = DungeonUtility.closeDoors(bareDungeon);
|
|
|
|
- lineDungeon = DungeonUtility.doubleWidth(DungeonUtility.hashesToLines(bareDungeon));
|
|
|
|
- // it's more efficient to get random floors from a packed set containing only (compressed) floor positions.
|
|
|
|
- short[] placement = CoordPacker.pack(bareDungeon, '.');
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- teamRed = new Array<>(numMonsters);
|
|
|
|
- teamBlue = new Array<>(numMonsters);
|
|
|
|
-
|
|
|
|
- redHealth = new IntArray(numMonsters);
|
|
|
|
- blueHealth = new IntArray(numMonsters);
|
|
|
|
-
|
|
|
|
- redPlaces = new OrderedSet<>(numMonsters);
|
|
|
|
- bluePlaces = new OrderedSet<>(numMonsters);
|
|
|
|
- for(int i = 0; i < numMonsters; i++)
|
|
|
|
- {
|
|
|
|
- Coord monPos = dungeonGen.utility.randomCell(placement);
|
|
|
|
- placement = CoordPacker.removePacked(placement, monPos.x, monPos.y);
|
|
|
|
-
|
|
|
|
- teamRed.add(display.animateActor(monPos.x, monPos.y, "50", 11, true));
|
|
|
|
- redHealth.add(50);
|
|
|
|
- redPlaces.add(monPos);
|
|
|
|
-
|
|
|
|
- Coord monPosBlue = dungeonGen.utility.randomCell(placement);
|
|
|
|
- placement = CoordPacker.removePacked(placement, monPosBlue.x, monPosBlue.y);
|
|
|
|
-
|
|
|
|
- teamBlue.add(display.animateActor(monPosBlue.x, monPosBlue.y, "50", 25, true));
|
|
|
|
- blueHealth.add(50);
|
|
|
|
- bluePlaces.add(monPosBlue);
|
|
|
|
- }
|
|
|
|
- // your choice of FOV matters here.
|
|
|
|
- los = new LOS(LOS.BRESENHAM);
|
|
|
|
- res = DungeonUtility.generateResistances(bareDungeon);
|
|
|
|
-
|
|
|
|
- ConeAOE cone = new ConeAOE(Coord.get(0, 0), 9, 0, 60, Radius.CIRCLE);
|
|
|
|
- cone.setMinRange(1);
|
|
|
|
- cone.setMaxRange(2);
|
|
|
|
- cone.setMetric(Radius.SQUARE);
|
|
|
|
-
|
|
|
|
- redCone = new Technique("Burning Breath", cone);
|
|
|
|
- redCone.setMap(bareDungeon);
|
|
|
|
-
|
|
|
|
- BlastAOE blast = new BlastAOE(Coord.get(0, 0), 3, Radius.CIRCLE);
|
|
|
|
- blast.setMinRange(3);
|
|
|
|
- blast.setMaxRange(5);
|
|
|
|
- blast.setMetric(Radius.CIRCLE);
|
|
|
|
-
|
|
|
|
- blueBlast = new Technique("Winter Orb", blast);
|
|
|
|
- blueBlast.setMap(bareDungeon);
|
|
|
|
-
|
|
|
|
- CloudAOE cloud = new CloudAOE(Coord.get(0, 0), 20, Radius.DIAMOND);
|
|
|
|
- cloud.setMinRange(4);
|
|
|
|
- cloud.setMaxRange(7);
|
|
|
|
- cloud.setMetric(Radius.CIRCLE);
|
|
|
|
-
|
|
|
|
- redCloud = new Technique("Acid Mist", cloud);
|
|
|
|
- redCloud.setMap(bareDungeon);
|
|
|
|
-
|
|
|
|
- BeamAOE beam = new BeamAOE(Coord.get(0, 0), 0.0, 8, 1, Radius.DIAMOND);
|
|
|
|
- beam.setMinRange(2);
|
|
|
|
- beam.setMaxRange(8);
|
|
|
|
- beam.setMetric(Radius.CIRCLE);
|
|
|
|
- blueBeam = new Technique("Atomic Death Ray", beam);
|
|
|
|
- blueBeam.setMap(bareDungeon);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- getToRed = new DijkstraMap(bareDungeon, DijkstraMap.Measurement.EUCLIDEAN);
|
|
|
|
- getToRed.rng = rng;
|
|
|
|
- getToBlue = new DijkstraMap(bareDungeon, DijkstraMap.Measurement.EUCLIDEAN);
|
|
|
|
- getToBlue.rng = rng;
|
|
|
|
-
|
|
|
|
- dijkstraAlert();
|
|
|
|
-
|
|
|
|
- awaitedMoves = new ArrayList<>(10);
|
|
|
|
- colors = DungeonUtility.generatePaletteIndices(bareDungeon);
|
|
|
|
- bgColors = DungeonUtility.generateBGPaletteIndices(bareDungeon);
|
|
|
|
- lights = DungeonUtility.generateLightnessModifiers(bareDungeon);
|
|
|
|
-
|
|
|
|
- // just quit if we get a Q.
|
|
|
|
- input = new SquidInput(new SquidInput.KeyHandler() {
|
|
|
|
- @Override
|
|
|
|
- public void handle(char key, boolean alt, boolean ctrl, boolean shift) {
|
|
|
|
- switch (key)
|
|
|
|
- {
|
|
|
|
- case 'Q':
|
|
|
|
- case 'q':
|
|
|
|
- case SquidInput.ESCAPE:
|
|
|
|
- {
|
|
|
|
- Gdx.app.exit();
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- // ABSOLUTELY NEEDED TO HANDLE INPUT
|
|
|
|
- // and then add display, our one visual component, to the list of things that act in Stage.
|
|
|
|
- display.setPosition(0, 0);
|
|
|
|
- stage.addActor(display);
|
|
|
|
- cache.awaitCache();
|
|
|
|
- blast.setCache(cache);
|
|
|
|
- cone.setCache(cache);
|
|
|
|
- Gdx.input.setInputProcessor(input);
|
|
|
|
-
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void dijkstraAlert()
|
|
|
|
- {
|
|
|
|
- /*
|
|
|
|
- getToBlue.clearGoals();
|
|
|
|
- getToBlue.resetMap();
|
|
|
|
- getToRed.clearGoals();
|
|
|
|
- getToRed.resetMap();
|
|
|
|
- ArrayList<AnimatedEntity> redCopy = new ArrayList<AnimatedEntity>(teamRed.size());
|
|
|
|
- redCopy.addAll(teamRed.keySet());
|
|
|
|
- BLUE_LOOP:
|
|
|
|
- for(AnimatedEntity blue : teamBlue.keySet())
|
|
|
|
- {
|
|
|
|
- for(AnimatedEntity red : redCopy)
|
|
|
|
- {
|
|
|
|
- if(los.isReachable(res, blue.gridX, blue.gridY, red.gridX, red.gridY, Radius.CIRCLE))
|
|
|
|
- {
|
|
|
|
- getToBlue.setGoal(blue.gridX, blue.gridY);
|
|
|
|
- getToRed.setGoal(red.gridX, red.gridY);
|
|
|
|
-
|
|
|
|
- redCopy.remove(red);
|
|
|
|
-
|
|
|
|
- continue BLUE_LOOP;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- getToBlue.scan(redPlaces);
|
|
|
|
- getToRed.scan(bluePlaces);
|
|
|
|
- */
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /**
|
|
|
|
- * Move a unit toward a good position to attack, but don't attack in this method.
|
|
|
|
- * @param idx the index of the unit in the appropriate ordered Map.
|
|
|
|
- */
|
|
|
|
- private void startMove(int idx) {
|
|
|
|
-// if(health <= 0) return;
|
|
|
|
- int i = 0;
|
|
|
|
- DijkstraMap whichDijkstra;
|
|
|
|
- Technique whichTech;
|
|
|
|
- Set<Coord> whichFoes, whichAllies = new OrderedSet<>(8);
|
|
|
|
- AnimatedEntity ae = null;
|
|
|
|
- int health = 0;
|
|
|
|
- Coord user = null;
|
|
|
|
- if(blueTurn)
|
|
|
|
- {
|
|
|
|
- whichDijkstra = getToRed;
|
|
|
|
- whichTech = (idx % 2 == 0) ? blueBeam : blueBlast;
|
|
|
|
- whichFoes = redPlaces;
|
|
|
|
- whichAllies = bluePlaces;
|
|
|
|
- ae = teamBlue.get(idx);
|
|
|
|
- health = blueHealth.get(idx);
|
|
|
|
- if(ae == null || health <= 0) {
|
|
|
|
- phase = Phase.MOVE_ANIM;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- user = Coord.get(ae.gridX, ae.gridY);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- whichDijkstra = getToBlue;
|
|
|
|
- whichTech = (idx % 2 == 0) ? redCloud : redCone;
|
|
|
|
- whichFoes = bluePlaces;
|
|
|
|
- whichAllies = redPlaces;
|
|
|
|
- ae = teamRed.get(idx);
|
|
|
|
- health = redHealth.get(idx);
|
|
|
|
- if(ae == null || health <= 0) {
|
|
|
|
- phase = Phase.MOVE_ANIM;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- user = Coord.get(ae.gridX, ae.gridY);
|
|
|
|
- }
|
|
|
|
- whichAllies.remove(user);
|
|
|
|
- /*for(Coord p : whichFoes)
|
|
|
|
- {
|
|
|
|
- AnimatedEntity foe = display.getAnimatedEntityByCell(p.x, p.y);
|
|
|
|
- if(los.isReachable(res, user.x, user.y, p.x, p.y) && foe != null && whichEnemyTeam.get(foe) != null && whichEnemyTeam.get(foe) > 0)
|
|
|
|
- {
|
|
|
|
- visibleTargets.add(p);
|
|
|
|
- }
|
|
|
|
- }*/
|
|
|
|
- ArrayList<Coord> path = whichDijkstra.findTechniquePath(moveLength, whichTech, bareDungeon, (LOS)null, whichFoes, whichAllies, user, whichFoes);
|
|
|
|
- if(path.isEmpty())
|
|
|
|
- path = whichDijkstra.findPath(moveLength, whichFoes, whichAllies, user, whichFoes.toArray(new Coord[whichFoes.size()]));
|
|
|
|
- /*
|
|
|
|
- System.out.println("User at (" + user.x + "," + user.y + ") using " +
|
|
|
|
- whichTech.name);
|
|
|
|
- */
|
|
|
|
- /*
|
|
|
|
- boolean anyFound = false;
|
|
|
|
-
|
|
|
|
- for (int yy = 0; yy < height; yy++) {
|
|
|
|
- for (int xx = 0; xx < width; xx++) {
|
|
|
|
- System.out.print((whichDijkstra.targetMap[xx][yy] == null) ? "." : "@");
|
|
|
|
- anyFound = (whichDijkstra.targetMap[xx][yy] != null) ? true : anyFound;
|
|
|
|
- }
|
|
|
|
- System.out.println();
|
|
|
|
- }*/
|
|
|
|
- awaitedMoves = new ArrayList<>(path);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- public void move(AnimatedEntity ae, int newX, int newY) {
|
|
|
|
- display.slide(ae, newX, newY, 2, 0.075f);
|
|
|
|
- phase = Phase.MOVE_ANIM;
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // check if a monster's movement would overlap with another monster.
|
|
|
|
- @SuppressWarnings("unused")
|
|
|
|
- private boolean checkOverlap(AnimatedEntity ae, int x, int y)
|
|
|
|
- {
|
|
|
|
- for(AnimatedEntity mon : teamRed)
|
|
|
|
- {
|
|
|
|
- if(mon.gridX == x && mon.gridY == y && !mon.equals(ae))
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- for(AnimatedEntity mon : teamBlue)
|
|
|
|
- {
|
|
|
|
- if(mon.gridX == x && mon.gridY == y && !mon.equals(ae))
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- return false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- private void postMove(int idx) {
|
|
|
|
-
|
|
|
|
- int i = 0;
|
|
|
|
- Technique whichTech;
|
|
|
|
- Set<Coord> whichFoes, whichAllies, visibleTargets = new OrderedSet<>(8);
|
|
|
|
- AnimatedEntity ae = null;
|
|
|
|
- int health = 0;
|
|
|
|
- Coord user = null;
|
|
|
|
- Color whichTint = Color.WHITE;
|
|
|
|
- Array<AnimatedEntity> whichEnemyTeam;
|
|
|
|
- IntArray whichEnemyHealth;
|
|
|
|
- OrderedMap<Coord, Double> effects;
|
|
|
|
- if (blueTurn) {
|
|
|
|
- whichTech = (idx % 2 == 0) ? blueBeam : blueBlast;
|
|
|
|
- whichFoes = redPlaces;
|
|
|
|
- whichAllies = bluePlaces;
|
|
|
|
- whichTint = Color.CYAN;
|
|
|
|
- whichEnemyTeam = teamRed;
|
|
|
|
- whichEnemyHealth = redHealth;
|
|
|
|
- ae = teamBlue.get(idx);
|
|
|
|
- health = blueHealth.get(idx);
|
|
|
|
- if (ae == null || health <= 0) {
|
|
|
|
- phase = Phase.ATTACK_ANIM;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- user = Coord.get(ae.gridX, ae.gridY);
|
|
|
|
- } else {
|
|
|
|
- whichTech = (idx % 2 == 0) ? redCloud : redCone;
|
|
|
|
- whichFoes = bluePlaces;
|
|
|
|
- whichAllies = redPlaces;
|
|
|
|
- whichTint = Color.RED;
|
|
|
|
- whichEnemyTeam = teamBlue;
|
|
|
|
- whichEnemyHealth = blueHealth;
|
|
|
|
- ae = teamRed.get(idx);
|
|
|
|
- health = redHealth.get(idx);
|
|
|
|
- if (ae == null || health <= 0) {
|
|
|
|
- phase = Phase.ATTACK_ANIM;
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- user = Coord.get(ae.gridX, ae.gridY);
|
|
|
|
- }
|
|
|
|
- for(Coord p : whichFoes)
|
|
|
|
- {
|
|
|
|
- AnimatedEntity foe = display.getAnimatedEntityByCell(p.x, p.y);
|
|
|
|
- int foeIdx;
|
|
|
|
- if(los.isReachable(res, user.x, user.y, p.x, p.y) && foe != null && (foeIdx = whichEnemyTeam.indexOf(foe, true)) >= 0
|
|
|
|
- && whichEnemyHealth.get(foeIdx) > 0)
|
|
|
|
- {
|
|
|
|
- visibleTargets.add(p);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- OrderedMap<Coord, ArrayList<Coord>> ideal = whichTech.idealLocations(user, visibleTargets, whichAllies);
|
|
|
|
- Coord targetCell = null;
|
|
|
|
- if(!ideal.isEmpty()) targetCell = ideal.firstKey();
|
|
|
|
-
|
|
|
|
- if(targetCell != null)
|
|
|
|
- {
|
|
|
|
- effects = whichTech.apply(user, targetCell);
|
|
|
|
-
|
|
|
|
- for(Map.Entry<Coord, Double> power : effects.entrySet())
|
|
|
|
- {
|
|
|
|
- Double strength = (idx % 2 == 0) ? rng.nextDouble() : power.getValue();
|
|
|
|
- whichTint.a = strength.floatValue();
|
|
|
|
- display.tint(power.getKey().x * 2 , power.getKey().y, whichTint, 0, display.getAnimationDuration());
|
|
|
|
- display.tint(power.getKey().x * 2 + 1, power.getKey().y, whichTint, 0, display.getAnimationDuration());
|
|
|
|
- AnimatedEntity tgt;
|
|
|
|
- for(int tgtIdx = 0; tgtIdx < whichEnemyTeam.size; tgtIdx++)
|
|
|
|
- {
|
|
|
|
- tgt = whichEnemyTeam.get(tgtIdx);
|
|
|
|
- if(tgt.gridX == power.getKey().x && tgt.gridY == power.getKey().y)
|
|
|
|
- {
|
|
|
|
- int currentHealth = Math.max(whichEnemyHealth.get(tgtIdx) - (int) (15 * strength), 0);
|
|
|
|
- whichEnemyTeam.set(tgtIdx, tgt);
|
|
|
|
- whichEnemyHealth.set(tgtIdx, currentHealth);
|
|
|
|
- tgt.setText(Integer.toString(currentHealth));
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- /*
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
-
|
|
|
|
- System.out.println("NO ATTACK POSITION: User at (" + user.x + "," + user.y + ") using " +
|
|
|
|
- whichTech.name);
|
|
|
|
-
|
|
|
|
- display.tint(user.x * 2 , user.y, highlightColor, 0, display.getAnimationDuration() * 3);
|
|
|
|
- display.tint(user.x * 2 + 1, user.y, highlightColor, 0, display.getAnimationDuration() * 3);
|
|
|
|
- }
|
|
|
|
- */
|
|
|
|
- whichAllies.add(user);
|
|
|
|
- phase = Phase.ATTACK_ANIM;
|
|
|
|
- }
|
|
|
|
- public void putMap()
|
|
|
|
- {
|
|
|
|
- for (int i = 0; i < width; i++) {
|
|
|
|
- for (int j = 0; j < height; j++) {
|
|
|
|
- display.put(i * 2, j, lineDungeon[i * 2][j], colors[i][j], bgColors[i][j], lights[i][j]);
|
|
|
|
- display.put(i * 2 + 1, j, lineDungeon[i * 2 + 1][j], colors[i][j], bgColors[i][j], lights[i][j]);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- @Override
|
|
|
|
- public void render () {
|
|
|
|
- // standard clear the background routine for libGDX
|
|
|
|
- Gdx.gl.glClearColor(bgColor.r / 255.0f, bgColor.g / 255.0f, bgColor.b / 255.0f, 1.0f);
|
|
|
|
- Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
|
|
|
- // not sure if this is always needed...
|
|
|
|
- Gdx.gl.glEnable(GL20.GL_BLEND);
|
|
|
|
-
|
|
|
|
- stage.act();
|
|
|
|
- boolean blueWins = false, redWins = false;
|
|
|
|
- for(int bh = 0; bh < blueHealth.size; bh++)
|
|
|
|
- {
|
|
|
|
- if(blueHealth.get(bh) > 0) {
|
|
|
|
- redWins = false;
|
|
|
|
- break;
|
|
|
|
- }redWins = true;
|
|
|
|
- }
|
|
|
|
- for(int rh = 0; rh < redHealth.size; rh++)
|
|
|
|
- {
|
|
|
|
- if(redHealth.get(rh) > 0) {
|
|
|
|
- blueWins = false;
|
|
|
|
- break;
|
|
|
|
- }blueWins = true;
|
|
|
|
- }
|
|
|
|
- if (blueWins) {
|
|
|
|
- // still need to display the map, then write over it with a message.
|
|
|
|
- putMap();
|
|
|
|
- display.putBoxedString(width / 2 - 11, height / 2 - 1, " BLUE TEAM WINS! ");
|
|
|
|
- display.putBoxedString(width / 2 - 11, height / 2 + 5, " q to quit. ");
|
|
|
|
-
|
|
|
|
- // because we return early, we still need to draw.
|
|
|
|
- stage.draw();
|
|
|
|
- // q still needs to quit.
|
|
|
|
- if(input.hasNext())
|
|
|
|
- input.next();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- else if(redWins)
|
|
|
|
- {
|
|
|
|
- putMap();
|
|
|
|
- display.putBoxedString(width / 2 - 11, height / 2 - 1, " RED TEAM WINS! ");
|
|
|
|
- display.putBoxedString(width / 2 - 11, height / 2 + 5, " q to quit. ");
|
|
|
|
-
|
|
|
|
- // because we return early, we still need to draw.
|
|
|
|
- stage.draw();
|
|
|
|
- // q still needs to quit.
|
|
|
|
- if(input.hasNext())
|
|
|
|
- input.next();
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- int i = 0;
|
|
|
|
- AnimatedEntity ae = null;
|
|
|
|
- int whichIdx = 0;
|
|
|
|
- if(blueTurn) {
|
|
|
|
- whichIdx = blueIdx;
|
|
|
|
- ae = teamBlue.get(blueIdx);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- whichIdx = redIdx;
|
|
|
|
- ae = teamRed.get(redIdx);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // need to display the map every frame, since we clear the screen to avoid artifacts.
|
|
|
|
- putMap();
|
|
|
|
- // if we are waiting for the player's input and get input, process it.
|
|
|
|
- if(input.hasNext()) {
|
|
|
|
- input.next();
|
|
|
|
- }
|
|
|
|
- // if the user clicked, we have a list of moves to perform.
|
|
|
|
- if(!awaitedMoves.isEmpty())
|
|
|
|
- {
|
|
|
|
- if(ae == null) {
|
|
|
|
- awaitedMoves.clear();
|
|
|
|
- }
|
|
|
|
- // extremely similar to the block below that also checks if animations are done
|
|
|
|
- // this doesn't check for input, but instead processes and removes Points from awaitedMoves.
|
|
|
|
- else if(!display.hasActiveAnimations()) {
|
|
|
|
- ++framesWithoutAnimation;
|
|
|
|
- if (framesWithoutAnimation >= 2) {
|
|
|
|
- framesWithoutAnimation = 0;
|
|
|
|
- Coord m = awaitedMoves.remove(0);
|
|
|
|
- move(ae, m.x, m.y);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // if the previous blocks didn't happen, and there are no active animations, then either change the phase
|
|
|
|
- // (because with no animations running the last phase must have ended), or start a new animation soon.
|
|
|
|
- else if(!display.hasActiveAnimations()) {
|
|
|
|
- ++framesWithoutAnimation;
|
|
|
|
- if (framesWithoutAnimation >= 2) {
|
|
|
|
- framesWithoutAnimation = 0;
|
|
|
|
- switch (phase) {
|
|
|
|
- case ATTACK_ANIM: {
|
|
|
|
- phase = Phase.MOVE_ANIM;
|
|
|
|
- blueTurn = !blueTurn;
|
|
|
|
- if(!blueTurn)
|
|
|
|
- {
|
|
|
|
- whichIdx = (whichIdx + 1) % numMonsters;
|
|
|
|
- redIdx = (redIdx + 1) % numMonsters;
|
|
|
|
- blueIdx = (blueIdx + 1) % numMonsters;
|
|
|
|
- }
|
|
|
|
- dijkstraAlert();
|
|
|
|
- startMove(whichIdx);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case MOVE_ANIM: {
|
|
|
|
- postMove(whichIdx);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // if we do have an animation running, then how many frames have passed with no animation needs resetting
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- framesWithoutAnimation = 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // stage has its own batch and must be explicitly told to draw(). this also causes it to act().
|
|
|
|
- stage.draw();
|
|
|
|
-
|
|
|
|
- OrderedSet<AnimatedEntity> entities = display.getAnimatedEntities(0);
|
|
|
|
- // display does not draw all AnimatedEntities by default.
|
|
|
|
- batch.begin();
|
|
|
|
- for (int j = 0; j < entities.size(); j++) {
|
|
|
|
- display.drawActor(batch, 1.0f, entities.getAt(j), 0);
|
|
|
|
- }
|
|
|
|
- entities = display.getAnimatedEntities(2);
|
|
|
|
- for (int j = 0; j < entities.size(); j++) {
|
|
|
|
- display.drawActor(batch, 1.0f, entities.getAt(j), 2);
|
|
|
|
- }
|
|
|
|
- /*
|
|
|
|
- for(AnimatedEntity mon : teamBlue.keySet()) {
|
|
|
|
- display.drawActor(batch, 1.0f, mon);
|
|
|
|
- }*/
|
|
|
|
- // batch must end if it began.
|
|
|
|
- batch.end();
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|