Improved code documentation and clarify comments for better readability and understanding

This commit is contained in:
Lukas Bauer
2024-10-11 14:53:59 +02:00
parent bf16a18b71
commit edff9e1ad9
11 changed files with 115 additions and 95 deletions

View File

@@ -9,7 +9,7 @@
# #
# Specifies the map used by the opponent in single mode. # Specifies the map used by the opponent in single mode.
# Single mode is activated if this property is set. # Single mode is activated if this property is set.
map.opponent=maps/map2.json #map.opponent=maps/map2.json
# #
# Specifies the map used by the player in single mode. # Specifies the map used by the player in single mode.
# The player must define their own map if this property is not set. # The player must define their own map if this property is not set.

View File

@@ -45,13 +45,6 @@ public static boolean enabledInPreferences() {
return PREFERENCES.getBoolean(ENABLED_PREF, true); return PREFERENCES.getBoolean(ENABLED_PREF, true);
} }
/**
* Toggles the game sound on or off.
*/
public void toggleSound() {
setEnabled(!isEnabled());
}
/** /**
* Sets the enabled state of this AppState. * Sets the enabled state of this AppState.
* Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)} * Overrides {@link com.jme3.app.state.AbstractAppState#setEnabled(boolean)}
@@ -101,6 +94,9 @@ private AudioNode loadSound(Application app, String name) {
return null; return null;
} }
/**
* Plays the missile launch sound effect.
*/
public void missileLaunch() { public void missileLaunch() {
missileLaunch.playInstance(); missileLaunch.playInstance();
} }
@@ -131,7 +127,6 @@ public void shipDestroyed() {
/** /**
* Checks the according case for the soundeffect * Checks the according case for the soundeffect
*
* @param event the received event * @param event the received event
*/ */
@Override @Override

View File

@@ -75,6 +75,10 @@ public Menu(BattleshipApp app) {
update(); update();
} }
/**
* Updates the volume if there is a change and adjusts it accordingly.
* @param tmp unused time parameter
*/
public void update(float tmp){ public void update(float tmp){
if(volumeRef.update()) { if(volumeRef.update()) {
double newVolume = volumeRef.get(); double newVolume = volumeRef.get();
@@ -82,10 +86,18 @@ public void update(float tmp){
} }
} }
/**
* Adjusts the background music volume to the specified value.
* @param newVolume the new volume level
*/
private void adjustVolume(double newVolume) { private void adjustVolume(double newVolume) {
app.getBackgroundMusic().setVolume((float) newVolume); app.getBackgroundMusic().setVolume((float) newVolume);
} }
/**
* Toggles the background music on or off.
*/
private void toggleMusic(){ private void toggleMusic(){
app.getBackgroundMusic().toogleMusic(); app.getBackgroundMusic().toogleMusic();
} }

View File

@@ -12,11 +12,8 @@
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.Spatial; import com.jme3.scene.Spatial;
import pp.battleship.model.Battleship; import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint;
import pp.battleship.model.Shell; import pp.battleship.model.Shell;
import pp.battleship.model.Shot; import pp.battleship.model.Shot;
import pp.util.FloatMath;
import pp.util.FloatPoint;
import pp.util.Position; import pp.util.Position;
import java.lang.System.Logger; import java.lang.System.Logger;
@@ -117,9 +114,9 @@ public Spatial visit(Battleship ship) {
} }
/** /**
* * Creates a visual representation (Spatial) for the given shell, attaching a control for its behavior.
* @param shell * @param shell the shell to visit and visualize
* @return * @return the constructed shell node (Spatial)
*/ */
@Override @Override
public Spatial visit(Shell shell) { public Spatial visit(Shell shell) {

View File

@@ -7,51 +7,26 @@
package pp.battleship.client.gui; package pp.battleship.client.gui;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager; import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort; import com.jme3.renderer.ViewPort;
import com.jme3.scene.control.AbstractControl; import com.jme3.scene.control.AbstractControl;
import pp.battleship.game.client.ClientGameLogic; import pp.battleship.game.client.ClientGameLogic;
import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.EffectMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.Shell; import pp.battleship.model.Shell;
import pp.battleship.notification.Sound; import pp.battleship.notification.Sound;
import pp.util.FloatPoint;
import pp.util.Position; import pp.util.Position;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import static pp.util.FloatMath.DEG_TO_RAD;
import static pp.util.FloatMath.TWO_PI;
import static pp.util.FloatMath.sin;
/** /**
* Controls the oscillating pitch motion of a battleship model in the game. * Controls the oscillating pitch motion of a battleship model in the game.
* The ship oscillates to simulate a realistic movement on water, based on its orientation and length. * The ship oscillates to simulate a realistic movement on water, based on its orientation and length.
*/ */
class ShellControl extends AbstractControl { class ShellControl extends AbstractControl {
/**
* A quaternion representing the ship's current pitch rotation.
*/
private final Quaternion pitch = new Quaternion();
/** private final Shell shell;
* The current time within the oscillation cycle, used to calculate the ship's pitch angle.
*/
private float time;
private Shell shell;
private MapView view; private MapView view;
private ClientGameLogic logic; private final ClientGameLogic logic;
private EffectMessage msg; private final EffectMessage msg;
private boolean hasPlayedSound = false; private boolean hasPlayedSound = false;
/**
* Logger for logging messages related to ShipControl operations.
*/
static final Logger LOGGER = System.getLogger(ShipControl.class.getName());
/** /**
* Constructs a new ShipControl instance for the specified Battleship. * Constructs a new ShipControl instance for the specified Battleship.
@@ -67,9 +42,10 @@ public ShellControl(Shell shell, ClientGameLogic clientGameLogic) {
} }
/** /**
* @param shell * Initializes ShellControl with a shell, map view, and game logic.
* @param view * @param shell the shell to be controlled
* @param clientGameLogic * @param view the map view to display the shell
* @param clientGameLogic the game logic instance
*/ */
public ShellControl(Shell shell, MapView view, ClientGameLogic clientGameLogic) { public ShellControl(Shell shell, MapView view, ClientGameLogic clientGameLogic) {
this.shell = shell; this.shell = shell;
@@ -86,7 +62,7 @@ public ShellControl(Shell shell, MapView view, ClientGameLogic clientGameLogic)
*/ */
@Override @Override
protected void controlUpdate(float tpf) { protected void controlUpdate(float tpf) {
// If spatial is null, do nothing
if (spatial == null) if (spatial == null)
return; return;
if (shell.isFinished() && !hasPlayedSound) { if (shell.isFinished() && !hasPlayedSound) {
@@ -109,12 +85,9 @@ else if (msg.getDestroyedShip() == null)
} }
/** /**
* This method is called during the rendering phase, but it does not perform any * Called during rendering, but no operations are needed as this control only affects spatial transformation.
* operations in this implementation as the control only influences the spatial's * @param rm the RenderManager rendering the spatial
* transformation, not its rendering process. * @param vp the ViewPort being rendered
*
* @param rm the RenderManager rendering the controlled Spatial (not null)
* @param vp the ViewPort being rendered (not null)
*/ */
@Override @Override
protected void controlRender(RenderManager rm, ViewPort vp) { protected void controlRender(RenderManager rm, ViewPort vp) {

View File

@@ -10,7 +10,6 @@
import com.jme3.network.*; import com.jme3.network.*;
import com.jme3.network.serializing.Serializer; import com.jme3.network.serializing.Serializer;
import pp.battleship.BattleshipConfig; import pp.battleship.BattleshipConfig;
import pp.battleship.client.server.ReceivedMessage;
import pp.battleship.game.server.Player; import pp.battleship.game.server.Player;
import pp.battleship.game.server.ServerGameLogic; import pp.battleship.game.server.ServerGameLogic;
import pp.battleship.game.server.ServerSender; import pp.battleship.game.server.ServerSender;
@@ -41,7 +40,6 @@ public class BattleshipServer implements MessageListener<HostedConnection>, Conn
private static final Logger LOGGER = System.getLogger(BattleshipServer.class.getName()); private static final Logger LOGGER = System.getLogger(BattleshipServer.class.getName());
private static final File CONFIG_FILE = new File("server.properties"); private static final File CONFIG_FILE = new File("server.properties");
private final BattleshipConfig config = new BattleshipConfig();
private Server myServer; private Server myServer;
private final ServerGameLogic logic; private final ServerGameLogic logic;
private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>(); private final BlockingQueue<ReceivedMessage> pendingMessages = new LinkedBlockingQueue<>();
@@ -63,17 +61,26 @@ public class BattleshipServer implements MessageListener<HostedConnection>, Conn
* Creates the server. * Creates the server.
*/ */
public BattleshipServer() { public BattleshipServer() {
BattleshipConfig config = new BattleshipConfig();
config.readFromIfExists(CONFIG_FILE); config.readFromIfExists(CONFIG_FILE);
LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS LOGGER.log(Level.INFO, "Configuration: {0}", config); //NON-NLS
logic = new ServerGameLogic(this, config); logic = new ServerGameLogic(this, config);
} }
/**
* Starts the server on the given port and continuously processes incoming messages.
* @param port the port to start the server on
*/
public void run(int port) { public void run(int port) {
startServer(port); startServer(port);
while (true) while (true)
processNextMessage(); processNextMessage();
} }
/**
* Initializes and starts the server on the specified port, handling exceptions if the server fails to start.
* @param port the port to start the server on
*/
private void startServer(int port) { private void startServer(int port) {
try { try {
LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS LOGGER.log(Level.INFO, "Starting server..."); //NON-NLS
@@ -89,6 +96,9 @@ private void startServer(int port) {
} }
} }
/**
*
*/
private void processNextMessage() { private void processNextMessage() {
try { try {
pendingMessages.take().process(logic); pendingMessages.take().process(logic);
@@ -99,6 +109,9 @@ private void processNextMessage() {
} }
} }
/**
* Processes the next message from the queue, handling interruptions during message retrieval.
*/
private void initializeSerializables() { private void initializeSerializables() {
Serializer.registerClass(GameDetails.class); Serializer.registerClass(GameDetails.class);
Serializer.registerClass(StartBattleMessage.class); Serializer.registerClass(StartBattleMessage.class);
@@ -110,12 +123,20 @@ private void initializeSerializables() {
Serializer.registerClass(Shot.class); Serializer.registerClass(Shot.class);
} }
/**
* Registers message and connection listeners for the server.
*/
private void registerListeners() { private void registerListeners() {
myServer.addMessageListener(this, MapMessage.class); myServer.addMessageListener(this, MapMessage.class);
myServer.addMessageListener(this, ShootMessage.class); myServer.addMessageListener(this, ShootMessage.class);
myServer.addConnectionListener(this); myServer.addConnectionListener(this);
} }
/**
* Handles received messages, logging the source and adding client messages to the pending queue.
* @param source the connection the message was received from
* @param message the received message
*/
@Override @Override
public void messageReceived(HostedConnection source, Message message) { public void messageReceived(HostedConnection source, Message message) {
LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS LOGGER.log(Level.INFO, "message received from {0}: {1}", source.getId(), message); //NON-NLS
@@ -123,12 +144,22 @@ public void messageReceived(HostedConnection source, Message message) {
pendingMessages.add(new ReceivedMessage(clientMessage, source.getId())); pendingMessages.add(new ReceivedMessage(clientMessage, source.getId()));
} }
/**
* Handles a new connection by logging it and adding a new player to the game logic.
* @param server the server receiving the connection
* @param hostedConnection the newly added connection
*/
@Override @Override
public void connectionAdded(Server server, HostedConnection hostedConnection) { public void connectionAdded(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS LOGGER.log(Level.INFO, "new connection {0}", hostedConnection); //NON-NLS
logic.addPlayer(hostedConnection.getId()); logic.addPlayer(hostedConnection.getId());
} }
/**
* Handles the removal of a connection by logging it, checking if it belongs to an active player, and exiting if necessary.
* @param server the server losing the connection
* @param hostedConnection the removed connection
*/
@Override @Override
public void connectionRemoved(Server server, HostedConnection hostedConnection) { public void connectionRemoved(Server server, HostedConnection hostedConnection) {
LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS LOGGER.log(Level.INFO, "connection closed: {0}", hostedConnection); //NON-NLS
@@ -141,6 +172,10 @@ public void connectionRemoved(Server server, HostedConnection hostedConnection)
} }
} }
/**
* Closes all client connections and terminates the server with the given exit value.
* @param exitValue the exit code to terminate the application with
*/
private void exit(int exitValue) { //NON-NLS private void exit(int exitValue) { //NON-NLS
LOGGER.log(Level.INFO, "close request"); //NON-NLS LOGGER.log(Level.INFO, "close request"); //NON-NLS
if (myServer != null) if (myServer != null)

View File

@@ -34,11 +34,19 @@ public BattleState(ClientGameLogic logic, boolean myTurn) {
this.myTurn = myTurn; this.myTurn = myTurn;
} }
/**
* displays the battle scene.
* @return true to show the battle
*/
@Override @Override
public boolean showBattle() { public boolean showBattle() {
return true; return true;
} }
/**
* Handles clicking on the opponent's map. If it's the player's turn and the position is valid, a ShootMessage is sent.
* @param pos the clicked position on the opponent's map
*/
@Override @Override
public void clickOpponentMap(IntPoint pos) { public void clickOpponentMap(IntPoint pos) {
if (!myTurn) if (!myTurn)
@@ -87,19 +95,4 @@ private ShipMap affectedMap(EffectMessage msg) {
private boolean destroyedOpponentShip(EffectMessage msg) { private boolean destroyedOpponentShip(EffectMessage msg) {
return msg.getDestroyedShip() != null && msg.isOwnShot(); return msg.getDestroyedShip() != null && msg.isOwnShot();
} }
/**
* Plays a sound based on the outcome of the shot. Different sounds are played for a miss, hit,
* or destruction of a ship.
*
* @param msg the effect message containing the result of the shot
*/
private void playSound(EffectMessage msg) {
if (!msg.getShot().isHit())
logic.playSound(Sound.SPLASH);
else if (msg.getDestroyedShip() == null)
logic.playSound(Sound.EXPLOSION);
else
logic.playSound(Sound.DESTROYED_SHIP);
}
} }

View File

@@ -8,12 +8,10 @@
package pp.battleship.game.client; package pp.battleship.game.client;
import pp.battleship.message.client.ClientMessage; import pp.battleship.message.client.ClientMessage;
import pp.battleship.message.client.MapMessage;
import pp.battleship.message.server.EffectMessage; import pp.battleship.message.server.EffectMessage;
import pp.battleship.message.server.GameDetails; import pp.battleship.message.server.GameDetails;
import pp.battleship.message.server.ServerInterpreter; import pp.battleship.message.server.ServerInterpreter;
import pp.battleship.message.server.StartBattleMessage; import pp.battleship.message.server.StartBattleMessage;
import pp.battleship.model.Battleship;
import pp.battleship.model.IntPoint; import pp.battleship.model.IntPoint;
import pp.battleship.model.ShipMap; import pp.battleship.model.ShipMap;
import pp.battleship.model.dto.ShipMapDTO; import pp.battleship.model.dto.ShipMapDTO;

View File

@@ -6,21 +6,22 @@
import pp.util.FloatMath; import pp.util.FloatMath;
public class Shell implements Item { public class Shell implements Item {
private Vector3f startPosition; // Startposition des Geschosses private final Vector3f startPosition; // Startposition des Geschosses
private Vector3f targetPosition; // Zielposition des Geschosses0 private final Vector3f targetPosition; // Zielposition des Geschosses0
private Vector3f currentPosition; // Aktuelle Position des Geschosses private final Vector3f currentPosition; // Aktuelle Position des Geschosses
private float speed; // Geschwindigkeit des Geschosses private final float speed; // Geschwindigkeit des Geschosses
private EffectMessage msg; private final EffectMessage msg;
private ClientGameLogic logic; private final ClientGameLogic logic;
private float progress; private float progress;
/** /**
* @param startPosition * Initializes a Shell with start position, target position, speed, message, and game logic.
* @param targetPosition * @param startPosition initial position of the shell
* @param speed * @param targetPosition target position of the shell
* @param msg * @param speed movement speed of the shell
* @param logic * @param msg effect message related to the shell
* @param logic game logic instance
*/ */
public Shell(Vector3f startPosition, Vector3f targetPosition, float speed, EffectMessage msg, ClientGameLogic logic) { public Shell(Vector3f startPosition, Vector3f targetPosition, float speed, EffectMessage msg, ClientGameLogic logic) {
this.startPosition = startPosition; this.startPosition = startPosition;
@@ -31,7 +32,10 @@ public Shell(Vector3f startPosition, Vector3f targetPosition, float speed, Effec
this.logic = logic; this.logic = logic;
} }
// Methode, um die Position des Geschosses basierend auf der Zeit zu aktualisieren /**
* Updates the shell's position based on elapsed time, using eased interpolation between start and target positions.
* @param deltaTime time elapsed since last update
*/
public void updatePosition(float deltaTime) { public void updatePosition(float deltaTime) {
progress += deltaTime * speed; progress += deltaTime * speed;
progress = FloatMath.clamp(progress, 0.0f, 1.0f); progress = FloatMath.clamp(progress, 0.0f, 1.0f);
@@ -44,20 +48,18 @@ public void updatePosition(float deltaTime) {
currentPosition.z = FloatMath.extrapolateLinear(t, startPosition.z, targetPosition.z); currentPosition.z = FloatMath.extrapolateLinear(t, startPosition.z, targetPosition.z);
} }
// Aktuelle Position des Geschosses /**
* getter for Current Position
* @return current position
*/
public Vector3f getCurrentPosition() { public Vector3f getCurrentPosition() {
return currentPosition; return currentPosition;
} }
// Überprüfen, ob das Ziel erreicht ist
public boolean isAtTarget() {
return currentPosition.distance(targetPosition) < 0.0001f; // Toleranz für die Zielgenauigkeit
}
/** /**
* @param visitor the visitor performing operations on the item * @param visitor the visitor performing operations on the item
* @param <T> * @param <T> generic type
* @return * @return shell
*/ */
@Override @Override
public <T> T accept(Visitor<T> visitor) { public <T> T accept(Visitor<T> visitor) {
@@ -65,6 +67,7 @@ public <T> T accept(Visitor<T> visitor) {
} }
/** /**
* Visitor pattern
* @param visitor the visitor to accept * @param visitor the visitor to accept
*/ */
@Override @Override
@@ -73,21 +76,24 @@ public void accept(VoidVisitor visitor) {
} }
/** /**
* @return * getter for the isFinished boolean
* @return true if progress lesser than 1, false otherwise
*/ */
public boolean isFinished() { public boolean isFinished() {
return progress >= 1; return progress >= 1;
} }
/** /**
* @return * getter for EffectMessage
* @return EffectMessage
*/ */
public EffectMessage getMsg() { public EffectMessage getMsg() {
return msg; return msg;
} }
/** /**
* @return * getter for Client logic
* @return Client logic
*/ */
public ClientGameLogic getLogic() { public ClientGameLogic getLogic() {
return logic; return logic;

View File

@@ -29,5 +29,11 @@ public interface Visitor<T> {
*/ */
T visit(Battleship ship); T visit(Battleship ship);
/**
* Visits a Shell element.
*
* @param shell the shell element to visit
* @return the result of visiting the Shell element
*/
T visit(Shell shell); T visit(Shell shell);
} }

View File

@@ -26,5 +26,10 @@ public interface VoidVisitor {
*/ */
void visit(Battleship ship); void visit(Battleship ship);
/**
* Visits a Shell element
*
* @param shell the Shell element to visit
*/
void visit(Shell shell); void visit(Shell shell);
} }