diff --git a/cs654/final-proj/BlobWars.java b/cs654/final-proj/BlobWars.java index 145f012..5c57bc2 100644 --- a/cs654/final-proj/BlobWars.java +++ b/cs654/final-proj/BlobWars.java @@ -78,16 +78,18 @@ public class BlobWars extends JFrame m_writer = new BufferedWriter( new OutputStreamWriter(m_socket.getOutputStream())); m_writer.write("NAME:" + m_nameField.getText() + "\n"); + m_writer.flush(); } catch (Exception e) { + e.printStackTrace(); JOptionPane.showMessageDialog(null, "Error connecting: " + e.getMessage()); return; } - (new Thread(new ClientHandler())).start(); m_connectButton.setEnabled(false); m_nameField.setEnabled(false); m_serverField.setEnabled(false); m_panel.requestFocusInWindow(); + (new Thread(new ClientHandler())).start(); m_timer = new javax.swing.Timer(50, m_handler); } @@ -100,6 +102,7 @@ public class BlobWars extends JFrame br = new BufferedReader( new InputStreamReader(m_socket.getInputStream())); } catch (Exception e) { + e.printStackTrace(); return; } @@ -111,9 +114,15 @@ public class BlobWars extends JFrame line = br.readLine(); } catch (Exception e) { e.printStackTrace(); + break; } + if (line == null) + break; System.out.println("GOT LINE: " + line); } + /* TODO: disconnected logic */ + System.out.println("client disconnected"); + // SwingUtilities .... doDisconnect(); } } @@ -136,15 +145,19 @@ public class BlobWars extends JFrame { case KeyEvent.VK_UP: m_writer.write("UP\n"); + m_writer.flush(); break; case KeyEvent.VK_DOWN: m_writer.write("DOWN\n"); + m_writer.flush(); break; case KeyEvent.VK_LEFT: m_writer.write("LEFT\n"); + m_writer.flush(); break; case KeyEvent.VK_RIGHT: m_writer.write("RIGHT\n"); + m_writer.flush(); break; } } catch (Exception ex) {} diff --git a/cs654/final-proj/BlobWarsServer.java b/cs654/final-proj/BlobWarsServer.java index 1ce5a90..4ba830a 100644 --- a/cs654/final-proj/BlobWarsServer.java +++ b/cs654/final-proj/BlobWarsServer.java @@ -73,10 +73,13 @@ public class BlobWarsServer tokens.add(st.nextToken()); } String[] arr = tokens.toArray(new String[1]); - if (arr.length < 2) + if (arr.length < 1) return; if (arr[0].equals("NAME")) { + if (arr.length < 2) + return; + System.out.println("Player '" + arr[1] + "' signed on."); m_world.addPlayer(arr[1]); m_socketToPlayerName.put(cu.socket, arr[1]); return; @@ -121,18 +124,17 @@ public class BlobWarsServer m_clientUpdates.clear(); } + /* step the BlobWars world */ m_world.step(); - /* push updates to clients */ + /* calculated updated players */ HashMap pushPlayers = new HashMap(); - HashMap pushShots = - new HashMap(); + HashMap players = m_world.getPlayers(); if (m_lastPlayers == null) pushPlayers.putAll(m_world.getPlayers()); else { - HashMap players = m_world.getPlayers(); for (String name : players.keySet()) { if (!m_lastPlayers.containsKey(name)) @@ -142,11 +144,16 @@ public class BlobWarsServer pushPlayers.put(name, players.get(name)); } } + m_lastPlayers = PlayerClone(players); + + /* calculate updated shots */ + HashMap pushShots = + new HashMap(); + HashMap shots = m_world.getShots(); if (m_lastShots == null) pushShots.putAll(m_world.getShots()); else { - HashMap shots = m_world.getShots(); for (Integer shotid : shots.keySet()) { if (!m_lastShots.containsKey(shotid)) @@ -156,6 +163,7 @@ public class BlobWarsServer pushShots.put(shotid, shots.get(shotid)); } } + m_lastShots = ShotClone(shots); /* write updated info to each client */ String sendLine = ""; @@ -172,10 +180,11 @@ public class BlobWarsServer for (Socket client : m_socketToPlayerName.keySet()) { try { - BufferedWriter br = new BufferedWriter( + BufferedWriter bw = new BufferedWriter( new OutputStreamWriter( client.getOutputStream())); - br.write(sendLine, 0, sendLine.length()); + bw.write(sendLine, 0, sendLine.length()); + bw.flush(); } catch (Exception e) { e.printStackTrace(); } @@ -212,26 +221,15 @@ public class BlobWarsServer String line; try { line = br.readLine(); - } catch (IOException ioe) { - // TODO: remove this line to not print stack trace for - // a client that disconnects, and remove socket from - // HashMap after for() loop - ioe.printStackTrace(); + } catch (Exception e) { +// e.printStackTrace(); break; } + if (line == null) + break; System.out.println("SERVER GOT LINE: " + line); if (line.equals("QUIT")) - { - synchronized (m_socketToPlayerName) - { - if (m_socketToPlayerName.containsKey(m_socket)) - m_socketToPlayerName.remove(m_socket); - try { - m_socket.close(); - } catch (Exception e) {} - } break; - } ClientUpdate cu = new ClientUpdate(); cu.socket = m_socket; cu.message = line; @@ -240,6 +238,44 @@ public class BlobWarsServer m_clientUpdates.add(cu); } } + + /* end of client handling loop, remove client from world */ + synchronized (m_socketToPlayerName) + { + if (m_socketToPlayerName.containsKey(m_socket)) + { + System.out.println("Player '" + + m_socketToPlayerName.get(m_socket) + + "' signed off."); + m_world.removePlayer(m_socketToPlayerName.get(m_socket)); + m_socketToPlayerName.remove(m_socket); + } + try { + m_socket.close(); + } catch (Exception e) {} + } } } + + public HashMap PlayerClone(HashMap orig) + { + HashMap newhm = new HashMap(); + for (String name : orig.keySet()) + { + Player p = orig.get(name).clone(); + newhm.put(name, p); + } + return newhm; + } + + public HashMap ShotClone(HashMap orig) + { + HashMap newhm = new HashMap(); + for (Integer id : orig.keySet()) + { + Shot s = orig.get(id).clone(); + newhm.put(id, s); + } + return newhm; + } } diff --git a/cs654/final-proj/BlobWarsWorld.java b/cs654/final-proj/BlobWarsWorld.java index b90f37f..d3b7bec 100644 --- a/cs654/final-proj/BlobWarsWorld.java +++ b/cs654/final-proj/BlobWarsWorld.java @@ -45,6 +45,11 @@ public class BlobWarsWorld return true; } + public void removePlayer(String name) + { + m_players.remove(name); + } + public void shoot(String playerName) { if (!m_players.containsKey(playerName)) @@ -89,7 +94,9 @@ public class BlobWarsWorld if (!m_players.containsKey(playerName)) return; Player p = m_players.get(playerName); - p.dr = PLAYER_SPIN_SPEED; + p.dr += PLAYER_SPIN_SPEED; + if (Math.abs(p.dr) < 0.001) + p.dr = 0; } public void moveRight(String playerName) @@ -97,7 +104,9 @@ public class BlobWarsWorld if (!m_players.containsKey(playerName)) return; Player p = m_players.get(playerName); - p.dr = -PLAYER_SPIN_SPEED; + p.dr -= PLAYER_SPIN_SPEED; + if (Math.abs(p.dr) < 0.001) + p.dr = 0; } public Vector collidesWith(GameItem gi) diff --git a/cs654/final-proj/Makefile b/cs654/final-proj/Makefile index 925f973..6c35e72 100644 --- a/cs654/final-proj/Makefile +++ b/cs654/final-proj/Makefile @@ -1,10 +1,12 @@ MAINCLASS := BlobWars -all: $(patsubst %.java,%.class,$(wildcard *.java)) +all: + javac *.java -%.class: %.java - javac $^ +.PHONY: runserver +runserver: + java $(MAINCLASS)Server .PHONY: run run: diff --git a/cs654/final-proj/Player.java b/cs654/final-proj/Player.java index 3168ae1..3d7c325 100644 --- a/cs654/final-proj/Player.java +++ b/cs654/final-proj/Player.java @@ -1,5 +1,7 @@ -public class Player extends GameItem +import java.util.*; + +public class Player extends GameItem implements Cloneable { public static final double DEFAULT_RADIUS = 0.06; public static final double COLLIDE_DAMAGE = 0.002; @@ -22,6 +24,18 @@ public class Player extends GameItem this.dy = 0; } + public Player clone() + { + Player p = new Player(name); + p.radius = radius; + p.health = health; + p.r = r; + p.dr = dr; + p.dx = dx; + p.dy = dy; + return p; + } + public boolean equals(Player other) { return this.name.equals(other.name) && @@ -38,4 +52,26 @@ public class Player extends GameItem return String.format("%s:%.3f:%.3f:%.3f:%.3f:%.3f:%.3f:%.3f:%.3f", name, radius, health, x, y, r, dr, dx, dy); } + + public void fromString(String s) + { + StringTokenizer st = new StringTokenizer(s, ":"); + Vector tokens = new Vector(); + while (st.hasMoreTokens()) + { + tokens.add(st.nextToken()); + } + String[] arr = tokens.toArray(new String[1]); + if (arr.length != 9) + return; + name = arr[0]; + radius = Double.parseDouble(arr[1]); + health = Double.parseDouble(arr[2]); + x = Double.parseDouble(arr[3]); + y = Double.parseDouble(arr[4]); + r = Double.parseDouble(arr[5]); + dr = Double.parseDouble(arr[6]); + dx = Double.parseDouble(arr[7]); + dy = Double.parseDouble(arr[8]); + } } diff --git a/cs654/final-proj/Shot.java b/cs654/final-proj/Shot.java index e72ee66..f674819 100644 --- a/cs654/final-proj/Shot.java +++ b/cs654/final-proj/Shot.java @@ -1,5 +1,7 @@ -public class Shot extends GameItem +import java.util.*; + +public class Shot extends GameItem implements Cloneable { public static final double DEFAULT_RADIUS = 0.03; public static final double SHOT_DURATION = 3.0; @@ -19,6 +21,14 @@ public class Shot extends GameItem this.dy = 0; } + public Shot clone() + { + Shot s = new Shot(id, createTime, x, y); + s.dx = dx; + s.dy = dy; + return s; + } + public boolean equals(Shot other) { return this.createTime == other.createTime && @@ -34,4 +44,23 @@ public class Shot extends GameItem return String.format("%d:%.3f:%.3f:%.3f:%.3f:%.3f", id, radius, x, y, dx, dy); } + + public void fromString(String s) + { + StringTokenizer st = new StringTokenizer(s, ":"); + Vector tokens = new Vector(); + while (st.hasMoreTokens()) + { + tokens.add(st.nextToken()); + } + String[] arr = tokens.toArray(new String[1]); + if (arr.length != 6) + return; + id = Integer.parseInt(arr[0]); + radius = Double.parseDouble(arr[1]); + x = Double.parseDouble(arr[2]); + y = Double.parseDouble(arr[3]); + dx = Double.parseDouble(arr[4]); + dy = Double.parseDouble(arr[5]); + } }