/** * Class ScaffoldCanvas draws a Hangman-style scaffold graphic in its own moveable * component according to the number of lives left (max 10, 11=reprieve). Just call * setLivesRemaining(int i) to redisplay, where 10 > i > 0 for normal stages, or * call decLivesRemaining() to decrement by one life. * * ScaffoldCanvas.KILL is a static constant 0 for instant death, or * ScaffoldCanvas.REPRIEVE is a static constant 11 for instant let-off. * * Everything is scaleable relative to the basic 9 x 16 matrix by setting a scale * factor with setScale(). Text only shows if scale factor is 10 or above. * * Constructors: Scaffold Canvas(), ScaffoldCanvas(int scaleFactor) * Methods: setLivesRemaining(int l) * decLivesRemaining() * getLivesRemaining(), returns int * setScale(int scaleFactor), */ import java.awt.*; public class ScaffoldCanvas extends Canvas { private int livesRemaining; private final String doomWord, joyWord; private final String [] elements; private final String [] messages; private boolean showText; public int gScale; static final int KILL = 0; //to be used as livesRemaining value static final int REPRIEVE = 11; //to be used as livesRemaining value /** * Constructor that includes scale (and therefore size implications) */ ScaffoldCanvas(int scaleFactor) { elements = new String[12]; /*swinger s *rope r *crossbar c *upright u *LarmU LAU *LarmD LAD *RarmU RAU *RarmD RAD *Lleg LL *Rleg RL *body b *head h *ground g *joyWord j *doomWord d */ elements[0]="g.u.c.s"; elements[1]="g.h.b.LL.RL.LAD.RAD.u.c.r.d"; elements[2]="g.h.b.LL.RL.LAD.RAD.u.c"; elements[3]="g.h.b.LL.RL.LAD.RAD.u"; elements[4]="g.h.b.LL.RL.LAD.RAD"; elements[5]="g.h.b.LL.RL.LAD"; elements[6]="g.h.b.LL.RL"; elements[7]="g.h.b.LL"; elements[8]="g.h.b"; elements[9]="g.h"; elements[10]="g"; elements[11]="g.h.b.LL.RL.LAU.RAU.j"; messages = new String[12]; messages[0]="Oh dear!"; messages[1]="Last chance!"; for (int i=2;i<11;i++) { messages[i]=i+" lives left"; } messages[11]="Well done!"; doomWord=" oo-er!"; joyWord=" yay!"; setScale(scaleFactor); setLivesRemaining(10); } /** * Constructor that includes no parameters. */ ScaffoldCanvas() { this(10); } /** * The setLivesRemaining method allows you to set the number of lives remaining * from 11 down to 0. 10 to 1 represent various stages of the process. * 0 represents the execution state and 11 represents a reprieve. * (You can also use final variables EXECUTE and REPRIEVE.) The full canvas graphic * is drawn each time, with no need to do this inc/decrementally. So it's * possible to start with only 5 lives left, etc. */ public void setLivesRemaining(int lr) { livesRemaining=lr; Color c; switch (lr) { case 11 : this.setBackground(Color.pink);break; case 0 : this.setBackground(new Color(100, 120, 140));break; default : this.setBackground(new Color(10*lr, 200-10*(10-lr), 255-7*(10-lr))); } this.repaint(); } /** * The decLivesRemaining method reduces the number of lives remaining by 1. * (0 decs to 11 for testing, but that shouldn't ever occur in use.) */ public void decLivesRemaining() { int l = getLivesRemaining(); l = (l==0) ? 11 : l-1; setLivesRemaining(l); repaint(); } /** *The method getLivesRemaining retrieves the current number of lives remaining. */ public int getLivesRemaining() {return this.livesRemaining;} /** *The setScale method sets the scale (and therefore the size) of the canvas. *Text messages don't fit when the scale factor is less than 10, so their flag *is set accordingly. */ public void setScale(int scaleFactor) { this.gScale = scaleFactor; showText = !(scaleFactor<10); this.setSize(9*gScale, 16*gScale); this.repaint(); } //////this is the paint method that does the business////////////////////// public void paint(Graphics g) { String s = elements[livesRemaining]; String m = messages[livesRemaining]; if (showText) drawString(g, m, 1, 15); if (s.indexOf("s")>-1) //swinger suspended from gallows { drawLine(g, 6, 2, 6, 6); // rope g.setColor(new Color(0, 0, 127)); drawOval(g, 4, 5, 2, 2); // head drawLine(g, 6, 6, 6, 8); // body //have to include gScale here for droopy arms/legs g.drawLine(6*gScale, 8*gScale, 5*gScale+6, 11*gScale); // right leg g.drawLine(6*gScale, 8*gScale, 7*gScale-6, 11*gScale); // left leg g.drawLine(6*gScale, 7*gScale, 5*gScale+6, 9*gScale); // right arm g.drawLine(6*gScale, 7*gScale, 7*gScale-6, 9*gScale); // left arm g.setColor(Color.black); } if (s.indexOf("h")>-1) drawOval(g, 5, 7, 2, 2); //head if (s.indexOf("b")>-1) drawLine(g, 6, 9, 6, 11); //body if (s.indexOf("RL")>-1) drawLine(g, 6, 11, 5, 14); //R leg if (s.indexOf("LL")>-1) drawLine(g, 6, 11, 7, 14); //L leg if (s.indexOf("RAD")>-1) drawLine(g, 6, 10, 4, 12); //R arm down if (s.indexOf("RAU")>-1) drawLine(g, 6, 10, 4, 9); //R arm up if (s.indexOf("LAD")>-1) drawLine(g, 6, 10, 8, 12); //L arm down if (s.indexOf("LAU")>-1) drawLine(g, 6, 10, 8, 9); //L arm up if (s.indexOf("u")>-1) { fillRect(g, 1, 2, 1, 12); //upright drawLine(g, 2, 4, 4, 2); //bracket } if (s.indexOf("c")>-1) fillRect(g, 1, 1, 6, 1); //crossbar if (s.indexOf("r")>-1) drawLine(g, 6, 2, 6, 7); //rope if (s.indexOf("g")>-1) drawLine(g, 0, 14, 9, 14); //ground if ((s.indexOf("j")>-1)&&(showText)) drawString(g, joyWord, 2, 7); //joyWord if ((s.indexOf("d")>-1)&&(showText)) drawString(g, doomWord, 2, 7); //doomWord } //these methods do the actual drawing, applying the scale factor private void drawOval(Graphics g, int a, int b, int c, int d) {g.drawOval(a*gScale, b*gScale, c*gScale, d*gScale);} private void drawLine(Graphics g, int a, int b, int c, int d) {g.drawLine(a*gScale, b*gScale, c*gScale, d*gScale);} private void fillRect(Graphics g, int a, int b, int c, int d) {g.fillRect(a*gScale, b*gScale, c*gScale, d*gScale);} private void drawString(Graphics g, String s, int a, int b) {g.drawString(s, a*gScale, b*gScale);} }