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

标签 java image swing hexagonal-tiles

我对六边形网格有疑问。我在互联网上找到了这段代码,您可以在下面看到,所以它不是我的。有两个公共(public)类:生成网格的 hexgame 和绘制并填充每个六边形的 hexmech。我想做的基本上是将图像插入到特定的六边形中,但我不知道如何编码以及应该将其放在类的哪个部分中。难道是我想错了?

非常感谢您的帮助!

六角游戏

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();
        }        
    }
}
}

六角机甲

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;
}

最佳答案

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

关于java - 如何将图像添加到六边形网格中的六边形中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30693204/

相关文章:

java - 在 Java 中从 Parquet 文件中读取小数字段

javascript - 使用 HTML5 canvas 和 getImageData 的透明像素?

java - 容器类所有者的子对象必须将组件添加到其父级容器中的问题

java - 停用组件,直到从 JComboBox 中选择一个元素

java - 如何从我的 java bean 中获取名称和 id?

java - Eclipse Tomcat 发布错误 : FlatFile Cannot be cast to IFlatFolder

java - Hashtable 比 HashMap 快?

java - 可点击图片

android - 如何在用户触摸事件时在 xml 布局上 move 图像?

java - JTable 中没有标题