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);
}
}
public
void UpdatePointer (int f, float x, float y, float z, float px, float py, float
opx, float opy) {
float[] val = new float[3];
if(f==0) {
val[0] = 0.0f;
val[1] = 0.0f;
val[2] = z;
pointer_translation.setValue(val);
}
else if (f==1) {
val[0] = x + px - opx;
val[1] = y + py - opy;
val[2] = 30.0f;
pointer_translation.setValue(val);
}
}
public
void UpdateRotation (int m, int f) {
float[] val = new float[4];
if (f==0) {
val[0] = 1.0f;
val[1] = 0.0f;
val[2] = 0.0f;
val[3] = -0.4f;
slant_rotation.setValue(val);
}
else if (f==1) {
val[0] = 0.0f;
val[1] = 1.0f;
val[2] = 0.0f;
val[3] = 0.4f;
slant_rotation.setValue(val);
}
else if (f==2) {
val[0] = 1.0f;
val[1] = 0.0f;
val[2] = 0.0f;
val[3] = 0.4f;
slant_rotation.setValue(val);
}
else if (f==3) {
val[0] = 0.0f;
val[1] = 1.0f;
val[2] = 0.0f;
val[3] = -0.4f;
slant_rotation.setValue(val);
}
else {
val[0] = 1.0f;
val[1] = 0.0f;
val[2] = 0.0f;
val[3] = 0.0f;
slant_rotation.setValue(val);
}
}
public
void UpdateColor (int m, int i) {
float[] val = new float[3];
if(i==0) {
val[0] = 1.0f;
val[1] = 1.0f;
val[2] = 1.0f;
}
else if (i==1) {
val[0] = 1.0f;
val[1] = 0.0f;
val[2] = 0.0f;
}
else if (i==2) {
val[0] = 0.0f;
val[1] = 0.0f;
val[2] = 1.0f;
}
else if (i==3) {
val[0] = 0.0f;
val[1] = 1.0f;
val[2] = 0.0f;
}
else if (i==4) {
val[0] = 1.0f;
val[1] = 1.0f;
val[2] = 0.0f;
}
else {
val[0] = 1.0f;
val[1] = 1.0f;
val[2] = 1.0f;
}
if(m==0) { diffuseColor.setValue(val); }
}
public
void UpdateScale (int i, float x) {
float[] val = new float[3];
val[0] = x;
val[1] = x;
val[2] = x;
set_scale[i].setValue(val);
}
public void Paletize(int mode) {
String shapestring = "";
int n=0;
int slot=0;
for(int nn=0;nn<7;nn++) {
if(mode==1) { n=pl.l[nn]; } else
if(mode==2) { n=el.l[nn]; } else { n=nn; }
shapestring =
"Transform {\n" +
" children [\n" +
" Shape {\n" +
" appearance Appearance {\n";
if(mode==1||mode==4) {
shapestring = shapestring
+ " material Material { diffuseColor " +
b.anim.ps.GetPiecesString(n);
} else if(mode==2) {
shapestring = shapestring
+ " material Material { diffuseColor " +
b.anim.es.GetEffectsString(n);
} else if (mode==3) {
shapestring = shapestring
+ " material Material { diffuseColor " +
b.anim.es.GetEffectsString(b.anim.ars.ReadFromArsenal(n));
}
if((mode==1||mode==4)&&n==4) {
shapestring = shapestring +
" }\n] rotation 0 0 1 .78
}\n";
} else
if((mode==1||mode==4)&&n==5) {
shapestring = shapestring +
" }\n] rotation 0 0 1 -.78
}\n";
} else {
shapestring = shapestring +
" }\n]}\n";
}
if(mode==1&&b.anim.round==1) {
ReplaceNode(2,slot++,shapestring);
} else {
ReplaceNode(0,slot++,shapestring);
}
}
}
public void addNode(int whichnode, int index,
double radius, double bx, double by, double ex, double ey) {
String shapestring = "";
try {
if(whichnode >= 100) { return; }
shapestring = "Transform
{\n" +
"
children [\n" +
" Shape {\n" +
" appearance Appearance {\n" +
" material Material { diffuseColor
";
if(index==1 || index==6) {
shapestring = shapestring +
b.anim.ps.GetPiecesString(index) +
" }\n" +
"] translation 0 0
15 }\n";
}
if(index==0) {
shapestring =
shapestring + " " + bx + " " + by + " " +
ex + " }\n" +
" }\n" +
" geometry Sphere {radius " +
radius + " }\n" +
" }\n" +
"]}\n";
}
else if(index==4) {
shapestring = shapestring +
b.anim.ps.GetPiecesString(2) +
" }\n" +
"] rotation 0 0 1
.78 }\n";
}
else if(index==5) {
shapestring = shapestring +
b.anim.ps.GetPiecesString(2) +
" }\n" +
"] rotation 0 0 1
-.78 }\n";
}
else {
shapestring = shapestring +
b.anim.ps.GetPiecesString(index) +
" }\n" +
"]}\n";
}
ReplaceNode(1,whichnode,shapestring);
curnode=whichnode;
}
catch (InvalidNodeException e) {
}
catch (InvalidEventInException e) {
}
catch (InvalidVrmlException e) {
}
}
public void ReplaceNode(int where, int ndx,
String str) {
String shapestring = "";
try {
if(where==0) { //Palette Piece Replace
removePI[ndx].setValue(pshape[ndx]);
pshape[ndx] =
browser.createVrmlFromString(str);
addPI[ndx].setValue(pshape[ndx]);
} else if(where==1) { //Add a Board
Piece
pieceshape[ndx] =
browser.createVrmlFromString(str);
addChildren[ndx].setValue(pieceshape[ndx]);
} else if(where==2) { //Pallete Piece
New
pshape[ndx] =
browser.createVrmlFromString(str);
addPI[ndx].setValue(pshape[ndx]);
}
}
catch (InvalidNodeException e) {
}
catch (InvalidEventInException e) {
}
catch (InvalidVrmlException e) {
}
}
public void addGoal(int whichgoal, int color,
double goalx, double goaly) {
String shapestring = "";
String colorstring = "";
try {
if(whichgoal >= b.anim.maxg) {
return; }
if(color==0) {
colorstring = "1 1 0";
}
else if (color==1) {
colorstring = "1 0 0";
} else if (color==2) {
colorstring = "0 0 1";
} else if (color==3) {
colorstring = "0 1 0";
} else colorstring = "0 0 0";
shapestring = "Transform
{\n" +
" children [\n" +
" Shape {\n" +
" appearance Appearance {\n" +
" material Material { diffuseColor
" + colorstring + " }\n"
+
" }\n" +
" geometry Cylinder {radius 20 height 5
}\n" +
" }\n" +
"] translation " +
goalx + " " + goaly + " 0 \n" +
" rotation 1 0 0 1.57 }\n";
goalshape[whichgoal] =
browser.createVrmlFromString(shapestring);
addGoal[whichgoal].setValue(goalshape[whichgoal]);
}
catch (InvalidNodeException e) {
}
catch (InvalidEventInException e) {
}
catch (InvalidVrmlException e) {
}
}
public void addSlQu(int whichslqu, int color,
boolean initial) {
String shapestring = "";
String colorstring = "";
String coordstring = "";
String transstring = "";
try {
if(whichslqu >= 4 || whichslqu <
0) {
return;
} else if (whichslqu==0) {
transstring = "-200 300 0";
} else if (whichslqu==1) {
transstring = "-200 400 0";
} else if (whichslqu==2) {
transstring = "-200 500 0";
} else {
transstring = "-200 600 0";
}
if (color==1) {
colorstring = "0 1 0";
coordstring = "point [ 0 0 25,
100 0 25, 100 100 -25, 0 100 -25 ]";
} else if (color==2) {
colorstring = "0 0 1";
coordstring = "point [ 0 0 25,
100 0 -25, 100 100 -25, 0 100 25 ]";
} else if(color==3) {
colorstring = "1 1 0";
coordstring = "point [ 0 0 -25,
100 0 -25, 100 100 25, 0 100 25 ]";
} else if (color==4) {
colorstring = "1 0 0";
coordstring = "point [ 0 0 -25,
100 0 25, 100 100 25, 0 100 -25 ]";
} else {
colorstring = "0 0 0
transparency 1";
}
if(!initial) {
removeslqu[whichslqu].setValue(qshape[whichslqu]);
}
shapestring = "Transform
{\n" +
" children [\n" +
" Shape {\n" +
" appearance Appearance {\n" +
" material Material { diffuseColor
" + colorstring + " }\n"
+
" }\n" +
" geometry IndexedFaceSet {\n" +
" coord Coordinate {\n" +
" " + coordstring +
"\n" +
" }\n" +
" coordIndex [ 0, 1, 2, 3 ]\n"
+
" }\n" +
" }\n" +
" ] translation " + transstring + "\n" +
"}\n";
qshape[whichslqu] =
browser.createVrmlFromString(shapestring);
addslqu[whichslqu].setValue(qshape[whichslqu]);
}
catch (InvalidNodeException e) {
}
catch (InvalidEventInException e) {
}
catch (InvalidVrmlException e) {
}
}
public void Bumpers(int whichmode) {
String colorstring = "";
if(pn==1){colorstring = " 1 0 0
";}
else if(pn==2){colorstring = " 0 0 1
";}
else if(pn==3){colorstring = " 0 1 0
";}
else if(pn==4){colorstring = " 1 1 0
";}
try {
if(whichmode == 1) { //Ball
bumpers =
browser.createVrmlFromString("Transform {\n" +
" children [\n" +
" Transform {\n" +
" children [\n" +
" DEF Bumper Shape {\n" +
" appearance Appearance {\n" +
" material Material { diffuseColor
" + colorstring + "}\n" +
" }\n" +
" geometry Box {}\n" +
" }\n" +
" ]\n" +
" scale 30 500 30\n" +
" translation -30 500 2\n" +
" },\n" +
" Transform {\n" +
" children [\n" +
" USE Bumper\n" +
" ]\n" +
" scale 30 500 30\n" +
" translation 1030 500 2\n" +
" },\n" +
" Transform {\n" +
" children [\n" +
" USE Bumper\n" +
" ]\n" +
" scale 560 30 30\n" +
" translation 500 1030 2\n" +
" },\n" +
" Transform {\n" +
" children [\n" +
" USE Bumper\n" +
" ]\n" +
" scale 560 30 30\n" +
" translation 500 -30 2\n" +
" },\n" +
"]}\n");
addSides.setValue(bumpers);
}
else {
removeSides.setValue(bumpers);
}
}
catch (InvalidNodeException e) {
}
catch (InvalidEventInException e) {
}
catch (InvalidVrmlException e) {
}
}
public void addPlayer(Player p) {
if (nump<4) player[nump++] = p;
}
public void stop() {
if (b!=null) b.stop();
}
//{{DECLARE_CONTROLS
//}}
}
//-------------------------------------------------------------------
// This class controls the main window
class
MainWindow extends Frame {
Animator anim;
Ticker tick;
Thread anim_thread;
Thread tick_thread;
boolean is_applet;
Marbles i;
MyFrame pwindow;
Scrollbar mgrav,fric,rest;
TextField grav;
Label
label1,label2,label3,label4,label5,label6,label7,label8,label9,inst;
Checkbox
trace,collide,mush,wrap,smooth,filled,cb1,cb2,cb3,cb4,cb5,cb6,cb7,cb8,cb9;
//
This method creates layout and main objects.
MainWindow(String title, boolean isapp,
Marbles i_in) {
super(title);
is_applet = isapp;
i = i_in;
Panel p = new Panel(); // control panel
Label n = new Label("Marbles
1.0");
p.setLayout(new GridLayout(0,1)); //
vertical layout
p.setFont(new
Font("Helvetica",Font.BOLD,12));
n.setFont(new
Font("TimesRoman",Font.BOLD,16));
p.add(n);
p.add(new Button("quit"));
p.add(inst=new Label(""));
p.add(grav=new TextField(40));
grav.setText("");
p.add(label1=new Label(""));
p.add(cb1=new Checkbox(""));
p.add(label2=new Label(""));
p.add(cb2=new Checkbox(""));
p.add(label3=new Label(""));
p.add(cb3=new Checkbox(""));
p.add(label4=new Label(""));
p.add(cb4=new Checkbox(""));
p.add(label5=new Label(""));
p.add(cb5=new Checkbox(""));
p.add(label6=new Label(""));
p.add(cb6=new Checkbox(""));
p.add(label7=new Label(""));
p.add(cb7=new Checkbox(""));
p.add(label8=new Label(""));
p.add(cb8=new Checkbox(""));
p.add(label9=new Label(""));
p.add(cb9=new Checkbox(""));
//Qgov();
Qctime();
tick = new Ticker(p); // pace maker for
the animator
anim = new Animator(tick,p,this);
setLayout(new BorderLayout(2,2));
add("Center",anim);
add("West",p);
pwindow = new MyFrame("Choose
Pieces",i);
pwindow.resize(400,480);
pwindow.hide();
}
//
This starts the threads.
public void start() {
if (anim_thread==null) {
anim_thread = new Thread(anim);
anim_thread.start(); //
start new thread
}
if (tick_thread==null) {
tick_thread = new Thread(tick);
tick_thread.start(); // start new thread
}
}
//
This stops the threads.
public void stop() {
if (anim_thread!=null) {
anim_thread.stop(); //
kill the thread
anim_thread = null; //
release object
}
if (tick_thread!=null) {
tick_thread.stop(); //
kill the thread
tick_thread = null; //
release object
}
}
//
These handle user input events.
public boolean action(Event e, Object arg) {
if (e.target instanceof Button) {
if
(((String)arg).equals("quit")) {
stop();
hide(); // I don't know if all this is necessary.
removeAll();
dispose();
if (!is_applet) System.exit(0);
}
else return false;
return true;
}
if(cb1.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "0");
cb1.setState(false);
}
else if(cb2.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "1");
cb2.setState(false);
}
else if(cb3.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "2");
cb3.setState(false);
}
else if(cb4.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "3");
cb4.setState(false);
}
else if(cb5.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "4");
cb5.setState(false);
}
else if(cb6.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "5");
cb6.setState(false);
}
else if(cb7.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "6");
cb7.setState(false);
}
else if(cb8.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "7");
cb8.setState(false);
}
else if(cb9.getState()==true) {
i.pts.writeToServer("1" +
i.qno + "" + i.pn + "8");
cb9.setState(false);
}
return false;
}
protected void Qgov() {
labelCheckBoxes("What Government
Type?","Democratic","Democratic Hi-Lo",
"Autocratic","","","","","","");
}
protected void Qlibrary() {
labelCheckBoxes("Library Game or
Players Rules","Library","Players",
"","","","","","","");
}
protected void Qchange() {
labelCheckBoxes("Which Do You Want
To Change Next Round?","Government","Objects",
"Events","Physics","Rules","Winning","","","");
}
protected void QnumEvents() {
labelCheckBoxes("How Many Event
Types Would You Like?","1","2",
"3","4","5","6","7","","");
}
protected void QnumPieces() {
labelCheckBoxes("How Many Piece
Types Would You Like?","1","2",
"3","4","5","6","7","","");
}
protected void QnumArsenal() {
labelCheckBoxes("How Many Arsenal
Items Would You Like?","1","2",
"3","4","5","6","7","","");
}
protected void Qctime() {
labelCheckBoxes("How Much Time To
Make Choices?","5 seconds","10 seconds",
"15
seconds","20 seconds","25 seconds","30
seconds","45 seconds",
"1
minute","2 minutes");
}
protected void QslantQtype() {
labelCheckBoxes("How Should the
Slant Queue Work?","Take Turns",
"FIFO","Random","","","","","","");
}
protected void QslantQwrap() {
labelCheckBoxes("Should the Slant
Queue Wrap to Next Round?","YES",
"NO","","","","","","","");
}
protected void QslantQtime() {
labelCheckBoxes("How Often Should
Slant Change?","20 frames","40 frames",
"60
frames","80 frames","100 frames","120
frames","150 frames",
"","");
}
protected void Qbumpers() {
labelCheckBoxes("Should There Be
Bumpers?","YES",
"NO","Change
w/Turns","","","","","","");
}
protected void Qwinning() {
labelCheckBoxes("How Compensated
for Winning?","More Goals","Bigger Ball",
"More
Points/Goal","","","","","","");
}
protected void QnextRound() {
labelCheckBoxes("What Type of
Round Next?","Competitive","Collaborative",
"Teams of
2","","","","","","");
}
protected void QeventQlag() {
labelCheckBoxes("How Many Frames
for Event Queue Lag?","20 frames","30 frames",
"40
frames","50 frames","60 frames","70
frames","","","");
}
protected void QeventDuration() {
labelCheckBoxes("How Many Frames
Is Event Active?","40 frames","60 frames",
"80
frames","100 frames","120 frames","150
frames","","","");
}
protected void Qgravity() {
labelCheckBoxes("How High Gravity
(1-low,9-high)?","1","2",
"3","4","5","6","7","8","9");
}
protected void Qrestitution() {
labelCheckBoxes("How High
Restitution (1-low,9-high)?","1","2",
"3","4","5","6","7","8","9");
}
protected void Qmass() {
labelCheckBoxes("How High Mass
(1-low,9-high)?","1","2",
"3","4","5","6","7","8","9");
}
protected void Qviscosity() {
labelCheckBoxes("How High
Viscosity (1-low,9-high)?","1","2",
"3","4","5","6","7","8","9");
}
protected void Qpieces() {
for(int x=1;x<7;x++) {
i.image[x-1]=i.getImage(i.getCodeBase(), "images/" + x +
".gif");
}
pwindow.label11.setText("Small
Spherical Barrier");
pwindow.label12.setText("Horizontal Stick Barrier");
pwindow.label13.setText("Vertical
Stick Barrier");
pwindow.label14.setText("Vertical
Rotated 45 Degrees");
pwindow.label15.setText("Vertical
Rotated -45 Degrees");
pwindow.label16.setText("Variable
Size Spherical Barrier");
pwindow.label17.setText("Pendulum");
pwindow.label18.setText("Rotating
Cross");
pwindow.label19.setText("");
pwindow.label20.setText("");
pwindow.show(); //.hide() will hide the
window.
}
protected void Qeffects() {
for(int x=1;x<7;x++) {
i.image[x-1]=null;
i.image[x-1]=i.getImage(i.getCodeBase(), "images/10" + x +
".gif");
}
pwindow.label11.setText("No
Collisions");
pwindow.label12.setText("Anti-Gravity");
pwindow.label13.setText("Stop");
pwindow.label14.setText("Grab A
Goal");
pwindow.label15.setText("Create a
New Barrier");
pwindow.label16.setText("Double
Ball Radius");
pwindow.label17.setText("");
pwindow.label18.setText("");
pwindow.label19.setText("");
pwindow.label20.setText("");
pwindow.show(); //.hide() will hide the
window.
}
protected void labelCheckBoxes(String txt,
String cblbl1, String cblbl2, String cblbl3,
String
cblbl4, String cblbl5, String cblbl6,
String
cblbl7, String cblbl8, String cblbl9) {
inst.setText(txt);
label1.setText(cblbl1);
label2.setText(cblbl2);
label3.setText(cblbl3);
label4.setText(cblbl4);
label5.setText(cblbl5);
label6.setText(cblbl6);
label7.setText(cblbl7);
label8.setText(cblbl8);
label9.setText(cblbl9);
}
//{{DECLARE_CONTROLS
//}}
//{{DECLARE_MENUS
//}}
}
class
MyFrame extends Frame {
Checkbox
cb11,cb12,cb13,cb14,cb15,cb16,cb17,cb18,cb19,cb20;
Label
label11,label12,label13,label14,label15,
label16,label17,label18,label19,label20;
MyCanvas pPictures;
Marbles m;
int fmode=0;
MyFrame(String title, Marbles m_in) {
super(title);
m = m_in;
setLayout(new GridLayout(1,3,0,0));
Panel one=new Panel();
Panel three=new Panel();
add("first",one);
pPictures = new MyCanvas(this);
pPictures.setBackground(Color.black);
add(pPictures);
add("third",three);
one.setLayout(new
GridLayout(11,1,0,0));
one.add(cb11=new
Checkbox(""));
one.add(cb12=new
Checkbox(""));
one.add(cb13=new
Checkbox(""));
one.add(cb14=new Checkbox(""));
one.add(cb15=new
Checkbox(""));
one.add(cb16=new
Checkbox(""));
one.add(cb17=new
Checkbox(""));
one.add(cb18=new
Checkbox(""));
one.add(cb19=new
Checkbox(""));
one.add(cb20=new
Checkbox(""));
//one.add(new Button("OK"));
three.setLayout(new
GridLayout(11,1,0,0));
three.add(label11=new
Label(""));
three.add(label12=new
Label(""));
three.add(label13=new
Label(""));
three.add(label14=new
Label(""));
three.add(label15=new
Label(""));
three.add(label16=new
Label(""));
three.add(label17=new
Label(""));
three.add(label18=new
Label(""));
three.add(label19=new
Label(""));
three.add(label20=new
Label(""));
}
public boolean action(Event e, Object arg)
{
if(cb11.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "1");
cb11.setState(false);
}
if(cb12.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "2");
cb12.setState(false);
}
if(cb13.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "3");
cb13.setState(false);
}
if(cb14.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "4");
cb14.setState(false);
}
if(cb15.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "5");
cb15.setState(false);
}
if(cb16.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "6");
cb16.setState(false);
}
if(cb17.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "7");
cb17.setState(false);
}
if(cb18.getState()==true) {
m.pts.writeToServer("1" +
m.qno + "" + m.pn + "8");
cb18.setState(false);
}
return true;
}
//{{DECLARE_CONTROLS
//}}
//{{DECLARE_MENUS
//}}
}
class
MyCanvas extends Canvas {
MyFrame f;
MyCanvas(MyFrame f_in) {
f=f_in;
}
public void drawPieces() {
}
public void paint(Graphics g) {
for(int x=0;x<6;x++) {
g.drawImage(f.m.image[x],5,(x*40)+5,this);
}
}
}
//-------------------------------------------------------------------
// This class performs the animation in the
main canvas.
class
Animator extends Canvas implements Runnable {
final int max = 50;
final int maxeg = 30;
final int maxp = 20;
int maxg = 10;
int num=0; // number of balls
int numo=0; // number of obstacles
int numg=0; // number of goals
int
captg=0; // number of captured
goals
int round=1;
Ball[] ball = new Ball[max]; // array of balls
Obstacle[] obstacle = new Obstacle[max]; // array of obstacles
SlantQueue sq = new SlantQueue(60);
EffectsQueue eq = new EffectsQueue(60);
Effects es = new Effects(20);
Arsenal ars = new Arsenal(7);
Pieces ps = new Pieces(20);
Goal[] goal = new Goal[maxeg]; //
array of goals
int goalvalue[]={100,100,100,100}; //current goal values
int[] rs = {0,0,0,0}; // round
scores
Physics[] phys = new Physics[maxp]; // array
of physics
Ticker tick;
long starttime;
boolean timeOK=true;
Date theDate;
long count=0;
MainWindow mw;
Rules rules = new Rules(); // Rules Structure
boolean clearAll;
//
The following are some "physical" properties. Each property
//
has a value and a control. The
values are updated once per
//
animation loop (this is for efficiency).
public double g,vg,hg,mg,f,r,bm;
public boolean trc,col,mu,wrapon,sm;
public int xsize,ysize,sqt,eql,eqd;
Animator(Ticker t, Panel p, MainWindow m) {
tick = t;
mw = m;
setBackground(Color.black);
xsize = 1000; //width of playing board
ysize = 1000; //height of playing board
vg = 0.0;
hg = 0.0;
sqt = 100;
eql = 50;
eqd = 150;
f = .50;
//effect of viscosity
g = .25;
//effect of gravity
r = .75;
//effect of restitution
bm = 64;
//ball mass
col = true;
wrapon = true;
loadPhysics();
}
//
The run method updates the locations of the balls.
public void run() {
while(true) {
while (captg<numg || numg==0) {
if(mw.i.mode>2 || mw.i.speedtest) {
if(mw.i.speedtest && count==0)
{
addBall(new
Ball(64,20,Color.blue,500,100,0.0,0.0,this,0));
mw.i.addNode(num-1,0,20,1,1,1,0);
addBall(new
Ball(64,20,Color.blue,100,500,0.0,0.0,this,0));
mw.i.addNode(num-1,0,20,1,1,1,0);
addBall(new
Ball(64,20,Color.blue,900,500,0.0,0.0,this,0));
mw.i.addNode(num-1,0,20,1,1,1,0);
addBall(new
Ball(64,20,Color.blue,500,900,0.0,0.0,this,0));
mw.i.addNode(num-1,0,20,1,1,1,0);
vg=.33;
theDate = new Date();
starttime =
theDate.getTime();
}
for (int i=0; i<num; ++i) {
if(ball[i].e!=1) { //e=1 means not
collidable
for (int j=0; j<numo; ++j) { //look for collisions with obstacles
ball[i].interact(obstacle[j]);
}
for (int j=i+1; j<num; ++j) { //look for collisions with balls
ball[i].interact(ball[j]);
}
}
if(i<4) { //ball is one of the
players
for (int j=0; j<numg; ++j) {
//look for collisions with goals
if (ball[i].interact(goal[j])) {
if(goal[j].c > 3 || ball[i].e==4) { //ball effect=4
is goal stealing
mw.i.removeGoal[j].setValue(mw.i.goalshape[j]);
if(goal[j].c > 3) {captg++;}
if(rules.roundtype==0)
{ goal[j].c = i; }
else
if(rules.roundtype==1) { goal[j].c=3; }
else
if(rules.roundtype==2) {
if(i==0||i==3) {
goal[j].c=2;
} else {
goal[j].c=1; }
}
rs[i]=rs[i]+goalvalue[i]; //value for each goal
mw.i.addGoal(j,goal[j].c,goal[j].x,goal[j].y);
}
}
}
}
}
for (int j=0; j<num; ++j) {
if(ball[j].t==0) {
if(ball[j].e==3) { //e=3 is ball stoppage
ball[j].vx = 0.0;
ball[j].vy = 0.0;
} else {
ball[j].update();
}
}
if(ball[j].t==1) {
ball[j].vx = 0.0;
ball[j].vy = 0.0;
}
if(ball[j].t==2||ball[j].t==8) {
//Pendulum
if(count%40==0) {
if(ball[j].t==2){
for(int k=1;k<5;k++) {
ball[j+k].x=ball[j].x-(21.25*k);
ball[j+k].y=ball[j].y-(10*k);
ball[j+k].vx=phys[k].x[0];
ball[j+k].vy=phys[k].y[0];
}
} else {
ball[j+1].y=ball[j].y+60;
ball[j+2].x=ball[j].x+60;
ball[j+3].y=ball[j].y-60;
ball[j+4].x=ball[j].x-60;
for(int k=1;k<5;k++)
{
ball[j+k].vx=phys[k].x[0];
ball[j+k].vy=phys[k].y[0];
}
}
} else {
int index=0;
while(count%40>=phys[1].t[index]) {
index++;
}
for(int k=1;k<5;k++) {
if(ball[j].t==2){
ball[j+k].vx=phys[k].x[index];
ball[j+k].vy=phys[k].y[index];
} else {
ball[j+k].vx=phys[k+5].x[index];
ball[j+k].vy=phys[k+5].y[index];
}
}
}
for(int k=0;k<5;k++) {
ball[j+k].y +=
ball[j+k].vy;
ball[j+k].x +=
ball[j+k].vx;
mw.i.UpdateVRML(3,j+k,(float)ball[j+k].x,(float)ball[j+k].y,0,0,0,0,0);
}
j=j+4;
}
if(ball[j].t==3) {
//Increasing Scale
ball[j].vx = 0.0;
ball[j].vy = 0.0;
ball[j].z *= 1.1;
mw.i.UpdateScale(j,(float)(ball[j].z/40));
if(ball[j].z > 40.0) {
ball[j].t = 4;
}
}
if(ball[j].t==4) {
//Decreasing Scale
ball[j].vx = 0.0;
ball[j].vy = 0.0;
ball[j].z *= (1/1.1);
mw.i.UpdateScale(j,(float)(ball[j].z/40));
if(ball[j].z < 2.0) {
ball[j].t = 3;
}
}
}
}
DrawBalls();
tick.poll(); // wait for tick
if (mw.i.mode>2 || mw.i.speedtest) {
if (count%sqt==0) {
int qs=sq.TakeFromSlantQueue();
if (qs==1) {
vg = g;
hg = 0.0;
mw.i.UpdateRotation(0,0);
mw.i.UpdateVRML(1,101,0,0,100,0,0,0,0);
}
else if (qs==2) {
vg = 0.0;
hg = g;
mw.i.UpdateRotation(0,1);
mw.i.UpdateVRML(1,101,0,0,100,0,0,0,0);
}
else if (qs==3) {
vg = -g;
hg = 0.0;
mw.i.UpdateRotation(0,2);
mw.i.UpdateVRML(2,101,0,0,0,0,0,0,0);
}
else if (qs==4) {
vg = 0.0;
hg = -g;
mw.i.UpdateRotation(0,3);
mw.i.UpdateVRML(2,101,0,0,0,0,0,0,0);
}
int val=sq.InterrogateSlantQueue(0);
if((val==-1)&&(mw.i.pn==mw.i.turncolor)&&(mw.i.mode>2))
{
val=(int)((Math.random()*4)+1);
mw.i.pts.writeToServer("2" + val); //can't have an empty slant
queue at any point in time
}
mw.i.addSlQu(0,val,false); //show
next queue
val=-1;
for(int ww=1;ww<4;ww++) { //Show
upcoming slants
val=sq.InterrogateSlantQueue(ww);
if(val>=0 &&
val<=4) { mw.i.addSlQu(ww,val,false); }
else if(val==-1) {
mw.i.addSlQu(ww,0,false); }
}
}
//HandleEventsQueue
if
(eq.GetEffectsQueueTime(0)<count) {
int cureffect =
eq.GetEffectsQueueEffect(0);
//cureffect is ball number plus event -- example: 101
int curballno = cureffect/100;
if(ball[curballno].e==6) { //e=6 is
grow marble
ball[curballno].z =
ball[curballno].z/2;
mw.i.UpdateScale(curballno,1);
}
ball[curballno].e =
eq.TakeFromEffectsQueue()%100;
if(ball[curballno].e==5) { //e=5 is add an obstacle
mw.i.curnode=50+numo;
mw.i.removeChildren[mw.i.curnode].setValue(mw.i.pieceshape[mw.i.curnode]);
mw.i.pts.writeToServer("4" + mw.i.pn + "" +
"2" + (100 + mw.i.curnode) +
(1000 + (int)
ball[curballno].x) + (1000 + (int) ball[curballno].y-25));
} else if(ball[curballno].e==6) {
//e=6 is make ball bigger
ball[curballno].z =
ball[curballno].z*2;
mw.i.UpdateScale(curballno,2);
}
}
count++;
if(count%50==0 &&
!mw.i.speedtest) { //coordinate speed
with server
theDate = new Date();
mw.i.pts.writeToServer("8" + mw.i.pn + "" +
(count/50 + 100) + "" + (theDate.getTime() - starttime));
starttime=theDate.getTime();
//timeOK=false;
//} else if((count-40)%100==0
&& !mw.i.speedtest) { //make
sure have a valid time back
//
if(timeOK=false){ tick.speed=2000; } //someone has not reported in yet
} else if(mw.i.speedtest &&
count==50) {
theDate = new Date();
mw.i.pts.writeToServer("8" + mw.i.pn + "100" +
(theDate.getTime() - starttime));
mw.i.speedtest=false;
count=0;
mw.i.UpdateColor(0,mw.i.pn); //show player who they are
for(int xz=0;xz<4;xz++) {
mw.i.removeChildren[xz].setValue(mw.i.pieceshape[xz]);
ball[xz].vx=0.0;
ball[xz].vy=0.0;
}
vg=0.0;
}
mw.i.showStatus("count= " +
count + " speed " + tick.speed);
if(count==2000) { //too long to wait
-- end turn
mw.i.pts.writeToServer("98" + captg);
numg=captg;
}
}
} //end while loop
if(count<2000) { //write out number of
frames to finish
mw.i.pts.writeToServer("99"
+ count);
}
ResetGame();
round++;
}
}
public void ResetGame() { //HGC
double share=0.0;
//TALLY RESULTS FROM LAST ROUND
for(int i=0;i<4;i++) {
if(rules.roundtype==0) {
mw.i.player[i].IncreasePlayerScore(rs[i]); }
else
if(rules.roundtype==1&&rules.winning==0) {
if(numg/maxg>.8) {
if(maxg<29) { maxg=maxg+2; } }
else if(numg/maxg>.5) {
if(maxg<30) { maxg++; } }
else if(numg/maxg>.2) {
if(maxg>2) { maxg=maxg-1; } }
else { if(maxg>3) { maxg=maxg-2; } }
}
else if(rules.roundtype==2) {
if(i==0||i==3) {
mw.i.player[i].IncreasePlayerScore((rs[0] + rs[3])/2);
} else {
mw.i.player[i].IncreasePlayerScore((rs[1] + rs[2])/2);
}
}
}
if(rules.winning==1) {
for(int i=0;i<4;i++) {
if(rules.roundtype==0) {
share=rs[i]/((rs[0]+rs[1]+rs[2]+rs[3])/4);
if(share==0) {
ball[i].z=ball[i].z*.7; }
else if(share<.15) {
ball[i].z=ball[i].z*.85; }
else if(share<.35) { } //No
Change
else if(share<.55) {
ball[i].z=ball[i].z/.85; }
else if(share<=1) { ball[i].z=ball[i].z/.7; }
}
else if(rules.roundtype==1) {
if(numg/maxg>.8) {
if(maxg<29) { ball[i].z=ball[i].z/.7; } }
else if(numg/maxg>.5) {
if(maxg<30) { ball[i].z=ball[i].z/.85; } }
else if(numg/maxg>.35) {
if(maxg>2) { } }
else if(numg/maxg>.2) {
if(maxg>2) { ball[i].z=ball[i].z*.85;} }
else { if(maxg>3) {
ball[i].z=ball[i].z*.7; } }
}
else if(rules.roundtype==2) {
if(i==0||i==3) {
share=(rs[0]+rs[3])/((rs[0]+rs[1]+rs[2]+rs[3])/4);
}
else {
share=(rs[1]+rs[2])/((rs[0]+rs[1]+rs[2]+rs[3])/4);
}
if(share==0) {
ball[i].z=ball[i].z*.7; }
else if(share<.3) { ball[i].z=ball[i].z*.85; }
else if(share<.7) { } //No
Change
else if(share<1) {
ball[i].z=ball[i].z/.85; }
else if(share==1) { ball[i].z=ball[i].z/.7; }
}
}
}
else if(rules.winning==2) {
for(int i=0;i<4;i++) {
if(rules.roundtype==0) {
share=rs[i]/((rs[0]+rs[1]+rs[2]+rs[3])/4);
if(share==0) {
goalvalue[i]=goalvalue[i]-16; }
else if(share<.15) {
goalvalue[i]=goalvalue[i]-8; }
else if(share<.35) { } //No
Change
else if(share<.55) {
goalvalue[i]=goalvalue[i]+8; }
else if(share<=1) { goalvalue[i]=goalvalue[i]+16; }
}
else if(rules.roundtype==1) {
if(numg/maxg>.8) {
goalvalue[i]=goalvalue[i]+16; }
else if(numg/maxg>.5) {
goalvalue[i]=goalvalue[i]+8; }
else if(numg/maxg>.35) { }
else if(numg/maxg>.2) {
goalvalue[i]=goalvalue[i]-8; }
else {
goalvalue[i]=goalvalue[i]-16; }
}
else if(rules.roundtype==2) {
if(i==0||i==3) {
share=(rs[0]+rs[3])/((rs[0]+rs[1]+rs[2]+rs[3])/4);
}
else {
share=(rs[1]+rs[2])/((rs[0]+rs[1]+rs[2]+rs[3])/4);
}
if(share==0) {
goalvalue[i]=goalvalue[i]-16; }
else if(share<.3) {
goalvalue[i]=goalvalue[i]-8; }
else if(share<.7) { } //No
Change
else if(share<1) {
goalvalue[i]=goalvalue[i]+8; }
else if(share==1) { goalvalue[i]=goalvalue[i]+16; }
}
}
}
mw.i.showStatus("Team Score
Time: " + count + " Captured
Goals: " + captg);
//mw.i.showStatus("Current
Score: Yellow " +
mw.i.player[0].GetPlayerScore() +
// " Red " +
mw.i.player[1].GetPlayerScore() +
// " Blue " +
mw.i.player[2].GetPlayerScore() +
// " Green " +
mw.i.player[3].GetPlayerScore());
for(int xx=0;xx<4;xx++) {
rs[xx]=0;
}
mw.i.mode=0;
mw.i.lastmodesent=0;
for(int x=0;x<50;x++) { //put balls
and obstacles back
if(x>3) {
mw.i.removeChildren[x].setValue(mw.i.pieceshape[x]);
ball[x]=null;
}
mw.i.removeChildren[x+50].setValue(mw.i.pieceshape[x+50]);
obstacle[x]=null;
}
for(int j=0; j<numg; ++j) { //put goals back
mw.i.removeGoal[j].setValue(mw.i.goalshape[j]);
goal[j]=null;
}
ball[0].x = 500;
ball[0].vx = 0.0;
ball[0].y = 100;
ball[0].vy = 0.0;
mw.i.UpdateVRML(3,0,(float)ball[0].x,(float)ball[0].y,0,0,0,0,0);
ball[1].x = 100;
ball[1].vx = 0.0;
ball[1].y = 500;
ball[1].vy = 0.0;
mw.i.UpdateVRML(3,1,(float)ball[1].x,(float)ball[1].y,0,0,0,0,0);
ball[2].x = 900;
ball[2].vx = 0.0;
ball[2].y = 500;
ball[2].vy = 0.0;
mw.i.UpdateVRML(3,2,(float)ball[2].x,(float)ball[2].y,0,0,0,0,0);
ball[3].x = 500;
ball[3].vx = 0.0;
ball[3].y = 900;
ball[3].vy = 0.0;
mw.i.UpdateVRML(3,3,(float)ball[3].x,(float)ball[3].y,0,0,0,0,0);
numo=0; num=4; numg=0; captg=0;
mw.i.UpdateRotation(0,4);
mw.i.UpdateVRML(1,101,0,0,0,0,0,0,0);
if(rules.slantQclear==true) { //reset
slant queue if chosen
for(int zz=0;zz<60;zz++) {
sq.t[zz]=-1;
sq.size=0;
sq.head=0;
sq.tail=0;
}
for(int xx=0;xx<4;xx++) {
mw.i.addSlQu(xx,0,false);
}
}
for(int yy=0;yy<60;yy++) { //reset
event queue
eq.t[yy]=-1;
eq.e[yy]=-1;
eq.size=0;
eq.head=0;
eq.tail=0;
}
mw.i.Paletize(4);
mw.i.Bumpers(1);
wrapon=false;
mw.i.UpdatePointer(0,0,0,30,0,0,0,0);
mw.i.pts.goalcount=0;
//mw.i.lst.createGoals(maxg);
}
//
The DrawBalls method displays objects.
public void DrawBalls() {
int j=0;
float x=0,y=0;
for (j=0; j<num; ++j) {
x = (float) (ball[j].x);
y = (float) (ball[j].y);
if(ball[j].t<1)
mw.i.UpdateVRML(1,j,x,y,0,0,0,0,0);
}
}
//
These adds balls
public void addMoving(int m,int r,float
x,float y,int t,int c0,int c1,int c2) {
addBall(new
Ball(m,r,Color.pink,x,y,0.0,0.0,this,t));
mw.i.addNode(num-1,0,r,c0,c1,c2,0);
x=(float)ball[num-1].x;
y=(float)ball[num-1].y;
addBall(new
Ball(m,r,Color.pink,x,y,3.0,1.5,this,t));
mw.i.addNode(num-1,0,r,c0,c1,c2,0);
mw.i.UpdateVRML(1,num-1,x,y,0,0,0,0,0);
addBall(new
Ball(m,r,Color.pink,x,y,6.0,3.0,this,t));
mw.i.addNode(num-1,0,r,c0,c1,c2,0);
mw.i.UpdateVRML(1,num-1,x,y,0,0,0,0,0);
addBall(new
Ball(m,r,Color.pink,x,y,9.0,4.5,this,t));
mw.i.addNode(num-1,0,r,c0,c1,c2,0);
mw.i.UpdateVRML(1,num-1,x,y,0,0,0,0,0);
addBall(new Ball(m,r,Color.pink,x,y,12.0,6.0,this,t));
mw.i.addNode(num-1,0,r,c0,c1,c2,0);
mw.i.UpdateVRML(1,num-1,x,y,0,0,0,0,0);
}
public void addBall(Ball b) {
if (num<max) ball[num++] = b;
}
//
This adds obstacles.
public void addObstacle(Obstacle o) {
if (numo<max) obstacle[numo++] = o;
}
public void addGoal(Goal g) {
if (numg<maxg) goal[numg++] = g;
if(numg==1) {
sq.AddtoSlantQueue((int)((goal[0].x%4)+1)); //start with a random slant
(can't be empty)
sq.AddtoSlantQueue((int)((goal[0].y%4)+1)); //and one random slant in
queue (can't be empty)
for(int ww=0;ww<4;ww++) { //Show
upcoming slants
int
val=sq.InterrogateSlantQueue(ww);
if(val>=0 && val<=4)
{ mw.i.addSlQu(ww,val,false); }
else if(val==-1) {
mw.i.addSlQu(ww,0,false); }
}
}
}
public void loadPhysics() {
phys[0] = new
Physics(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[1] = new
Physics(2.125,2.125,-2.125,-2.125,0.0,0.0,0.0,0.0,
-1.0,1.0,-1.0,1.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[2] = new
Physics(4.25,4.25,-4.25,-4.25,0.0,0.0,0.0,0.0,
-2.0,2.0,-2.0,2.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[3] = new
Physics(6.375,6.375,-6.375,-6.375,0.0,0.0,0.0,0.0,
-3.0,3.0,-3.0,3.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[4] = new
Physics(8.5,8.5,-8.5,-8.5,0.0,0.0,0.0,0.0,
-4.0,4.0,-4.0,4.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[5] = new
Physics(0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[6] = new
Physics(6.0,-6.0,-6.0,6.0,0.0,0.0,0.0,0.0,
-6.0,-6.0,6.0,6.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[7] = new
Physics(-6.0,-6.0,6.0,6.0,0.0,0.0,0.0,0.0,
-6.0,6.0,6.0,-6.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[8] = new
Physics(-6.0,6.0,6.0,-6.0,0.0,0.0,0.0,0.0,
6.0,6.0,-6.0,-6.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
phys[9] = new
Physics(6.0,6.0,-6.0,-6.0,0.0,0.0,0.0,0.0,
6.0,-6.0,-6.0,6.0,0.0,0.0,0.0,0.0,
10,20,30,40,0,0,0,0);
}
//
This returns the index of the ball nearest to x,y
//
excluding ex. (wrap is not taken
into account).
int nearestBall(int x, int y, int ex) {
double d=1e20,t; int j=0;
for (int i=0; i<num; ++i) {
t = Ball.hypot(x - ball[i].x, y -
ball[i].y);
if (t < d && i!=ex) { d = t;
j = i; }
}
return j;
}
void rotate(int j) {
double d,mm,dx,dy,tt;
d =
Ball.hypot(ball[j].x-ball[j-1].x,ball[j].y-ball[j-1].y);
if
(d<1e-20) return; // too close
mm = ball[j].m + ball[j-1].m;
if (mm<1e-50 && mm>-1e-50)
return; // too small
tt = Math.sqrt(20/mm/d)/d;
dy = tt*(ball[j].x - ball[j-1].x); // perpendicular direction vector
dx = tt*(ball[j-1].y - ball[j].y);
ball[j].vx = - dx*ball[j-1].m;
ball[j].vy = - dy*ball[j-1].m;
}
// This adjusts the frame of reference so
that the total momentum becomes zero.
void zeroMomentum() {
double mx=0,my=0,M=0;
for (int i=0; i<num; ++i) {
mx += ball[i].vx * ball[i].m;
my += ball[i].vy * ball[i].m;
M += ball[i].m;
}
if (M != 0)
for (int i=0; i<num; ++i) {
ball[i].vx -= mx/M;
ball[i].vy -= my/M;
}
}
//
This adjusts the centroid to the center of the canvas.
//
Note, the "while" loops here could be simply use %= but some
//
interpreters have bugs with %=.
void centerMass() {
double x,y,cx=0,cy=0,M=0;
for (int i=0; i<num; ++i) {
x = ball[i].x; y = ball[i].y;
if (wrapon) { // if wrap, convert the top 1/4 to negative
if (x > xsize*0.75) x -= xsize;
if (y > ysize*0.75) y -= ysize;
}
cx += ball[i].x * ball[i].m;
cy += ball[i].y * ball[i].m;
M += ball[i].m;
}
if (M != 0)
for (int i=0; i<num; ++i) {
ball[i].x += xsize/2 - cx/M;
ball[i].y += ysize/2 - cy/M;
while (ball[i].x < 0) ball[i].x +=
xsize;
while (ball[i].x > xsize) ball[i].x
-= xsize;
while (ball[i].y < 0) ball[i].y +=
ysize;
while (ball[i].y > ysize) ball[i].y
-= ysize;
}
}
}
//--------------------------------------------------------------------------------------------
// The Ball class
class
Ball {
double x,y;
// location
double z; // radius
double vx,vy; // velocity
Color c; // color
double m; // mass
boolean hit;
// scratch field
double ox,oy; // old location (for smooth redraw)
final double vmin = 1e-20;
// a weak force to prevent overlapping
Animator a;
boolean iok;
// image is ok.
Image img;
// a bitmap to use in "filled" mode
int t; // type of Ball
int e; // current effect on the ball
Ball(double mass, double radius, Color
color,
double px, double py, double sx, double
sy, Animator an, int typ) {
m=mass; z=radius-0.5; c=color; t=typ;
if (z<0.5) z =
Math.min(Math.sqrt(Math.abs(m)),Math.min(px,py));
if (z<0.5) z=0.5;
x=px; y=py; vx=sx; vy=sy;
iok = false;
a = an;
e = 0;
if(color==Color.white) t=1;
}
//
This updates a ball according to the physical universe.
//
The reason I exempt a ball from gravity during a hit is
//
to simulate "at rest" equilibrium when the ball is resting
//
on the floor or on another ball.
void UpdateBall(double dx, double dy) {
x=dx; y=dy;
}
void AddBallEffect(int ex) {
e=ex;
}
public void update() {
x += vx;
if (x+z > a.xsize)
if (a.wrapon) {
x -= a.xsize;
} else {
if (vx > 0) vx *= a.r; // restitution
vx = -Math.abs(vx)-vmin; // reverse velocity
x = a.xsize-z;
hit = true;
//
Check if location is completely off screen
if (x-z > a.xsize) x = a.xsize + z;
}
if (x-z < 0)
if (a.wrapon) x += a.xsize;
else {
if (vx < 0) vx *= a.r; // restitution
vx = Math.abs(vx)+vmin; // reverse velocity
x = z;
hit = true;
if (x+z < 0) x = -z;
}
y += vy;
if (y+z > a.ysize) {
if (a.wrapon) y -= a.ysize;
else {
vy = -1*vy;
y = a.ysize-z;
}
}
if (y-z < 0) {
if (a.wrapon) {
y += a.ysize;
}
else {
vy = -1*vy;
y = z;
}
}
if (a.f > 0 && m != 0) { // viscosity
double t = 100/(100 +
a.f*hypot(vx,vy)*z*z/m);
vx *= t; vy *= t;
}
if (!hit) {
if (e==2) { // effect of 2 means anti-gravity
vy -= a.vg; // if not hit, exert anti-gravity
vx -= a.hg;
} else {
vy += a.vg; // if not hit, exert gravity
vx += a.hg;
}
}
hit = false; // reset flag
}
//
This computes the interaction of two balls, either collision
//
or gravitational force.
public boolean interact(Goal g) {
double p = g.x - x;
double q = g.y - y;
double h2 = p*p + q*q;
double h = Math.sqrt(h2);
if (h < z+g.r) { // HIT
hit = true;
return true;
} else {
return false;
}
}
public boolean interact(Ball b) {
double p = b.x - x;
double q = b.y - y;
if (a.wrapon) { // wrap around, use shortest distance
if (p > a.xsize/2) p-=a.xsize;
else if (p < -a.xsize/2) p+=a.xsize;
if (q > a.ysize/2) q-=a.ysize;
else if (q < -a.ysize/2) q+=a.ysize;
}
double h2 = p*p + q*q;
double h = Math.sqrt(h2);
if (a.col) { // collisions enabled
if (h < z+b.z) { // HIT
hit = b.hit = true;
if (h > 1e-10) {
// Compute the elastic collision
of two balls.
double v1,v2,r1,r2,s,t2,v;
p /= h;
q /= h; //
normalized impact direction
v1 = vx*p + vy*q;
v2 = b.vx*p + b.vy*q; // impact velocity
r1 = vx*q - vy*p;
r2 = b.vx*q - b.vy*p; // remainder velocity
if (v1<v2) return false;
s = m + b.m; //
total mass
if (s==0) return false;
t2 = (v1*m + v2*b.m)/s;
if(t==0) {
v = t2 + a.r*(v2 - v1)*b.m/s;
vx = v*p + r1*q;
vy = v*q - r1*p;
}
if(b.t==0) {
v = t2 + a.r*(v1 - v2)*m/s;
b.vx = v*p + r2*q;
b.vy = v*q - r2*p;
}
}
}
}
if (a.mg != 0 && h2 > 1e-10
&&
!hit && !b.hit) { // gravity is enabled
double dv;
if(t==0) {
dv = a.mg*b.m/h2/h; // for ver 2.2 added '/h'
vx += dv*p;
vy += dv*q;
}
if(b.t==0) {
dv = a.mg*m/h2/h;
b.vx -= dv*p;
b.vy -= dv*q;
}
}
return false;
}
public boolean interact(Obstacle b) {
double p,q,h,e,n,h2,yadj;
if (a.col) { // collisions enabled
p = b.x - x;
q = b.y - y;
h2 = p*p + q*q;
h = Math.sqrt(h2);
p = b.xend - x;
q = b.yend - y;
h2 = p*p + q*q;
e = Math.sqrt(h2);
if ((b.s >100 || b.s < -100)
&& x>b.x-z && x<b.xend+z && y>b.y &&
y<b.yend) { //hit vertical
hit = true;
vx = vx*-a.r;
if(x>b.x){x=b.x+z;} else
{x=b.x-z;}
}
else if ((b.s <0 && x<b.x
&& x>b.xend)||(b.s >=0 && x>b.x &&
x<b.xend)) { //If x within x of obst.
yadj = b.y + (x-b.x)*b.s;
p = 0.0;
q = yadj - y;
h2 = p*p + q*q;
n = Math.sqrt(h2);
if (n < z+b.z) { // If collide with length of obstacle
hit = true;
if (b.s<.001 &&
b.s>-.001) { //hit horizontal
vy = vy*-a.r;
if(y>b.y){y=b.y+z;}
else {y=b.y-z;}
} else {
if (n > 1e-10) {
//
Compute the elastic collision
double v1,v2,r1,r2,s,t,v;
p = b.s*((y-yadj)/2)/n;
q =
Math.abs(1/b.s)*((yadj-y)/2)/n; //
normalized impact direction
v1 = vx*p + vy*q;
v2 = (-vx)*p + (-vy)*q; // impact velocity
r1 = vx*q - vy*p;
r2 = (-vx)*q - (-vy)*p; // remainder velocity
if (v1<v2) return false;
s = m + b.m; // total mass
if (s==0) return false;
t = (v1*m + v2*b.m)/s;
v = t + a.r*(v2 - v1)*b.m/s;
vx = v*p + r1*q;
vy = v*q - r1*p;
v = t + a.r*(v1 -
v2)*m/s;
}
}
}
}
else if (h < z+b.z) { // If collide
with head of obstacle
hit = true;
if (h > 1e-10) {
// Compute the elastic collision
of two balls.
// The math involved here is not
for the faint of heart!
double v1,v2,r1,r2,s,t,v;
p = (b.x - x)/h; q = (b.y - y)/h; //
normalized impact direction
v1 = vx*p + vy*q;
v2 = 0.0*p + 0.0*q; // impact velocity
r1 = vx*q - vy*p;
r2 = 0.0*q - 0.0*p; // remainder velocity
if (v1<v2) return false;
s = m + b.m; //
total mass
if (s==0) return false;
t = (v1*m + v2*b.m)/s;
v = t + a.r*(v2 - v1)*b.m/s;
vx = v*p + r1*q;
vy = v*q - r1*p;
v = t + a.r*(v1 - v2)*m/s;
}
}
else if (e < z+b.z) { // If collide with tail of obstacle
hit = true;
if (e > 1e-10) {
//
Compute the elastic collision of two balls.
//
The math involved here is not for the faint of heart!
double v1,v2,r1,r2,s,t,v;
p = (b.xend - x)/e; q = (b.yend - y)/e; // normalized impact direction
v1 = vx*p + vy*q;
v2 = 0.0*p + 0.0*q; // impact velocity
r1 = vx*q - vy*p;
r2 = 0.0*q - 0.0*p; // remainder velocity
if (v1<v2) return false;
s = m + b.m; //
total mass
if (s==0) return false;
t = (v1*m + v2*b.m)/s;
v = t + a.r*(v2 - v1)*b.m/s;
vx = v*p + r1*q;
vy = v*q - r1*p;
v = t + a.r*(v1 - v2)*m/s;
}
}
}
return false;
}
static double hypot(double x,double y) {
return Math.sqrt(x*x + y*y);
}
}
//--------------------------------------------------------------------------------------------
class
Obstacle {
double x,y;
// head location
double xend,yend; // tail location
double z;
// width
Color c;
// color
double m;
// mass
double s;
// slope
int t;
Obstacle(double mass, double width, Color
color,
double bx, double by, double ex, double
ey, int typ) {
m=mass; z=width; c=color; t=typ;
if (by<=ey) {
x=bx;y=by;xend=ex;yend=ey; }
else { x=ex;y=ey;xend=bx;yend=by; }
if(color==Color.white) t=1;
if(xend==x) {
s=10000;
} else {
s = (yend-y)/(xend-x);
}
}
void UpdateObstacle(double dx, double dy) {
double oldx=x, oldy=y;
x=dx+((oldx-xend)/2);
y=dy+((oldy-yend)/2); xend=dx+((xend-oldx)/2); yend=dy+((yend-oldy)/2);
}
}
//-------------------------------------------------------------------------------------------
class
Goal {
double x,y; // head location
double r; // radius
int c; // color
Goal(double radius, int color, double bx,
double by) {
c=color;x=bx;y=by;r=radius;
}
}
class
Player {
long score; // score
Player() {
score=0;
}
public long GetPlayerScore() {
return score;
}
public int IncreasePlayerScore(int v) {
score = score + v;
return 1;
}
}
class
SlantQueue {
int[]
t={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};
int size; // queue size
int head; // head number of queue
int tail; // tail number of queue
SlantQueue(int s) {
size=s;
head=0;
tail=0;
}
public int InterrogateSlantQueue(int slant)
{
if(head+slant+1>size){
return t[head+slant+1-size];
} else {
return t[head+slant+1];
}
}
public void AddtoSlantQueue(int slant) {
tail++;
if(tail>=size){tail=0;}
t[tail]=slant;
}
public int TakeFromSlantQueue() {
int headval;
if(head!=tail){
head++;
if(head>=size){head=0;}
headval=t[head];
t[head]=-1;
return headval;
}
return -1;
}
}
class
EffectsQueue {
long[]
t={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; // queue values
int size; // queue size
int head; // head number of queue
int tail; // tail number of queue
int[]
e={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// queue values
EffectsQueue(int s) {
size=s;
head=0;
tail=0;
}
public int GetEffectsQueueEffect(int eq) {
if(head+eq+1>size){
return e[head+eq+1-size];
} else {
return e[head+eq+1];
}
}
public long GetEffectsQueueTime(int eq) {
if(head+eq+1>size){
return t[head+eq+1-size];
} else {
return t[head+eq+1];
}
}
public void AddtoEffectsQueue(long eqt, int
eqe) {
int
f=head;
int x=0;
boolean found=false;
tail++;
if(tail>=size){tail=0;}
while(!found && f!=tail) { //Find
appropriate place in queue
if(t[f]>eqt) {
found=true; //f is the right place
} else {
f++;
if(f>=size){f=0;}
}
}
if(!found) {
t[tail]=eqt; //if not found, tail is right place
e[tail]=eqe;
} else {
x=tail; //if found, work back to make room for f
while(x!=f) {
if(x==0) {
t[0]=t[size-1];
e[0]=e[size-1];
x=size-1;
} else {
t[x]=t[x-1];
e[x]=e[x-1];
x--;
}
}
t[f]=eqt; // fill f with new queue item
e[f]=eqe;
}
}
public int TakeFromEffectsQueue() {
if(head!=tail){
head++;
if(head>=size){head=0;}
return e[head];
}
return 0;
}
}
class
Effects {
String[]
es={"","","","","","","","","","","","","","","","","","","",""}; // VRMLstrings
int maxe;
Effects(int m) {
maxe = m;
es[0] = " 1 1 0 transparency 1
}\n" + " }\n" + //already used
" geometry Sphere {radius 30}\n";
es[1] = " 1 1 0 }\n" + " }\n" +
//no collision
" geometry IndexedFaceSet {\n" +
" coord Coordinate { point [\n" +
" 71.01 39.43 0, 92.72 -21.44 0, 67 0.9883 0, 64.59
-22.23 0, \n" +
" 46.94 -4.622 0, 40.54 -20.62 0, 29.33 -2.231 0,
6.145 -28.59 0, \n" +
" -27.35 0.934 0, -44.85 -21.38 0, -50.42 4.107 0,
-67.09 -10.23 0, \n" +
" -69.47 12.05 0, -98.79 -1.492 0, -70.27 45.47 0,
-21.77 14.49 0, \n" +
" 31.73 15.36 0, 71.01 39.43 20, 92.72 -21.44 20,
\n" +
" 67 0.9883 20, 64.59 -22.23 20, 46.94 -4.622 20,
40.54 -20.62 20, \n" +
"
29.33 -2.231 20, 6.145 -28.59 20, -27.35 0.934 20, \n" +
" -44.85 -21.38 20, -50.42 4.107 20, -67.09 -10.23
20, -69.47 12.05 20, \n" +
" -98.79 -1.492 20, -70.27 45.47 20, -21.77 14.49 20,
31.73 15.36 20]\n" +
" }\n" +
" coordIndex [\n" +
" 17, 18, 1, 0 -1, 18, 19, 2, 1, -1, 19, 20, 3, 2,
-1, \n" +
" 20, 21, 4, 3, -1, 21, 22, 5, 4, -1, 22, 23, 6, 5,
-1, \n" +
" 23, 24, 7, 6, -1, 24, 25, 8, 7, -1, 25, 26, 9, 8,
-1, \n" +
" 26, 27, 10, 9, -1, 27, 28, 11, 10, -1, 28, 29, 12,
11, \n" +
" -1, 29, 30, 13, 12, -1, 30, 31, 14, 13, -1, 31, 32,
\n" +
" 15, 14, -1, 32, 33, 16, 15, -1, 33, 17, 0, 16,
\n" +
" -1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
15, 16, 0, \n" +
" -1,
33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20, 19, 18, 17, \n" +
" -1]\n" +
" }\n";
es[2] = " 1 0 1 }\n" + " }\n" +
//anti-gravity
" geometry IndexedFaceSet {\n" +
" coord
Coordinate { point [\n" +
" 51.09 5.645
0, 21.21 6.609 0, 21.21 -44.48 0, -18.32 -44.48 0, \n" +
" -18.32 5.645
0, -58.8 5.645 0, 1.928 65.4 0, 51.09 5.645 20, \n" +
" 21.21 6.609
20, 21.21 -44.48 20, -18.32 -44.48 20, \n" +
" -18.32 5.645
20, -58.8 5.645 20, 1.928 65.4 20]\n" +
" }\n" +
" coordIndex
[\n" +
" 7, 8, 1,, 0,
-1, 8, 9, 2, 1 -1, 9, 10, 3, 2, -1, 10, 11, 4, \n" +
" 3, -1, 11,
12, 5, 4, -1, 12, 13, 6, 5, -1, 13, 7, 0, 6, \n" +
" -1, 5, 6, 0,
1, 2, 3, 4, -1, 10, 9, 8, 7, 13, 12, 11, -1]\n" +
"}\n";
es[3] = " 1 0 0 }\n" + " }\n" +
//stop (pause)
" geometry DEF NGon01-FACES IndexedFaceSet
{\n" +
" coord DEF NGon01-COORD Coordinate {
point [\n" +
" 64.29 0 0, 45.46 -45.46 0, 0 -64.29
0, -45.46 -45.46 0, \n" +
" -64.29 0 0, -45.46 45.46 0, 0 64.29
0, 45.46 45.46 0, \n" +
" 64.29 0 20, 45.46 -45.46 20, 0 -64.29
20, -45.46 -45.46 20, \n" +
" -64.29 0 20, -45.46 45.46 20, 0 64.29
20, 45.46 45.46 20]\n" +
" }\n" +
" coordIndex [\n" +
" 8, 9, 1, 0, -1, 10, 9, 2, 1, -1, 10,
11, 3, 2, -1, \n" +
" 11, 12, 4, 3, -1, 12, 13, 5, 4, -1,
13, 14, 6, 5, -1, \n" +
" 14, 15, 7, 6, -1, 15, 8, 0, 7, -1, 7, 0, 1, 2, 3, 4, 5, 6,
\n" +
" -1, 13, 12, 11, 10, 9, 8, 15, 14,
-1]\n" +
" }\n";
es[4] = " 1 1 1 }\n" + " }\n" +
//goal stealing
" geometry DEF Line01-FACES IndexedFaceSet {\n" +
" coord DEF Line01-COORD Coordinate { point [\n" +
" 10.74 3.404 0, 25.14 40.18 0, 38.76 36.21 0, 29.15
-0.5878 0, \n" +
" 52.4 8.221 0, 61.23 -4.585 0, 35.56 -31.78 0, 11.54
-48.53 0, \n" +
" 13.14 -68.51 0, -11.62 -67.64 0, -10.83 -46.89 0,
-41.91 -26.91 0, \n" +
" -55.43 20.91 0, -45.89 26.5 0, -30.76 -3.789 0,
-37.13 37.67 0, \n" +
" -22.79 41.68 0, -13.22 0.2021 0, -14.02 42.5 0,
5.946 41.74 0, \n" +
" 10.74 3.404 20, 25.14 40.18 20, 38.76 36.21 20,
\n" +
"
29.15 -0.5878 20, 52.4 8.221 20, 61.23 -4.585 20, \n" +
" 35.56 -31.78 20, 11.54 -48.53 20, 13.14 -68.51 20,
\n" +
" -11.62 -67.64 20, -10.83 -46.89 20, -41.91 -26.91
20, -55.43 20.91 20, \n" +
" -45.89 26.5 20, -30.76 -3.789 20, -37.13 37.67 20,
-22.79 41.68 20, \n" +
" -13.22 0.2021 20, -14.02 42.5 20, 5.946 41.74
20]\n" +
" }\n" +
"
coordIndex [\n" +
" 20, 21, 1, 0, -1, 21, 22, 2, 1, -1, 22, 23, 3, 2,
-1, \n" +
" 23, 24, 4, 3, -1, 24, 25, 5, 4, -1, 25, 26, 6, 5,
-1, \n" +
" 26, 27, 7, 6, -1, 27, 28, 8, 7, -1, 28, 29, 9, 8,
-1, \n" +
" 29, 30, 10, 9, -1, 30, 31, 11, 10, -1, 31, 32, 12,
\n" +
" 11, -1, 32, 33, 13, 12, -1, 33, 34, 14, 13, -1, 34,
\n" +
" 35, 15, 14,
-1, 35, 36, 16, 15, -1, 36, 37, 17, 16, \n" +
" -1, 37, 38, 18, 17, -1, 38, 39, 19, 18, -1, 39, 20,
\n" +
" 0, 19, -1, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
18, \n" +
" 19, 0, 1, 2, 3, 4, 5, 6, 7, -1, 26, 25, 24, 23, 22,
21, \n" +
" 20, 39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28,
27, -1]\n" +
" }\n";
es[5] = " 0 1 1 }\n" + " }\n" + //add an obstacle
" geometry DEF Line01-FACES IndexedFaceSet {\n" +
" coord DEF Line01-COORD Coordinate { point [\n" +
" -50 0 -18, 49 0 -18, 50 0 2.5, 55 0 7.5, \n" +
" 40 0 7.5, 46 0 2.5, 45 0 -3, -45 0 -2.5, \n" +
" -45 0 2.5, -40 0 8, -55 0 8, -50 0 3, \n" +
" -50 12 -18, 49 12 -18, 50 12 2.5, 55 12 7.5, \n" +
" 40 12 7.5, 46 12 2.5, 45 12 -3, -45 12 -2.5, \n" +
" -45 12 2.5, -40 12 8, -55 12 8, -50 12 3] \n" +
" }\n" +
" coordIndex [\n" +
" 12, 13, 1, 0, -1, 13, 14, 2, 1, -1, \n" +
" 14, 15, 3, 2, -1, 15, 16, 4, 3, -1, 16, 17, 5, 4, -1,
\n" +
" 17, 18, 6, 5, -1, 18, 19, 7, 6, -1, 19, 20, 8, 7, -1,
\n" +
" 20, 21, 9, 8, -1, 21, 22, 10, 9, -1, 22, 23, 11, 10,
\n" +
" -1, 23, 12, 0, 11, -1,
4,5,6,7,8,9,10,11,0,1,2,3,-1,\n" +
" 14,13,12,23,22,21,20,19,18,17,16,15,-1]\n" +
" }\n";
es[6] = " 1 1 1 }\n" + " }\n" +
//bigger ball
" geometry Sphere {radius 50}\n";
es[7] = " .00001 0 0 }\n"
+ " }\n" +
//goal clearing
" geometry Sphere {radius 30}\n";
}
public String GetEffectsString(int en) {
if(en < maxe) {
return es[en];
}
return null;
}
}
class
Pieces {
String[]
ps={"","","","","","","","","","","","","","","","","","","",""}; // VRMLstrings
int maxp;
Pieces(int m) {
maxp = m;
ps[0] = "0 0 1 transparency 1
}\n" + " }\n" +
" geometry Sphere {radius 30}\n";
ps[1] = "1 0 1 }\n" + " }\n" +
" geometry Sphere {radius 20}\n";
ps[2] = "1 1 0 }\n" + " }\n" +
" geometry
IndexedFaceSet {\n" +
" coord Coordinate { point [\n" +
" -50 0 2, 49 0 2, 50 0 22.5, 55 0 27.5, \n" +
" 40 0 27.5, 46 0 22.5, 45 0 17, -45 0 17.5, \n" +
" -45 0 22.5, -40 0 28, -55 0 28, -50 0 23, \n" +
" -50 16 2, 49 16 2, 50 16 22.5, 55 16 27.5, \n" +
" 40 16 27.5, 46 16 22.5, 45 16 17, -45 16 17.5, \n"
+
" -45 16 22.5, -40 16 28, -55 16 28, -50 16 23] \n"
+
" }\n" +
" coordIndex [\n" +
" 12, 13, 1, 0, -1, 13, 14, 2, 1, -1, \n" +
" 14, 15, 3, 2, -1, 15, 16, 4, 3, -1, 16, 17, 5, 4, -1,
\n" +
" 17, 18, 6, 5, -1, 18, 19, 7, 6, -1, 19, 20, 8, 7, -1,
\n" +
" 20, 21, 9, 8, -1, 21, 22, 10, 9, -1, 22, 23, 11, 10,
\n" +
" -1, 23, 12, 0, 11, -1, 4,5,6,7,8,9,10,11,0,1,2,3,-1,\n"
+
" 14,13,12,23,22,21,20,19,18,17,16,15,-1]\n" +
" }\n";
ps[3] = "1 1 0 }\n" + " }\n" +
" geometry IndexedFaceSet {\n" +
" coord Coordinate { point [\n" +
" 0 -50 2, 0 49 2, 0 50 22.5, 0 55 27.5, \n" +
" 0 40 27.5, 0 46 22.5, 0 45 17, 0 -45 17.5, \n" +
" 0 -45 22.5, 0 -40 28, 0 -55 28, 0 -50 23, \n" +
" 16 -50 2,
16 49 2, 16 50 22.5, 16 55 27.5, \n" +
" 16 40 27.5, 16 46 22.5, 16 45 17, 16 -45 17.5, \n"
+
" 16 -45 22.5, 16 -40 28, 16 -55 28, 16 -50 23] \n"
+
" }\n" +
" coordIndex [\n" +
" 12, 13, 1, 0, -1, 13, 14, 2, 1, -1, \n" +
" 14, 15, 3, 2, -1, 15, 16, 4, 3, -1, 16, 17, 5, 4, -1,
\n" +
" 17, 18, 6, 5, -1, 18, 19, 7, 6, -1, 19, 20, 8, 7, -1,
\n" +
" 20, 21, 9, 8, -1, 21, 22, 10, 9, -1, 22, 23, 11, 10,
\n" +
" -1, 23, 12, 0, 11, -1,
4,5,6,7,8,9,10,11,0,1,2,3,-1,\n" +
" 14,13,12,23,22,21,20,19,18,17,16,15,-1]\n" +
" }\n";
// " geometry Box {size 20 100
20}\n";
ps[4] = ps[2];
ps[5] = ps[2];
ps[6] = "1 1 1 }\n" + " }\n" +
" geometry Sphere {radius 40}\n";
ps[7] = "0 1 1 }\n" +
" }\n" +
" geometry Sphere {radius 20}\n";
ps[8] = "1 1 0 }\n" + " }\n" +
" geometry Sphere {radius 20}\n";
}
public String GetPiecesString(int pn) {
if(pn < maxp) {
return ps[pn];
}
return null;
}
}
class
Arsenal {
int[] a={0,0,0,0,0,0,0,0,0,0}; // e values
int numa;
int maxa;
Arsenal(int m) {
numa=0;
maxa=m;
}
public int AddToArsenal(int ae) {
if(numa<maxa){
a[numa]=ae;
numa++;
return 1;
}
return 0;
}
public int ReadFromArsenal(int ae) {
if(ae<maxa) {
return a[ae];
}
return 0;
}
public int TakeFromArsenal(int ae) {
int n;
if(ae<maxa) {
n=a[ae];
a[ae]=0;
return n;
}
return 0;
}
}
class
Physics {
double[] x =
{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; // x increment
double[] y =
{0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0}; // y increment
int[] t = {0,0,0,0,0,0,0,0}; // max time
Physics(double x0, double x1, double x2,
double x3, double x4, double x5, double x6,
double x7, double y0, double y1,
double y2, double y3, double y4, double y5,
double y6, double y7, int t0, int
t1, int t2, int t3, int t4, int t5, int t6,
int t7 ) {
x[0]=x0;x[1]=x1;x[2]=x2;x[3]=x3;x[4]=x4;x[5]=x5;x[6]=x6;x[7]=x7;
y[0]=y0;y[1]=y1;y[2]=y2;y[3]=y3;y[4]=y4;y[5]=y5;y[6]=y6;y[7]=y7;
t[0]=t0;t[1]=t1;t[2]=t2;t[3]=t3;t[4]=t4;t[5]=t5;t[6]=t6;t[7]=t7;
}
}
class
PieceList {
int[] l={0,0,0,0,0,0,0,0,0,0}; // e values
int nump;
int maxp;
PieceList(int m) {
nump=0;
maxp=m;
}
public int AddtoPieceList(int pe) {
if(nump<maxp){
l[nump++]=pe;
return 1;
}
return 0;
}
}
class
EffectList {
int[] l={0,0,0,0,0,0,0,0,0,0}; // e values
int nume;
//max Effects
int maxe;
EffectList(int m) {
nume=0;
maxe=m;
}
public int AddtoEffectList(int pe) {
if(nume<maxe){
l[nume++]=pe;
return 1;
}
return 0;
}
}
class
Rules {
int gov=0;
// communications type
int regov=0; // whether to choose a different communication type for
next round
//int vetos=0; // number of vetos allowed
//int portals=0; // portal rules type
int order=0; // order of play
int winning=0; // rules for winning
int roundtype=1; // rulestype of round: 0-competitive, 1-collaborative,
2-teams
int end=0; // rules for end of round
int slantQmgmt=0; // Slant Queue Management Type
boolean slantQclear=true; // Slant Queue
Cleared Between Rounds
double gravity=0.0; // value of gravity parameter
double viscosity=0.0; // value of viscosity parameter
double restitution=0.0; // value of
restitution parameter
int timelimit=0; // time limit for a round
int queuedelay=0; // delay for event queue after select
int dictator=0; // number of player who is dictator
Rules() {
}
}
//-------------------------------------------------------------------
// To use the Ticker class, create an object
and create a thread
// to run it. Thereafter,
any other thread can use it as a
// pacemaker.
class
Ticker implements Runnable {
int t; //
ticks elapsed
int speed=20; // animation rate
Ticker(Panel p) {
speed=20;
}
public void run() {
while (true) {
try { Thread.sleep(speed); }
catch (InterruptedException e) {}
}
}
public void setSpeed(int s) {
speed = s;
}
public int getSpeed() {
return speed;
}
void poll(int eat) { // poll for non-zero tick
while (t==0) {
try { Thread.sleep(speed); }
catch (InterruptedException e) {}
t++;
}
if (eat > t) t = 0;
else t-=eat;
}
void poll() { poll(30000); }
}
//
Connect to world server to exchange information
class
PortToServer extends NetPortToServer {
Marbles i;
int playerno;
int goalx;
int goalcount;
public PortToServer (String host, int
port, Marbles i_in) throws IOException {
super (host,port);
i = i_in;
playerno = -1;
goalcount=0;
}
protected void readInput() throws
IOException {
String line = readUTF();
i.showStatus("LINE= " +
line);
int value;
int value2,value3,value4;
value = line.charAt(0);
if (value=='0') { //players
if(playerno == -1) {
playerno =
Integer.parseInt("" + line.charAt(1));
i.pn = playerno;
}
i.numplay =
Integer.parseInt("" + line.charAt(1));
i.sim_type =
Integer.parseInt("" + line.charAt(2));
} else if (value=='1') { //rules
value=Integer.parseInt("" + line.charAt(1)+ line.charAt(2)+
line.charAt(3));
value2=Integer.parseInt("" + line.substring(7));
//Process Value from Previous
Question
if(value==101) {
i.b.anim.rules.gov = value2; }
else if(value==103) {
i.b.grav.setText("" + (value2/1000) + " seconds to
choose");
} //server maintains time limit
for choosing
else if(value==104) {
value2++;
i.b.grav.setText("Max
" + value2 + " Pieces");
i.pl.maxp=value2;
}
else if(value==105) {
value2++;
i.b.grav.setText("Max
" + value2 + " Events");
i.el.maxe=value2;
}
else if(value==106) {
value2++;
i.b.grav.setText("Max
" + value2 + " in Arsenal");
i.b.anim.ars.maxa=value2;
}
else if(value==107) {
i.b.anim.rules.slantQmgmt=value2;
}
else if(value==108) {
if(value2==0) {
i.b.anim.rules.slantQclear=false; }
else {
i.b.anim.rules.slantQclear=true; }
}
else if(value==109) {
if(value2==0) { i.b.anim.sqt=20; }
else if(value2==1) {
i.b.anim.sqt=40; }
else if(value2==2) {
i.b.anim.sqt=60; }
else if(value2==3) {
i.b.anim.sqt=80; }
else if(value2==4) {
i.b.anim.sqt=100; }
else if(value2==5) {
i.b.anim.sqt=120; }
else if(value2==6) {
i.b.anim.sqt=150; }
i.b.grav.setText("slant
queue changes every " + i.b.anim.sqt + " frames");
}
else if(value==110) {
i.b.anim.rules.winning=value2;
}
else if(value==111) {
i.b.anim.rules.roundtype=value2;
}
else if(value==112) {
if(value2==0) { i.b.anim.eql=20; }
else if(value2==1) {
i.b.anim.eql=30; }
else if(value2==2) {
i.b.anim.eql=40; }
else if(value2==3) { i.b.anim.eql=50; }
else if(value2==4) {
i.b.anim.eql=60; }
else if(value2==5) {
i.b.anim.eql=70; }
i.b.grav.setText("effects active after " + i.b.anim.eql +
" frames");
}
else if(value==113) {
if(value2==0) { i.b.anim.eqd=40; }
else if(value2==1) {
i.b.anim.eqd=60; }
else if(value2==2) {
i.b.anim.eqd=80; }
else if(value2==3) {
i.b.anim.eqd=100; }
else if(value2==4) {
i.b.anim.eqd=120; }
else if(value2==5) {
i.b.anim.eqd=150; }
i.b.grav.setText("effects active for " + i.b.anim.eqd + "
frames");
}
else if(value==114) {
i.b.anim.g=.1 + value2*.04;
i.b.grav.setText("gravity coefficient= " + i.b.anim.g);
}
else if(value==115) {
i.b.anim.r=.5 + value2*.05;
i.b.grav.setText("restitution coefficient=
" + i.b.anim.r);
}
else if(value==116) {
i.b.anim.bm=5 + value2*10;
i.b.grav.setText("mass
coefficient= " + i.b.anim.bm);
}
else if(value==117) {
i.b.anim.f=value2*.005;
i.b.grav.setText("viscosity coefficient= " + i.b.anim.f);
}
else if(value==200) {
i.pl.AddtoPieceList(value2);
}
else if(value==201) {
i.el.AddtoEffectList(value2);
}
i.qno=Integer.parseInt("" + line.charAt(4)+ line.charAt(5)+
line.charAt(6));
if(i.sim_type==0) {
if(i.qno<200) {
i.b.show(); }
if(i.qno==102) {
i.b.Qlibrary(); }
else if(i.qno==103) {
i.b.Qctime(); }
else if(i.qno==104) {
i.b.QnumPieces(); }
else if(i.qno==105) {
i.b.QnumEvents(); }
else if(i.qno==106) {
i.b.QnumArsenal(); }
else if(i.qno==107) {
i.b.QslantQtype(); }
else if(i.qno==108) {
i.b.QslantQwrap(); }
else if(i.qno==109) {
i.b.QslantQtime(); }
else if(i.qno==110) {
i.b.Qwinning(); }
else if(i.qno==111) {
i.b.QnextRound(); }
else if(i.qno==112) {
i.b.QeventQlag(); }
else if(i.qno==113) {
i.b.QeventDuration(); }
else if(i.qno==114) {
i.b.Qgravity(); }
else if(i.qno==115) {
i.b.Qrestitution(); }
else if(i.qno==116) {
i.b.Qmass(); }
else if(i.qno==117) {
i.b.Qviscosity(); }
else if(i.qno==200) {
i.b.Qpieces();
i.b.hide();
i.b.pwindow.setTitle("Choose Pieces");
}
else if(i.qno==201) {
i.b.Qeffects();
i.b.hide();
i.b.pwindow.setTitle("Choose Effects");
}
else if(i.qno==999) {
i.b.pwindow.hide(); i.b.hide(); }
}
} else if (value=='2') { //slant
queue
i.b.anim.sq.AddtoSlantQueue(Integer.parseInt("" +
line.charAt(1)));
i.turncolor++;
if(i.turncolor>i.numplay)
{i.turncolor=1;}
i.UpdateColor(0,i.turncolor);
} else if (value=='3') { //events
queue
i.b.anim.eq.AddtoEffectsQueue(Integer.parseInt("" +
line.substring(4)),
Integer.parseInt("" + line.charAt(1)+ line.charAt(2)+
line.charAt(3)));
} else if (value=='4') { //objects
value=Integer.parseInt("" + line.charAt(3)+ line.charAt(4)+
line.charAt(5))-100;
value2=Integer.parseInt("" + line.charAt(2));
i.removeChildren[value].setValue(i.pieceshape[value]);
if (value2==1) {
i.b.anim.addBall(new
Ball(64,18,Color.white,0,0,0.0,0.0,i.b.anim,1));
i.addNode(value,1,0,1,0,1,0);
} else if (value2==2) {
i.b.anim.addObstacle(new
Obstacle(64,5,Color.gray,-50,0,50,0,0));
i.addNode(value,2,0,-50,0,50,0);
} else if (value2==3) {
i.b.anim.addObstacle(new
Obstacle(64,5,Color.gray,0,50,0,-50,0));
i.addNode(value,3,0,0,50,0,-50);
} else if (value2==4) {
i.b.anim.addObstacle(new
Obstacle(64,5,Color.gray,35,35,-35,-35,0));
i.addNode(value,4,0,0,0,0,0);
} else if (value2==5) {
i.b.anim.addObstacle(new
Obstacle(64,5,Color.gray,-35,35,35,-35,0));
i.addNode(value,5,0,0,0,0,0);
} else if (value2==6) {
i.b.anim.addBall(new
Ball(64,40,Color.pink,0,0,0.0,0.0,i.b.anim,4));
i.addNode(value,0,40,1,1,1,0);
} else if (value2==7) {
i.b.anim.addMoving(64,20,0,0,2,0,1,1);
} else if (value2==8) {
i.b.anim.addMoving(4,20,0,0,8,1,1,0);
}
value3=Integer.parseInt("" + line.charAt(6)+ line.charAt(7)+
line.charAt(8) + line.charAt(9))-1000;
value4=Integer.parseInt("" + line.charAt(10)+ line.charAt(11)+
line.charAt(12) + line.charAt(13))-1000;
i.UpdateVRML(1,value,value3,value4,0,0,0,0,0); //Update visual
if(value>=50) { //Update virtual machine
i.b.anim.obstacle[value-50].UpdateObstacle(value3,value4);
}
else {
i.b.anim.ball[value].UpdateBall(value3,value4);
}
i.turncolor =
Integer.parseInt("" + line.charAt(1));
i.UpdateColor(0,i.turncolor);
} else if (value=='6') { //goals
value3=Integer.parseInt("" + line.charAt(1)+ line.charAt(2)+
line.charAt(3) + line.charAt(4))-1000;
value4=Integer.parseInt("" + line.charAt(5)+ line.charAt(6)+
line.charAt(7) + line.charAt(8))-1000;
i.b.anim.addGoal(new
Goal(20,5,value3,value4));
i.addGoal(goalcount,5,value3,value4);
goalcount++;
} else if (value=='8') { //timer
speed
i.b.anim.tick.setSpeed(Integer.parseInt("" +
line.substring(1)));
i.b.anim.timeOK=true;
} else if (value=='9') { //world
mode
i.mode =
Integer.parseInt("" + line.charAt(1));
if(i.mode==3) {
i.b.anim.theDate = new
Date();
i.b.anim.starttime =
i.b.anim.theDate.getTime();
}
i.lastmodesent = 1;
i.Paletize(i.mode);
}
}
protected void writeToServer(String
outgoing) {
try {
writeUTF(outgoing);
flush();
}
catch(IOException e) {}
}
}