Răsfoiți Sursa

Network server now working!

jancoow 10 ani în urmă
părinte
comite
111f3a4cb0

+ 59 - 0
server/server/LevelReader.java

@@ -0,0 +1,59 @@
+package server;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.List;
+
+import server.match.levels.Level;
+import server.match.objects.Ball;
+
+public class LevelReader {
+	/* LEVEL FILE READING, PARSING AND PLAYING */
+
+	public static ArrayList<Level> readLevelsFromFiles(){
+		ArrayList<Level> levels = new ArrayList<Level>();
+		File root = new File(Main.class.getResource("/model/levels").getPath());
+        File[] list = root.listFiles();
+        for ( File f : list ) {
+        	if(f.isFile() && f.getName().endsWith(".bb")){
+        		try {
+					levels.add(readLevel(Files.readAllLines(f.toPath())));		
+				}catch (IOException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
+					System.out.println("Level file corrputed");
+					e.printStackTrace();
+				}
+        	}
+        }
+        return levels;
+	}
+	
+	private static Level readLevel(List<String> levelfile) throws NumberFormatException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{
+		Level level = new Level();
+		if(levelfile.size() == 3){
+			String[] ballsstrings = levelfile.get(0).split("\\|"); //split all the balls
+			for(String ball:ballsstrings){
+				String[]ballstring = ball.split(",");
+				if(ballstring.length == 7){
+					level.addBall(new Ball(
+										Integer.parseInt(ballstring[0]), 
+										Integer.parseInt(ballstring[1]),
+										(Color)Color.class.getField(ballstring[2]).get(null),
+										Integer.parseInt(ballstring[3]),
+										Integer.parseInt(ballstring[4]),
+										Integer.parseInt(ballstring[5]),
+										Double.parseDouble(ballstring[6])
+										)
+								);
+				}
+			}
+			
+			String[] powerupsstring = levelfile.get(1).split("\\|");
+			
+			level.setTime(Integer.parseInt(levelfile.get(2)));
+		}
+		return level;
+	}
+}

+ 0 - 9
server/server/Match.java

@@ -1,9 +0,0 @@
-package server;
-
-public class Match {
-	private NetworkUser nwuser1, nwuser2;
-	
-	public Match(NetworkUser nwuser1, NetworkUser nwuser2){
-		
-	}
-}

+ 75 - 16
server/server/NetworkUser.java

@@ -1,42 +1,101 @@
 package server;
 
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
 import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
 import java.net.Socket;
 
+import server.match.Match;
+
 public class NetworkUser {
 	private String name;
 	private Socket client;
-	private InputStream input;
-	private OutputStream output;
+	private DataOutputStream dout;
+	private DataInputStream din;
+	private Thread receivethread;
+	private Match match;
+	private int pid;
 	
-	public NetworkUser(String username, Socket client){
-		this.name = username;
+	public NetworkUser(Socket client){
 		this.client = client;
 		try {
-			input = client.getInputStream();
-			output = client.getOutputStream();
+			dout = new DataOutputStream(client.getOutputStream());
+			din = new DataInputStream(client.getInputStream());
 		} catch (IOException e) {
 			System.err.println("Somethings nasty happends with a user");
 		}
+		try {
+			client.setSoTimeout(5000);
+			name = din.readUTF();
+			System.out.println(name);
+			client.setSoTimeout(0);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		receivethread = new Thread(new Runnable() {
+			@Override
+			public void run() {
+				while(true){
+					receiveMessage();
+				}
+			}
+		});
 	}
 
-	/* GETTERS AND SETTERS */
 	
-	/**
-	 * @return the name of the user
-	 */
-	public String getName() {
-		return name;
-	}
+	/* NETWORK CONTROL METHODS */
 	
 	public boolean checkConnection(){
 		try {
-			output.write(0);
+			dout.writeUTF("0");
 		} catch (IOException e) {
+			e.printStackTrace();
 			return false;
 		} 
 		return true;
 	}
+	
+	public void startMatch(String p1, String p2, int pid, Match match){
+		sendMessage("1|"+p1+"|"+p2);
+		this.pid = pid;
+		this.match = match;
+		receivethread.start();
+	}
+	
+	public void sendMessage(String m){
+		try {
+			dout.writeUTF(m);
+		} catch (IOException e) {
+			System.err.println("User disconnected");
+			match.stopMatch();
+		}
+	}
+	
+	public void receiveMessage(){
+		try {
+			String message = din.readUTF();
+			String[] messagesplit = message.split("\\|");
+			switch (messagesplit[0]){
+				case "1":												//Player input information
+					match.setPlayerDirection(pid, Integer.parseInt(messagesplit[1]));
+					if(Integer.parseInt(messagesplit[2]) == 1){
+						match.playerShoot(pid);
+					}
+					break;
+			}
+		} catch (IOException e) {
+			System.err.println("User disconnected");
+			receivethread.stop();
+			match.stopMatch();
+		}
+	}
+	
+	/* GETTERS AND SETTERS */
+	
+	/**
+	 * @return the name of the user
+	 */
+	public String getName() {
+		return name;
+	}
 }

+ 16 - 14
server/server/Server.java

@@ -7,6 +7,8 @@ import java.net.Socket;
 import java.util.ArrayList;
 import java.util.Iterator;
 
+import server.match.Match;
+
 
 public class Server {
 	private ArrayList<NetworkUser> matchMakingUsers;
@@ -21,28 +23,28 @@ public class Server {
 				try {
 					ServerSocket server = new ServerSocket(port);
 					while(true){
-						System.out.println("Waiting for clients...");
 						try {
 							Socket client = server.accept();
 							
-							//Wait until user has send his username (timeout of 5 seconds)
-							DataInputStream input= new DataInputStream(client.getInputStream());
-							client.setSoTimeout(5000);
-							matchMakingUsers.add(new NetworkUser(input.readUTF(), client));
+							matchMakingUsers.add(new NetworkUser(client));
 							
 							//Check if all users in the matchMakingList are still connected
-							Iterator<NetworkUser> i = matchMakingUsers.iterator();
-							while(i.hasNext()){
-								if(!i.next().checkConnection()){
-									i.remove();
-								}
-							}
-							
+//							Iterator<NetworkUser> i = matchMakingUsers.iterator();
+//							while(i.hasNext()){
+//								if(!i.next().checkConnection()){
+//									i.remove();
+//									System.out.println("Someone dissconected :(");
+//
+//								}
+//							}
+//							
 							//Check if there are enough players to make a match
 							if(matchMakingUsers.size()  >= 2){
-								new Match(matchMakingUsers.get(0), matchMakingUsers.get(1));
+								new Thread(new Match(matchMakingUsers.get(0), matchMakingUsers.get(1)));
+								matchMakingUsers.remove(1);
+								matchMakingUsers.remove(0);
 							}
-							
+							System.out.println(matchMakingUsers.size());
 							System.out.println("New client connected: " + client.getRemoteSocketAddress());
 						} catch (IOException e) {
 							e.printStackTrace();

+ 207 - 0
server/server/match/Match.java

@@ -0,0 +1,207 @@
+package server.match;
+
+import java.awt.Color;
+import java.io.File;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.util.ArrayList;
+import java.util.ConcurrentModificationException;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Timer;
+import java.util.TimerTask;
+
+import resources.image.Images;
+import resources.image.Images.ImageType;
+import server.LevelReader;
+import server.Main;
+import server.NetworkUser;
+import server.match.levels.Level;
+import server.match.objects.Ball;
+import server.match.objects.Player;
+import server.match.objects.ShootingLine;
+
+public class Match implements Runnable {
+	private NetworkUser nwuser1, nwuser2;
+	private Player player1;
+	private Player player2;
+	private ShootingLine line1;
+	private ShootingLine line2;
+	private ArrayList<Ball> balls;
+	private int p1direction, p2direction;
+	
+	private ArrayList<Level> levels;
+	private Timer timer;
+	private int currentlevel;
+	private int timeleft;
+	private long lasttime;
+	
+	public Match(NetworkUser nwuser1, NetworkUser nwuser2){
+		nwuser1.startMatch(nwuser1.getName(), nwuser2.getName(), 1, this);
+		nwuser2.startMatch(nwuser2.getName(), nwuser1.getName(), 2, this);
+		player1 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550);
+		player2 = new Player(Images.getImage(ImageType.PLAYER1), 240, 550);
+		balls = new ArrayList<Ball>();
+		this.nwuser1 = nwuser1;
+		this.nwuser2 = nwuser2;
+		System.out.println("New Match!");
+		levels = LevelReader.readLevelsFromFiles();
+		
+		timer = new Timer();
+		timer.schedule(new TimerTask() {
+			@Override
+			public void run() {
+				update();				
+			}
+		}, 0, 1000/30);
+		
+		playLevel(getCurrentLevel());
+	}
+	
+	public void playLevel(Level level){
+		balls.clear();
+		for(Ball b:level.getStartballs()){
+			balls.add(b.clone());
+		}
+		timeleft = level.getTime();
+		player1.reset();
+		player2.reset();
+		line1=null;	
+		lasttime = System.currentTimeMillis();
+	}
+	
+	public Level getCurrentLevel(){
+		if(currentlevel >= 0 && currentlevel < levels.size()){
+			return levels.get(currentlevel);
+		}
+		return null;
+	}
+	
+	/* UPDATE */
+	public void update() {		
+		if(p1direction == 1)
+			player1.walkRight();
+		else if(p1direction == -1)
+			player1.walkLeft();
+		player1.update();
+		if(p2direction == 1)
+			player2.walkRight();
+		else if(p2direction == -1)
+			player2.walkLeft();
+		player2.update();
+		
+		if(line1 != null){
+			line1.setLength(line1.getLength()+1);
+			if(line1.getMaxHeight() < 0){ 										//Line hit the ceiling, so "remove" it
+				line1 = null;
+			}
+		}
+		if(line2 != null){
+			line2.setLength(line2.getLength()+1);
+			if(line2.getMaxHeight() < 0){ 		
+				line2 = null;
+			}
+		}
+		
+		
+		//Collision detection
+		try{
+			ListIterator<Ball> b = balls.listIterator(); 
+			while(b.hasNext()){
+				Ball bal = b.next(); 
+				if(line1 != null && bal.hitLine(line1)){								// Collision between line and ball
+					line1 = null;
+					b.remove();
+					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player1.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), -1, Math.abs(bal.getYSpeed())*-1));
+					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player1.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), 1, Math.abs(bal.getYSpeed())*-1));
+				}else if(line2 != null && bal.hitLine(line2)){								// Collision between line and ball
+					line2 = null;
+					b.remove();
+					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player1.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), -1, Math.abs(bal.getYSpeed())*-1));
+					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player1.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), 1, Math.abs(bal.getYSpeed())*-1));
+				}else if(bal.hitPlayer(player1)){														// Collision between player and ball
+					player1.setHealth(player1.getHealth()-1);
+					playLevel(getCurrentLevel());
+				}else if(bal.hitPlayer(player2)){														// Collision between player and ball
+					player2.setHealth(player2.getHealth()-1);
+					playLevel(getCurrentLevel());
+				}else if(bal.getSize() <= 0 ){															// Remove ball from arraylist when size is 0 (not visible)
+					b.remove();
+				}else{
+					bal.update();
+				}
+			}
+		}catch(ConcurrentModificationException e){
+			
+		}
+		timeleft -= (System.currentTimeMillis() - lasttime);
+		if(balls.size() == 0){
+			if(player1.getHealth() > 0)
+				player1.setScore(player1.getScore()+(timeleft/100));
+			else
+				player1.setScore(player1.getScore()+(timeleft/100)/2);
+			
+			if(player2.getHealth() > 0)
+				player2.setScore(player2.getScore()+(timeleft/100));
+			else
+				player2.setScore(player2.getScore()+(timeleft/100)/2);
+				playLevel(levels.get(currentlevel+=1));
+		}else if(timeleft < 0){
+			player1.setHealth(player1.getHealth()-1);
+			player2.setHealth(player2.getHealth()-1);
+			playLevel(getCurrentLevel());
+		}else if(player1.getHealth() <= 0) {
+			
+		}
+		lasttime = System.currentTimeMillis();	
+	
+		
+		//Sending the new information to the players
+		String playerinfo = "2|"+player1.getX()+"|"+player1.getY()+"|"+player1.getHealth()+"|"+player1.getSpeed()+"|"+player1.getScore()+"|"+	
+							player2.getX()+"|"+player2.getY()+"|"+player2.getHealth()+"|"+player2.getSpeed()+"|"+player2.getScore();
+		
+		String ballsinfo =",";
+		for(Ball b:balls){
+			ballsinfo +=  b.getX()+"|"+b.getY()+"|"+b.getSize()+"|"+b.getColor().getRGB() + "|" ;
+		}
+		
+		String linesinfo = "," ;
+		if(line1 != null)
+			linesinfo += line1.getX() + "|" + line1.getY() + "|" + line1.getLength() + "|";
+		else
+			linesinfo += "0|0|0|";
+		if(line2 != null)
+			linesinfo += line2.getX() + "|" + line2.getY() + "|" + line2.getLength();
+		else
+			linesinfo += "0|0|0|";
+		
+		String timeleft = ","+(int)(this.timeleft/(double)getCurrentLevel().getTime()*1000);
+		
+		nwuser1.sendMessage(playerinfo+ballsinfo+linesinfo+timeleft);
+		nwuser2.sendMessage(playerinfo+ballsinfo+linesinfo+timeleft);
+		
+	}
+	
+	/* GETTERS AND SETTERS */
+	public void setPlayerDirection(int pid, int dir){
+		if(pid == 1)
+			p1direction = dir;
+		if(pid == 2)
+			p2direction = dir;
+	}
+	public void playerShoot(int pid){
+		if(pid == 1)
+			line1 = new ShootingLine(player1.getX()+player1.getWidth()/2, player1.getY()+player1.getHeigth());
+		if(pid == 2)
+			line2 = new ShootingLine(player2.getX(), player2.getY());
+	}
+	
+	public void stopMatch(){
+		timer.cancel();
+	}
+
+	@Override
+	public void run() {
+		
+	}
+}

+ 44 - 0
server/server/match/levels/Level.java

@@ -0,0 +1,44 @@
+package server.match.levels;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import server.match.objects.Ball;
+import server.match.objects.PowerUp;
+
+public class Level {
+	private List<Ball> startballs;
+	private List<PowerUp> powerups;
+	private int time;
+	
+	public Level(){
+		this.startballs = new ArrayList<Ball>();
+		this.powerups = new ArrayList<PowerUp>();
+	}
+	
+	public void addBall(Ball b){
+		startballs.add(b);
+	}
+	
+	public void addPowerUp(PowerUp p){
+		powerups.add(p);
+	}
+	
+	public void setTime(int t){
+		time = t;
+	}
+
+	public List<Ball> getStartballs() {
+		return startballs;
+	}
+
+	public List<PowerUp> getPowerups() {
+		return powerups;
+	}
+
+	public int getTime() {
+		return time;
+	}
+	
+	
+}

+ 3 - 0
server/server/match/levels/level1.bb

@@ -0,0 +1,3 @@
+2,200,red,200,400,-1,0.0
+speed
+18000

+ 3 - 0
server/server/match/levels/level2.bb

@@ -0,0 +1,3 @@
+2,200,green,200,200,-1,0.0|3,300,magenta,500,200,1,0.0
+speed|life
+30000

+ 120 - 0
server/server/match/objects/Ball.java

@@ -0,0 +1,120 @@
+package server.match.objects;
+
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.geom.Ellipse2D;
+
+import main.Window;
+
+public class Ball {
+	private Color color;
+	private int size, bounceheight, direction;
+	private Ellipse2D.Double bal;
+
+	double rx, ry; 			// position
+	double vx, vy; 	// velocity
+
+	public Ball(int size, int bounceheight, Color color, int x, int y, int direction, double velocity) {
+		this.color = color;
+		this.size = size*20;
+		this.bounceheight = bounceheight;
+		this.direction = direction;
+		this.vx = direction*3;
+		this.vy = velocity;
+		setDirection(direction);
+		rx = x;
+		ry = y;
+		bal = new Ellipse2D.Double(x, y, this.size, this.size);
+	}
+
+	public boolean hitLine(ShootingLine l){
+		return bal.intersects(l.getX(), l.getY()-l.getHeight(), l.getWidth(), l.getHeight());
+	}
+	
+	public boolean hitPlayer(Player p){
+		return bal.intersects(p.getX(),p.getY(),p.getWidth(),p.getHeigth());
+	}
+	
+	public Ball clone(){
+		return new Ball(getSize(), getBounceHeight(), getColor(), getX(), getY(), direction, vy);
+	}
+	
+	//** Calculating **//
+	
+	public void update() {
+		if (rx >= (Window.WIDTH - size - 10))
+			vx = -3;
+		else if (rx <= 10)
+			vx =3;
+		
+		vy += 0.5;
+		
+		if(ry+size < 600-bounceheight && vy < 0)
+		{
+			vy +=0.5;
+		}
+		else if(ry+size < 600-bounceheight && vy > 0)
+		{
+			vy -=0.2;
+		}
+
+		if (ry >= (600-size))
+			vy *= -1;
+		
+		rx += vx;
+		ry += vy;
+		setX((int) rx);
+		setY((int) ry);
+	}
+	
+	//** Getters and Setters **//
+	
+	public int getSize() {
+		return size/20;
+	}
+
+	public int getBounceHeight() {
+		return bounceheight;
+	}
+
+	public int getX() {
+		return (int) bal.getX();
+	}
+
+	public int getY() {
+		return (int) bal.getY();
+	}
+
+	public int getWidth() {
+		return (int) bal.getWidth();
+	}
+
+	public int getHeight() {
+		return (int) bal.getHeight();
+	}
+	
+	public Color getColor() {
+		return color;
+	}
+
+	public void setX(int x) {
+		bal.setFrame(x, getY(), getWidth(), getHeight());
+	}
+
+	public void setY(int y) {
+		bal.setFrame(getX(), y, getWidth(), getHeight());
+	}
+	
+	public void setDirection(int d){
+		if(d == -1 || d == 1){
+			direction = d;
+			vx = d*3;
+		}
+	}
+	
+	public double getYSpeed()
+	{
+		return vy;
+	}
+	
+}

+ 60 - 0
server/server/match/objects/DrawObject.java

@@ -0,0 +1,60 @@
+package server.match.objects;
+
+import java.awt.geom.Point2D;
+import java.awt.image.BufferedImage;
+
+public class DrawObject {
+	
+	protected Point2D position;
+	protected BufferedImage image;
+	
+	public DrawObject(BufferedImage image)
+	{
+		this.image = image;
+		
+		position = new Point2D.Double(0,0);
+	}
+	
+	public void update(){};
+	
+	/* Helper Functions */
+	
+	public void setX(int x)
+	{
+		position.setLocation(x, position.getY());
+	}
+	public void setY(int y)
+	{
+		position.setLocation(position.getX(), y);
+	}
+	public void setPosition(Point2D p)
+	{
+		position.setLocation(p);
+	}
+	public void setPosition(int x, int y)
+	{
+		position.setLocation(x, y);
+	}
+	
+	public int getX()
+	{
+		return (int)position.getX();
+	}
+	public int getY()
+	{
+		return (int)position.getY();
+	}
+	public Point2D getPosition()
+	{
+		return position;
+	}
+	
+	public int getWidth()
+	{
+		return image.getWidth();
+	}
+	public int getHeigth()
+	{
+		return image.getHeight();
+	}
+}

+ 63 - 0
server/server/match/objects/Player.java

@@ -0,0 +1,63 @@
+package server.match.objects;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Point2D.Double;
+import java.awt.image.BufferedImage;
+import java.util.ArrayList;
+
+import main.Window;
+
+public class Player extends DrawObject {
+
+	private int score, health, speed = 10;
+	private ArrayList<PowerUp> powerups;
+	private Double beginlocation;
+	
+	public Player(BufferedImage image, int x, int y) {
+		super(image.getSubimage(38, 0, 40, 54));
+		super.setPosition(x, y);
+		beginlocation = new Point2D.Double(x,y);
+		health = 5;
+		powerups = new ArrayList<PowerUp>();
+	}
+	
+	public void walkLeft(){
+		if(getX() - speed > 10){
+			setX(getX()-speed);
+		}
+	}
+	
+	public void walkRight(){
+		if(getX() + getWidth() + speed < Window.WIDTH -10){
+			setX(getX()+speed);
+		}
+	}
+	
+	public void reset(){
+		setPosition(beginlocation);
+		speed = 10;
+	}
+	
+	//** Getters and Setters **//
+	
+	public int getScore() {
+		return score;
+	}
+	public void setScore(int score)
+	{
+		this.score = score;
+	}
+
+	public int getHealth() {
+		return health;
+	}
+	
+	public void setHealth(int health){
+		this.health = health;
+	}
+
+	public int getSpeed() {
+		return speed; 
+	}
+	
+}

+ 11 - 0
server/server/match/objects/PowerUp.java

@@ -0,0 +1,11 @@
+package server.match.objects;
+
+import java.awt.image.BufferedImage;
+
+public class PowerUp extends DrawObject {
+	
+	public PowerUp(BufferedImage image) {
+		super(image);
+	}
+
+}

+ 44 - 0
server/server/match/objects/ShootingLine.java

@@ -0,0 +1,44 @@
+package server.match.objects;
+
+import java.awt.Graphics2D;
+import java.awt.geom.Path2D;
+
+public class ShootingLine {
+	private int startx,starty, length;
+
+	public ShootingLine(int startx, int starty){
+		this.startx = startx;
+		this.starty = starty;
+	}
+
+
+	//** Getters and Setters **//
+	
+	public int getLength(){
+		return length;
+	}
+	
+	public int getMaxHeight(){
+		return starty - length * 30;
+	}
+	
+	public int getX(){
+		return startx;
+	}
+	
+	public int getY(){
+		return starty;
+	}
+	
+	public int getWidth(){
+		return 10;
+	}
+	
+	public int getHeight(){
+		return getLength() * 30;
+	}
+	
+	public void setLength(int length){
+		this.length = length;
+	}
+}

+ 12 - 16
src/model/InfoPanel.java

@@ -5,27 +5,23 @@ import java.awt.Font;
 import java.awt.Graphics2D;
 
 import main.Window;
-import model.objects.Player;
 import model.state.PlayState;
 import resources.image.Images;
 import resources.image.Images.ImageType;
 
 public class InfoPanel {
 	private PlayState play;
-	private Player player1, player2;
 	
 	private int OFFSET = 610;
 		
-	public InfoPanel(Player p1, Player p2, PlayState play){
-		player1 = p1;
-		player2 = p2;
+	public InfoPanel(PlayState play){
 		this.play = play;
 	}
 	
 	public void paint(Graphics2D g2d)
 	{
 		g2d.setColor(Color.red);
-		g2d.fillRect(200, OFFSET, (int) (400*((double)play.getTimeleft()/play.getCurrentLevel().getTime())), 20);
+		g2d.fillRect(200, OFFSET, (int) (400*((play.getTimeleftpercent())/1000)), 20);
 		
 		g2d.setColor(Color.black);
 		g2d.setFont(new Font("Century Schoolbook L", Font.ROMAN_BASELINE, 22));
@@ -33,9 +29,9 @@ public class InfoPanel {
 
 		//Player 1
 		g2d.drawLine(35, OFFSET, 35, Window.HEIGHT);
-		g2d.drawString(player1.getName(), 40, OFFSET + 5 + g2d.getFont().getSize());
-		g2d.drawString(player1.getScore() + " xp", 40, OFFSET + 5 + g2d.getFont().getSize()*2+5);
-		for(int i = 0; i < player1.getHealth(); i++)
+		g2d.drawString(play.getPlayer1().getName(), 40, OFFSET + 5 + g2d.getFont().getSize());
+		g2d.drawString(play.getPlayer1().getScore() + " xp", 40, OFFSET + 5 + g2d.getFont().getSize()*2+5);
+		for(int i = 0; i < play.getPlayer1().getHealth(); i++)
 		{
 			g2d.drawImage(Images.getImage(ImageType.HEARTH), null, 5, OFFSET + (30*i));
 		}
@@ -44,17 +40,17 @@ public class InfoPanel {
 		
 		//Chat
 		g2d.drawLine(200, OFFSET, 200, Window.HEIGHT);
-		g2d.drawString("[" + player1.getName().toUpperCase() + "] > Hi!", 210, OFFSET + 50);
-		g2d.drawString("[" + player2.getName().toUpperCase() + "] > Hello", 210, OFFSET + 50 + g2d.getFont().getSize());
-		g2d.drawString("[" + player1.getName().toUpperCase() + "] > How are you?", 210, OFFSET + 50 + g2d.getFont().getSize()*2);
-		g2d.drawString("[" + player2.getName().toUpperCase() + "] > Good :D", 210, OFFSET + 50 + g2d.getFont().getSize()*3);
+		g2d.drawString("[" + play.getPlayer1().getName().toUpperCase() + "] > Hi!", 210, OFFSET + 50);
+		g2d.drawString("[" + play.getPlayer2().getName().toUpperCase() + "] > Hello", 210, OFFSET + 50 + g2d.getFont().getSize());
+		g2d.drawString("[" + play.getPlayer1().getName().toUpperCase() + "] > How are you?", 210, OFFSET + 50 + g2d.getFont().getSize()*2);
+		g2d.drawString("[" + play.getPlayer2().getName().toUpperCase() + "] > Good :D", 210, OFFSET + 50 + g2d.getFont().getSize()*3);
 		g2d.drawLine(600, OFFSET, 600, Window.HEIGHT);
 
 		
 		g2d.drawLine(Window.WIDTH - 35, OFFSET, Window.WIDTH - 35, Window.HEIGHT);
-		g2d.drawString(player2.getName(), Window.WIDTH - 40 - player2.getName().length()*15, OFFSET + 5 + g2d.getFont().getSize());
-		g2d.drawString(player2.getScore() + " xp", Window.WIDTH - 40 - ((player2.getScore() + " ").length() +3)*15, OFFSET + 5 + g2d.getFont().getSize()*2+5);
-		for(int i = 0; i < player2.getHealth(); i++)
+		g2d.drawString(play.getPlayer2().getName(), Window.WIDTH - 40 - play.getPlayer2().getName().length()*15, OFFSET + 5 + g2d.getFont().getSize());
+		g2d.drawString(play.getPlayer2().getScore() + " xp", Window.WIDTH - 40 - ((play.getPlayer1().getScore() + " ").length() +3)*15, OFFSET + 5 + g2d.getFont().getSize()*2+5);
+		for(int i = 0; i < play.getPlayer2().getHealth(); i++)
 		{
 			g2d.drawImage(Images.getImage(ImageType.HEARTH), null, Window.WIDTH - 30, OFFSET + (30*i));
 		}

+ 69 - 3
src/model/NetworkConnection.java

@@ -1,18 +1,26 @@
 package model;
 
+import java.awt.Color;
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
 import java.net.Socket;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
+
+import model.objects.Ball;
+import model.state.PlayState;
 
 public class NetworkConnection {
 	private static final int port = 1234;
-	private static final String address = "62.195.226.247";
+	private static final String address = "localhost";
 	private DataOutputStream dout;
 	private DataInputStream din;
-	
-	
+	private PlayState play;
+		
+	public NetworkConnection(PlayState play){
+		this.play = play;
+	}
 	
 	public void connect(String name) throws UnknownHostException, IOException{
 		if(checkConnection()){
@@ -22,9 +30,20 @@ public class NetworkConnection {
 		dout = new DataOutputStream(server.getOutputStream());
 		din = new DataInputStream(server.getInputStream());
 		dout.writeUTF(name);
+		new Thread(new Runnable() {
+			@Override
+			public void run() {
+				while(true){
+					receiveMessage();
+				}
+			}
+		}).start();
+		
 	}
 	
 	public boolean checkConnection(){
+		if(dout == null)
+			return false;
 		try {
 			dout.write(0);
 		} catch (IOException e) {
@@ -33,4 +52,51 @@ public class NetworkConnection {
 		return true;
 	}
 	
+	private void receiveMessage(){
+		try {
+			String message = din.readUTF();
+			String[] messagesplit = message.split("\\|");
+			switch (messagesplit[0]){
+				case "1":												//New Match
+					play.newMatch(messagesplit[1], messagesplit[2]);
+					break;
+				case "2":	//Update message
+					messagesplit = message.split(",");
+					
+					String[] playersplit = messagesplit[0].split("\\|");
+					play.updatePlayerInfo(Integer.parseInt(playersplit[1]), Integer.parseInt(playersplit[2]), Integer.parseInt(playersplit[3]), Integer.parseInt(playersplit[4]), Integer.parseInt(playersplit[5]), play.getPlayer1());
+					play.updatePlayerInfo(Integer.parseInt(playersplit[6]), Integer.parseInt(playersplit[7]), Integer.parseInt(playersplit[8]), Integer.parseInt(playersplit[9]), Integer.parseInt(playersplit[10]), play.getPlayer2());
+					
+					String[] ballsplit = messagesplit[1].split("\\|");
+					if(ballsplit.length/4 != play.getBalls().size()){
+						play.getBalls().clear();
+					}
+					for(int i = 0; i < ballsplit.length/4; i++){
+						play.getBall(i).updateInfo(Integer.parseInt(ballsplit[(i*4)+0]), Integer.parseInt(ballsplit[(i*4)+1]), Color.decode(ballsplit[(i*4)+3]), Integer.parseInt(ballsplit[(i*4)+2]));
+					}
+					
+					String[] linesplit = messagesplit[2].split("\\|");
+					play.updateLines(Integer.parseInt(linesplit[0]), Integer.parseInt(linesplit[1]), Integer.parseInt(linesplit[2]), Integer.parseInt(linesplit[3]), Integer.parseInt(linesplit[4]), Integer.parseInt(linesplit[5]));
+					
+					play.setTimeleftpercent(Integer.parseInt(messagesplit[3]));
+					
+			}
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+		
+	}
+	
+	public void sendInput(int direction, int shoot){
+		sendMessage("1|"+direction+"|"+shoot);
+	}
+	
+	private void sendMessage(String m){
+		try {
+			dout.writeUTF(m);
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
+	}
+	
 }

+ 14 - 60
src/model/objects/Ball.java

@@ -4,74 +4,33 @@ import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.geom.Ellipse2D;
 
+import jdk.nashorn.internal.ir.SetSplitState;
 import main.Window;
 
 public class Ball {
 	private Color color;
-	private int size, bounceheight, direction;
+	private int size;
 	private Ellipse2D.Double bal;
 
-	double rx, ry; 			// position
-	double vx, vy; 	// velocity
 
-	public Ball(int size, int bounceheight, Color color, int x, int y, int direction, double velocity) {
+	public Ball(int size, Color color, int x, int y) {
 		this.color = color;
 		this.size = size*20;
-		this.bounceheight = bounceheight;
-		this.direction = direction;
-		this.vx = direction*3;
-		this.vy = velocity;
-		setDirection(direction);
-		rx = x;
-		ry = y;
 		bal = new Ellipse2D.Double(x, y, this.size, this.size);
 	}
-
-	public boolean hitLine(ShootingLine l){
-		return bal.intersects(l.getX(), l.getY()-l.getHeight(), l.getWidth(), l.getHeight());
-	}
 	
-	public boolean hitPlayer(Player p){
-		return bal.intersects(p.getX(),p.getY(),p.getWidth(),p.getHeigth());
-	}
-	
-	public Ball clone(){
-		return new Ball(getSize(), getBounceHeight(), getColor(), getX(), getY(), direction, vy);
+	public Ball(){
+		this(0, Color.black, 0, 0);
 	}
+
 	
 	//** Drawing and Calculating **//
 	
 	public void paint(Graphics2D g2d) {
-		g2d.setColor(color);
+		g2d.setColor(Color.BLUE);
 		g2d.fill(bal);
-		g2d.drawLine(0, 600-bounceheight, 500, 600-bounceheight);
 	}
 
-	public void update() {
-		if (rx >= (Window.WIDTH - size - 10))
-			vx = -3;
-		else if (rx <= 10)
-			vx =3;
-		
-		vy += 0.5;
-		
-		if(ry+size < 600-bounceheight && vy < 0)
-		{
-			vy +=0.5;
-		}
-		else if(ry+size < 600-bounceheight && vy > 0)
-		{
-			vy -=0.2;
-		}
-
-		if (ry >= (600-size))
-			vy *= -1;
-		
-		rx += vx;
-		ry += vy;
-		setX((int) rx);
-		setY((int) ry);
-	}
 	
 	//** Getters and Setters **//
 	
@@ -79,10 +38,6 @@ public class Ball {
 		return size/20;
 	}
 
-	public int getBounceHeight() {
-		return bounceheight;
-	}
-
 	public int getX() {
 		return (int) bal.getX();
 	}
@@ -111,16 +66,15 @@ public class Ball {
 		bal.setFrame(getX(), y, getWidth(), getHeight());
 	}
 	
-	public void setDirection(int d){
-		if(d == -1 || d == 1){
-			direction = d;
-			vx = d*3;
-		}
+	public void setSize(int size){
+		bal.setFrame(getX(), getY(), size, size);
 	}
 	
-	public double getYSpeed()
-	{
-		return vy;
+	public void updateInfo(int x, int y, Color color, int size){
+		setX(x);
+		setY(y);
+		this.color = color;
+		setSize(size*20);
 	}
 	
 }

+ 8 - 41
src/model/objects/DrawObject.java

@@ -8,8 +8,6 @@ import java.awt.image.BufferedImage;
 public class DrawObject {
 	
 	protected Point2D position;
-	protected double scale;
-	protected double rotation;
 	protected BufferedImage image;
 	
 	public DrawObject(BufferedImage image)
@@ -17,33 +15,22 @@ public class DrawObject {
 		this.image = image;
 		
 		position = new Point2D.Double(0,0);
-		scale = 1;
-		rotation = 0;
 	}
 	
 	public void paint(Graphics2D g2d)
 	{
-		g2d.drawImage(image, getTransform(), null);
+		g2d.drawImage(image, getX(),getY(),getWidth(),getHeigth(), null);
 	}
 	
 	public void update(){};
 	
-	private AffineTransform getTransform()
-	{
-		AffineTransform tx = new AffineTransform();
-		tx.translate(position.getX(), position.getY());
-		tx.scale(scale, scale);
-		tx.rotate(rotation, image.getWidth()/2, image.getHeight()/2);
-		return tx;
-	}
-	
 	/* Helper Functions */
 	
-	public void setX(double x)
+	public void setX(int x)
 	{
 		position.setLocation(x, position.getY());
 	}
-	public void setY(double y)
+	public void setY(int y)
 	{
 		position.setLocation(position.getX(), y);
 	}
@@ -56,38 +43,18 @@ public class DrawObject {
 		position.setLocation(x, y);
 	}
 	
-	public void setRotation(double r)
-	{
-		this.rotation = r;
-	}
-	public void setScale(double s)
-	{
-		this.scale = s;
-	}
-	
-	
-	public double getX()
+	public int getX()
 	{
-		return position.getX();
+		return (int)position.getX();
 	}
-	public double getY()
+	public int getY()
 	{
-		return position.getY();
+		return (int)position.getY();
 	}
 	public Point2D getPosition()
 	{
 		return position;
-	}
-	
-	public double getRotation()
-	{
-		return rotation;
-	}
-	public double getScale()
-	{
-		return scale;
-	}
-	
+	}	
 	public int getWidth()
 	{
 		return image.getWidth();

+ 18 - 18
src/model/objects/Player.java

@@ -25,7 +25,6 @@ public class Player extends DrawObject {
 		beginlocation = new Point2D.Double(x,y);
 		this.name = name;
 		spriteimage = image;
-		health = 5;
 		powerups = new ArrayList<PowerUp>();
 	}
 	
@@ -39,23 +38,7 @@ public class Player extends DrawObject {
 			image = spriteimage.getSubimage(2+(((frame / 4) % 4) * 38), 54*lastDirection, 38, 50);
 		}
 	}
-	
-	public void walkLeft(){
-		if(getX() - speed > 10){
-			setX(getX()-speed);
-			lastDirection = 1;
-			lastMovement = System.currentTimeMillis();	
-		}
-	}
-	
-	public void walkRight(){
-		if(getX() + getWidth() + speed < Window.WIDTH -10){
-			setX(getX()+speed);
-			lastDirection = 2;
-			lastMovement = System.currentTimeMillis();
-		}
-	}
-	
+		
 	public void reset(){
 		setPosition(beginlocation);
 		speed = 10;
@@ -83,4 +66,21 @@ public class Player extends DrawObject {
 		this.health = health;
 	}
 	
+	public void setX(int x){
+		if(x < getX())
+			lastDirection = 1;
+		else if(x > getX())
+			lastDirection = 2;	
+		if(x != getX())
+			lastMovement = System.currentTimeMillis();
+		super.setX(x);
+	}
+		
+	public int getSpeed() {
+		return speed;
+	}
+	
+	public void setSpeed(int speed){
+		this.speed = speed;
+	}
 }

+ 17 - 0
src/model/objects/ShootingLine.java

@@ -35,10 +35,27 @@ public class ShootingLine {
 	
 	//** Getters and Setters **//
 	
+	
 	public int getLength(){
 		return length;
 	}
 	
+	public int getStartx() {
+		return startx;
+	}
+
+	public void setStartx(int startx) {
+		this.startx = startx;
+	}
+
+	public int getStarty() {
+		return starty;
+	}
+
+	public void setStarty(int starty) {
+		this.starty = starty;
+	}
+
 	public int getMaxHeight(){
 		return starty - length * 30;
 	}

+ 1 - 1
src/model/state/MenuState.java

@@ -34,7 +34,7 @@ public class MenuState extends State {
 
 	@Override
 	public void paint(Graphics2D g2) {
-		g2.drawString("Press ENTER to start the game", Window.WIDTH/2, Window.HEIGHT/2);
+		g2.drawString("Fill in your name and press ENTER to start the game", Window.WIDTH/2, Window.HEIGHT/2);
 	}
 	
 	

+ 83 - 143
src/model/state/PlayState.java

@@ -3,110 +3,57 @@ package model.state;
 import java.awt.Color;
 import java.awt.Graphics2D;
 import java.awt.event.KeyEvent;
-import java.io.File;
 import java.io.IOException;
-import java.nio.file.Files;
 import java.util.ArrayList;
-import java.util.Collection;
-import java.util.ConcurrentModificationException;
-import java.util.List;
-import java.util.ListIterator;
 
 import model.GameStateManager;
 import model.InfoPanel;
-import model.levels.Level;
+import model.NetworkConnection;
 import model.objects.Ball;
 import model.objects.Player;
 import model.objects.ShootingLine;
 import resources.image.Images;
 import resources.image.Images.ImageType;
-import server.Main;
 
 public class PlayState extends State{
 	
-	private Player player;
+	private Player player1;
 	private Player player2;
-	private ShootingLine line;
+	private ShootingLine line1;
+	private ShootingLine line2;
 	private ArrayList<Ball> balls;
-	private ArrayList<Level> levels;
 	private InfoPanel infopanel;
-	private int direction;
-	
-	private int currentlevel;
-	private int timeleft;
-	private long lasttime;
+	private NetworkConnection nwc;
+	private int timeleftpercent, direction, shoot;
 	
 	public PlayState(GameStateManager gsm) {
 		super("play", gsm);
-		player = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, "Janco");
-		player2 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, "Kenneth");
-		infopanel = new InfoPanel(player, player2, this);
+		player1 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, "");
+		player2 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, "");
+		infopanel = new InfoPanel(this);
 		balls = new ArrayList<Ball>();
-		readLevelsFromFiles();
-		playLevel(levels.get(currentlevel));
 	}
 
 	
-	/* LEVEL FILE READING, PARSING AND PLAYING */
-
-	private void readLevelsFromFiles(){
-		levels = new ArrayList<>();
-		File root = new File(Main.class.getResource("/model/levels").getPath());
-        File[] list = root.listFiles();
-        for ( File f : list ) {
-        	if(f.isFile() && f.getName().endsWith(".bb")){
-        		try {
-					levels.add(readLevel(Files.readAllLines(f.toPath())));		
-				}catch (IOException | IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) {
-					System.out.println("Level file corrputed");
-					e.printStackTrace();
-				}
-        	}
-        }
-	}
-	
-	private Level readLevel(List<String> levelfile) throws NumberFormatException, IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException{
-		Level level = new Level();
-		if(levelfile.size() == 3){
-			String[] ballsstrings = levelfile.get(0).split("\\|"); //split all the balls
-			for(String ball:ballsstrings){
-				String[]ballstring = ball.split(",");
-				if(ballstring.length == 7){
-					level.addBall(new Ball(
-										Integer.parseInt(ballstring[0]), 
-										Integer.parseInt(ballstring[1]),
-										(Color)Color.class.getField(ballstring[2]).get(null),
-										Integer.parseInt(ballstring[3]),
-										Integer.parseInt(ballstring[4]),
-										Integer.parseInt(ballstring[5]),
-										Double.parseDouble(ballstring[6])
-										)
-								);
-				}
-			}
-			
-			String[] powerupsstring = levelfile.get(1).split("\\|");
-			
-			level.setTime(Integer.parseInt(levelfile.get(2)));
-		}
-		return level;
+	/* NETWORK CONTROL */
+	public void newMatch(String p1, String p2){
+		player1 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, p1);
+		player2 = new Player(Images.getImage(ImageType.PLAYER1), 40, 550, p2);
+		infopanel = new InfoPanel(this);
+		balls = new ArrayList<Ball>();
 	}
 	
-	public void playLevel(Level level){
-		balls.clear();
-		for(Ball b:level.getStartballs()){
-			balls.add(b.clone());
-		}
-		timeleft = level.getTime();
-		player.reset();
-		line=null;	
-		lasttime = System.currentTimeMillis();
-	}
+
 	
 	/* INIT AND EXIT */
 	@Override
 	public void init() {
-		playLevel(levels.get(0));
+		nwc = new NetworkConnection(this);
+		try {
+			nwc.connect("Janco");
+		} catch (IOException e) {
+			e.printStackTrace();
+		}
 	}
 	
 	@Override 
@@ -115,89 +62,78 @@ public class PlayState extends State{
 	}
 
 	
-	/* UPDATE */
+	/* UPDATE AND PAINTING*/
+	public void updatePlayerInfo(int x, int y, int health, int speed, int score, Player player){
+		player.setX(x);
+		player.setY(y);
+		player.setHealth(health);
+		player.setScore(score);
+	}
+	public void updateLines(int l1x, int l1y, int l1h, int l2x, int l2y, int l2h){
+		if(line1 == null)
+			line1 = new ShootingLine(l1x, l1y);
+		line1.setLength(l1h);
+		line1.setStartx(l1x);
+		line1.setStarty(l1y);
+		if(line2 == null)
+			line2 = new ShootingLine(l2x, l2y);
+		line2.setLength(l2h);
+		line2.setStartx(l2x);
+		line2.setStarty(l2y);
+	};
+	
 	@Override
 	public void update() {		
-		if(direction == 1)
-			player.walkRight();
-		else if(direction == -1)
-			player.walkLeft();
-		player.update();
-		if(line != null){
-			line.setLength(line.getLength()+1);
-			if(line.getMaxHeight() < 0){ 										//Line hit the ceiling, so "remove" it
-				line = null;
-			}
-		}
-		
-		//Collision detection
-		try{
-			ListIterator<Ball> b = balls.listIterator(); 
-			while(b.hasNext()){
-				Ball bal = b.next(); 
-				if(line != null && bal.hitLine(line)){								// Collision between line and ball
-					line = null;
-					b.remove();
-					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), -1, Math.abs(bal.getYSpeed())*-1));
-					b.add(new Ball(bal.getSize()-1, (int) Math.max(bal.getBounceHeight()/1.5, player.getHeigth() +5), bal.getColor(), bal.getX(), bal.getY(), 1, Math.abs(bal.getYSpeed())*-1));
-				}else if(bal.hitPlayer(player)){														// Collision between player and ball
-					player.setHealth(player.getHealth()-1);
-					playLevel(getCurrentLevel());
-				}else if(bal.getSize() <= 0 ){															// Remove ball from arraylist when size is 0 (not visible)
-					b.remove();
-				}else{
-					bal.update();
-				}
-			}
-		}catch(ConcurrentModificationException e){
-			
-		}
-		timeleft -= (System.currentTimeMillis() - lasttime);
-		if(balls.size() == 0){
-			if(player.getHealth() > 0)
-				player.setScore(player.getScore()+(timeleft/100));
-			else
-				player.setScore(player.getScore()+(timeleft/100)/2);
-			
-			if(player2.getHealth() > 0)
-				player2.setScore(player2.getScore()+(timeleft/100));
-			else
-				player2.setScore(player2.getScore()+(timeleft/100)/2);
-			
-			if(currentlevel+1 >= levels.size())
-				gsm.setState("end");
-			else
-				playLevel(levels.get(currentlevel+=1));
-		}else if(timeleft < 0){
-			player.setHealth(player.getHealth()-1);
-			playLevel(getCurrentLevel());
-		}else if(player.getHealth() <= 0) {
-			gsm.setState("end");
-		}
-		lasttime = System.currentTimeMillis();		
+		player1.update();
+		player2.update();
 	}
 
 	@Override
 	public void paint(Graphics2D g2d) {	
 		g2d.drawImage(Images.getImage(ImageType.BACKGROUND),null,0,0);
-		if(line != null){
-			line.paint(g2d);
+		if(line1 != null){
+			line1.paint(g2d);
+		}
+		if(line2 != null){
+			line2.paint(g2d);
 		}
 		for(Ball b: balls){
 			b.paint(g2d);
 		}
-		player.paint(g2d);
+		player1.paint(g2d);
+		player2.paint(g2d);
 		infopanel.paint(g2d);
 	}
 
 	/* GETTERS AND SETTERS */
 	
-	public Level getCurrentLevel(){
-		return levels.get(currentlevel);
+	public Player getPlayer1(){
+		return player1;
+	}
+	
+	public Player getPlayer2(){
+		return player2;
 	}
 	
-	public int getTimeleft() {
-		return timeleft;
+	public int getTimeleftpercent() {
+		return timeleftpercent;
+	}
+		
+	public Ball getBall(int i){
+		try{
+			return balls.get(i);
+		}catch(IndexOutOfBoundsException e){
+			balls.add(i, new Ball());
+			return balls.get(i);
+		}
+	}
+	
+	public ArrayList<Ball> getBalls(){
+		return balls;
+	}
+	
+	public void setTimeleftpercent(int timeleftpercent) {
+		this.timeleftpercent = timeleftpercent;
 	}
 	
 	/* EVENTS */
@@ -212,10 +148,10 @@ public class PlayState extends State{
 			direction = -1;
 			break;
 		case KeyEvent.VK_SPACE:
-			if(line == null){
-				line = new ShootingLine((int)player.getX()+player.getWidth()/2, 600);
-			}
+			shoot = 1;
+			break;
 		}
+		nwc.sendInput(direction, shoot);
 	}
 	@Override
 	public void keyReleased(KeyEvent e) {
@@ -226,10 +162,14 @@ public class PlayState extends State{
 		case KeyEvent.VK_LEFT:
 			direction = 0;
 			break;
+		case KeyEvent.VK_SPACE:
+			shoot = 0;
+			break;
 		case KeyEvent.VK_ESCAPE:
 			gsm.setState("menu");
 			break;
 		}
+		nwc.sendInput(direction, shoot);
 	}
 	@Override
 	public void keyTyped(KeyEvent e) {};