Commit d5a3df8f authored by Thomas Dupriez's avatar Thomas Dupriez

Some cleanup

parent 286a005a
......@@ -6,7 +6,6 @@ package graphics.display_test;
import artificial_intelligence.AIControler;
import artificial_intelligence.AIEntities.AgressiveEntity;
import artificial_intelligence.AIEntities.EnumBehaviourType;
import com.sun.javafx.scene.traversal.Direction;
import gameloop.DummyLocalGameLoop;
import gameloop.GameStarter;
import graphics.graphical_abstraction.GraphicsMasterAbstraction;
......
package graphics.graphical_utility.applicationData.lounge;
import java.util.ArrayList;
/**
* Created by dupriez on 06/12/15.
*
* This class defines a Lounge, without any link to the gui.
* It allows listeners to subscribe to the changes made to the content of the slots. (observer pattern)
* For this reason, it makes sure that no one can ever have a pointer to one of the PlayerInformation stored in it,
* because they would be able to bypass the modification notification system.
*/
public class Lounge {
//Number of players able to be in the Lounge (hence the number of players of a session of the game)
private int numberOfSlots;
private PlayerInformation[] slots;
//This array stores whether the slots are occupied or not
private boolean[] slotsOccupation;
private int numberOfOccupiedSlots = 0;
/** Implementation of the observer pattern **/
private ArrayList<LoungeModificationListener> listeners = new ArrayList<>();
public void subscribeToModification(LoungeModificationListener subscriber){
listeners.add(subscriber);
}
private void slotModified(int modifiedSlotNumber){
for (LoungeModificationListener listener : listeners) {
listener.loungeModificationHandler(modifiedSlotNumber);
}
}
public Lounge(int numberOfSlots) {
this.numberOfSlots = numberOfSlots;
slots = new PlayerInformation[numberOfSlots];
slotsOccupation = new boolean[numberOfSlots];
//Filling the slots with EmptyPlayerDefinitions, and filling slotsOccupation with false
for (int i = 0; i < numberOfSlots; i++) {
slots[i] = PlayerInformation.makeEmptyPlayerInformation();
slotsOccupation[i] = false;
}
}
/**
* If there is one, create another PlayerInformation object with the same values as playerInformation_ReadOnly,
* puts it in the slot and outputs the number of the slot.
* If no free slot exists, does nothing and outputs -1
* @param playerInformation
* @return
*/
public int addPlayer(PlayerInformation playerInformation) {
int firstFreeSlot = -1;
for (int i = 0; i < slotsOccupation.length; i++) {
if (!slotsOccupation[i]){
firstFreeSlot = i;
break;
}
}
if (firstFreeSlot==-1){ //No free slot found
return -1;
}
PlayerInformation newPlayerInformation = playerInformation.clone();
slots[firstFreeSlot] = newPlayerInformation;
slotsOccupation[firstFreeSlot] = true;
numberOfOccupiedSlots++;
//Notify listeners of the modification
slotModified(firstFreeSlot);
return firstFreeSlot;
}
/**
* If there was a player at slot number slotNumber, creates another PlayerInformation object with the same values as
* playerInformation_ReadOnly and put it in the slot whose number is slotNumber and outputs 1.
* If the slot number slotNumber is empty, does nothing and outputs -1.
* @param playerInformation
* @param slotNumber
* @return
*/
public int updatePlayer(PlayerInformation playerInformation, int slotNumber) {
if (slotsOccupation[slotNumber]){ //Player found at the slot
PlayerInformation newPlayerInformation = playerInformation.clone();
slots[slotNumber] = newPlayerInformation;
//Notify the listeners of the change
slotModified(slotNumber);
return 1;
}
return -1;
}
/**
* Removes the playerInformation of the slot whose number is given in argument. Fills the slot with an EmptyPlayerInformation.
* Outputs 1 if there was a player at the slot, -1 if not.
* @param slotNumber
* @return
*/
public int removePlayer(int slotNumber) {
if (slotsOccupation[slotNumber]) { //Player found at the slot
slots[slotNumber] = PlayerInformation.makeEmptyPlayerInformation();
slotsOccupation[slotNumber] = false;
numberOfOccupiedSlots--;
//Notify listeners of the modification
slotModified(slotNumber);
return 1;
}
return -1;
}
/**
* Return the PlayerInformation stored at the slot whose number is given as argument.
* @param slotNumber
* @return
*/
public PlayerInformation_ReadOnly getPlayerAtSlot(int slotNumber) {
return slots[slotNumber];
}
public int getNumberOfSlots() {
return numberOfSlots;
}
/**
* Outputs whether the Lounge is full of non-empty PlayerInformation
* @return
*/
public boolean isFull(){
return numberOfOccupiedSlots==numberOfSlots;
}
}
package graphics.graphical_utility.applicationData.lounge;
/**
* Created by dupriez on 06/12/15.
*
* To be implemented by anyone interested in the changes done to a Lounge (PlayerInformationList_SubPanel for instance)
*/
public interface LoungeModificationListener {
//What to do when a slot of the Lounge is modified
void loungeModificationHandler(int modifiedSlotNumber);
}
package graphics.graphical_utility.applicationData.lounge;
/**
* Created by dupriez on 06/12/15.
*
* Define a player on the LoungePanel, so that it can be displayed in the PlayerInformationList_SubPanel
*/
public class PlayerInformation implements PlayerInformation_ReadOnly{
private String playerName;
private boolean ready = false;
public PlayerInformation(String playerName) {
this.playerName = playerName;
}
static public PlayerInformation makeEmptyPlayerInformation() {
return new PlayerInformation("Empty");
}
/**
* Build another instance of PlayerInformation, whose fields contain the same values as "this".
* @return
*/
@Override
public PlayerInformation clone() {
PlayerInformation result = new PlayerInformation(this.playerName);
result.setReady(this.isReady());
return result;
}
@Override
public PlayerInformation cloneAsEditableVersion() {
return this.clone();
}
/** Getters and Setters **/
@Override
public String getPlayerName() {
return playerName;
}
public void setPlayerName(String playerName) {
this.playerName = playerName;
}
@Override
public boolean isReady() {
return ready;
}
public void setReady(boolean ready) {
this.ready = ready;
}
}
package graphics.graphical_utility.applicationData.lounge;
/**
* Created by dupriez on 06/12/15.
*
* A different view of the class PlayerInformation, with only the getters method.
*/
public interface PlayerInformation_ReadOnly {
String getPlayerName();
boolean isReady();
/**
* Returns a PlayerInformation object, whose fields contain the same values as this PlayerInformation_ReadOnly
* @return
*/
PlayerInformation cloneAsEditableVersion();
}
......@@ -10,7 +10,6 @@ import graphics.guiSkeleton.guiPanel.menuPanel.configuration.ConfigurationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameCreation.MultiPlayer_GameCreationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameCreation.SinglePlayer_GameCreationPanel;
import graphics.guiSkeleton.guiPanel.menuPanel.gameLoad.SinglePlayer_LoadGamePanel;
import graphics.guiSkeleton.guiPanel.menuPanel.loungePanel.LoungePanel;
import graphics.guiSkeleton.guiPanel.menuPanel.multiPlayer_MenuPanel.MultiPlayer_MenuPanel;
import graphics.guiSkeleton.inputManagement.MainFrameKeyListener;
import ingame_programming.IGPpanel;
......@@ -48,7 +47,6 @@ public class GraphicsMaster extends GraphicsMasterAbstraction {
mapGUIStatesToGUIPanel.put(GUIStates.INPUT_CONFIG_PANEL, new ConfigurationPanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.IGP_PANEL, new IGPpanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.LOUNGE, new LoungePanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.MULTIPLAYER_GAME_CREATION, new MultiPlayer_GameCreationPanel(this));
mapGUIStatesToGUIPanel.put(GUIStates.MULTIPLAYER_CHARACTER_CHOICE, new MultiPlayer_CharacterChoicePanel(this));
......
......@@ -20,7 +20,7 @@ import graphics.guiSkeleton.sprites.Sprite;
/**
* Created by dupriez on 14/11/15.
*
* Each entity should have one instance of a subclass of this class
* Each entity should have one instance of this class
* It is used by the gui to know how to display the said entity
*/
public class EntityDisplayer implements Serializable {
......@@ -78,7 +78,6 @@ public class EntityDisplayer implements Serializable {
public char getTermSprite() {
return charForTerminalSprite;
}
//abstract public PositionedSpriteTerm getPositionedSpriteTerm(GraphicsMapTerm graphicsMap);
public Entity getAssociatedEntity() {
return associatedEntity;
......
package graphics.guiSkeleton.entityDisplayer;
import java.io.Serializable;
/**
* Created by dupriez on 14/11/15.
*
* Each entity should have one instance of a subclass of this class
* It is used by the gui to know how to display the said entity
*/
abstract public class EntityDisplayer2 implements Serializable {
// // les images doivent avoir leurs animations alignées horizontalement
// //The Entity this Displayer is associated to
// private Entity associatedEntity;
// int sprite_num; // le numéro d'image où on en est de l'animation
// int persofixe[][] = new int[8][4]; // dim 1 : directions, dim 2 : case 0: position sur la sprite, 1: hauteur, 2: largeur, 3: nb_images
// int marche[][] = new int[8][4];
// int attaque[][] = new int[8][4];
// int touche[][] = new int[8][4];
// final static int DEFAULT_SPRITE=1;
//
// public EntityDisplayer2(Entity associatedEntity, int sprite_num, int[] nb_images,
// int[][] persofixe, int[][] marche, int[][] attaque1, int[][] hit) {
// this.associatedEntity = associatedEntity;
// this.sprite_num = sprite_num;
// for (int i =0; i<persofixe.length-1; i++){
// System.arraycopy(persofixe[i], 0, this.persofixe[i], 0, this.persofixe[i].length);
// System.arraycopy(marche[i], 0, this.marche[i], 0, this.marche[i].length);
// System.arraycopy(attaque[i], 0, this.attaque[i], 0, this.attaque[i].length);
// System.arraycopy(touche[i], 0, this.touche[i], 0, this.touche[i].length);
// }
// }
//
// public PositionedSprite getPositionedSprite(GraphicsMap graphicsMap) {
// /**
// * The purpose of this function is to be called by the gui when it displays the entity related to this displayer
// * @param graphicsMap: the GraphicsMap of the map the associatedEntity is on
// * @return The PositionedSprite that the gui should display to represent this entity
// */
// Sprite sprite = SpriteStorage.getInstance().getRonflex();
//
// Entity entity = getAssociatedEntity();
// GraphicsMapPoint entityPositionGraphicsMapPoint = graphicsMap.makeMapPointFromCoreCoordinates(entity.getX(), entity.getY());
// //applying translation
// GraphicsMapPoint spriteTopLeftGraphicsMapPoint = entityPositionGraphicsMapPoint.translate(-sprite_width / 2, -sprite_height / 2);
// int direction = entity.getDirection().ordinal();
// int x_sprite = 0;
// int y_sprite = 0;
// int sprite_height = 0;
// int sprite_width = 0;
// int nbSprites = DEFAULT_SPRITE;
// int index = direction / 45;
// if (entity.hasAction(STAND)) {
// y_sprite = persofixe[index][0];
// sprite_height = persofixe[index][1];
// sprite_width = persofixe[index][2];
// nbSprites = persofixe[index][3];
// } else if (entity.hasAction(WALK)) {
// y_sprite = marche[index][0];
// sprite_height = marche[index][1];
// sprite_width = marche[index][2];
// nbSprites = marche[index][3];
// } else if (entity.hasAction(ATTACK)) {
// y_sprite = attaque[index][0];
// sprite_height = attaque[index][1];
// sprite_width = attaque[index][2];
// nbSprites = attaque[index][3];
// } else if (entity.hasAction(HIT)) {
// y_sprite = touche[index][0];
// sprite_height = touche[index][1];
// sprite_width = touche[index][2];
// nbSprites = touche[index][3];
// }
//
//
// sprite_num = (sprite_num + 1) % (10 * nbSprites);
// for (int u = 0; u < nbSprites; u++) {
// if (sprite_num < 10 * u) x_sprite = x_sprite + sprite_width;
// }
// Sprite res = new Sprite((sprite.getSpriteImage()).getSubimage(x_sprite, y_sprite, sprite_height, sprite_width));
// return PositionedSprite.PositionSprite(res, spriteTopLeftGraphicsMapPoint);
// }
// public Entity getAssociatedEntity() {
// return associatedEntity;
// }
}
......@@ -28,13 +28,10 @@ public class HealthBarDisplayer {
private static int xOffsetForHealthBar = 2;
private static int yOffsetForHealthBar = 2;
//These 2 variables are are multiplied to the dimensions of the images of healthBar and healthBarContainer to reduce them
// private static float xShrinkRatio = ((float)2)/3;
// private static float yShrinkRatio = ((float)4)/5;
private static float xShrinkRatio = ((float) 2)/3;
private static float yShrinkRatio = ((float) 2)/3;
//TODO topleft unused ?
public static PositionedSprite getPositionedSpriteOfHealthBar(Being being, GraphicsMap graphicsMap) {
public static PositionedSprite getPositionedSpriteOfHealthBar(Being being) {
int hp = being.getHP();
int maxHP = being.getMaxHP();
float healthRatio = ((float)hp)/maxHP;
......
......@@ -30,7 +30,6 @@ import java.util.logging.Logger;
*
* This class is the panel that displays the game window (what the player sees when he's playing)
*/
//TODO: Replace DummyEntitybis by Entity (or Entity id) (or whatever)
public class GamePanel extends GUIPanel implements GameContentMapChangeListener, GamePanelAbstraction {
private GamePanelAbstractionController controller = new GamePanelAbstractionController(this);
......@@ -47,33 +46,20 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
private GameContent gameContent;
//Defines the portion of the map this panel must display
private VisionBox visionBox;
//React to the key typed
//private InputInterpreter MyInputInterpreter;
//Spells of the character
private SpellDisplayer MySpellDisplayer;
//Avatar of the character
private AvatarDisplayer MyAvatarDisplayer;
//Minimap
private MinimapDisplayer MyMinimapDisplayer;
private Logger LOGGER = Logging.getInstance().getLogger();
//private boolean spellReleased=true;
//private boolean attackReleased=true;
public GamePanel(GraphicsMaster graphicsMaster) {
super(graphicsMaster);
}
/**
*
*/
@Override
public void keyTypedHandler(Input e) {
}
public void keyTypedHandler(Input e) {}
/**
* Function to be called when the gui goes into the state GAME_PANEL, to prepare the Game Panel
......@@ -85,8 +71,6 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
controller.initialise();
followedRelayer = DummyLocalGameLoop.getInstance().getFollowedRelayer();
//MyInputInterpreter = new InputInterpreter(followedRelayer);
gameContent = DummyLocalGameLoop.getInstance().getContent();
//subscribe to the map changes of gameContent
//gameContent.addMapChangeListener(this);
......@@ -117,10 +101,6 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
public void finalise() {
initialised = false;
RepaintTimer.getInstance().exitPlayingFrameRateMode();
// mapBImg = null;
// followedDummyEntitybis = null;
// vBox2 = null;
this.remove(topLeftLabel);
}
......@@ -165,19 +145,9 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
*/
private void drawZone(Zone zone, Color color, Stroke stroke, Graphics g){
//I know that instanceOf and Casts are highly discouraged, but I don't want to put graphics code in the Zone classes
//Moreover, this display is just for helping finding out bugs and won't stay in the final version of the project
//Moreover, this display is just for helping finding out bugs and to be able to "see" things in the game like hitbox.
Point coreTopLeft =zone.getTopLeft();
//Debug
// System.out.println("coreEntityTopLeft "+processedEntity.getTopLeft().getPosX()+","+processedEntity.getTopLeft().getPosY());
//Debug
// System.out.println("coreColBoxTopLeft "+collisionBox.getTopLeft().getPosX()+","+collisionBox.getTopLeft().getPosY());
GraphicsMapPoint graphicsTopLeft = GraphicalBridgeConfiguration.makeMapPointFromCoreCoordinates(coreTopLeft.getPosX(), coreTopLeft.getPosY());
//Debug
// GraphicsMapPoint graphicsEntityTopLeft = visionBox.getGraphicsMap().makeMapPointFromCoreCoordinates(processedEntity.getTopLeft().getPosX(), processedEntity.getTopLeft().getPosY());
//Debug
// System.out.println("graphicsEntityTopLeft " + graphicsEntityTopLeft.getX() + "," + graphicsEntityTopLeft.getY());
//Debug
// System.out.println("graphicsColBoxTopLeft " + graphicsTopLeft.getX() + "," + graphicsTopLeft.getY());
GamePanelMapPoint gpmp = new GamePanelMapPoint(graphicsTopLeft, visionBox.getTopLeftGraphicsMapPoint());
g.setColor(color);
((Graphics2D) g).setStroke(stroke);
......@@ -194,7 +164,6 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
@Override
public void paintComponent(Graphics g) {
//System.out.println("GamePanel drawing"+followedRelayer);
super.paintComponent(g);
if(initialised) {
if (debug) {
......@@ -234,23 +203,20 @@ public class GamePanel extends GUIPanel implements GameContentMapChangeListener,
if (processedEntity instanceof core.gamestate.Character) {
core.gamestate.Character processedChar = (core.gamestate.Character) processedEntity;
if (processedChar.getName() != followedRelayer.getCharacter().getName()) {
drawPositionedSprite(HealthBarDisplayer.getPositionedSpriteOfHealthBar((Being) processedEntity, visionBox.getGraphicsMap()), g);
drawPositionedSprite(HealthBarDisplayer.getPositionedSpriteOfHealthBar((Being) processedEntity), g);
}
} else {
drawPositionedSprite(HealthBarDisplayer.getPositionedSpriteOfHealthBar((Being) processedEntity, visionBox.getGraphicsMap()), g);
drawPositionedSprite(HealthBarDisplayer.getPositionedSpriteOfHealthBar((Being) processedEntity), g);
}
}
//Display the collisionBox of the entity
drawZone(processedEntity.getCollisionBox(), new Color(0, 0, 255), new BasicStroke(1), g);
//Display the attackZone of the entity if it's a Character
//Display also the avatar (image on the top left of the screen)
//TODO: remove dirty instanceOf and cast
if (processedEntity instanceof core.gamestate.Character) {
core.gamestate.Character processedChar = (core.gamestate.Character) processedEntity;
//DO NOT DRAW THE ATTACK ZONE ANYMORE, because it makes no sense with the new Ability system (the Attack box is useless)
// drawZone(processedChar.getAttackZone(), new Color(255,0,0), new BasicStroke(1), g);
// Avatar Display :
if (processedChar.getName() == followedRelayer.getCharacter().getName()) {
......
package graphics.guiSkeleton.guiPanel;
import core.gamestate.*;
import core.relayer.Relayer;
import core.zone.Circle;
import core.zone.Point;
import core.zone.Rectangle;
import core.zone.Zone;
import gameloop.DummyLocalGameLoop;
import gameloop.GameStarter;
import graphics.graphical_abstraction.panel.GamePanelAbstraction;
import graphics.graphical_abstraction.panel.GamePanelAbstractionController;
import graphics.graphical_utility.GraphicalBridgeConfiguration;
import graphics.graphical_utility.coreProcesses.GameContentMapChangeListener;
import graphics.guiSkeleton.*;
import graphics.guiSkeleton.entityDisplayer.HealthBarDisplayer;
import graphics.guiSkeleton.mapManagement.*;
import graphics.ingame_input_listener.Input;
import logging.Logging;
import map_generation.map.Map;
import javax.swing.*;
import java.awt.*;
import java.util.logging.Logger;
/**
* Created by dupriez on 10/11/15.
*
* This class is the panel that displays the game window (what the player sees when he's playing)
*/
//TODO: Replace DummyEntitybis by Entity (or Entity id) (or whatever)
public class GamePanel2 extends GUIPanel implements GameContentMapChangeListener, GamePanelAbstraction {
private GamePanelAbstractionController controller = new GamePanelAbstractionController(this);
private static final long serialVersionUID = -4309173330106121587L;
private boolean initialised = false;
private JLabel topLeftLabel;
private boolean debugMapPoint = false;
//If set to true, this class will print information in the console
private boolean debug = false;
//The relayer of the entity that the player plays
private Relayer followedRelayer;
//The place where are stored the information the game panel has to display (entities + map)
private GameContent gameContent;
//Defines the portion of the map this panel must display
private VisionBox visionBox;
//React to the key typed
//private InputInterpreter MyInputInterpreter;
//Spells of the character
private SpellDisplayer MySpellDisplayer;
//Avatar of the character
private AvatarDisplayer MyAvatarDisplayer;
private Logger LOGGER = Logging.getInstance().getLogger();
//private boolean spellReleased=true;
//private boolean attackReleased=true;
public GamePanel2(GraphicsMaster graphicsMaster) {
super(graphicsMaster);
}
/**
*
*/
@Override
public void keyTypedHandler(Input e) {
}
/**
* Function to be called when the gui goes into the state GAME_PANEL, to prepare the Game Panel
*/
@Override
public void initialise(){
RepaintTimer.getInstance().enterPlayingFramerateMode();
controller.initialise();
followedRelayer = DummyLocalGameLoop.getInstance().getFollowedRelayer();
//MyInputInterpreter = new InputInterpreter(followedRelayer);
gameContent = DummyLocalGameLoop.getInstance().getContent();
//subscribe to the map changes of gameContent
//gameContent.addMapChangeListener(this);
//Getting the map, creating a bufferedImage out of it and storing it
GraphicsMap graphicsMap = MapDrawer.drawMap(gameContent.getMap());
GraphicsMapPoint initialTopLeftGraphicsMapPoint = GraphicalBridgeConfiguration.makeMapPointFromCoreCoordinates(followedRelayer.getCharacter().getX(), followedRelayer.getCharacter().getY());
visionBox = new VisionBox(initialTopLeftGraphicsMapPoint, getSize().width, getSize().height, graphicsMap);
topLeftLabel = new JLabel("Press ESC to go back to main menu");
topLeftLabel.setFont(new Font("Inconsolata", Font.BOLD, 26));
topLeftLabel.setForeground(new Color(255, 185, 15));
topLeftLabel.setHorizontalAlignment(SwingConstants.LEFT);
topLeftLabel.setOpaque(true);
topLeftLabel.setBackground(new Color(0, 0, 0));
this.add(topLeftLabel, BorderLayout.NORTH);
initialised = true;
}
/**
* Function to be called when the gui leave the state GAME_PANEL, to clean up the GamePanel
*/
@Override
public void finalise() {
initialised = false;