lundi 11 mai 2015

PongSpiel Netzwerk

Guten Tag,

Ich habe die Aufgabe bekommen ein Netzwerk für ein SpielProjekt zu erstellen in der Uni. Dabei handelt es sich um ein Pongspiel welches mit Javafx geschrieben wurde. Dabei haben wir alle Klassen im MVC-Prinzip eingeteilt.
Auch habe ich schon einen (Chat)Server geschrieben/frankenstein'd/ aus anderen Beispielen zusammengebastelt der auf eine Nachricht von einem Client wartet und diese dann anschließend an alle anderen Clients schickt

Jetzt zum eigentlichen Problem:

Ich bekomme es einfach nicht das Spiel mit sowohl Server als auch Client zu verbinden. Mein Ansatz den ich gerade hätte wäre dieser:

Der Client (beinhaltet nur Keylistener und den View) schickt bei einem Tastendruck eine Nachricht an den Server.
Dieser wiederum hat Kontrolle über den Rest des Controllers und der Modelklasse und führt alle Berechnungen durch. Danach schickt er wieder alle relevanten Informationen ( Positionen der Schläger und des Balles) wieder zu einem "Clientthread" zurück der dann wiederum auf die lokale Modelklassen schreibt. Schlussendlich liest der Client wieder von der dieser lokalen Modelklasse zurück und stellt alles auf der Timeline dar.

Davor habe ich schon versucht meinen gesamten Controller in den Client hineinzupacken, jedoch war dann das Spielfenster gefreezed als der Client sich verbunden hatte.

Ist diese Einteilung von Aufgaben sinnvoll und wie bekomme ich es zum Beispiel hin einen KeyListener in den Client zu implementieren. Da habe ich zur Zeit die meisten Probleme..


Javacode:
Controller:
Java Code:

  1. package controller;
  2.  
  3. import view.LocalMultiView;
  4. import javafx.animation.KeyFrame;
  5. import javafx.animation.Timeline;
  6. import javafx.event.ActionEvent;
  7. import javafx.event.EventHandler;
  8. import javafx.scene.Scene;
  9. import javafx.scene.input.KeyCode;
  10. import javafx.scene.input.KeyEvent;
  11. import javafx.scene.layout.Pane;
  12. import javafx.scene.shape.Circle;
  13. import javafx.scene.shape.Rectangle;
  14. import javafx.util.Duration;
  15. import javafx.geometry.Bounds;
  16. import model.Player;
  17. import model.ScreenModel;
  18.  
  19.  
  20. public class LocalMultiController
  21. {
  22.  
  23.  
  24. // private model.RacketModel racketModel;
  25. // private model.BallModel ballModel;
  26. private ScreenModel model;
  27. private view.LocalMultiView view;
  28. private Integer i = 0;
  29.  
  30.  
  31. private Player life1;
  32. private Player life2;
  33.  
  34.  
  35.  
  36. public LocalMultiController (ScreenModel model)
  37. {
  38. // this.racketModel = new RacketModel();
  39. // this.ballModel = new BallModel();
  40. this.view = new LocalMultiView();
  41. this.model = model;
  42.  
  43. this.life1 = new Player(3);
  44. this.life2 = new Player(3);
  45.  
  46. addEvent();
  47. }
  48.  
  49. public void show ()
  50. {
  51. view.show(model.getStage());
  52. }
  53.  
  54. public void addEvent ()
  55. {
  56. final Circle ball = view.getBall();
  57. final Rectangle schlaeger1 = view.getRacket1().getRacket();
  58. final Rectangle schlaeger2 = view.getRacket2().getRacket();
  59. Scene scene = view.getPlayScene();
  60. final Pane canvas = view.getPane();
  61.  
  62.  
  63. /**
  64.   * Eventhandler für linken Schläger: S: runter, W: hoch
  65.   */
  66. scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>()
  67. {
  68. public void handle(KeyEvent ke)
  69. {
  70. double yPos1 = schlaeger1.getY();
  71. if (ke.getCode() == KeyCode.S)
  72. {
  73. if ((yPos1 + schlaeger1.getHeight() + 20) > canvas.getBoundsInLocal().getMaxY())
  74. {
  75. yPos1 = canvas.getBoundsInLocal().getMaxY() - schlaeger1.getHeight();
  76. }
  77. else
  78. {
  79. yPos1 += 20;
  80. }
  81. schlaeger1.setY(yPos1);
  82. }
  83. else if (ke.getCode() == KeyCode.W)
  84. {
  85. if (yPos1 - 20 < 0)
  86. {
  87. yPos1 = 0;
  88. }
  89. else
  90. {
  91. yPos1 -= 20;
  92. }
  93. schlaeger1.setY(yPos1);
  94. }
  95. }
  96. });
  97.  
  98. /**
  99.   * Eventhandler für rechten Schlaeger: Pfeil hoch: hoch, Pfeil runter: runter
  100.   */
  101. scene.addEventHandler(KeyEvent.KEY_PRESSED, new EventHandler<KeyEvent>()
  102. {
  103. public void handle(KeyEvent ke)
  104. {
  105. double yPos2 = schlaeger2.getY();
  106.  
  107. if (ke.getCode() == KeyCode.DOWN)
  108. {
  109. if ((yPos2 + schlaeger2.getHeight() + 20) > canvas.getBoundsInLocal().getMaxY())
  110. {
  111. yPos2 = canvas.getBoundsInLocal().getMaxY() - schlaeger2.getHeight();
  112. }
  113. else
  114. {
  115. yPos2 += 20;
  116. }
  117. schlaeger2.setY(yPos2);
  118. }
  119. else if (ke.getCode() == KeyCode.UP)
  120. {
  121. if (yPos2 - 20 < 0)
  122. {
  123. yPos2 = 0;
  124. }
  125. else
  126. {
  127. yPos2 -= 20;
  128. }
  129. schlaeger2.setY(yPos2);
  130. }
  131. }
  132. });
  133.  
  134.  
  135. /**
  136.   * Timeline mit unendlicher Wiederholung alle 20 Millisekunden
  137.   * für die Bewegung des Balls
  138.   */
  139. Timeline timeline = new Timeline(new KeyFrame(Duration.millis(20),
  140. new EventHandler<ActionEvent>()
  141. {
  142. double xPos = 3;
  143. double yPos = 5;
  144.  
  145.  
  146. @Override
  147. public void handle(ActionEvent arg0)
  148. {
  149. /*
  150.   // Every 20 frames 10% faster
  151.   if (i++ % 50 == 0) {
  152.   xPos += (xPos<0 ? -1 : 1) * 0.5;
  153.   yPos += (yPos<0 ? -1 : 1) * 0.5;
  154.   }
  155.   */
  156.  
  157. double oldX = ball.getLayoutX();
  158. double schlaeger1CollisionX = schlaeger1.getX() + schlaeger1.getWidth();
  159. double schlaeger2CollisionX = schlaeger2.getX();
  160.  
  161.  
  162. ball.setLayoutX(ball.getLayoutX() + xPos);
  163. ball.setLayoutY(ball.getLayoutY() + yPos);
  164.  
  165.  
  166. Bounds bounds = canvas.getBoundsInLocal();
  167. //Kollision unten
  168. boolean boundBottom = ball.getLayoutY() >= (bounds
  169. .getMaxY() - ball.getRadius());
  170.  
  171. //Kollision oben
  172. boolean boundTop = (ball.getLayoutY() - ball.getRadius()) <= 0;
  173.  
  174. //Kollision rechts
  175. boolean boundRight = ball.getLayoutX() >= (bounds
  176. .getMaxX() - ball.getRadius());
  177.  
  178. //Kollision links
  179. boolean boundLeft = (ball.getLayoutX() - ball.getRadius()) <= bounds.getMinX();
  180.  
  181. //Kollision Schlaeger
  182. boolean boundSchlaeger1 = ball.getLayoutX() - ball.getRadius() <= schlaeger1CollisionX && oldX >= schlaeger1CollisionX && ball.getLayoutY() + ball.getRadius() >= schlaeger1.getY() && ball.getLayoutY() - ball.getRadius() <= schlaeger1.getY() + schlaeger1.getHeight() && xPos < 0;
  183. boolean boundSchlaeger2 = ball.getLayoutX() + ball.getRadius() >= schlaeger2CollisionX && oldX <= schlaeger2CollisionX && ball.getLayoutY() + ball.getRadius() >= schlaeger2.getY() && ball.getLayoutY() - ball.getRadius() <= schlaeger2.getY() + schlaeger2.getHeight() && xPos > 0;
  184.  
  185. //Richtungswechsel
  186. if (boundBottom || boundTop)
  187. {
  188. yPos *= -1;
  189. }
  190. //Abprallen
  191. if (boundSchlaeger2 || boundSchlaeger1)
  192. {
  193. xPos *= -1;
  194. }
  195.  
  196. if (boundLeft)
  197. {
  198. ball.relocate(20, 30);
  199. xPos = 3;
  200. yPos = 5;
  201. life1.subLife();
  202. System.out.println("Sp1: " + life1.getLife());
  203. }
  204.  
  205. if (boundRight)
  206. {
  207. ball.relocate(20, 30);
  208. xPos = 3;
  209. yPos = 5;
  210. life2.subLife();
  211. System.out.println("Sp2: " + life2);
  212. }
  213.  
  214. if (life1.getLife() == 0)
  215. {
  216. xPos = 0;
  217. yPos = 0;
  218. // To-Do Player2 hat gewonnen
  219. //Try again
  220. }
  221. if (life2.getLife() == 0){
  222. xPos = 0;
  223. yPos = 0;
  224. //To-Do Player1 hat gewonnen
  225. //Try again
  226. }
  227.  
  228. }
  229. }));
  230.  
  231. // unendliche Anzahle an Wiederholungen
  232. timeline.setCycleCount(Timeline.INDEFINITE);
  233. timeline.play();
  234. }
  235. }


Server:
Java Code:

  1.  
  2. package net;
  3.  
  4.  
  5. import java.io.*;
  6. import java.net.*;
  7. import java.util.*;
  8.  
  9.  
  10.  
  11.  
  12. public class Server {
  13.  
  14.  
  15.  
  16. private ArrayList<ClientThread> ClientListe;
  17. private int port;
  18. private boolean Loopjanein;
  19.  
  20. public Server(int port) {
  21.  
  22.  
  23. this.port = port;
  24. ClientListe = new ArrayList<ClientThread>();
  25. }
  26.  
  27. public void start() {
  28. Loopjanein = true;
  29. try
  30. {
  31.  
  32.  
  33.  
  34. ServerSocket serverSocket = new ServerSocket(port);
  35. while(Loopjanein)
  36. {
  37. // format message saying we are waiting
  38. System.out.println("Server waiting for Clients on port " + port + ".");
  39. Socket socket = serverSocket.accept();
  40. if(!Loopjanein)
  41. break;
  42. ClientThread t = new ClientThread(socket);
  43. ClientListe.add(t);
  44. t.start();
  45. }
  46.  
  47.  
  48. try {
  49. serverSocket.close();
  50. }catch(Exception e) {}
  51. } catch (IOException e) {
  52. }
  53. }
  54.  
  55.  
  56. private void display(String msg) {
  57. String yay = " " + msg;
  58. System.out.println(yay);
  59.  
  60.  
  61. }
  62.  
  63.  
  64. private synchronized void allsenden(String message) { // broadcast
  65. String Message = message + "\n";
  66. System.out.print(Message);
  67.  
  68. for(int i = ClientListe.size(); --i >= 0;) {
  69. ClientThread ClientT = ClientListe.get(i);
  70. if(!ClientT.writeMsg(Message)) {
  71. ClientListe.remove(i);
  72. display("Disconnected Client " + ClientT.username + " removed from list.");
  73. }
  74. }
  75. }
  76.  
  77.  
  78.  
  79.  
  80. synchronized void rm(int id) {
  81. for(int i = 0; i < ClientListe.size(); ++i) {
  82. ClientThread ct = ClientListe.get(i);
  83. if(ct.id == id) {
  84. ClientListe.remove(i);
  85. return;
  86. }
  87. }
  88. }
  89.  
  90.  
  91. public static void main(String[] args) {
  92. int portNumber = 1500;
  93. Server server = new Server(portNumber);
  94. server.start();
  95. }
  96.  
  97.  
  98. /** One instance of this thread will run for each client */
  99. public class ClientThread extends Thread {
  100. Socket socket;
  101. int id;
  102. String username;
  103. ChatMessage cm;
  104. ClientThread(Socket socket) {
  105.  
  106.  
  107. this.socket = socket;
  108. System.out.println("Thread trying to create Object Input/Output Streams");
  109. try
  110. {
  111. sOutput = new ObjectOutputStream(socket.getOutputStream());
  112. sInput = new ObjectInputStream(socket.getInputStream());
  113. username = (String) sInput.readObject();
  114. display(username + " just connected.");
  115. }
  116. catch (IOException e) {
  117. display("Exception creating new Input/output Streams: " + e);
  118. return;
  119. }
  120. }
  121.  
  122.  
  123. }
  124.  
  125.  
  126. public void run() {
  127. boolean keepGoing = true;
  128. while(keepGoing) {
  129. try {
  130. cm = (ChatMessage) sInput.readObject();
  131. }
  132. catch (IOException e) {
  133. display(username + " Exception reading Streams: " + e);
  134. break;
  135. }
  136. break;
  137. }
  138.  
  139.  
  140. String message = cm.getMessage();
  141. switch(cm.getType()) {
  142. case ChatMessage.MESSAGE:
  143. allsenden(username + ": " + message);
  144. break;
  145. case ChatMessage.LOGOUT:
  146. display(username + " disconnected with a LOGOUT message.");
  147. keepGoing = false;
  148. break;
  149.  
  150.  
  151. }
  152. }
  153.  
  154.  
  155. rm(id);
  156. close();
  157. }
  158.  
  159. private void close() {
  160. try {if(sOutput != null) sOutput.close();}
  161. catch(Exception e) {}
  162. try {if(sInput != null) sInput.close();}
  163. catch(Exception e) {};
  164. try {if(socket != null) socket.close();}
  165. catch (Exception e) {}
  166. }
  167. private boolean writeMsg(String msg) {
  168. if(!socket.isConnected()) {
  169. close();
  170. return false;
  171. }
  172. try {
  173. sOutput.writeObject(msg);
  174. }
  175. catch(IOException e) {
  176. display("Error sending message to " + username);
  177. display(e.toString());
  178. }
  179. return true;
  180. }
  181. }
  182. }


Client:
Java Code:

  1. package net;import java.net.*;
  2. import java.io.*;
  3. import java.util.*;
  4.  
  5.  
  6. import model.ScreenModel;
  7. import javafx.animation.KeyFrame;
  8. import javafx.animation.Timeline;
  9. import javafx.event.ActionEvent;
  10. import javafx.event.EventHandler;
  11. import javafx.event.EventType;
  12. import javafx.geometry.Bounds;
  13. import javafx.scene.Scene;
  14. import javafx.scene.input.KeyCode;
  15. import javafx.scene.input.KeyEvent;
  16. import javafx.scene.layout.Pane;
  17. import javafx.scene.shape.Circle;
  18. import javafx.scene.shape.Rectangle;
  19. import javafx.util.Duration;
  20.  
  21.  
  22. public class Client {
  23.  
  24.  
  25. private ObjectInputStream sInput;
  26. private ObjectOutputStream sOutput;
  27. private Socket socket;
  28.  
  29.  
  30. private static ScreenModel model;
  31. private static view.LocalMultiView view;
  32. private static Integer i = 0;
  33. private String server, username;
  34. private int port;
  35.  
  36.  
  37.  
  38.  
  39. public Client(String server, int port, String username) {
  40. this.server = server;
  41. this.port = port;
  42. this.username = username;
  43.  
  44.  
  45. }
  46.  
  47.  
  48. public boolean start() {
  49.  
  50.  
  51. try {
  52. socket = new Socket(server, port);
  53. }
  54.  
  55.  
  56. catch(Exception ec) {
  57. display("Error connectiong to server:" + ec);
  58. return false;
  59. }
  60.  
  61. String msg = "Connection accepted " + socket.getInetAddress() + ":" + socket.getPort();
  62. display(msg);
  63.  
  64.  
  65.  
  66. try
  67. {
  68. sInput = new ObjectInputStream(socket.getInputStream());
  69. sOutput = new ObjectOutputStream(socket.getOutputStream());
  70. }
  71. catch (IOException eIO) {
  72. display("Exception creating new Input/output Streams: " + eIO);
  73. return false;
  74. }
  75.  
  76.  
  77.  
  78.  
  79. new ListenFromServer().start();
  80.  
  81.  
  82. try
  83. {
  84. sOutput.writeObject(username);
  85. }
  86. catch (IOException eIO) {
  87. display("Exception doing login : " + eIO);
  88. disconnect();
  89. return false;
  90. }
  91.  
  92.  
  93. return true;
  94. }
  95.  
  96.  
  97.  
  98.  
  99. private void display(String msg) {
  100.  
  101.  
  102. System.out.println(msg);
  103.  
  104.  
  105. }
  106.  
  107.  
  108.  
  109. public void sendMessage(ChatMessage msg) {
  110. try {
  111. sOutput.writeObject(msg);
  112. }
  113. catch(IOException e) {
  114. display("Exception writing to server: " + e);
  115. }
  116. }
  117.  
  118.  
  119.  
  120.  
  121. private void disconnect() {
  122. try {
  123. if(sInput != null) sInput.close();
  124. }
  125. catch(Exception e) {}
  126. try {
  127. if(sOutput != null) sOutput.close();
  128. }
  129. catch(Exception e) {}
  130. try{
  131. if(socket != null) socket.close();
  132. }
  133. catch(Exception e) {}
  134. }
  135.  
  136.  
  137. public static void main(String[] args) {
  138.  
  139.  
  140. int portNumber = 7777;
  141. String serverAddress = "localhost";
  142. String userName = "Anonymous";
  143.  
  144.  
  145. switch(args.length) {
  146. case 3:
  147. serverAddress = args[2];
  148. case 2:
  149. try {
  150. portNumber = Integer.parseInt(args[1]);
  151. }
  152. catch(Exception e) {
  153. System.out.println("Invalid port number.");
  154. System.out.println("Usage is: > java Client [username] [portNumber] [serverAddress]");
  155. return;
  156. }
  157. case 1:
  158. userName = args[0];
  159. case 0:
  160. break;
  161. default:
  162. System.out.println("Usage is: > java Client [username] [portNumber] {serverAddress]");
  163. return;
  164. }
  165. Client client = new Client(serverAddress, portNumber, userName);
  166. if(!client.start())
  167. return;
  168.  
  169.  
  170.  
  171. Scanner scan = new Scanner(System.in);
  172. while(true) { // waypoint
  173.  
  174.  
  175. String msg = scan.nextLine();
  176. if(msg.equalsIgnoreCase("LOGOUT")) {
  177. client.sendMessage(new ChatMessage(ChatMessage.LOGOUT, ""));
  178. break;
  179. }
  180. else if(msg.equalsIgnoreCase("WHOISIN")) {
  181. client.sendMessage(new ChatMessage(ChatMessage.WHOISIN, ""));
  182. }
  183. else {
  184. client.sendMessage(new ChatMessage(ChatMessage.MESSAGE, msg));
  185. }
  186. }
  187.  
  188.  
  189. client.disconnect();
  190. }
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199. class ListenFromServer extends Thread {
  200.  
  201.  
  202. public void run() {
  203. while(true) {
  204. try {
  205. String msg = (String) sInput.readObject();
  206. System.out.println(msg);
  207.  
  208.  
  209.  
  210.  
  211. }
  212.  
  213.  
  214. catch(IOException e) {
  215. display("Server has close the connection: " + e);
  216.  
  217.  
  218. break;
  219. }
  220. }
  221. }
  222. }
  223. }
  224. }


Ich probiere es jetzt mal aus den Controller im größten Teil einfach so zu lassen, jedoch bei den KeyEventlistener Methoden ausführen zu lassen die im Client stehen und die wiederum Nachrichten an den Server schicken.

Grüße Minti


PongSpiel Netzwerk

0 commentaires:

Enregistrer un commentaire