如何将图像添加到六边形网格中的六边形?

时间:2015-06-07 11:52:52

标签: java image swing hexagonal-tiles

我的六边形网格有问题。我发现这个代码你可以在互联网上看到,所以它不是我的。有两个公共类:hexgame生成网格,hexmech绘制并填充每个六边形。我想要做的基本上是将图像插入特定的六边形,但我不知道如何编写这个以及我应该把它放在哪个类的部分。我的想法是错误的吗?

非常感谢你的帮助!

Hexgame

package hex;

import java.awt.*;
import javax.swing.*;
import java.awt.event.*; 

public class hexgame
{
private hexgame() {
    initGame();
    createAndShowGUI();
}

final static Color COLOURBACK =  Color.WHITE;
final static Color COLOURCELL =  Color.WHITE;    
final static Color COLOURGRID =  Color.BLACK;    
final static Color COLOURONE = new Color(255,255,255,200);
final static Color COLOURONETXT = Color.BLUE;
final static Color COLOURTWO = new Color(0,0,0,200);
final static Color COLOURTWOTXT = new Color(255,100,255);
final static Color COLOURSAFE = Color.WHITE;
final static Color COLOURDANGEROUS = Color.LIGHT_GRAY;
final static int EMPTY = 0;
final static int UNKNOWN = -1;
final static int SAFE = 1;
final static int DANGEROUS = 2;
final static int CLICKED = 3;
final static int COLUMN_SIZE = 23;
final static int ROW_SIZE = 14;
final static int HEXSIZE = 45;
final static int BORDERS = 15;  

int[][] board = new int[COLUMN_SIZE][ROW_SIZE];

void initGame(){

    hexmech.setXYasVertex(false);
    hexmech.setHeight(HEXSIZE);
    hexmech.setBorders(BORDERS);

    for (int i=0;i<COLUMN_SIZE;i++) {
        for (int j=0;j<ROW_SIZE;j++) {
            board[i][j]=EMPTY;
        }
    }

    board[5][5] = SAFE;
    board[5][6] = SAFE;
    board[5][7] = SAFE;
    board[6][5] = SAFE;
    board [6][6] = SAFE;
    board[4][4] = UNKNOWN;
}

private void createAndShowGUI()
{
    DrawingPanel panel = new DrawingPanel();
    JFrame frame = new JFrame("Hex Testing 4");
    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
    Container content = frame.getContentPane();
    content.add(panel);
    frame.setSize(825, 630);
    frame.setResizable(true);
    frame.setLocationRelativeTo( null );
    frame.setVisible(true);
}

class DrawingPanel extends JPanel
{   

    public DrawingPanel()
    {   
        setBackground(COLOURBACK);

        MyMouseListener ml = new MyMouseListener(); 
        addMouseListener(ml);
    }

    public void paintComponent(Graphics g)
    {
        Graphics2D g2 = (Graphics2D)g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        g.setFont(new Font("TimesRoman", Font.PLAIN, 15));
        super.paintComponent(g2);

        for (int i=0;i<COLUMN_SIZE;i++) {
            for (int j=0;j<ROW_SIZE;j++) {
                if (board[i][j] != UNKNOWN)
                    hexmech.drawHex(i,j,g2);
            }
        }
        for (int i=0;i<COLUMN_SIZE;i++) {
            for (int j=0;j<ROW_SIZE;j++) {
                if (board[i][j] != UNKNOWN)
                    hexmech.fillHex(i,j,board[i][j],g2);
            }
        }
    }

    class MyMouseListener extends MouseAdapter  { 
        public void mouseClicked(MouseEvent e) { 
            int x = e.getX(); 
            int y = e.getY(); 
            Point p = new Point( hexmech.pxtoHex(e.getX(),e.getY()) );
            if (p.x < 0 || p.y < 0 || p.x >= COLUMN_SIZE || p.y >= ROW_SIZE) return;

            board[p.x][p.y] = CLICKED;
            repaint();
        }        
    }
}
}

Hexmech

package hex;

import java.awt.*;
import javax.swing.*;

public class hexmech
{

 #define HEXEAST 0
 #define HEXSOUTHEAST 1
 #define HEXSOUTHWEST 2
 #define HEXWEST 3
 #define HEXNORTHWEST 4
 #define HEXNORTHEAST 5

public final static boolean orFLAT= true;
public final static boolean orPOINT= false;
public static boolean ORIENT= orFLAT;

public static boolean XYVertex=true;

private static int BORDERS=50

private static int s=0; // length of one side
private static int t=0; // short side of 30o triangle outside of each hex
private static int r=0; // radius of inscribed circle (centre to middle of each side). r= h/2
private static int h=0; // height. Distance between centres of two adjacent hexes. Distance between two opposite sides in a hex.

public static void setXYasVertex(boolean b) {
    XYVertex=b;
}
public static void setBorders(int b){
    BORDERS=b;
}

public static void setSide(int side) {
    s=side;
    t =  (int) (s / 2);         //t = s sin(30) = (int) CalculateH(s);
    r =  (int) (s * 0.8660254037844);
    h=2*r;
}
public static void setHeight(int height) {
    h = height;
    r = h/2;            // r = radius of inscribed circle
    s = (int) (h / 1.73205);    // s = (h/2)/cos(30)= (h/2) / (sqrt(3)/2) = h / sqrt(3)
    t = (int) (r / 1.73205);    // t = (h/2) tan30 = (h/2) 1/sqrt(3) = h / (2 sqrt(3)) = r / sqrt(3)
}


public static Polygon hex (int x0, int y0) {

    int y = y0 + BORDERS;
    int x = x0 + BORDERS;

    if (s == 0  || h == 0) {
        System.out.println("ERROR: size of hex has not been set");
        return new Polygon();
    }

    int[] cx,cy;


    if (XYVertex) 
        cx = new int[] {x,x+s,x+s+t,x+s,x,x-t};  //this is for the top left vertex being at x,y. Which means that some of the hex is cutoff.
    else
        cx = new int[] {x+t,x+s+t,x+s+t+t,x+s+t,x+t,x}; //this is for the whole hexagon to be below and to the right of this point

    cy = new int[] {y,y,y+r,y+r+r,y+r+r,y+r};
    return new Polygon(cx,cy,6);

}

public static void drawHex(int i, int j, Graphics2D g2) {
    int x = i * (s+t);
    int y = j * h + (i%2) * h/2;
    Polygon poly = hex(x,y);
    g2.setColor(hexgame.COLOURCELL);
    //g2.fillPolygon(hexmech.hex(x,y));
    g2.fillPolygon(poly);
    g2.setColor(hexgame.COLOURGRID);
    g2.drawString(String.format("%c;%d", 'A'+i, j+1), x+20, y+40);
    g2.drawPolygon(poly);
}



public static void fillHex(int i, int j, int n, Graphics2D g2) {
    char c='o';
    int x = i * (s+t);
    int y = j * h + (i%2) * h/2;
    /*if (n < 0) {
        g2.setColor(hexgame.COLOURONE);
        g2.fillPolygon(hex(x,y));
        g2.setColor(hexgame.COLOURONETXT);
        c = (char)(-n);
        g2.drawString(""+c, x+r+BORDERS, y+r+BORDERS+4); //FIXME: handle XYVertex
        //g2.drawString(x+","+y, x+r+BORDERS, y+r+BORDERS+4);
    }
    if (n > 0) {
        g2.setColor(hexgame.COLOURTWO);
        g2.fillPolygon(hex(x,y));
        g2.setColor(hexgame.COLOURTWOTXT);
        c = (char)n;

    if (n==3) {
        g2.setColor(hexgame.COLOURTWO);
        g2.fillPolygon(hex(x,y));
        g2.setColor(hexgame.COLOURTWOTXT);
    }
}

public static Point pxtoHex(int mx, int my) {
    Point p = new Point(-1,-1);

    //correction for BORDERS and XYVertex
    mx -= BORDERS;
    my -= BORDERS;
    if (XYVertex) mx += t;

    int x = (int) (mx / (s+t));
    int y = (int) ((my - (x%2)*r)/h);

    int dx = mx - x*(s+t);
    int dy = my - y*h;

    if (my - (x%2)*r < 0) return p; // prevent clicking in the open halfhexes at the top of the screen

    //System.out.println("dx=" + dx + " dy=" + dy + "  > " + dx*r/t + " <");

    //even columns
    if (x%2==0) {
        if (dy > r) {   //bottom half of hexes
            if (dx * r /t < dy - r) {
                x--;
            }
        }
        if (dy < r) {   //top half of hexes
            if ((t - dx)*r/t > dy ) {
                x--;
                y--;
            }
        }
    } else {  // odd columns
        if (dy > h) {   //bottom half of hexes
            if (dx * r/t < dy - h) {
                x--;
                y++;
            }
        }
        if (dy < h) {   //top half of hexes
            //System.out.println("" + (t- dx)*r/t +  " " + (dy - r));
            if ((t - dx)*r/t > dy - r) {
                x--;
            }
        }
    }
    p.x=x;
    p.y=y;
    return p;
}

1 个答案:

答案 0 :(得分:1)

paintComponent()的实施中,使用合适的setClip()调用Shape,例如Polygon。您可以使用createTransformedShape()AffineTransform方法调整Polygon的大小并进行翻译,以匹配目标六边形。使用多边形边界的坐标作为调用drawImage()时使用的坐标的基础。使用Ellipse2D的相关示例显示为here