APPENDIX B

MARBLES WORLD CLIENT CODE

import java.awt.*;

import java.applet.*;

import java.util.*;

import java.io.*;

import java.net.*;

import java.util.Date;

import vrml.external.field.*;

import vrml.external.Node;

import vrml.external.Browser;

import vrml.external.exception.*;

import netscape.javascript.JSObject;

import dtai.net.*;

 

//  ball.e is currently as follows:

//  #

//  0 - no effect

//  1 - non-collidable

//  2 - anti-gravity

//  3 - stop

//  4 - goal stealing

//  5 - add a fence

//  6 - bigger

 

//-------------------------------------------------------------------

//  This is the main applet class

 

public class Marbles extends Applet implements EventOutObserver  {

 

  TextArea output = null;

  //Main Window for Controls

  MainWindow b;

  // Browser we're using

  Browser browser;

  // Root of the scene graph (to which we add our clumps)

  Node board = null;

  Node pointer = null;

  Node designer  = null;

  Node sides  = null;

  Node slant = null;

  Node pitem[] = {null,null,null,null,null,null,null};

  Node slqu[] = {null,null,null,null};

  Node material = null;



  EventInSFColor diffuseColor = null;

  EventInMFNode addPI[] = {null,null,null,null,null,null,null};

  EventInMFNode removePI[] = {null,null,null,null,null,null,null};

  EventInMFNode addslqu[] = {null,null,null,null};

  EventInMFNode removeslqu[] = {null,null,null,null};

  Node gl[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInMFNode addGoal[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInMFNode removeGoal[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  Node sensor[] = {null,null,null,null,null,null,null};

  Node slantSensor[] = {null,null,null,null};

  Node wrapSensor = null;

  Node root[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInMFNode addChildren[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventOutSFVec3f translation_changed[] = {null,null,null,null,null,null,null,null,null,null};

  EventOutSFVec3f pointer_changed = null;

  EventInSFVec3f pointer_translation = null;

  EventInMFNode addSides = null;

  EventInMFNode removeSides = null;

  EventInMFNode removeChildren[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInSFVec3f set_translation[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInSFVec3f slant_translation = null;

  EventInSFVec3f set_scale[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  EventInSFRotation slant_rotation = null;

  EventOutSFTime touchTime[] = {null,null,null,null,null,null,null};

  EventOutSFTime slantTouchTime[] = {null,null,null,null};

  EventOutSFTime wrapTouchTime = null;

  EventOutSFVec3f hitb = null;

  EventOutSFVec3f hitt = null;

  Node[] goalshape[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  Node[] pshape[] = {null,null,null,null,null,null,null,null,null,null};

  Node[] qshape[] = {null,null,null,null};

  Node[] shape = null;

  Node[] bumpers = null;

  Node[] pieceshape[] = {null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null};

  int marker=0;

  int newpiecex=0, newpiecey=0;

  int curnode=0;

  int curtype=0;

  double hitpoint[] = {0.0,0.0,0.0,0.0};

  float offsetx=0.0f,offsety=0.0f,oldx=0.0f,oldy=0.0f,oldz=0.0f;

  int mode = 0;

  boolean speedtest=true;  //test the speed of the animator for each client

  int qno = 103;

  boolean designing = false;

  int lastmodesent = 0;

  Player[] player = new Player[4];  // array of players

  int pn; //client player number

  int nump=0;

  int numplay=0;

  int turncolor=1;

  int sim_type=1;

  public final static int PORT=8765;

  PieceList pl = new PieceList(7);

  EffectList el = new EffectList(7);

  Image image[]={null,null,null,null,null,null,null};

  PortToServer pts;

 

  public void init() {

 

    //

    // Initialize connection to Cosmo Player

    //

 

    JSObject win = JSObject.getWindow(this);

    JSObject doc = (JSObject) win.getMember("document");

    JSObject embeds = (JSObject) doc.getMember("embeds");

    browser = (Browser) embeds.getSlot(0);

 

    try {

 

    pts = new PortToServer(this.getCodeBase().getHost(),PORT,this);

    pts.start();

      for(int x=0;x<100;x++) {

         root[x] = browser.getNode("T" + x);

         addChildren[x] = (EventInMFNode) root[x].getEventIn("addChildren");

         removeChildren[x] = (EventInMFNode) root[x].getEventIn("removeChildren");

         set_translation[x] = (EventInSFVec3f) root[x].getEventIn("translation");

         set_scale[x] = (EventInSFVec3f) root[x].getEventIn("scale");

      }

      for(int x=0;x<4;x++) {

         slantSensor[x] = browser.getNode("SS" + x);

         slantTouchTime[x] = (EventOutSFTime) slantSensor[x].getEventOut("touchTime");

         slantTouchTime[x].advise(this, new Integer(10 + x));

         slqu[x] = browser.getNode("SQ" + x);

         addslqu[x] = (EventInMFNode) slqu[x].getEventIn("addChildren");

         removeslqu[x] = (EventInMFNode) slqu[x].getEventIn("removeChildren");

      }

      for(int x=0;x<7;x++) {

         pitem[x] = browser.getNode("PI" + x);

         addPI[x] = (EventInMFNode) pitem[x].getEventIn("addChildren");

         removePI[x] = (EventInMFNode) pitem[x].getEventIn("removeChildren");

      }

      for(int x=0;x<30;x++) {

         gl[x] = browser.getNode("G" + x);

         addGoal[x] = (EventInMFNode) gl[x].getEventIn("addChildren");

         removeGoal[x] = (EventInMFNode) gl[x].getEventIn("removeChildren");

      }

      board = browser.getNode("TSB");

      slant = browser.getNode("BOARD");

      wrapSensor = browser.getNode("WRAP");

      wrapTouchTime = (EventOutSFTime) wrapSensor.getEventOut("touchTime");

      wrapTouchTime.advise(this, new Integer(14));

      pointer = browser.getNode("T100");

      pointer_translation = (EventInSFVec3f) pointer.getEventIn("translation");

      slant_rotation = (EventInSFRotation) slant.getEventIn("rotation");

      slant_translation = (EventInSFVec3f) slant.getEventIn("translation");

      pointer_changed = (EventOutSFVec3f) pointer.getEventOut("translation_changed");

      designer = browser.getNode("TSD");

      sides = browser.getNode("SIDES");

      addSides = (EventInMFNode) sides.getEventIn("addChildren");

      removeSides = (EventInMFNode) sides.getEventIn("removeChildren");

      for(int x=0;x<7;x++) {

         sensor[x] = browser.getNode("TS" + x);

         touchTime[x] = (EventOutSFTime) sensor[x].getEventOut("touchTime");

         touchTime[x].advise(this, new Integer(x+1));

      }

      // Get the material node...

      material = browser.getNode("MAT");

      // Get the diffuseColor EventIn

      diffuseColor = (EventInSFColor) material.getEventIn("set_diffuseColor");

      // Get Hit Point for Board

      hitb = (EventOutSFVec3f) board.getEventOut("translation_changed");

      hitt = (EventOutSFVec3f) designer.getEventOut("hitPoint_changed");

      // Set up the callback

      hitb.advise(this, new Integer(0));

      hitt.advise(this, new Integer(7));

    }

    catch (InvalidVrmlException e) {

      showStatus("PROBLEMS!: " + e);

    }

    catch (InvalidEventInException e) {

      showStatus("PROBLEMS!: " + e);

    }

    catch (InvalidEventOutException e) {

      showStatus("PROBLEMS!: " + e);

    }

    catch (IOException e) {

      showStatus("PROBLEMS!: " + e.toString());

    }

 

    b = new MainWindow("Controls",true,this);

    b.resize(250,480);

    if(sim_type==0) {b.show();}

    b.start();

 

    for(int x=0;x<4;x++) {

        addPlayer(new Player());

    }

    for(int ww=0;ww<4;ww++) {

        addSlQu(ww,0,true);

    }

    for(int xx=1;xx<8;xx++) {

        pl.AddtoPieceList(xx);

        el.AddtoEffectList(xx);

    }

}

 

public void callback(EventOut who, double when, Object which) {

    Integer whichNum = (Integer) which;

 

if (whichNum.intValue()>0 && whichNum.intValue()<10 ) {

       if(!designing && turncolor==pn && sim_type==0){

          float[] val = hitb.getValue();

          offsetx = val[0];

          offsety = val[1];

          UpdatePointer(0,0,0,30,0,0,0,0);

          oldx = 0;

          oldy = 0;

       }

    }

    if (whichNum.intValue()==0) {

          float[] val = hitb.getValue();

          UpdateVRML(4,curnode,oldx,oldy,oldz,val[0],val[1],offsetx,offsety);

          UpdatePointer(1,oldx,oldy,oldz,val[0],val[1],offsetx,offsety);

    }

    else if (whichNum.intValue()>0 && whichNum.intValue()<8) {

       int iv=whichNum.intValue()-1;

       if (mode==1 && !designing && pl.l[iv]>0 && turncolor==pn && sim_type==0) {

           if(pl.l[iv]==1 || pl.l[iv]==6 || pl.l[iv]==7) {

               curnode=b.anim.num;

           } else {

               curnode=50+b.anim.numo;

           }

           curtype=pl.l[iv];

           addNode(curnode,curtype,0,0,0,0,0);

           designing = true;

       } else if (mode==2) {

           b.anim.ars.AddToArsenal(el.l[iv]);

       } else if (mode==3){

           String eventstring = "3" + ((100*pn) + b.anim.ars.TakeFromArsenal(iv));

           eventstring = eventstring + (b.anim.count+b.anim.eql);

           pts.writeToServer(eventstring);

           ReplaceNode(0,iv,LoadString());

           eventstring = "3" + (100*pn);

           eventstring = eventstring + (b.anim.count+b.anim.eqd);

           pts.writeToServer(eventstring);

       }

    }

    else if (whichNum.intValue()>=10 && whichNum.intValue()<=13) {  //if animating, slant added to queue

        if(mode==1 && lastmodesent==0) { //ignore request for mode change if already made a request -- only server updates mode

            pts.writeToServer("92");

            lastmodesent++;

            //Paletize(2);

        }

        else if(mode==2 && lastmodesent==1) {

            pts.writeToServer("93");

            if(designing==true) {

                  removeChildren[curnode].setValue(pieceshape[curnode]);

                  designing=false;

            }

            UpdatePointer(0,0,0,30,0,0,0,0);

            lastmodesent++;

            Bumpers(1);

            b.anim.wrapon = false;

            //Paletize(3);

        }

        else if(mode==3&&turncolor==pn) {

            pts.writeToServer("2" + (whichNum.intValue()-9));

        }

    }

    else if (whichNum.intValue()==14) {

         if(mode==0) {

              pts.writeToServer("6" + pn);  //request goals for next round

              Paletize(1);

              mode=1;

              UpdateColor(0,turncolor);

              //Four Corner Balls

              b.anim.ball[0].x=500; b.anim.ball[0].y=100; b.anim.ball[0].m=b.anim.bm;

              addNode(0,0,20,1,1,0,0);             

              //if(b.anim.rules.roundtype==0) { addNode(0,0,20,1,1,0,0); }

              //else if(b.anim.rules.roundtype==1) { addNode(0,0,20,0,1,0,0); }

              //else if(b.anim.rules.roundtype==2) { addNode(0,0,20,0,0,1,0); }

              b.anim.ball[1].x=100; b.anim.ball[1].y=500; b.anim.ball[1].m=b.anim.bm;

              addNode(1,0,20,1,0,0,0);

              //if(b.anim.rules.roundtype==0) { addNode(1,0,20,1,0,0,0); }

              //else if(b.anim.rules.roundtype==1) { addNode(1,0,20,.6,1,0,0); }

              //else if(b.anim.rules.roundtype==2) { addNode(1,0,20,1,0,0,0); }

              b.anim.ball[2].x=900; b.anim.ball[2].y=500; b.anim.ball[2].m=b.anim.bm;

              addNode(2,0,20,0,0,1,0);

              //if(b.anim.rules.roundtype==0) { addNode(2,0,20,0,0,1,0); }

              //else if(b.anim.rules.roundtype==1) { addNode(2,0,20,0,1,.6,0); }

              //else if(b.anim.rules.roundtype==2) { addNode(2,0,20,1,.4,0,0); }

              b.anim.ball[3].x=500; b.anim.ball[3].y=900; b.anim.ball[3].m=b.anim.bm;

              addNode(3,0,20,0,1,0,0);

              //if(b.anim.rules.roundtype==0) { addNode(3,0,20,0,1,0,0); }

              //else if(b.anim.rules.roundtype==1) { addNode(3,0,20,0,1,.4,0); }

              //else if(b.anim.rules.roundtype==2) { addNode(3,0,20,0,.6,1,0); }

         }

         else if(mode>1) {

              //Do nothing

         } else {

              if(sim_type==0) {

                  removeChildren[curnode].setValue(pieceshape[curnode]);

                  pts.writeToServer("4" + pn + "" + curtype + (100 + curnode) + (1000 + newpiecex) + (1000 + newpiecey));

                  designing = false;

              }

         }

    }

}

 

public String LoadString() {

     String shapestring;

 

     shapestring  =  "Transform {\n" +

                     "  children [\n" +

                     "      Shape {\n" +

                     "         appearance Appearance {\n";

     shapestring = shapestring +  "   material Material { diffuseColor " + b.anim.ps.GetPiecesString(0);

     shapestring = shapestring + "    }\n]}\n";

     return shapestring;

}

 

public void UpdateVRML (int f, int m, float x, float y, float z, float px, float py, float opx, float opy) {

  float[] val = new float[3];

  if(f==0) {

      val[0] = 6.0f;

      val[1] = y + py - opy;

      val[2] = z - px + opx;

      set_translation[m].setValue(val);

  }

  else if (f==1 || f==4) {

      val[0] = x + px - opx;

      val[1] = y + py - opy;

      if (m==101){

         val[2] = z;

         slant_translation.setValue(val);

      } else {

         val[2] = 0.35f;

         set_translation[m].setValue(val);

      }

      if(f==4) {

         newpiecex = (int)val[0];  //prepare for final location to send to other players

         newpiecey = (int)val[1];

      }

  }

  else if (f==2) {

      val[0] = 0.0f;

      val[1] = 0.0f;

      val[2] = -400.0f;

      slant_translation.setValue(val);

  }

  else if (f==3) {

      val[0] = x;

      val[1] = y;

      val[2] = 0.35f;

      set_translation[m].setValue(val);