Skift Wolf Skift Wolf - 1 month ago 9
Java Question

Can I add different canvas strokes into an array?

I am currently using a switch/case grouping to add body parts to my hangman game. As the incorrect guesses increase, a limb is added. This is forming a long switch block and was wondering if I can add each case to an array, ArrayList, TreeMap, etc. of some sort and call the body parts based on their index number? Some are strokeLines, while others are strokeOvels.

I am not a student, but was helping a friend who is and while I coded this myself, I am stuck at a rode block with ugly code. That said, due to this being used for many CS classes (based on google searches), I am changing the numbers to X's and Y's. I am here for help, not to hand others a cheatsheet to their assignments.

public void paint(){
GraphicsContext g = gameCanvas.getGraphicsContext2D();

switch (newGame.getIncGuessMade()){
case 0:{
//gallows...
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
g.strokeLine(X,Y,X,Y);
}
break;
case 1: g.strokeOval(X,Y,X,Y); //head
break;
case 2: g.strokeLine(X,Y,X,Y); //chest
break;
case 3: g.strokeLine(X,Y,X,Y); //Right Arm
break;
case 4: g.strokeLine(X,Y,X,Y); //Left Arm
break;
case 5: g.strokeLine(X,Y,X,Y); //Right Leg
break;
case 6: g.strokeLine(X,Y,X,Y); //Left Leg
break;
case 7: g.strokeOval(X,Y,X,Y); //Right Eye
break;
case 8: g.strokeOval(X,Y,X,Y); //Left Eye
break;
}

}

Answer

Option 1: You could do a 2d array.

double[][] strokes = new double[][] {
    { ... },
    ...
    { ... }
};

Then,

public void paint(){
    GraphicsContext g = gameCanvas.getGraphicsContext2D();
    int i = newGame.getIncGuessMade();
    g.strokeLine(strokes[i][0], ..., strokes[i][3]);
}

Of course, you would have to handle the gallows and others with different methods a little differently with a check on i which makes it less than great.


Option 2: I would opt for a Gallows with a draw(g) method that is constructed with the values and stored there. The same argument could be made for all the drawing components as well.

public interface Drawable {
    void draw(GraphicsContext g);
}

public class Gallows implements Drawable {
    @Override
    public void draw(GraphicsContext g) {
        // call what you need to draw the gallows.
    }
}

public class Head implements Drawable {
    @Override
    public void draw(GraphicsContext g) {
        // call what you need to draw the head.
    }
}

Each of these drawables will have their coordinates locally. The calling code need not know any details of what draw means for each; it only needs to know to call draw on them.


Option 3: If you don't like that way and you're using Java 8 you could have the same 2d double array as before and write BiConsumer<GraphicsContext, double[]>s and store them in an array or list as well. Example:

BiConsumer<GraphicsContext, double[]> chest = (g, strokes) -> {
    g.strokeLine(strokes[0], ..., strokes[3]); 
};

You'd then call it like:

chest.accept(g, strokes[i]);

or, assuming it's in an array, like this:

consumers[i].accept(g, strokes[i]);

Comments