Skip to content
Snippets Groups Projects
Commit 76e5e14f authored by Susan Yuen's avatar Susan Yuen
Browse files

Cleaned up code in MouseHandler. Extracted logic into GameFunction.

parent dd187df6
No related branches found
No related tags found
No related merge requests found
......@@ -2,9 +2,11 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Model;
using View;
using Microsoft.Xna.Framework;
namespace Controller
{
......@@ -17,20 +19,6 @@ namespace Controller
*/
static class GameFunction
{
/**
Returns whether an enemy unit is in range of the specified unit.
\param graph Graph representing the current game map.
\param unit Unit to find enemies for.
*/
public static bool isAnEnemyUnitInRange(Graph graph, Unit unit)
{
if (enemyUnitsInRange(graph, unit).Count == 0)
{
return false;
}
return true;
}
/**
Returns whether or not the specified enemy unit is within attack range of the specified unit.
\param graph Graph representing the current game map.
......@@ -72,29 +60,6 @@ namespace Controller
GameState.beforeMove = true;
}
/**
Returns all enemy units in strict attack range of the specified unit.
\param graph Graph representing the current game map.
\param unit Unit to find enemy units for.
*/
public static LinkedList<Unit> enemyUnitsInRange(Graph graph, Unit unit)
{
//TODO: int range = unit.getEquippedWeapon().getRange(); // use this to determine all hitable squares
LinkedList<Unit> enemyUnitsInRange = new LinkedList<Unit>();
LinkedList<Unit> allEnemyUnits = GameState.enemyPlayer.getUnits();
foreach (Unit enemyUnit in allEnemyUnits)
{
if (isEnemyUnitInRange(graph, unit, enemyUnit))
{
enemyUnitsInRange.AddLast(enemyUnit);
}
}
return enemyUnitsInRange;
}
/**
Returns whether or not the specified unit can perform actions.
\param unit Specified unit.
......@@ -197,6 +162,7 @@ namespace Controller
}
}
}
GameState.moveableNodes = moveableNodes;
return moveableNodes;
}
......@@ -218,8 +184,8 @@ namespace Controller
{
for (int y = 0; y < graph.Height; y++)
{
if ((isNodeAttackable(unit, moveableNode.getPositionX(),
moveableNode.getPositionY(), graph.getNode(x, y))) && (!attackableNodes.Contains(graph.getNode(x, y)))) //make sure attackable nodes is only added once each to list
if (isNodeAttackable(unit, moveableNode.getPositionX(), moveableNode.getPositionY(), graph.getNode(x, y)) &&
!attackableNodes.Contains(graph.getNode(x, y)))
{
// if node is attackable, add it to list of attackable nodes
attackableNodes.AddLast(graph.getNode(x, y));
......@@ -227,6 +193,7 @@ namespace Controller
}
}
}
return attackableNodes;
}
......@@ -250,6 +217,7 @@ namespace Controller
}
}
}
return attackableNodes;
}
......@@ -264,6 +232,7 @@ namespace Controller
{
// TODO: (OPTIONAL, IGNORE FOR NOW) incorporate movability of nodes in the calculation
// if end node is not movable, then there cannot be a path
if (end.isObstacle || end.isOccupied())
{
return null;
......@@ -305,6 +274,7 @@ namespace Controller
}
}
}
return null;
}
......@@ -357,5 +327,452 @@ namespace Controller
graph.getNode(unit.Position).unitOnNode = null;
player.removeUnit(unit);
}
/**
Deselects any selected unit.
*/
public static void deselectUnit()
{
setSelectedUnit(null, false);
GameState.TurnState = TurnState.Wait;
GameState.unitToAttack = null;
GameState.attackConfirmOpen = false;
GameState.dropDownMenuOpen = false;
GameState.attackSelect = false;
}
/**
Sets selection of unit state inside GameState.
\param unit Unit to set selection of.
\param selected Indicates whether or not a selection is occuring.
*/
public static void setSelectedUnit(Unit unit, bool selected)
{
GameState.playableUnitSelected = selected;
GameState.selectedUnit = unit;
}
/**
If unit exists where user clicked (that belongs to player), return it; else, return null.
\param clickedNode Node where user has clicked.
\param positionClicked position (by node) of where the user has clicked.
\param player Player that is currently moving.
*/
public static Unit getUnitOnNodeClicked(Node clickedNode, Vector2 positionClicked, Player player)
{
for (int i = 0; i < player.getNumOfUnits(); i++)
{
Unit unit = player.getUnits().ElementAt(i);
int unitX = unit.Position.Item1;
int unitY = unit.Position.Item2;
int clickedX = (int)Math.Floor(positionClicked.X / 32);
int clickedY = (int)Math.Floor(positionClicked.Y / 32);
if (unitX == clickedX && unitY == clickedY)
{
return unit;
}
}
return null;
}
/**
Updates the unit's position to the clicked position.
\param graph Graph representing the current game map.
\param position Position (by node) to move the unit to.
\param path Path to move the unit along.
*/
public static void updateUnitPosition(Graph graph, Vector2 position, LinkedList<Node> path)
{
Unit unit = GameState.selectedUnit;
GameState.isAnimating = true;
// updates the unit's position to each node in the path (node by node)
foreach (Node node in path)
{
animateUnitPosition(graph, unit, node);
unit.Position = (new Tuple<int, int>(node.getPositionX(), node.getPositionY()));
node.unitOnNode = (unit);
GameState.dropDownMenuOpen = true;
}
GameState.isAnimating = false;
}
/**
Ends the current player's turn and starts the enemy player's turn.
*/
public static void endTurn()
{
Player tempPlayer = GameState.currentPlayer;
GameState.currentPlayer = (GameState.enemyPlayer);
GameState.enemyPlayer = (tempPlayer);
startTurn(GameState.currentPlayer);
GameState.endTurnButton = false;
GameState.transitionTurn = true;
}
/**
Updates the Model based upon button clicks.
\param button Button that was clicked.
\param graph Graph of the map.
*/
// TODO: MOVE ANIMATION PARTS TO ANIMATION CLASS
public static void buttonAction(Button button, Graph graph)
{
Unit unit = GameState.selectedUnit;
Unit enemyUnit = GameState.unitToAttack;
switch (button.getButtonType())
{
#region Attack Button
// if attack clicked
case ButtonType.Attack:
GameState.TurnState = TurnState.Attack;
GameState.dropDownMenuOpen = false; // close the dropdown menu when selecting who to attack
GameState.attackSelect = true;
break;
#endregion
#region Attack Confirm Button
// if confirm attack clicked
case ButtonType.AttackConfirm:
button.Active = false;
unit.getButtonType(ButtonType.Move).Active = false; // move button is no longer active
unit.getButtonType(ButtonType.Attack).Active = false; // attack button is no longer active
//Gets attack animation direction
#region Attack Animation Direction
Direction attackDir = Direction.Up;
Direction counterAttackDir = Direction.Up;
if (unit.Position.Item1 < enemyUnit.Position.Item1) // attack right
{
attackDir = Direction.Right;
counterAttackDir = Direction.Left;
unit.setCurrentFrame(7);
enemyUnit.setCurrentFrame(4);
}
else if (unit.Position.Item1 > enemyUnit.Position.Item1) // attack left
{
attackDir = Direction.Left;
counterAttackDir = Direction.Right;
unit.setCurrentFrame(4);
enemyUnit.setCurrentFrame(7);
}
else if (unit.Position.Item2 < enemyUnit.Position.Item2) // attack down
{
attackDir = Direction.Down;
counterAttackDir = Direction.Up;
unit.setCurrentFrame(1);
enemyUnit.setCurrentFrame(10);
}
else if (unit.Position.Item2 > enemyUnit.Position.Item2) // attack up
{
attackDir = Direction.Up;
counterAttackDir = Direction.Down;
unit.setCurrentFrame(10);
enemyUnit.setCurrentFrame(1);
}
#endregion
bool magicalAttack = isMagicalAttack(unit); // find what attack type unit is making
int damageDealt = DamageCalculations.finalDamage(unit, enemyUnit, magicalAttack); // gets damage dealt
GameState.lastAttackingUnit = unit;
GameState.lastDefendingUnit = enemyUnit;
GameState.CurrentPlayerDamageDealt = damageDealt.ToString();
enemyUnit.Hp = enemyUnit.Hp - damageDealt; // updates hp
GameState.currentPlayerDamagePopup = true;
attackAnimation(attackDir, unit);
// if enemy unit is still alive, perform a counter attack
if (enemyUnit.Alive && isEnemyUnitInRange(graph, enemyUnit, unit))
{
Thread.Sleep(750);
magicalAttack = isMagicalAttack(enemyUnit); // gets attack type
int damageTaken = DamageCalculations.finalDamage(enemyUnit, unit, magicalAttack); // damage dealt
GameState.EnemyPlayerDamageDealt = damageTaken.ToString();
unit.Hp = unit.Hp - damageTaken; // update hp
GameState.enemyPlayerDamagePopup = true;
attackAnimation(counterAttackDir, enemyUnit);
}
deselectUnit();
break;
#endregion
#region Move Button
// if Move is clicked
case ButtonType.Move:
if (button.Active) // if unit hasn't already moved
{
GameState.TurnState = TurnState.Move;
GameState.dropDownMenuOpen = false; // close the dropdownmenu when selecting where to move
}
break;
#endregion
#region Item Button
case ButtonType.Items: // if item is clicked
GameState.TurnState = TurnState.Items;
GameState.inventoryOpen = true;
break;
#endregion
#region Wait Button
// if wait is clicked
case ButtonType.Wait:
GameState.TurnState = TurnState.Wait;
deselectUnit();
button.Active = false;
break;
#endregion
#region Inventory Buttons
case ButtonType.Inventory1:
GameState.inventoryOpen = false;
unit.equippedWeapon = button.weapon;
break;
case ButtonType.Inventory2:
GameState.inventoryOpen = false;
unit.equippedWeapon = button.weapon;
break;
case ButtonType.Inventory3:
GameState.inventoryOpen = false;
unit.equippedWeapon = button.weapon;
break;
case ButtonType.Inventory4:
GameState.inventoryOpen = false;
unit.equippedWeapon = button.weapon;
break;
#endregion
default:
break;
}
}
// returns whether or not the unit performed a magical attack
// TODO: change this function to factor the weapon type rather than unit type
private static bool isMagicalAttack(Unit unit)
{
if ((unit.getClass() == UnitType.Warrior) || (unit.getClass() == UnitType.Archer))
{
return false;
}
else
{
return true;
}
}
// TODO: MOVE TO ANIMATION CLASS
private static void attackAnimation(Direction direction, Unit unit)
{
GameState.isAnimating = true;
float originalLocationX = unit.PixelCoordinates.X;
float originalLocationY = unit.PixelCoordinates.Y;
#region Attack Right
if (direction == Direction.Right) //attack right
{
for (float i = originalLocationX; i <= originalLocationX + 8; i++)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X + 1, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(10);
}
for (float i = unit.PixelCoordinates.X; i > originalLocationX; i--)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X - 1, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(10);
}
}
#endregion
#region Attack Left
else if (direction == Direction.Left) //attack left
{
for (float i = originalLocationX; i >= originalLocationX - 8; i--)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X - 1, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(10);
}
for (float i = unit.PixelCoordinates.X; i < originalLocationX; i++)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X + 1, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(10);
}
}
#endregion
#region Attack Down
else if (direction == Direction.Down) //attack down
{
for (float i = originalLocationY; i <= originalLocationY + 8; i++)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y + 1);
Game.Instance.Tick();
Thread.Sleep(10);
}
for (float i = unit.PixelCoordinates.Y; i > originalLocationY; i--)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y - 1);
Game.Instance.Tick();
Thread.Sleep(10);
}
}
#endregion
#region Attack Up
else if (direction == Direction.Up) //attack up
{
for (float i = originalLocationY; i >= originalLocationY - 8; i--)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y - 1);
Game.Instance.Tick();
Thread.Sleep(10);
}
for (float i = unit.PixelCoordinates.Y; i < originalLocationY; i++)
{
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y + 1);
Game.Instance.Tick();
Thread.Sleep(10);
}
}
#endregion
GameState.isAnimating = false;
}
// Moves unit to move from to different nodes
// TODO: MOVE TO ANIMATION CLASS
private static void animateUnitPosition(Graph graph, Unit unit, Node node)
{
int nodePixelX = node.getPositionX() * 32;
int nodePixelY = node.getPositionY() * 32;
int pixelDifference = 4;
graph.getNode(unit.Position).unitOnNode = (null);
while (unit.PixelCoordinates.X != nodePixelX)
{
if (unit.PixelCoordinates.X < nodePixelX)
{
unit.animate(Direction.Right);
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X + pixelDifference, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(40);
}
else
{
unit.animate(Direction.Left);
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X - pixelDifference, unit.PixelCoordinates.Y);
Game.Instance.Tick();
Thread.Sleep(40);
}
}
while (unit.PixelCoordinates.Y != nodePixelY)
{
if (unit.PixelCoordinates.Y < nodePixelY)
{
unit.animate(Direction.Down);
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y + pixelDifference);
Game.Instance.Tick();
Thread.Sleep(40);
}
else
{
unit.animate(Direction.Up);
unit.PixelCoordinates = new Vector2(unit.PixelCoordinates.X, unit.PixelCoordinates.Y - pixelDifference);
Game.Instance.Tick();
Thread.Sleep(40);
}
}
}
/**
Returns the menu button that was clicked; if no menu button was clicked, returns null.
\param mouseCoordinates Coordinates of the mouse click.
\param camera The camera of the game.
*/
public static Button getMenuButtonClicked(Vector2 mouseCoordinates, Camera camera)
{
Unit unit = GameState.selectedUnit;
Button[] menuButtons = unit.getButtons();
int clickX = (int)mouseCoordinates.X; // coordinates relative to map
int clickY = (int)mouseCoordinates.Y;
int stationaryClickX = (int)mouseCoordinates.X + (int)camera.Position.X; // coordinates relative to window
int stationaryClickY = (int)mouseCoordinates.Y + (int)camera.Position.Y;
for (int i = 0; i < menuButtons.Length; i++)
{
int buttonX = (int)menuButtons[i].getPixelCoordinates().X;
int buttonY = (int)menuButtons[i].getPixelCoordinates().Y;
if (buttonX <= clickX && clickX < buttonX + 128 && buttonY <= clickY && clickY < buttonY + 32)
{
if (GameState.dropDownMenuOpen)
{
return menuButtons[i];
}
}
}
int ButtonX = (int)unit.getButtonType(ButtonType.AttackConfirm).getPixelCoordinates().X;
int ButtonY = (int)unit.getButtonType(ButtonType.AttackConfirm).getPixelCoordinates().Y;
if (ButtonX + 90 <= stationaryClickX && stationaryClickX < ButtonX + 214 &&
ButtonY + 127 <= stationaryClickY && stationaryClickY < ButtonY + 172)
{
if (GameState.attackConfirmOpen)
{
return unit.getButtonType(ButtonType.AttackConfirm);
}
}
return null;
}
/**
Enables scrolling of the map based on mouse position.
\param camera The camera of the game.
\param mouseX x-coordinate of the mouse position.
\param mouseY y-coordinate of the mouse position.
*/
public static void scrollMap(Camera camera, int mouseX, int mouseY)
{
const int scrollSpeed = 3; // change in pixels while scrolling
const int boundaryX = -640;
const int boundaryY = -320;
if (Game.Instance.IsActive) // if game window is in focus
{
// scroll map to the left
if (mouseX <= 0 && camera.Position.X < 0)
{
camera.Position = new Vector2(camera.Position.X + scrollSpeed, camera.Position.Y);
}
// scroll map to the right
if (mouseX >= GameState.SCREEN_WIDTH && camera.Position.X > boundaryX)
{
camera.Position = new Vector2(camera.Position.X - scrollSpeed, camera.Position.Y);
}
// scroll map downwards
if (mouseY >= GameState.SCREEN_HEIGHT && camera.Position.Y > boundaryY)
{
camera.Position = new Vector2(camera.Position.X, camera.Position.Y - scrollSpeed);
}
// scroll map upwards
if (mouseY <= 0 && camera.Position.Y < 0)
{
camera.Position = new Vector2(camera.Position.X, camera.Position.Y + scrollSpeed);
}
}
}
}
}
\ No newline at end of file
......@@ -78,6 +78,10 @@ namespace Model
*/
public static bool transitionTurn { get; set; }
/**
Sets and gets the current TurnState of the selected unit.
*/
public static TurnState TurnState { get; set; }
/**
Sets and gets whether damage dealt number pops up for current player
*/
public static bool currentPlayerDamagePopup { get; set; }
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment