diff options
Diffstat (limited to 'src/jrummikub/view/impl')
-rw-r--r-- | src/jrummikub/view/impl/Board.java | 12 | ||||
-rw-r--r-- | src/jrummikub/view/impl/StonePainter.java | 148 |
2 files changed, 133 insertions, 27 deletions
diff --git a/src/jrummikub/view/impl/Board.java b/src/jrummikub/view/impl/Board.java index dc26dd4..2e02f75 100644 --- a/src/jrummikub/view/impl/Board.java +++ b/src/jrummikub/view/impl/Board.java @@ -2,7 +2,9 @@ package jrummikub.view.impl; import java.awt.Color; import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; +import java.awt.RenderingHints; import java.util.Collections; import java.util.Map; @@ -18,6 +20,7 @@ public class Board extends JPanel implements IBoard { private final static ImageIcon background = new ImageIcon(Board.class.getResource("/jrummikub/resource/wood.png")); private Map<Stone, Position> stones = Collections.emptyMap(); + private StonePainter stonePainter = new StonePainter(StonePainter.BOARD_SCALE); Board() { super(true); @@ -26,10 +29,10 @@ public class Board extends JPanel implements IBoard { } @Override - protected void paintComponent(Graphics g) { + protected void paintComponent(Graphics g1) { Insets insets = getInsets(); int x = insets.left, y = insets.top, width = getWidth()-insets.left-insets.right, height = getHeight()-insets.top-insets.bottom; - g = g.create(x, y, width, height); + Graphics2D g = (Graphics2D)g1.create(x, y, width, height); for(int xpos = 0; xpos < width; xpos += background.getIconWidth()) { background.paintIcon(this, g, xpos, 0); @@ -38,8 +41,11 @@ public class Board extends JPanel implements IBoard { background.paintIcon(this, g, xpos, 75); } + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + for (Map.Entry<Stone, Position> stone : stones.entrySet()) { - StonePainter.paintStone(g, stone.getKey(), stone.getValue(), StonePainter.BOARD_SCALE); + stonePainter.paintStone(g, stone.getKey(), stone.getValue()); } } diff --git a/src/jrummikub/view/impl/StonePainter.java b/src/jrummikub/view/impl/StonePainter.java index e536e32..9e836e5 100644 --- a/src/jrummikub/view/impl/StonePainter.java +++ b/src/jrummikub/view/impl/StonePainter.java @@ -1,11 +1,12 @@ package jrummikub.view.impl; +import java.awt.BasicStroke; import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; -import java.awt.Graphics; import java.awt.Graphics2D; -import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.geom.GeneralPath; import java.awt.geom.Rectangle2D; import jrummikub.model.Position; @@ -15,40 +16,53 @@ import jrummikub.model.StoneColor; class StonePainter { private static final float ASPECT_RATIO = 0.75f; private static final float DEFAULT_WIDTH = 40; - private static final float CIRCLE_WIDTH = 0.5f; + private static final float TEXT_POS = 0.275f; + private static final float FACE_WIDTH = 0.475f; + private static final float CIRCLE_POS = 0.725f; + private static final float CIRCLE_WIDTH = 0.45f; + private static final Color BACKGROUND_COLOR = new Color(0.9f, 0.9f, 0.6f); public static final float BOARD_SCALE = 75.0f*ASPECT_RATIO/DEFAULT_WIDTH; + private float scale; + + + private static int even(float f) { + return 2*(int)(f/2); + } + private static Color getColor(StoneColor color) { switch(color) { case BLACK: - return Color.BLACK; + return new Color(0.15f, 0.15f, 0.15f); case BLUE: - return Color.BLUE; + return new Color(0.0f, 0.0f, 1.0f); case ORANGE: - return new Color(1.0f, 0.6f, 0); + return new Color(1.0f, 0.6f, 0.0f); case RED: - return Color.RED; + return new Color(0.9f, 0.0f, 0.25f); } return null; } - public static void paintStone(Graphics g, Stone stone, Position p, float scale) { - if (g instanceof Graphics2D) { - ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, - RenderingHints.VALUE_ANTIALIAS_ON); - } - - int width = (int)(DEFAULT_WIDTH*scale); - int height = (int)(DEFAULT_WIDTH*scale/ASPECT_RATIO); - - int x = (int)(p.getX()*width); - int y = (int)(p.getY()*height); - + public void setScale(float scale) { + this.scale = scale; + } + + public float getScale() { + return scale; + } + + StonePainter(float scale) { + this.scale = scale; + } + + private void paintStoneBackground(Graphics2D g, int x, int y, + int width, int height) { // Paint background g.setColor(BACKGROUND_COLOR); g.fillRect(x, y, width, height); @@ -73,23 +87,109 @@ class StonePainter { g.fillRect(x, y+height-1, width, 1); g.setColor(BACKGROUND_COLOR.darker()); g.fillRect(x+1, y+height-2, width-2, 1); + } + + private void paintJokerFace(Graphics2D g, int x, int y, int width, int height, + Stone stone) { + Stroke oldStroke = g.getStroke(); + + g.setStroke(new BasicStroke(2)); + g.drawOval(x, y, width, height); + + g.setStroke(new BasicStroke(1)); + GeneralPath path = new GeneralPath(); + // nose + path.moveTo(x+0.5f*width, y+0.45f*height); + path.lineTo(x+0.53f*width, y+0.6f*height); + path.lineTo(x+0.47f*width, y+0.6f*height); + path.closePath(); + g.fill(path); + + path.reset(); + // mouth, left + path.moveTo(x+0.23f*width, y+0.75f*width); + path.lineTo(x+0.27f*width, y+0.65f*width); + // mouth, middle + path.moveTo(x+0.25f*width, y+0.7f*width); + path.lineTo(x+0.5f*width, y+0.8f*width); + path.lineTo(x+0.75f*width, y+0.7f*width); + // mouth, right + path.moveTo(x+0.77f*width, y+0.75f*width); + path.lineTo(x+0.73f*width, y+0.65f*width); + g.draw(path); + + path.reset(); + // left eye + path.moveTo(x+0.3f*width, y+0.41f*height); + path.lineTo(x+0.375f*width, y+0.375f*height); + path.lineTo(x+0.3f*width, y+0.34f*height); + path.lineTo(x+0.225f*width, y+0.375f*height); + path.closePath(); + g.draw(path); + + path.reset(); + // right eye + path.moveTo(x+0.7f*width, y+0.41f*height); + path.lineTo(x+0.625f*width, y+0.375f*height); + path.lineTo(x+0.7f*width, y+0.34f*height); + path.lineTo(x+0.775f*width, y+0.375f*height); + path.closePath(); + g.draw(path); + + g.setStroke(oldStroke); + } + + private void paintJoker(Graphics2D g, int x, int y, int width, int height, + Stone stone) { + int faceSize = even(FACE_WIDTH*width); + int pos = y + (int)(TEXT_POS*height); + + g.setColor(getColor(stone.getColor())); + paintJokerFace(g, x+width/2-faceSize/2, pos-faceSize/2, faceSize, faceSize, stone); + } + + private void paintStoneNumber(Graphics2D g, int x, int y, int width, + int height, Stone stone) { + int pos = y + (int)(TEXT_POS*height); - // Paint number g.setFont(new Font("SansSerif", Font.BOLD, height/4)); FontMetrics fm = g.getFontMetrics(); String value = Integer.toString(stone.getValue()); Rectangle2D stringRect = fm.getStringBounds(value, g); g.setColor(getColor(stone.getColor()).darker()); - g.drawString(value, (int)(x+width/2-stringRect.getWidth()/2)+1, y+height/4+(fm.getAscent()-fm.getDescent())/2+1); + g.drawString(value, (int)(x+width/2-stringRect.getWidth()/2)+1, pos+(fm.getAscent()-fm.getDescent())/2+1); g.setColor(getColor(stone.getColor())); - g.drawString(value, (int)(x+width/2-stringRect.getWidth()/2), y+height/4+(fm.getAscent()-fm.getDescent())/2); + g.drawString(value, (int)(x+width/2-stringRect.getWidth()/2), pos+(fm.getAscent()-fm.getDescent())/2); + } + + private void paintCircle(Graphics2D g, int x, int y, int width, int height) { + int size = even(width*CIRCLE_WIDTH); + int pos = y + (int)(CIRCLE_POS*height); // Paint circle g.setColor(BACKGROUND_COLOR.darker()); - g.drawArc((int)(x+width/2-width*CIRCLE_WIDTH/2), (int)(y+height*0.65f-width*CIRCLE_WIDTH/2), (int)(width*CIRCLE_WIDTH), (int)(width*CIRCLE_WIDTH), 50, 170); + g.drawArc(x+width/2-size/2, pos-size/2, size, size, 50, 170); g.setColor(BACKGROUND_COLOR.brighter()); - g.drawArc((int)(x+width/2-width*CIRCLE_WIDTH/2), (int)(y+height*0.65f-width*CIRCLE_WIDTH/2), (int)(width*CIRCLE_WIDTH), (int)(width*CIRCLE_WIDTH), -130, 170); + g.drawArc((int)(x+width/2-size/2), pos-size/2, size, size, -130, 170); + } + + public void paintStone(Graphics2D g, Stone stone, Position p) { + int width = even(DEFAULT_WIDTH*scale); + int height = (int)(DEFAULT_WIDTH*scale/ASPECT_RATIO); + + int x = (int)(p.getX()*width); + int y = (int)(p.getY()*height); + + paintStoneBackground(g, x, y, width, height); + + if (stone.isJoker()) { + paintJoker(g, x, y, width, height, stone); + } else { + paintStoneNumber(g, x, y, width, height, stone); + } + + paintCircle(g, x, y, width, height); } } |