# Conflicts: # racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java # racevisionGame/src/main/resources/visualiser/scenes/newRaceView.fxmlmain
commit
58cde8ce44
@ -0,0 +1,38 @@
|
|||||||
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.bytesToInt;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decoder for {@link BoatState} messages
|
||||||
|
*/
|
||||||
|
public class BoatStateDecoder implements MessageDecoder {
|
||||||
|
/**
|
||||||
|
* Decoded BoatState message
|
||||||
|
*/
|
||||||
|
private BoatState message;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AC35Data decode(byte[] encodedMessage) throws InvalidMessageException {
|
||||||
|
byte[] sourceID = Arrays.copyOfRange(encodedMessage, 0, 4);
|
||||||
|
byte boatHealth = encodedMessage[4];
|
||||||
|
|
||||||
|
// Unpack bytes into BoatState
|
||||||
|
this.message = new BoatState(
|
||||||
|
bytesToInt(sourceID),
|
||||||
|
boatHealth
|
||||||
|
);
|
||||||
|
|
||||||
|
// Return BoatState
|
||||||
|
return this.message;
|
||||||
|
}
|
||||||
|
|
||||||
|
public BoatState getMessage() {
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,32 @@
|
|||||||
|
package network.MessageEncoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.Messages.AC35Data;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
|
import static network.Utils.ByteConverter.intToBytes;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encoder for {@link BoatState} message
|
||||||
|
*/
|
||||||
|
public class BoatStateEncoder implements MessageEncoder {
|
||||||
|
@Override
|
||||||
|
public byte[] encode(AC35Data message) throws InvalidMessageException {
|
||||||
|
// Downcast message
|
||||||
|
BoatState boatState = (BoatState)message;
|
||||||
|
|
||||||
|
//Serialise message
|
||||||
|
byte[] sourceID = intToBytes(boatState.getSourceID());
|
||||||
|
byte boatHealth = (byte)boatState.getBoatHealth();
|
||||||
|
|
||||||
|
// Pack bytes into string
|
||||||
|
ByteBuffer boatStateMessage = ByteBuffer.allocate(5);
|
||||||
|
boatStateMessage.put(sourceID);
|
||||||
|
boatStateMessage.put(boatHealth);
|
||||||
|
|
||||||
|
// Return byte string
|
||||||
|
return boatStateMessage.array();
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,31 @@
|
|||||||
|
package network.Messages;
|
||||||
|
|
||||||
|
import network.Messages.Enums.MessageType;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents the information in a BoatState message according to protocol meeting
|
||||||
|
*/
|
||||||
|
public class BoatState extends AC35Data {
|
||||||
|
/**
|
||||||
|
* Source ID of boat described in message
|
||||||
|
*/
|
||||||
|
private int sourceID;
|
||||||
|
/**
|
||||||
|
* Health between 0-100 of boat with above source ID
|
||||||
|
*/
|
||||||
|
private int boatHealth;
|
||||||
|
|
||||||
|
public BoatState(int sourceID, int boatHealth) {
|
||||||
|
super(MessageType.BOATSTATE);
|
||||||
|
this.sourceID = sourceID;
|
||||||
|
this.boatHealth = boatHealth;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSourceID() {
|
||||||
|
return sourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getBoatHealth() {
|
||||||
|
return boatHealth;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
package visualiser.Commands.VisualiserRaceCommands;
|
||||||
|
|
||||||
|
import mock.model.commandFactory.Command;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
import shared.exceptions.BoatNotFoundException;
|
||||||
|
import visualiser.model.VisualiserBoat;
|
||||||
|
import visualiser.model.VisualiserRaceState;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates boats on visualiser when their health changes
|
||||||
|
*/
|
||||||
|
public class BoatStateCommand implements Command {
|
||||||
|
private BoatState boatState;
|
||||||
|
private VisualiserRaceState visualiserRace;
|
||||||
|
|
||||||
|
public BoatStateCommand(BoatState boatState, VisualiserRaceState visualiserRace) {
|
||||||
|
this.boatState = boatState;
|
||||||
|
this.visualiserRace = visualiserRace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute() {
|
||||||
|
try {
|
||||||
|
VisualiserBoat boat = visualiserRace.getBoat(boatState.getSourceID());
|
||||||
|
boat.setHealth(boatState.getBoatHealth());
|
||||||
|
} catch (BoatNotFoundException e) {
|
||||||
|
// Fail silently
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -0,0 +1,111 @@
|
|||||||
|
package visualiser.layout;
|
||||||
|
|
||||||
|
import javafx.geometry.Point3D;
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.media.AudioClip;
|
||||||
|
import javafx.scene.paint.Color;
|
||||||
|
import javafx.scene.paint.PhongMaterial;
|
||||||
|
import javafx.scene.shape.*;
|
||||||
|
import javafx.scene.transform.Rotate;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by zwu18 on 24/09/17.
|
||||||
|
*/
|
||||||
|
public class HealthEffect extends Subject3D {
|
||||||
|
|
||||||
|
private int sourceID;
|
||||||
|
private long currentTime;
|
||||||
|
private AudioClip warningSound = new AudioClip(this.getClass().getResource("/visualiser/sounds/warning.mp3").toExternalForm());
|
||||||
|
private AudioClip deadSound = new AudioClip(this.getClass().getResource("/visualiser/sounds/dead1.wav").toExternalForm());
|
||||||
|
|
||||||
|
public HealthEffect(int sourceID, long currentTime){
|
||||||
|
super(createEffect(), 0);
|
||||||
|
this.sourceID = sourceID;
|
||||||
|
this.currentTime = currentTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the mesh view with image
|
||||||
|
* @return Mesh view
|
||||||
|
*/
|
||||||
|
private static Shape3D createEffect(){
|
||||||
|
|
||||||
|
Image image = new Image(HealthEffect.class.getClassLoader().getResourceAsStream("images/warning.png"));
|
||||||
|
|
||||||
|
Plane3D plane = new Plane3D(20, 20, 10, 10);
|
||||||
|
|
||||||
|
PhongMaterial material = new PhongMaterial();
|
||||||
|
material.setDiffuseColor(Color.web("#FFFFFF"));
|
||||||
|
material.setSpecularColor(Color.web("#000000"));
|
||||||
|
material.setDiffuseMap(image);
|
||||||
|
|
||||||
|
MeshView imageSurface = new MeshView(plane);
|
||||||
|
|
||||||
|
|
||||||
|
imageSurface.setMaterial(material);
|
||||||
|
imageSurface.setMouseTransparent(true);
|
||||||
|
//imageSurface.toFront(); this.flashInterval = flashInterval;
|
||||||
|
|
||||||
|
return imageSurface;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotateView(Double angle, Double pivotX, Double pivotY, Double pivotZ, Point3D axis){
|
||||||
|
Rotate rotate = new Rotate(angle, axis);
|
||||||
|
rotate.setPivotX(pivotX);
|
||||||
|
rotate.setPivotY(pivotY);
|
||||||
|
rotate.setPivotZ(pivotZ);
|
||||||
|
this.getMesh().getTransforms().add(rotate);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setVisible(boolean bool){
|
||||||
|
this.getMesh().setVisible(bool);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public int getSourceID(){
|
||||||
|
return sourceID;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSourceID(int id){
|
||||||
|
this.sourceID = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display visual indication when boat dies
|
||||||
|
* @param player boolean if player is current user or not
|
||||||
|
*/
|
||||||
|
public void displayDeath(boolean player){
|
||||||
|
Image image = new Image(HealthEffect.class.getClassLoader().getResourceAsStream("images/warning2.png"));
|
||||||
|
PhongMaterial material = (PhongMaterial) this.getMesh().getMaterial();
|
||||||
|
material.setDiffuseColor(Color.web("#FFFFFF"));
|
||||||
|
material.setSpecularColor(Color.web("#000000"));
|
||||||
|
material.setDiffuseMap(image);
|
||||||
|
this.getMesh().setMaterial(material);
|
||||||
|
if(player) {
|
||||||
|
deadSound.play();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flash the mesh view at a certain interval
|
||||||
|
* @param checkTime The current time of flash
|
||||||
|
* @param flashInterval Desired flash interval
|
||||||
|
* @param playerBoat Whether or not this effect is for the player's boat.
|
||||||
|
*/
|
||||||
|
public void flash(long checkTime, long flashInterval, boolean playerBoat){
|
||||||
|
if(checkTime >= (currentTime+flashInterval)){
|
||||||
|
this.currentTime = checkTime;
|
||||||
|
if(this.getMesh().isVisible()){
|
||||||
|
this.setVisible(false);
|
||||||
|
} else {
|
||||||
|
if(playerBoat) {
|
||||||
|
warningSound.setVolume(0.1);
|
||||||
|
warningSound.play();
|
||||||
|
}
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -0,0 +1,66 @@
|
|||||||
|
package visualiser.layout;
|
||||||
|
|
||||||
|
import javafx.scene.image.Image;
|
||||||
|
import javafx.scene.image.WritableImage;
|
||||||
|
import javafx.scene.layout.*;
|
||||||
|
import javafx.scene.shape.Rectangle;
|
||||||
|
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by connortaylorbrown on 21/09/17.
|
||||||
|
*/
|
||||||
|
public class HealthSlider extends Pane {
|
||||||
|
/**
|
||||||
|
* Image used to fill health slider
|
||||||
|
*/
|
||||||
|
private Image fillImage;
|
||||||
|
/**
|
||||||
|
* Size of background for image configuration
|
||||||
|
*/
|
||||||
|
private BackgroundSize backgroundSize;
|
||||||
|
/**
|
||||||
|
* Percentage of image cropped out from top
|
||||||
|
*/
|
||||||
|
private double crop;
|
||||||
|
|
||||||
|
public HealthSlider(Image fillImage) {
|
||||||
|
this.fillImage = fillImage;
|
||||||
|
this.crop = 1;
|
||||||
|
this.backgroundSize = new BackgroundSize(
|
||||||
|
100,
|
||||||
|
100,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
true,
|
||||||
|
false);
|
||||||
|
drawSlider();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCrop(double crop) {
|
||||||
|
this.crop = crop;
|
||||||
|
drawSlider();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void drawSlider() {
|
||||||
|
int top = Math.max(0,(int)(fillImage.getHeight() - crop * fillImage.getHeight()));
|
||||||
|
|
||||||
|
WritableImage croppedImage = new WritableImage(
|
||||||
|
fillImage.getPixelReader(),
|
||||||
|
0,
|
||||||
|
top,
|
||||||
|
(int)fillImage.getWidth(),
|
||||||
|
(int)fillImage.getHeight() - top
|
||||||
|
);
|
||||||
|
|
||||||
|
BackgroundImage backgroundImage = new BackgroundImage(
|
||||||
|
croppedImage,
|
||||||
|
BackgroundRepeat.NO_REPEAT,
|
||||||
|
BackgroundRepeat.NO_REPEAT,
|
||||||
|
BackgroundPosition.CENTER,
|
||||||
|
backgroundSize
|
||||||
|
);
|
||||||
|
|
||||||
|
this.setBackground(new Background(backgroundImage));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 3.1 MiB |
|
After Width: | Height: | Size: 5.5 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,33 @@
|
|||||||
|
package network.MessageDecoders;
|
||||||
|
|
||||||
|
import network.Exceptions.InvalidMessageException;
|
||||||
|
import network.MessageEncoders.RaceVisionByteEncoder;
|
||||||
|
import network.Messages.BoatState;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.testng.Assert.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for the {@link network.Messages.BoatState} encoder and decoder.
|
||||||
|
*/
|
||||||
|
public class BoatStateDecoderTest {
|
||||||
|
private BoatState originalMessage;
|
||||||
|
private BoatState decodedMessage;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws InvalidMessageException {
|
||||||
|
originalMessage = new BoatState(0, 100);
|
||||||
|
|
||||||
|
byte[] encodedMessage = RaceVisionByteEncoder.encode(originalMessage);
|
||||||
|
BoatStateDecoder decoder = new BoatStateDecoder();
|
||||||
|
decoder.decode(encodedMessage);
|
||||||
|
decodedMessage = decoder.getMessage();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void decodingEqualsOriginal() {
|
||||||
|
assertEquals(originalMessage.getSourceID(), decodedMessage.getSourceID());
|
||||||
|
assertEquals(originalMessage.getBoatHealth(), decodedMessage.getBoatHealth());
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in new issue