From 78dcf6879ae11f852c07ce430c48b5c417d57d28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20N=C3=B8rup?= Date: Fri, 27 Oct 2023 13:01:52 +0200 Subject: [PATCH 1/2] Added results screen to custom battle --- .../CustomBattleView/CustomBattleScene.java | 60 ++++++++++++++++++- .../CustomBattleView/CustomBattleView.java | 23 ++++++- .../MCTSBattleAI/MCTSBattleAIFactory.java | 2 +- 3 files changed, 81 insertions(+), 4 deletions(-) diff --git a/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleScene.java b/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleScene.java index b5321c38..9442b76b 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleScene.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleScene.java @@ -42,6 +42,10 @@ public class CustomBattleScene { private int screenWidth = 1280; private int screenHeight = 720; + private boolean showResults; + private String resultsHeader; + private String[] resultLines; + private Rectangle resultContainer; private Rectangle teamAContainer; private Rectangle teamBContainer; private Rectangle[] teamAMonsterBoxes; @@ -53,6 +57,7 @@ public CustomBattleScene(IGameSettings settings) { spriteBatch = new SpriteBatch(); shapeRenderer = new ShapeRenderer(); + resultContainer = DrawingUtils.createRectangle(Rectangle.class, 0, 0, 0, 0); teamAContainer = DrawingUtils.createRectangle(Rectangle.class, 0, 0, 0, 0); teamBContainer = DrawingUtils.createRectangle(Rectangle.class, 0, 0, 0, 0); int teamSize = 6; @@ -121,6 +126,7 @@ public void draw(GameData gameData) { teamBMonsterBoxes[i].draw(shapeRenderer, dt); } + spriteBatch.end(); shapeRenderer.end(); @@ -154,8 +160,44 @@ public void draw(GameData gameData) { text.drawBigBoldRoboto(spriteBatch, "START BATTLE!", startBattleColor, gameData.getDisplayWidth() / 2f, 50 ); text.drawBigBoldRoboto(spriteBatch, errorText, new Color(1,0,0, errorOpacity), errorPosition.getX(), errorPosition.getY() ); - text.setCoordinateMode(TextUtils.CoordinateMode.TOP_LEFT); spriteBatch.end(); + + if(showResults){ + // Results need to be drawn on top of everything. Thus, we need two spritebatch-blocks again. + // One for the box, and another for the text + spriteBatch.begin(); + shapeRenderer.setAutoShapeType(true); + shapeRenderer.setColor(Color.WHITE); + shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); + resultContainer.draw(shapeRenderer, dt); + shapeRenderer.end(); + spriteBatch.end(); + + // RESULTS TEXT SPRITE BATCH + + spriteBatch.begin(); + var topOfResults = resultContainer.getY() + resultContainer.getHeight(); + var headerY = topOfResults - 50; + var textY = headerY - 60; + var lineHeight = 25; + var textX = resultContainer.getX() + 50; + text.setCoordinateMode(TextUtils.CoordinateMode.CENTER); + text.drawTitleFont(spriteBatch, resultsHeader, Color.BLACK, gameData.getDisplayWidth() / 2f, headerY ); + + text.setCoordinateMode(TextUtils.CoordinateMode.TOP_LEFT); + if(resultLines != null){ + int i = 0; + for(String s : resultLines){ + text.drawNormalRoboto(spriteBatch, s, Color.BLACK, textX, textY - (i * lineHeight) ); + i++; + } + } + + text.setCoordinateMode(TextUtils.CoordinateMode.CENTER); + text.drawSmallRoboto(spriteBatch, "Press [action] to continue!", Color.DARK_GRAY, gameData.getDisplayWidth() / 2f, resultContainer.getY() + 15 ); + spriteBatch.end(); + } + text.setCoordinateMode(TextUtils.CoordinateMode.TOP_LEFT); } private void drawMonsterWithName(IMonster monster, Rectangle rectangle, boolean drawMonsterSwitcher) { @@ -258,6 +300,18 @@ public void setErrorSize(float errorSize) { this.errorSize = errorSize; } + public void setShowResults(boolean showResults) { + this.showResults = showResults; + } + + public void setResultsHeader(String resultsHeader) { + this.resultsHeader = resultsHeader; + } + + public void setResultLines(String[] resultLines) { + this.resultLines = resultLines; + } + public int getScreenWidth() { return screenWidth; } @@ -280,6 +334,10 @@ private void calculateBoxSizes(GameData gameData) { teamAContainer.setHeight(containerHeight); teamBContainer.setHeight(containerHeight); + resultContainer.setPosition(new Position(50, 50)); + resultContainer.setWidth(gameData.getDisplayWidth() - 2*50); + resultContainer.setHeight(gameData.getDisplayHeight() - 2*50); + final float monsterBoxSize = 110; final float topOfContainers = teamAContainer.getY() + teamAContainer.getHeight(); final float monsterGap = 20; diff --git a/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleView.java b/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleView.java index 9fff7a49..8c2b2e94 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleView.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/CustomBattleView/CustomBattleView.java @@ -59,12 +59,13 @@ public void init(IGameViewManager gameViewManager) { private int cursorPosition = 0; private boolean editingMode = false; private boolean redrawRoulettes = true; + private boolean showingResults = false; @Override public void update(GameData gameData, IGameViewManager gameViewManager) { cursorPosition = MathUtils.clamp(cursorPosition, 0, 14); - + scene.setShowResults(showingResults); var nextAnimation = backgroundAnimations.peek(); if(nextAnimation != null){ nextAnimation.update(gameData); @@ -138,10 +139,19 @@ public void handleInput(GameData gameData, IGameViewManager gameViewManager) { } if (gameData.getKeys().isPressed(GameKeys.ACTION)) { + if(showingResults){ + showingResults = false; + return; + } + editingMode = !editingMode; chooseSound.play(getSoundVolume()); } + if(showingResults){ + return; // Don't allow any movement when showing results + } + if (gameData.getKeys().isPressed(GameKeys.DELETE) && cursorPosition < 13) { addToSelectedIndicies(null); editingMode = false; @@ -221,8 +231,17 @@ private void startBattle(IGameViewManager gameViewManager){ customBattleMusic.play(); gameViewManager.setView(this); boolean teamAWon = result.getWinner() == result.getPlayer(); - System.out.println("The winner is team: " + (teamAWon ? "A" : "B") + "!"); + var winnerTeamName = teamAWon ? + (teamAAI == null ? "You" : teamAAI.toString()) + : (teamBAI.toString()); + scene.setResultsHeader("The winner is: " + winnerTeamName +"!"); + scene.setResultLines(new String[]{ + "TODO: Collect some stats from the battle and display them here", + "On multiple lines", + "Wow! This is amazing!!" + }); cursorPosition = 0; + showingResults = true; editingMode = false; }); diff --git a/src/main/java/dk/sdu/mmmi/modulemon/MCTSBattleAI/MCTSBattleAIFactory.java b/src/main/java/dk/sdu/mmmi/modulemon/MCTSBattleAI/MCTSBattleAIFactory.java index 078182bd..bad80c42 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/MCTSBattleAI/MCTSBattleAIFactory.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/MCTSBattleAI/MCTSBattleAIFactory.java @@ -31,6 +31,6 @@ public void removeSettingsService(IGameSettings settings) { @Override public String toString() { - return "Monte-Carlo Tree Search"; + return "MCTS"; } } From 487f5cc704a17942e927c0f3c1ba9809a2334e9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20N=C3=B8rup?= Date: Fri, 27 Oct 2023 13:42:42 +0200 Subject: [PATCH 2/2] Moved thinking indicator to the health box --- .../BattleScene/BattleSpeedController.java | 4 +- .../modulemon/BattleScene/BattleView.java | 38 +++-- .../BattleScene/scenes/BattleScene.java | 131 ++++++++++-------- .../BattleSimulation/BattleSimulation.java | 5 + .../IBattleSimulation.java | 1 + .../modulemon/common/drawing/TextUtils.java | 2 +- 6 files changed, 106 insertions(+), 75 deletions(-) diff --git a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleSpeedController.java b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleSpeedController.java index 29d6fe79..6dfad425 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleSpeedController.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleSpeedController.java @@ -1,7 +1,5 @@ package dk.sdu.mmmi.modulemon.BattleScene; -import dk.sdu.mmmi.modulemon.common.drawing.MathUtils; - public class BattleSpeedController { private static final int incrementAmount = 200; @@ -25,6 +23,6 @@ public int getSpeed(){ @Override public String toString() { - return "Battle delay: " + speed + "ms"; + return "Min. turn delay: " + speed + "ms"; } } diff --git a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleView.java b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleView.java index d76cdb38..7ec14521 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleView.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/BattleView.java @@ -73,7 +73,6 @@ public class BattleView implements IGameViewService, IBattleView { public Sound getAttackSound(IMonsterMove monsterMove) { Sound returnSound = null; - try { returnSound = loader.getSoundAsset(monsterMove.getSoundPath(), monsterMove.getClass()); } catch (GdxRuntimeException ex) { @@ -252,9 +251,26 @@ public void update(GameData gameData, IGameViewManager gameViewManager) { _battleScene.setTextBoxRectStyle(Rectangle.class); } - updateHasRunOnce = true; + // Check the current AI is done thinking + if(_battleSimulation.hasNextBattleEvent()){ + _battleScene.setShowEnemySpinner(false); + _battleScene.setShowPlayerSpinner(false); + }else{ + if(_battleSimulation.isPlayerControlledByAI() && _battleSimulation.getState().isPlayersTurn()){ + // there is no current event, and the player is controlled by an AI + _battleScene.setShowPlayerSpinner(true); + _battleScene.setShowEnemySpinner(false); + }else if(!_battleSimulation.getState().isPlayersTurn()){ + _battleScene.setShowPlayerSpinner(false); + _battleScene.setShowEnemySpinner(true); + }else { + _battleScene.setShowEnemySpinner(false); + _battleScene.setShowPlayerSpinner(false); + } + } + //Is there any animations active? if (!blockingAnimations.isEmpty()) { //Set in update() because some animations depend on it. @@ -295,9 +311,7 @@ public void update(GameData gameData, IGameViewManager gameViewManager) { PlayerBattleAttackAnimation battleAnimation = new PlayerBattleAttackAnimation(_battleScene, getAttackSound(event.getMove()), settings); if (forcedAIDelay.getSpeed() > 0) { battleAnimation.setOnEventDone(() -> { - var anim = addEmptyAnimation(forcedAIDelay.getSpeed(), true); - anim.setOnEventDone(() -> _battleScene.setShowEnemySpinner(false)); - _battleScene.setShowEnemySpinner(true); + addEmptyAnimation(forcedAIDelay.getSpeed(), true); }); } battleAnimation.start(); @@ -309,9 +323,7 @@ public void update(GameData gameData, IGameViewManager gameViewManager) { battleAnimation.start(); if (_battleSimulation.isPlayerControlledByAI() && forcedAIDelay.getSpeed() > 0) { battleAnimation.setOnEventDone(() -> { - var anim = addEmptyAnimation(forcedAIDelay.getSpeed(), true); - anim.setOnEventDone(() -> _battleScene.setShowPlayerSpinner(false)); - _battleScene.setShowPlayerSpinner(true); + addEmptyAnimation(forcedAIDelay.getSpeed(), true); }); } blockingAnimations.add(battleAnimation); @@ -331,14 +343,16 @@ public void update(GameData gameData, IGameViewManager gameViewManager) { blockingAnimations.add(changeOutAnimation); } - EmptyAnimation delay = new EmptyAnimation(1000); + EmptyAnimation delay = addEmptyAnimation(forcedAIDelay.getSpeed(), true); delay.setOnEventDone(() -> _currentBattleState = eventState); blockingAnimations.add(delay); PlayerChangeInAnimation changeInAnimation = new PlayerChangeInAnimation(_battleScene); blockingAnimations.add(changeInAnimation); - addEmptyAnimation(2000, false); + if(forcedAIDelay.getSpeed() > 0) { + addEmptyAnimation(forcedAIDelay.getSpeed(), false); + } this._battleScene.setTextToDisplay(battleEvent.getText()); } else { if (causedByFaintingMonster) { @@ -390,7 +404,9 @@ public void update(GameData gameData, IGameViewManager gameViewManager) { } else { //Unknown event (Or TextEvent) _currentBattleState = eventState; - addEmptyAnimation(2000, true); + if(forcedAIDelay.getSpeed() > 0) { + addEmptyAnimation(forcedAIDelay.getSpeed(), true); + } this._battleScene.setTextToDisplay(battleEvent.getText()); } } diff --git a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/scenes/BattleScene.java b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/scenes/BattleScene.java index e992ea19..ea83481e 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/scenes/BattleScene.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/BattleScene/scenes/BattleScene.java @@ -79,14 +79,14 @@ public BattleScene() { _enemyBase = loader.getImageAsset("/battleart/enemybase1.png", this.getClass()); _playerSpinner = loader.getImageAsset("/battleart/spinner.png", this.getClass()); _enemySpinner = loader.getImageAsset("/battleart/spinner.png", BattleView.class); - _textBoxRect = new Rectangle(-100,-100, 0,0); // All these values are dynamically calculated anyway - _actionBoxRect = new Rectangle(-100,-100, BattleSceneDefaults.actionBoxWidth(), BattleSceneDefaults.actionBoxHeight()); - _enemyHealthRect = new Rectangle(-100,-100, BattleSceneDefaults.enemyHealthBoxWidth(), BattleSceneDefaults.enemyHealthBoxHeight()); - _playerHealthRect = new Rectangle(-100,-100, BattleSceneDefaults.playerHealthBoxWidth(), BattleSceneDefaults.playerHealthBoxHeight()); - _playerHPBoxBorderRect = new Rectangle(-100,-100, 0, 0); - _playerHPBoxFillRect = new Rectangle(-100,-100, 0, 0); - _enemyHPBoxBorderRect = new Rectangle(-100,-100, 0, 0); - _enemyHPBoxFillRect = new Rectangle(-100,-100, 0, 0); + _textBoxRect = new Rectangle(-100, -100, 0, 0); // All these values are dynamically calculated anyway + _actionBoxRect = new Rectangle(-100, -100, BattleSceneDefaults.actionBoxWidth(), BattleSceneDefaults.actionBoxHeight()); + _enemyHealthRect = new Rectangle(-100, -100, BattleSceneDefaults.enemyHealthBoxWidth(), BattleSceneDefaults.enemyHealthBoxHeight()); + _playerHealthRect = new Rectangle(-100, -100, BattleSceneDefaults.playerHealthBoxWidth(), BattleSceneDefaults.playerHealthBoxHeight()); + _playerHPBoxBorderRect = new Rectangle(-100, -100, 0, 0); + _playerHPBoxFillRect = new Rectangle(-100, -100, 0, 0); + _enemyHPBoxBorderRect = new Rectangle(-100, -100, 0, 0); + _enemyHPBoxFillRect = new Rectangle(-100, -100, 0, 0); spriteBatch = new SpriteBatch(); shapeRenderer = new ShapeRenderer(); playerControllerName = "Your monster"; @@ -96,28 +96,24 @@ public BattleScene() { public void draw(float dt, OrthographicCamera camera) { //DRAW THE IMAGES - if(camera != null) + if (camera != null) spriteBatch.setProjectionMatrix(camera.combined); spriteBatch.begin(); _backdropPosition.updatePosition(_backdrop); _playerBasePosition.updatePosition(_playerBase); _enemyBasePosition.updatePosition(_enemyBase); - if(_playerMonster != null) { + if (_playerMonster != null) { _playerMonster.setOrigin(_playerMonster.getImageWidth() / 2, _playerMonster.getImageHeight() / 2); _playerMonster.setRotation(_playerMonsterRotation); _playerMonsterPosition.updatePosition(_playerMonster); - _playerSpinner.setOrigin(_playerSpinner.getImageWidth() / 2, _playerSpinner.getImageHeight() / 2); - _playerSpinner.setPosition(_playerBasePosition.getX() + _playerBase.getImageWidth()/2f - _playerSpinner.getImageWidth()/2f, _playerBasePosition.getY()+160); + } - if(_enemyMonster != null) { + if (_enemyMonster != null) { _enemyMonster.setOrigin(_enemyMonster.getImageWidth() / 2, _enemyMonster.getImageHeight() / 2); _enemyMonster.setRotation(_enemyMonsterRotation); _enemyMonsterPosition.updatePosition(_enemyMonster); - - _enemySpinner.setOrigin(_enemySpinner.getImageWidth() / 2, _enemySpinner.getImageHeight() / 2); - _enemySpinner.setPosition(_enemyBasePosition.getX() + _enemyBase.getImageWidth()/2f - _enemySpinner.getImageWidth()/2f, _enemyBasePosition.getY()+100); } _backdrop.setSize(this.gameWidth, this.gameHeight); @@ -131,16 +127,6 @@ public void draw(float dt, OrthographicCamera camera) { if (_enemyMonster != null) _enemyMonster.draw(spriteBatch, 1); - if(_showPlayerSpinner){ - _playerSpinner.rotateBy(_spinnerSpeed * dt); - _playerSpinner.draw(spriteBatch, 1); - } - - if(_showEnemySpinner){ - _enemySpinner.rotateBy(_spinnerSpeed * dt); - _enemySpinner.draw(spriteBatch, 1); - } - spriteBatch.end(); @@ -149,14 +135,14 @@ public void draw(float dt, OrthographicCamera camera) { shapeRenderer.setColor(Color.WHITE); Gdx.gl.glEnable(GL20.GL_BLEND); //Alows for opacity - if(camera != null) + if (camera != null) shapeRenderer.setProjectionMatrix(camera.combined); shapeRenderer.begin(ShapeRenderer.ShapeType.Filled); //HP Box float hpBarAnimationSpeed = 40f; var biggestHpDiff = Math.max(Math.abs(this.intermediatePlayerHP - this.playerHP), Math.abs(this.intermediateEnemyHP - this.enemyHP)); - if(biggestHpDiff > 50){ + if (biggestHpDiff > 50) { // If there's lots of hp to fill in, then speed it up. hpBarAnimationSpeed = MathUtils.map(biggestHpDiff, 50, 5000, 40, 1500); } @@ -167,8 +153,8 @@ public void draw(float dt, OrthographicCamera camera) { _enemyHealthRect.setPosition(_enemyHealthBoxPosition); setHpBarDimentions(this.intermediateEnemyHP, this.maxEnemyHP, _enemyHealthBoxPosition, _enemyHPBoxFillRect, _enemyHPBoxBorderRect); _enemyHealthRect.draw(shapeRenderer, dt); - _enemyHPBoxBorderRect.draw(shapeRenderer,dt); - _enemyHPBoxFillRect.draw(shapeRenderer,dt); + _enemyHPBoxBorderRect.draw(shapeRenderer, dt); + _enemyHPBoxFillRect.draw(shapeRenderer, dt); _playerHealthRect.setPosition(_playerHealthBoxPosition); setHpBarDimentions(this.intermediatePlayerHP, this.maxPlayerHP, _playerHealthBoxPosition, _playerHPBoxFillRect, _playerHPBoxBorderRect); @@ -180,13 +166,13 @@ public void draw(float dt, OrthographicCamera camera) { if (actions.length > 0) { _actionBoxRect.setPosition(_actionBoxPosition); _actionBoxRect.setBorderColor(new Color(0, 0, 0, _actionBoxAlpha)); - _actionBoxRect.setFillColor(new Color(1,1,1, _actionBoxAlpha)); + _actionBoxRect.setFillColor(new Color(1, 1, 1, _actionBoxAlpha)); _actionBoxRect.draw(shapeRenderer, dt); } //Text box _textBoxRect.setPosition(_textBoxPosition); - _textBoxRect.setWidth(this.gameWidth-40); + _textBoxRect.setWidth(this.gameWidth - 40); _textBoxRect.setHeight(BattleSceneDefaults.textBoxHeight()); _textBoxRect.draw(shapeRenderer, dt); @@ -197,12 +183,36 @@ public void draw(float dt, OrthographicCamera camera) { spriteBatch.begin(); //Health box - textUtils.drawNormalRoboto(spriteBatch, this.enemyControllerName+": " + this.enemyMonsterName, Color.BLACK, _enemyHealthBoxPosition.getX() + 10, _enemyHealthBoxPosition.getY() + 85); + textUtils.drawNormalRoboto(spriteBatch, this.enemyControllerName + ": " + this.enemyMonsterName, Color.BLACK, _enemyHealthBoxPosition.getX() + 10, _enemyHealthBoxPosition.getY() + 85); textUtils.drawNormalRoboto(spriteBatch, "HP:", Color.BLACK, _enemyHealthBoxPosition.getX() + 10, _enemyHealthBoxPosition.getY() + 55); - textUtils.drawNormalRoboto(spriteBatch, this.enemyHP+"/"+this.maxEnemyHP, Color.BLACK, _enemyHealthBoxPosition.getX() + 52, _enemyHealthBoxPosition.getY() + 28); - textUtils.drawNormalRoboto(spriteBatch, this.playerControllerName+": " + this.playerMonsterName, Color.BLACK, _playerHealthBoxPosition.getX() + 10, _playerHealthBoxPosition.getY() + 85); + textUtils.drawNormalRoboto(spriteBatch, this.enemyHP + "/" + this.maxEnemyHP, Color.BLACK, _enemyHealthBoxPosition.getX() + 52, _enemyHealthBoxPosition.getY() + 28); + textUtils.drawNormalRoboto(spriteBatch, this.playerControllerName + ": " + this.playerMonsterName, Color.BLACK, _playerHealthBoxPosition.getX() + 10, _playerHealthBoxPosition.getY() + 85); textUtils.drawNormalRoboto(spriteBatch, "HP:", Color.BLACK, _playerHealthBoxPosition.getX() + 10, _playerHealthBoxPosition.getY() + 55); - textUtils.drawNormalRoboto(spriteBatch, this.playerHP+"/"+this.maxPlayerHP, Color.BLACK, _playerHealthBoxPosition.getX() + 52, _playerHealthBoxPosition.getY() + 28); + textUtils.drawNormalRoboto(spriteBatch, this.playerHP + "/" + this.maxPlayerHP, Color.BLACK, _playerHealthBoxPosition.getX() + 52, _playerHealthBoxPosition.getY() + 28); + + // Spinners on health boxes + if (_showPlayerSpinner) { + _playerSpinner.setOrigin(_playerSpinner.getImageWidth() / 2, _playerSpinner.getImageHeight() / 2); + _playerSpinner.setSize(16, 16); + _playerSpinner.setPosition(_playerHealthRect.getX() + _playerHealthRect.getWidth() - _playerSpinner.getImageWidth() - 5, _playerHealthRect.getY() + 5); + _playerSpinner.rotateBy(_spinnerSpeed * dt); + _playerSpinner.draw(spriteBatch, 1); + textUtils.setCoordinateMode(TextUtils.CoordinateMode.BOTTOM_RIGHT); + textUtils.drawSmallRoboto(spriteBatch, "AI thinking", Color.BLACK, _playerSpinner.getX() - 8, _playerSpinner.getY() + 3); + textUtils.setCoordinateMode(TextUtils.CoordinateMode.TOP_LEFT); + } + + if (_showEnemySpinner) { + _enemySpinner.setOrigin(_enemySpinner.getImageWidth() / 2, _enemySpinner.getImageHeight() / 2); + _enemySpinner.setSize(16, 16); + _enemySpinner.setPosition(_enemyHealthRect.getX() + _enemyHealthRect.getWidth() - _enemySpinner.getImageWidth() - 5, _enemyHealthRect.getY() + 5); + _enemySpinner.rotateBy(_spinnerSpeed * dt); + _enemySpinner.draw(spriteBatch, 1); + textUtils.setCoordinateMode(TextUtils.CoordinateMode.BOTTOM_RIGHT); + textUtils.drawSmallRoboto(spriteBatch, "AI thinking", Color.BLACK, _enemySpinner.getX() - 8, _enemySpinner.getY() + 3); + textUtils.setCoordinateMode(TextUtils.CoordinateMode.TOP_LEFT); + } + //Draw health indicator if (_healthIndicatorText != null && !_healthIndicatorText.isEmpty()) @@ -238,7 +248,7 @@ public void draw(float dt, OrthographicCamera camera) { int normalTextHeight = 24; int actionTopTextHeight = 186; int offsetFromActionHeadToFirstAction = 8; - + int renderHeight = actionTopTextHeight - triangleHeight - normalTextHeight - offsetFromActionHeadToFirstAction; renderHeight = renderHeight + selectedActionIndex * -smallTextHeight * 2; @@ -254,7 +264,7 @@ public void draw(float dt, OrthographicCamera camera) { Gdx.gl.glDisable(GL20.GL_BLEND); } - private static void setHpBarDimentions(float hp, int maxHp, Position basePosition, Rectangle fillRect, Rectangle broderRect){ + private static void setHpBarDimentions(float hp, int maxHp, Position basePosition, Rectangle fillRect, Rectangle broderRect) { float hpBarOffsetX = 58; float hpBarOffsetY = 35; float hpBarHeight = 20; @@ -276,11 +286,11 @@ private static void setHpBarDimentions(float hp, int maxHp, Position basePositio fillRect.setWidth(hpBasedWidth); float healthPercentage = hpBasedWidth / hpBarFullWidth; - if(healthPercentage > .5f) { + if (healthPercentage > .5f) { fillRect.setFillColor(Color.GREEN); - }else if(healthPercentage > .15f){ + } else if (healthPercentage > .15f) { fillRect.setFillColor(Color.YELLOW); - }else{ + } else { fillRect.setFillColor(Color.RED); } } @@ -296,7 +306,7 @@ public String getTextToDisplay() { } public void setEnemySprite(String spritePath, Class reference) { - if(!spritePath.equalsIgnoreCase(this._enemyMonsterSpritePath)) { + if (!spritePath.equalsIgnoreCase(this._enemyMonsterSpritePath)) { this._enemyMonster = loader.getImageAsset(spritePath, reference); this._enemyMonsterSpritePath = spritePath; } @@ -323,7 +333,7 @@ public void setMaxEnemyHP(int maxEnemyHP) { } public void setPlayerSprite(String spritePath, Class reference) { - if(!spritePath.equalsIgnoreCase(this._playerMonsterSpritePath)) { + if (!spritePath.equalsIgnoreCase(this._playerMonsterSpritePath)) { this._playerMonster = loader.getImageAsset(spritePath, reference); this._playerMonsterSpritePath = spritePath; } @@ -336,6 +346,7 @@ public void setPlayerMonsterName(String playerMonsterName) { public void setPlayerHP(int playerHP) { this.playerHP = playerHP; } + public void setMaxPlayerHP(int maxPlayerHP) { this.maxPlayerHP = maxPlayerHP; } @@ -442,15 +453,15 @@ public void setEnemyHealthBoxPosition(Position _enemyHealthBoxPosition) { this._enemyHealthBoxPosition = _enemyHealthBoxPosition; } - public Rectangle getEnemyBoxRect(){ + public Rectangle getEnemyBoxRect() { return this._enemyHealthRect; } - public void setEnemyBoxRectStyle(Class clazz){ + public void setEnemyBoxRectStyle(Class clazz) { try { - _enemyHealthRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100,-100, BattleSceneDefaults.enemyHealthBoxWidth(), BattleSceneDefaults.enemyHealthBoxHeight()); - _enemyHPBoxBorderRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100,-100, 0, 0); - _enemyHPBoxFillRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100,-100, 0, 0); + _enemyHealthRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100, -100, BattleSceneDefaults.enemyHealthBoxWidth(), BattleSceneDefaults.enemyHealthBoxHeight()); + _enemyHPBoxBorderRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100, -100, 0, 0); + _enemyHPBoxFillRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100, -100, 0, 0); } catch (Exception ex) { System.out.println("[WARNING] Failed to change rectangles."); } @@ -464,15 +475,15 @@ public void setPlayerHealthBoxPosition(Position _playerHealthBoxPosition) { this._playerHealthBoxPosition = _playerHealthBoxPosition; } - public Rectangle getPlayerBoxRect(){ + public Rectangle getPlayerBoxRect() { return this._playerHealthRect; } - public void setPlayerBoxRectStyle(Class clazz){ + public void setPlayerBoxRectStyle(Class clazz) { try { - _playerHealthRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100,-100, BattleSceneDefaults.playerHealthBoxWidth(), BattleSceneDefaults.playerHealthBoxHeight()); - _playerHPBoxBorderRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100,-100, 0, 0); - _playerHPBoxFillRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100,-100, 0, 0); + _playerHealthRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100, -100, BattleSceneDefaults.playerHealthBoxWidth(), BattleSceneDefaults.playerHealthBoxHeight()); + _playerHPBoxBorderRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100, -100, 0, 0); + _playerHPBoxFillRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(-100, -100, 0, 0); } catch (Exception ex) { System.out.println("[WARNING] Failed to change rectangles."); } @@ -494,13 +505,13 @@ public void setActionBoxAlpha(float _actionBoxOpacity) { this._actionBoxAlpha = _actionBoxOpacity; } - public Rectangle getActionBoxRect(){ + public Rectangle getActionBoxRect() { return this._actionBoxRect; } - public void setActionBoxRectStyle(Class clazz){ + public void setActionBoxRectStyle(Class clazz) { try { - _actionBoxRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100,-100, BattleSceneDefaults.actionBoxWidth(), BattleSceneDefaults.actionBoxHeight()); + _actionBoxRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100, -100, BattleSceneDefaults.actionBoxWidth(), BattleSceneDefaults.actionBoxHeight()); } catch (Exception ex) { System.out.println("[WARNING] Failed to change rectangles."); } @@ -530,14 +541,14 @@ public String getHealthIndicatorText() { return this._healthIndicatorText; } - public Rectangle getTextBoxRect(){ + public Rectangle getTextBoxRect() { return this._textBoxRect; } - public void setTextBoxRectStyle(Class clazz){ + public void setTextBoxRectStyle(Class clazz) { try { // Arguments for this one, does not matter as it is calculated on the fly in draw() - _textBoxRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100,-100, 0, 0); + _textBoxRect = (Rectangle) clazz.getDeclaredConstructors()[0].newInstance(100, -100, 0, 0); } catch (Exception ex) { System.out.println("[WARNING] Failed to change rectangles."); } @@ -560,7 +571,7 @@ public void resetPositions() { _playerBasePosition = BattleSceneDefaults.playerBasePosition(); _enemyBasePosition = BattleSceneDefaults.enemyBasePosition(); _enemyMonsterPosition = BattleSceneDefaults.enemyMonsterPosition(); - _playerMonsterPosition =BattleSceneDefaults.playerMonsterPosition(); + _playerMonsterPosition = BattleSceneDefaults.playerMonsterPosition(); _enemyHealthBoxPosition = BattleSceneDefaults.enemyHealthBoxPosition(); _playerHealthBoxPosition = BattleSceneDefaults.playerHealthBoxPosition(); _actionBoxPosition = BattleSceneDefaults.actionBoxPosition(this.gameWidth); diff --git a/src/main/java/dk/sdu/mmmi/modulemon/BattleSimulation/BattleSimulation.java b/src/main/java/dk/sdu/mmmi/modulemon/BattleSimulation/BattleSimulation.java index 3d1dd5a0..e632ec51 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/BattleSimulation/BattleSimulation.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/BattleSimulation/BattleSimulation.java @@ -261,6 +261,11 @@ public synchronized IBattleEvent getNextBattleEvent() { return event; } + @Override + public boolean hasNextBattleEvent() { + return nextEvent != null; + } + private IBattleAI getOpponentAI() { if (this.opponentAI ==null) { if (this.opponentAIFactory ==null) { diff --git a/src/main/java/dk/sdu/mmmi/modulemon/CommonBattleSimulation/IBattleSimulation.java b/src/main/java/dk/sdu/mmmi/modulemon/CommonBattleSimulation/IBattleSimulation.java index 1d0c860c..6366b93b 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/CommonBattleSimulation/IBattleSimulation.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/CommonBattleSimulation/IBattleSimulation.java @@ -24,6 +24,7 @@ public interface IBattleSimulation { * Returns `null` if there is no more battle events */ IBattleEvent getNextBattleEvent(); + boolean hasNextBattleEvent(); boolean isPlayerControlledByAI(); diff --git a/src/main/java/dk/sdu/mmmi/modulemon/common/drawing/TextUtils.java b/src/main/java/dk/sdu/mmmi/modulemon/common/drawing/TextUtils.java index 753743c8..c749ab31 100644 --- a/src/main/java/dk/sdu/mmmi/modulemon/common/drawing/TextUtils.java +++ b/src/main/java/dk/sdu/mmmi/modulemon/common/drawing/TextUtils.java @@ -157,7 +157,7 @@ public void drawSmallBoldRoboto(SpriteBatch batch, String text, Color color, flo private Position getAdjustedCoordinates(GlyphLayout layout, float x, float y) { return switch (currentCoordinateMode) { case TOP_LEFT -> new Position(x, y); - case BOTTOM_RIGHT -> new Position(x - layout.width, y - layout.height); + case BOTTOM_RIGHT -> new Position(x - layout.width, y + layout.height); case CENTER -> new Position(x - (layout.width / 2f), y + (layout.height/2f)); }; }