Serveri kood käigupõhiseks virtuaalseks lauamänguks¶
Packetite ja Player klassi loomine
Kõigepealt loome 4 Packetit ja Player klass. Käigupõhist kaardimängu luues pole vaja mängija koordinaate saata ehk PositionPacket on üleliigne.
ConnectionPacketPositionPacketScorePacketCurrentActivePlayerPacket
ConnectionPacket ja CurrentActivePlayerPacket sisaldavad ühte muutujat, milleks on int id muutujat ja meetodeid getId ning setId.
PositionPacket ja ScorePacket sisaldavad kõik kahte muutujat. PositionPacket sisaldab int id ja Vector2 (mängija x ja y koordinaadid) ning mõlemal muutujal on get ja set meetodid. ScorePacket'il on int id ja int score muutujad, kuid ühtegi meetodi jaoks pole vajadust.
Player klass
Muutujad
- private Vector2 position
- private int id
- private boolean yourTurn = false
- private int currentPoints (algväärtuse seame konstruktoris nulliks)
Kõigile muutujatele peale yourTurn loome lisaks harilikul viisil get ja set meetodid väljaarvatud setCurrentPoints meetod, kus punkte määratakse juurdeliitmisega olemasolevale punktisummale. Loome ka updatePosition meetodi, sest kliendi pool täpsustame x ja y koordinaate.
public class Player {
private Vector2 position; // lisaks get ja set meetod
private int id; // lisaks get ja set meetod
private int currentPoints; // lisaks get meetod
private boolean yourTurn = false
public Player() {
this.currentPoints = 0;
}
public void setCurrentPoints(int points) {
this.currentPoints += points;
}
public void flipTurn() {
yourTurn = !yourTurn;
}
public void updatePosition(Vector2 position) {
this.position = position;
}
}
ChatServer klass
Muutujad
- private static Server server
- private HashMap<Integer, Player> playersId = new HashMap<>()
- private int currentActiveIndex = 0
- private boolean gameStarted = false
ChatServer konstruktoris loome uue serveri instantsi ja registreerime selle Network'i.
public ChatServer() throws IOException {
Log.set(Log.LEVEL_WARN);
server = new Server();
Network.register(server);
Chatserver konstruktorisse panema ka Event Listener'i, mille sees on kolm meetodit:
connectedreceiveddisconnected
Connected meetod
Alustuseks Loome uue Player instantsi ja lisame ta playersId HashMap'i ning saadame ConnectionPacket'i teistele mängijatele.
public void connected(Connection c) {
if (!gameStarted) {
Player player = new Player();
player.setId(c.getID());
playersId.put(c.getID(), player);
ConnectionPacket packet = new ConnectionPacket();
packet.setId(c.getID());
// teavitame teisi uuest mängijast
server.sendToAllExceptTCP(c.getID(), packet);
for (Player player : playersId.values()) {
if (player.getId() != c.getID()) {
// saadame teiste mängijate positsioonid uuele mängijale
ConnectionPacket connectionPacket = new ConnectionPacket();
connectionPacket.setId(player.getId());
server.sendToTCP(c.getID(), connectionPacket);
}
}
}
}
connected meetod lõppeb ühenduse sulgemisega kui proovitakse uut mängu alustada, serveris, kus juba mäng käib.
} else {
c.close();
}
Disconnected meetod
Siin ühtegi Packet'it ei saada.
public void disconnected(Connection c) {
playersId.remove(c.getID());
sendMessageToAllExcept(c.getID(), "User #%d has left the chat.".formatted(c.getID()));
if (playersId.isEmpty()) {
playersId = new HashMap<>();
currentActiveIndex = 0;
}
}
Received meetod
Sama Event Listeneri sees kontrollime, kas kliendi poolt on saadetud PositionPacket, et uuendada mängija asukohta ja jagada seda asukohta teiste mängijatega.
if (o instanceof PositionPacket pkg) {
Player player = playersId.get(c.getID());
Vector2 vector2 = pkg.getVector2();
player.updatePosition(vector2);
server.sendToAllExceptTCP(c.getID(), pkg);
}
ScorePacket, et uuendada nii mängija skoori, kui ka määrata, millise mängija kord nüüd on käia (ehk saadame ka CurrentActivePlayerPacket'i), sest ScorePacket saadetakse käigu lõpus.
if (o instanceof ScorePacket pkg) {
Player player = playersId.get(pkg.id);
player.setCurrentPoints(pkg.score);
ScorePacket scorePacket = new ScorePacket();
scorePacket.id = pkg.id;
scorePacket.score = pkg.score;
server.sendToAllExceptTCP(c.getID(), scorePacket);
currentActiveIndex = (currentActiveIndex + 1) % playersId.size();
List<Integer> id = new ArrayList<>(playersId.keySet());
int currentId = id.get(currentActiveIndex);
CurrentActivePlayerPacket packet = new CurrentActivePlayerPacket();
packet.setId(currentId);
server.sendToAllUDP(packet);
}
Seejärel saame Event Listener’i sulgeda ning lisame konstruktorisse veel serveri käivitamise.
server.start();
server.bind(Network.TCP_PORT, Network.UTP_PORT);
Peale konstruktori vajab ChatServer klass lisaks veel sendMessageToAllExcept meetodit.
private void sendMessageToAllExcept(int clientId, String text) {
Network.Message msg = new Network.Message();
msg.text = text;
server.sendToAllExceptUDP(clientId, msg);
}
Ära unusta Network klassis kyro.register teha kõigile Packetitele, Player klassile ning Chatserver'ile.