import vrml.*; import vrml.node.*; import vrml.field.*; public class Laser extends Script { final static int IDLE = 0; final static int MOVING = 1; final static int EXPLODE = 2; final static int RELOAD = 3; //internal private int state; private float initial[]; private Browser b; private int count; private float s; //fields private float damage; private Node thisLaser; private Node owner; private Node ownerScript; private Node world; private Node choice; private Node clock; //outputs private SFVec3f translation_changed; private SFVec3f scale_changed; private SFInt32 choice_changed; private SFInt32 laser_hit; // This method is called when the script is loaded public void initialize() { SFVec3f temp; initial = new float[3]; state = IDLE; damage = ((SFFloat) getField("damage")).getValue(); thisLaser = (Node) ((SFNode) getField("thisLaser")).getValue(); owner = (Node) ((SFNode) getField("owner")).getValue(); ownerScript = (Node) ((SFNode) getField("ownerScript")).getValue(); world = (Node) ((SFNode) getField("world")).getValue(); choice = (Node) ((SFNode) getField("choice")).getValue(); clock = (Node) ((SFNode) getField("clock")).getValue(); temp = (SFVec3f)thisLaser.getExposedField("translation"); initial[0] = temp.getX(); initial[1] = temp.getY(); initial[2] = temp.getZ(); //eventouts translation_changed = (SFVec3f) getEventOut("translation_changed"); scale_changed = (SFVec3f) getEventOut("scale_changed"); choice_changed = (SFInt32) getEventOut("choice_changed"); laser_hit = (SFInt32) getEventOut("laser_hit"); b = world.getBrowser(); //routings b.addRoute(this,"translation_changed",thisLaser,"set_translation"); b.addRoute(this,"scale_changed",thisLaser,"set_scale"); b.addRoute(this,"choice_changed",choice,"set_whichChoice"); b.addRoute(clock,"fraction_changed",this,"set_fraction"); b.addRoute(this,"laser_hit",ownerScript,"laser_hit"); } private void set_fraction(ConstSFFloat frac) { int i; SFVec3f l,d; boolean isHit; switch (state) { case IDLE: break; case MOVING: if (count < 5) { count++; } else { translation_changed.setValue(initial[0],initial[1],initial[2]+s); choice_changed.setValue(1); state = EXPLODE; s = 1.0f; } //m = (SFVec3f)thisLaser.getExposedField("translation"); /* isHit = false; for (i=0; i<otherRobot.getSize(); i++) { d = (SFVec3f)((Node)otherRobot.get1Value(i)).getExposedField("translation"); l = (float)Math.sqrt( (m.getX()-d.getX())*(m.getX()-d.getX())+(m.getY()-d.getY())*(m.getY()-d.getY())+ (m.getZ()-d.getZ())*(m.getZ()-d.getZ()) ); if (l < 0.5f) { missle_hit.setValue(i); isHit = true; break; } } if (!isHit) { if ( (Math.abs(m.getX()) > 8.0) || (Math.abs(m.getY()) > 8.0) ) state = RELOAD; else translation_changed.setValue(m.getX()+delta[0],m.getY()+delta[1],m.getZ()+delta[2]); } else { choice_changed.setValue(1); s = 1.0f; state = EXPLODE; } */ break; case EXPLODE: if (s < 3.0) { s = s+0.5f; scale_changed.setValue(s,s,s); } else { state = RELOAD; } break; case RELOAD: laser_hit.setValue(0); scale_changed.setValue(1.0f,1.0f,1.0f); choice_changed.setValue(-1); translation_changed.setValue(initial[0],initial[1],initial[2]); state = IDLE; break; } } private void set_target(ConstSFVec3f t) { SFVec3f r,l; float dx,dz; r = (SFVec3f)owner.getExposedField("translation"); l = (SFVec3f)thisLaser.getExposedField("translation"); dx = t.getX()-r.getX(); dz = t.getZ()-r.getZ(); choice_changed.setValue(0); s = (float)Math.sqrt(dx*dx+dz*dz); translation_changed.setValue(l.getX(),l.getY(),l.getZ()+s/2.0f); scale_changed.setValue(1.0f,1.0f,s); count = 0; state = MOVING; } // In Java, you have to explicitly handle each event using the // processEvent method. Use it to call a private method for each event. public void processEvent (Event e) { String EventName = e.getName(); if (EventName.equals("set_fraction")) set_fraction((ConstSFFloat)e.getValue()); else if (EventName.equals("set_target")) set_target((ConstSFVec3f)e.getValue()); } }