Man, this class is pretty... tough!

Lecture Notes Five: Anatomy of a Simple Networked Game


Adding a puck, with collisions. Hockey as pinball. More 3D. Plans.

Before Spring Break we will have a complete 3D game working.

Meanwhile we need to keep working at the basics.

Besides trying to understand App3DCore we also want to finish the Hockey game.

We will add a puck and implement collisions today.

Here's also a game like Jason wants to implement.

You can find it in

/l/www/classes/a348/t540/lectures/Cannon
where you can find anything we present in this class.

The URL for this game is on the What's New? page.

Let's start from a basic working version of the Hockey program.

I am putting the starting point in

/l/www/classes/a348/t540/lectures/Hockey
Here's what you will find there.

frilled.cs.indiana.edu%pwd
/nfs/grouchy/home/user2/www/classes/a348-dger/t540/lectures/Hockey
frilled.cs.indiana.edu%du -a
4	./ChatClient.java
1	./.java.policy
1	./ClientExports.java
3	./ChatServer.java
1	./Player.java
3	./ChatClient.class
1	./ServerExports.java
1	./ClientExports.class
1	./Player.class
1	./ServerExports.class
3	./ChatServer.class
3	./ChatClient_Stub.class
2	./ChatClient_Skel.class
4	./ChatServer_Stub.class
2	./ChatServer_Skel.class
32	.
frilled.cs.indiana.edu%
(You will need all of this).

Here's how you get all you need.

burrowww.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/pucka
burrowww.cs.indiana.edu% cp /l/www/classes/a348/t540/lectures/Hockey/* .
burrowww.cs.indiana.edu% du -a . 
3       ./ChatClient.class
4       ./ChatClient.java
2       ./ChatClient_Skel.class
3       ./ChatClient_Stub.class
3       ./ChatServer.class
3       ./ChatServer.java
2       ./ChatServer_Skel.class
4       ./ChatServer_Stub.class
1       ./ClientExports.class
1       ./ClientExports.java
1       ./Player.class
1       ./Player.java
1       ./ServerExports.class
1       ./ServerExports.java
31      .
burrowww.cs.indiana.edu% cp /l/www/classes/a348/t540/lectures/Hockey/.jav* ~
burrowww.cs.indiana.edu% ls -ld ~/.jav*
-rw-r--r--   1 dgerman  faculty        73 Feb 21 11:07 /u/dgerman/.java.policy
burrowww.cs.indiana.edu% cat ~/.jav*
grant {
  permission java.net.SocketPermission "*", "connect,accept";
};
burrowww.cs.indiana.edu% 
Make sure all of this works:

Once we are sure this works, let's start making the changes.

We want the server to move a Puck around.

So we make the changes,

import java.rmi.*;
// ... 

public class ChatServer extends UnicastRemoteObject 
                        implements ServerExports {
    
    // ... 
    
    Puck puck; 

    // ... 
    
    public ChatServer() throws RemoteException {
        // ... 
	puck = new Puck(ChatClient.WIDTH, ChatClient.HEIGHT, this); 
	System.out.println("Puck has been initialized... "); 
	puck.start(); 
    }
    
    // ... 

}

class Puck extends Thread {
    int width, height;
    ChatServer server; 
    Puck(int w, int h, ChatServer s) {
	width = w; height = h; 
        server = s; 
    }
    public void run() {
	while (true) {
	    try {

		System.out.println("I am the puck..."); 
		Thread.sleep(1000); 

	    } catch(Exception e) {

	    }
	}
    }
}
and then recompile:

tucotuco.cs.indiana.edu% pwd
/nfs/paca/home/user1/dgerman/pucka
tucotuco.cs.indiana.edu% javac *.java
Note: ChatClient.java uses or overrides a deprecated API.  Recompile with "-deprecation" for details.
1 warning
tucotuco.cs.indiana.edu% rmic ChatClient
tucotuco.cs.indiana.edu% rmic ChatServer
tucotuco.cs.indiana.edu%
Now the puck becomes more complex.

class Puck extends Thread {
    int width, height;
    int x, y; 
    ChatServer server; 
    Puck(int w, int h, ChatServer s) {
	width = w; height = h; 
	server = s; 
    }
    public void run() {
	while (true) {
	    try {
		System.out.println("I am the puck..." + this.report()); 
		this.move(); 
		Thread.sleep(1000); 

	    } catch(Exception e) {

	    }
	}
    }
    int dx = 3, dy = 3; 
    public void move() {
	x += dx; 
	y += dy; 
	if (x < 0) { x = 0; dx = -dx; } 
	else if (x > width) { x = width; dx = -dx; } 
	if (y < 0) { y = 0; dy = -dy; } 
	else if (y > height) { y = height; dy = -dy; } 

    }
    public String report() {
	return "(" + this.x + ", " + this.y + ")"; 
    }
}
Our next goal would be for the clients to report this.

// ... 

public class ChatServer extends UnicastRemoteObject 
                        implements ServerExports {

    // ...     

    public void notify(int x, int y) {
	System.out.println("I am the server, the puck's at: (" + 
			   x + ", " + y + ")"); 
	for (int i = 0; i <= size; i++) {
	    // check for collisions with players[i] 
	}

	for (int i = 0; i <= size; i++) {
	    try { 
		clients[i].updatePuckPosition(x, y); 
	    } catch (Exception e) {

	    }
	}

    }
    
    // ... 

}

class Puck extends Thread {

    // ...

    public String report() {
	server.notify(x, y); 
	return "(" + this.x + ", " + this.y + ")"; 
    }

    // ... 
}

// ... 

public class ChatClient extends Frame implements ClientExports, 
						 KeyListener {

    // ... 

    public void updatePuckPosition(int x, int y) {
	System.out.println("I am a client, the puck is at: (" + 
			   x + ", " + y + ")"); 
    }
    
    // ... 

}

// ... 

public interface ClientExports extends Remote {
    // ...
    public void updatePuckPosition(int x, int y) throws RemoteException; 
}
Check that this works, then let's represent the puck in the client.

I'll explain the last part in class.

I will also use the following notes:

http://www.cs.indiana.edu/classes/a348/t540/lectures/Feb21.html
They will contain the material for the 3D experiments that we will undertake today.

The final code is in

/l/www/classes/a348/t540/lectures/ten/hockey


Last updated: Feb 21, 2002 by Adrian German for T540