package cannon; /*######################################################################## * * Auth: Sean E. Russell * University of Oregon, CIS * Date: Thu Aug 10 10:34:06 PDT 1995 * * Synopsis: * * - Mon Aug 14 15:23:46 PDT 1995 * It's not my fault. I started this when Java was in it's Alpha-3 * release, when the documentation was non-existant, examples were * scarce, and the AWT package was primative. I refuse to take any * blame for injuries incurred while reading this code. * That said, cannon is a Java class for HotJava which is supposed * to provide an example of a simple gravity/velocity environment. The * user has a cannon which he may shoot. He is able to vary the angle * of the cannon and the velocity of the projectile, and view the * results of his input. That's all it does so far, and it doesn't * do it well. AWT is a nightmare. * * - Thu Aug 17 17:41:59 PDT 1995 * Well, considering what I had to go through to figure out how the * layout engine behaves, the code doesn't look *too* bad. Sound and * rudimentry animation has been added. As it is, I would consider * this a usable app. * Needing to be done: explosion for target and sounds for a miss. * There are numerous cosmetic features that can be worked on, but * I'll leave those until someone requests them. * * - Sun Aug 20 00:34:18 PDT 1995 * Ha! Perfection! The animation, the smoke trail; the sound... * it even refreshes correctly. I don't like the way the code looks; * it's very messy, and a lot of things are hardcode that shouldn't be. * Due to the need for my services on a number of other projects, I'm * not going to fix things like the dependancy on a small font size in * the UI. Maybe later. * I was harsh on AWT. Its not poorly designed; its just poorly * documented. All in all, not bad for an Alpha release, even if the * layout engine is unpredictable at times. * ######################################################################*/ import java.awt.*; import java.net.*; import java.lang.Math; import java.lang.Integer; public class cannon extends java.applet.Applet { double dx, dy, theta, velocity, gravity, windage; int xmax, ymax, numshots; Color black, erase; double x, y; double xo[] = new double[4]; double yo[] = new double[4]; double rads; boolean dosound; CannonFrame frame; Graphics drawarea; Image can, shot, targ, targ2, bang1, puff1, puff2, puff3, puff4; public void more() { numshots = 4; repaint(); } public void shootShot() { if (numshots > 0) { numshots--; play(getCodeBase(), "sounds/cannon.au"); dosound = true; repaint(); } } public void loadImages() { can = getImage(getCodeBase(), "images/cannon.gif"); shot = getImage(getCodeBase(), "images/ammo.gif"); targ = getImage(getCodeBase(), "images/target.gif"); targ2 = getImage(getCodeBase(), "images/target2.gif"); bang1 = getImage(getCodeBase(), "images/bang1.gif"); puff1 = getImage(getCodeBase(), "images/puff1.gif"); puff2 = getImage(getCodeBase(), "images/puff2.gif"); puff3 = getImage(getCodeBase(), "images/puff3.gif"); puff4 = getImage(getCodeBase(), "images/puff4.gif"); } public void init() { loadImages(); numshots = 4; rads = 57.29577866f; xmax = 600; ymax = 300; resize(xmax,ymax+20); theta = 60; // degrees theta /= rads; // -> radians velocity = 3; // m/s x 10^-1 gravity = .098f; // m/s^2 x 10^-2 windage = 0; black = Color.black; erase = Color.blue; frame = new CannonFrame(this); } public void changeAngle(int val) { Integer temp = new Integer(val); theta = (double)val; // degrees theta /= rads; // -> radians frame.ang.setText(temp.toString()); } public void changeVelocity(int val) { Integer temp = new Integer(val); velocity = (double)val / 5; frame.vel.setText(temp.toString()); } public void changeGravity(int val) { Float temp = new Float((float)val / 10); gravity = (double)val / 1000; frame.grav.setText(temp.toString()); } public void changeWindage(int val) { Integer temp = new Integer(val); windage = (double)val / 200; frame.wind.setText(temp.toString()); } public void paint(Graphics g) { if (can == null) { return; } drawarea = g; //##### Cannon part //##### Draw images g.drawImage(can, 20, ymax - can.getHeight(this), this); g.drawImage(targ, xmax - (targ.getWidth(this) + 10), ymax - targ.getHeight(this), this); if (numshots > 3) g.drawImage(shot, 0, ymax - ((2*shot.getHeight(this))+2), this); if (numshots > 2) g.drawImage(shot, 2 + shot.getWidth(this), ymax - ((2*shot.getHeight(this))+2), this); if (numshots > 1) g.drawImage(shot, 0, ymax - shot.getHeight(this), this); if (numshots >0) g.drawImage(shot, 2 + shot.getWidth(this), ymax - shot.getHeight(this), this); if (numshots < 4) { //##### Shoot da shot x = 65; y = ymax-55; dx = velocity * Math.cos(theta); dy = velocity * Math.sin(theta); g.setColor(Color.gray); while ((x > 0) && (x < xmax) && (y < ymax)) { if (xo[3] != 0) g.clearRect((int)xo[3] - 4, (int)yo[3] - 4, 8, 7); if (xo[0] != 0) g.drawRect((int)xo[0]-1, (int)yo[0]-1, 2, 2); g.drawImage(shot, (int)x - 4, (int)y - 4, this); if (x < 75) g.drawImage(can, 20, ymax - can.getHeight(this), this); if ((x>xmax-(targ.getWidth(this)+10)) && (y>ymax-targ.getHeight(this))) g.drawImage(targ, xmax - (targ.getWidth(this)+10), ymax - targ.getHeight(this), this); if (dosound)try {Thread.sleep(5);} catch (InterruptedException e){} xo[0] = xo[1]; xo[1] = xo[2]; xo[2] = xo[3]; yo[0] = yo[1]; yo[1] = yo[2]; yo[2] = yo[3]; xo[3] = x; yo[3] = y; x += dx; dx -= windage/2; y -= dy; dy -= gravity/2; //##### Check for hit if ((x>(xmax-43)) && (x<(xmax-27)) && (y>(ymax-40)) && (y<(ymax-25))) { if (dosound) { play(getCodeBase(), "sounds/explosion.au"); //##### Draw FX // Bang over full target g.drawImage(bang1, xmax - (targ.getWidth(this)+10), ymax - targ.getHeight(this), this); // puff1 over targ2 try {Thread.sleep(75);} catch (InterruptedException e){} g.clearRect(xmax-(targ.getWidth(this)+10), ymax-targ2.getHeight(this), (targ.getWidth(this)+10), targ2.getHeight(this)); g.drawImage(targ2, xmax - (targ.getWidth(this)+10), ymax - targ2.getHeight(this), this); play(getCodeBase(), "sounds/applause.au"); g.drawImage(puff1, xmax - (targ.getWidth(this)+15), ymax - (targ.getHeight(this)+40), this); // Puff2 over targ2 try {Thread.sleep(75);} catch (InterruptedException e){} g.clearRect(xmax-(targ.getWidth(this)+15), ymax-(targ.getHeight(this)+40), (targ.getWidth(this)+15), (targ.getHeight(this)+40)); g.drawImage(targ2, xmax - (targ.getWidth(this)+10), ymax - targ2.getHeight(this), this); g.drawImage(puff2, xmax - (targ.getWidth(this)+15), ymax - (targ.getHeight(this)+40), this); // puff3 over targ2 try {Thread.sleep(75);} catch (InterruptedException e){} g.clearRect(xmax-(targ.getWidth(this)+15), ymax-(targ.getHeight(this)+40), (targ.getWidth(this)+15), (targ.getHeight(this)+40)); g.drawImage(targ2, xmax - (targ.getWidth(this)+10), ymax - targ2.getHeight(this), this); g.drawImage(puff3, xmax - (targ.getWidth(this)+10), ymax - (targ.getHeight(this)+40), this); // puff4 over targ2 try {Thread.sleep(75);} catch (InterruptedException e){} g.clearRect(xmax-(targ.getWidth(this)+15), ymax-(targ.getHeight(this)+40), (targ.getWidth(this)+15), (targ.getHeight(this)+40)); g.drawImage(targ2, xmax - (targ.getWidth(this)+10), ymax - targ2.getHeight(this), this); g.drawImage(puff4, xmax - (targ.getWidth(this)+10), ymax - (targ.getHeight(this)+40), this); dosound = false; try {Thread.sleep(75);} catch (InterruptedException e){} } // targ2 g.clearRect(xmax-(targ.getWidth(this)+15), ymax-(targ.getHeight(this)+40), (targ.getWidth(this)+15), (targ.getHeight(this)+40)); g.drawImage(targ2, xmax - (targ.getWidth(this)+10), ymax - targ2.getHeight(this), this); x=0; } } for (int i=0; i<4; i++) xo[i] = yo[i] = 0; } } public void start() { if (frame != null) { frame.show(); } } public void stop() { if (frame != null) { frame.hide(); } } public void destroy() { if (frame != null) { frame.dispose(); frame = null; } } } class CannonFrame extends Frame { cannon can; TextField ang; TextField vel; TextField grav; TextField wind; Scrollbar s_ang; Scrollbar s_vel; Scrollbar s_grav; Scrollbar s_wind; CannonFrame(cannon can) { this.can = can; setTitle("Cannon"); Panel p; add("North", p = new Panel()); p.add(new Label("Ang:")); p.add(ang = new TextField("60", 4)); ang.setEditable(false); p.add(new Label("Vel:")); p.add(vel = new TextField("15", 4)); vel.setEditable(false); p.add(new Label("Grav:")); p.add(grav = new TextField("9.8", 4)); grav.setEditable(false); p.add(new Label("Wind:")); p.add(wind = new TextField("0", 4)); wind.setEditable(false); add("Center", p = new Panel()); p.setLayout(new GridLayout(4, 0)); p.add(s_ang = new Scrollbar(Scrollbar.HORIZONTAL)); s_ang.setValues(60, 10, 1, 90); p.add(s_vel = new Scrollbar(Scrollbar.HORIZONTAL)); s_vel.setValues(10, 2, 1, 30); p.add(s_grav = new Scrollbar(Scrollbar.HORIZONTAL)); s_grav.setValues(98, 10, 40, 200); p.add(s_wind = new Scrollbar(Scrollbar.HORIZONTAL)); s_wind.setValues(0, 1, -10, 10); add("South", p = new Panel()); p.add(new Button("Shoot")); p.add(new Button("More Ammo")); pack(); //list(); } public boolean handleEvent(Event evt) { //System.out.println("evt = " + evt); if (evt.target == s_ang) { can.changeAngle(((Integer)evt.arg).intValue()); return true; } if (evt.target == s_vel) { can.changeVelocity(((Integer)evt.arg).intValue()); return true; } if (evt.target == s_grav) { can.changeGravity(((Integer)evt.arg).intValue()); return true; } if (evt.target == s_wind) { can.changeWindage(((Integer)evt.arg).intValue()); return true; } if ("Shoot".equals(evt.arg)) { can.shootShot(); return true; } if ("More Ammo".equals(evt.arg)) { can.more(); return true; } return super.handleEvent(evt); } }