먼저 체스판을 준비해야 합니다. 적절한 크기와 비율, 위치를 갖춘 인터페이스입니다. 그런 다음 특정 형태에 직선과 대각선을 그립니다. 값은 인터페이스의 크기에 따라 설정됩니다. 이렇게 그린 인터페이스가 깔끔하고 아름답네요~
public void paint(Graphics g){ super.paint(g);//重写画图函数 Font f=new Font("微软雅黑",Font.BOLD,30); g.setFont(f); g.drawRect(60, 50, 500, 560);//外圈 g.drawRect(70, 60, 480, 540);//内圈 //横线部分 int length=60; for(int i=0;i<9;i++){ g.drawLine(70, length, 550, length); length+=60; } //中间汉字 g.drawString("楚河", 160, 340); g.drawString("汉界", 400, 340); //竖线部分 length=130; for(int i=0;i<7;i++){ //上半部分竖线 g.drawLine( length,60, length,300); //下半部分竖线 g.drawLine( length,360, length,600); length+=60; } //上半部分九宫格斜线 g.drawLine(250, 60, 370, 180); g.drawLine(370, 60, 250, 180); //下半部分九宫格斜线 g.drawLine(250, 480, 370, 600); g.drawLine(250, 600, 370, 480); }
체스판을 그린 후 기능버튼을 추가해 주세요. 현재 기능은 구현되지 않은 것으로 간주하고 임의로 추가하시면 됩니다. 당신의 취향에 따라. 적시에 추가 및 삭제가 용이하도록 버튼 유형을 배열로 설정하는 것이 좋습니다.
//添加到面板上 String[] type = {"开始游戏","重新开始","认 输","悔 棋"}; for(int i=0;i<type.length;i++){ Button btn = new Button(type[i]); btn.setPreferredSize(new Dimension(150,50)); anniu.add(btn); }
이때 버튼이 매우 컴팩트하다는 것을 알 수 있습니다. 내 해결책은 이 패널에 다른 패널을 추가하고 이를 흰색으로 설정하여 버튼이 흐름에 따라 배치되도록 하는 것입니다. 패널이 아래로 이동합니다. 빈 패널의 너비를 조정하면 버튼의 위치가 변경됩니다.
체스판 교차점에 체스 조각 그림을 추가하여 나중에 다른 컴퓨터에서도 프로그램을 실행할 수 있도록 14가지 유형의 그림을 모두 패키지에 추가하세요. png 형식, jpg 형식에는 사각형 테두리가 있습니다).
다음 세 단계는
1입니다. 각 위치의 데이터를 저장하기 위해 10개의 행과 9개의 열이 있는 정수 배열을 만듭니다.
2 체스 조각 유형에 해당하는 길이가 14인 이미지 배열을 만듭니다. . 정수 배열을 탐색하고 해당 체스 말을 그립니다.
//初始化给每个chess定义 for(int k=0; k<14; k++){ chess[k] = new ImageIcon(this.getClass().getResource((k+1)+".png")).getImage(); }
//根据棋盘布局 for(int i=0;i<place.length;i++){ for(int j=0;j<place[0].length;j++){ if(place[i][j] >0){ bg.drawImage(chess[place[i][j]-1], chessX+60*j, chessY+60*i, 50, 50, null); } } }
int x1, y1, x2, y2; public void mousePressed(MouseEvent e) { x1 = e.getX(); y1 = e.getY(); x1 = getj(x1); y1 = geti(y1); } public void mouseReleased(MouseEvent e) { x2 = e.getX(); y2 = e.getY(); x2 = getj(x2); y2 = geti(y2); } //根据点的坐标得到其代表的位置,具体参数可以微调,我的格子是60x60大小 public int getj(int x){ return (x-50)/60; } public int geti(int y){ return (y-40)/60; }
BufferedImage buffer = new BufferedImage(this.getWidth(), this.getHeight(), BufferedImage.TYPE_INT_ARGB); Graphics bg = buffer.getGraphics(); //这个中间写的是你画界面的方法,也就是上面提到的paint方法内部 //...... //绘制缓存到窗体上 g.drawImage(buffer, 0, 0, null);
(showMessageDialog 메소드는 상자에서 직접 뛰어내릴 수 있습니다)
//判断游戏结束并显示胜局 public void isWine() { System.out.println(place[y1][x1]+" "+place[y2][x2]); if (place[y2][x2]==7&&place[y1][x1]!=0) { place[y2][x2] = place[y1][x1]; place[y1][x1] = 0; UI.repaint(); JOptionPane.showMessageDialog(null, "黑方 胜利!"); again(); } else if(place[y2][x2]==14&&place[y1][x1]!=0) { place[y2][x2] = place[y1][x1]; place[y1][x1] = 0; UI.repaint(); JOptionPane.showMessageDialog(null, "红方 胜利!"); again(); } } //游戏结束时要重绘 public void again(){ for(int i=0; i<place.length; i++){ for(int j=0; j<place[0].length; j++){ place[i][j] = 0; } } }
public void actionPerformed(ActionEvent e) { type = e.getActionCommand(); if("开始游戏".equals(type)||"重新开始".equals(type)){ x=0; count = 1;//这里要把每次的走棋方刷新,认输时也需要刷新 init(); UI.repaint(); } } //初始化place坐标 public void init(){ /*红兵 1.png *红炮 2.png *红車 3.png *红马 4.png *红相 5.png *红仕 6.png *红帥 7.png *黑卒 8.png *黑炮 9.png *黑車 10.png *黑马 11.png *黑象 12.png *黑士 13.png *黑将 14.png */ for(int i=0;i<place.length;i++){ for(int j=0;j<place[0].length;j++){ place[i][j] = 0; } } place[0][0] = 10; place[9][0] = 3; place[0][1] = 11; place[9][1] = 4; place[0][2] = 12; place[9][2] = 5; place[0][3] = 13; place[9][3] = 6; place[0][4] = 14; place[9][4] = 7; place[0][5] = 13; place[9][5] = 6; place[0][6] = 12; place[9][6] = 5; place[0][7] = 11; place[9][7] = 4; place[0][8] = 10; place[9][8] = 3; place[2][1] = 9; place[7][1] = 2; place[2][7] = 9; place[7][7] = 2; place[3][0] = 8; place[6][0] = 1; place[3][2] = 8; place[6][2] = 1; place[3][4] = 8; place[6][4] = 1; place[3][6] = 8; place[6][6] = 1; place[3][8] = 8; place[6][8] = 1; }
//规定各个棋子的移动规则 public boolean rule(int gi, int gj,int si, int sj){ int x = place[gi][gj]; int y = place[si][sj]; int start, end; //判断为何种棋子 //車:只能走直线 if(x == 3||x == 10){ if(gi != si&&gj != sj) return false; else if(gi == si){ start = Math.min(gj, sj); end = Math.max(gj, sj); for(int m = 1; m < end - start; m++){ if(place[gi][start+m] != 0) return false; } return true; } else if(gj == sj){ start = Math.min(gi, si); end = Math.max(gi, si); for(int m = 1; m < end - start; m++){ if(place[start+m][gj] != 0) return false; } return true; } else return true; } //马:走日,且某个位置不可以有棋子 else if(x == 4||x == 11){ //下 if(si - gi == 2&&Math.abs(gj-sj) == 1&&place[gi+1][gj] == 0) return true; //上 else if(gi - si == 2&&Math.abs(gj-sj) == 1&&place[gi-1][gj] == 0) return true; //右 else if(sj - gj == 2&&Math.abs(gi-si) == 1&&place[gi][gj+1] == 0) return true; //左 else if(gj - sj == 2&&Math.abs(gi-si) == 1&&place[gi][gj-1] == 0) return true; //否则不可以走 else return false; } //相:走田,且不能过河 else if(x == 5||x == 12){ //左上 if(gi - si == 2&&gj - sj == 2&&place[gi-1][gj-1] == 0){ if((x == 5&&si >= 5)||(x == 12&&si < 5)) return true; else return false; } //右上 else if(gi - si == 2&&sj - gj == 2&&place[gi-1][gj+1] == 0){ if((x == 5&&si >= 5)||(x == 12&&si < 5)) return true; else return false; } //左下 else if(si - gi == 2&&gj - sj == 2&&place[gi+1][gj-1] == 0){ if((x == 5&&si >= 5)||(x == 12&&si < 5)) return true; else return false; } //右下 else if(si - gi == 2&&sj - gj == 2&&place[gi+1][gj+1] == 0){ if((x == 5&&si >= 5)||(x == 12&&si < 5)) return true; else return false; } else return false; } //士:斜着走不能出田字格 else if(x == 6||x == 13){ if(Math.abs(gj-sj)==1&&Math.abs(gi-si)==1){ if(x == 6&&si >= 7&&sj >= 3&&sj <= 5) return true; else if(x == 13&&si <= 2&&sj >= 3&&sj <= 5) return true; else return false; } else return false; } //将:不能出田字格且不能会面 else if(x == 7||x == 14){ if((Math.abs(gj-sj)==1&&gi - si ==0)||(gj - sj ==0&&Math.abs(gi-si)==1)){ if(x == 7&&si >= 7&&sj >= 3&&sj <= 5) return true; else if(x == 14&&si <= 2&&sj >= 3&&sj <= 5) return true; else return false; } else return false; } //炮:隔一个 else if(x == 2||x == 9){ //若要吃棋子,必须中间有且只有一枚棋子 if(x*y!=0){ int t = 0; if(gi == si){ for(int m = Math.min(gj, sj); m <= Math.max(gj, sj); m++){ if(place[gi][m] != 0) t++; } } else if(gj == sj){ for(int m = Math.min(gi, si); m <= Math.max(gi, si); m++){ if(place[m][gj] != 0) t++; } } if(t == 3) return true; } //若为不吃棋子的情况,中间不可以有其他棋子,且只能走直线 else { int t = 0; if(gi == si){ for(int m = Math.min(gj, sj); m <= Math.max(gj, sj); m++){ if(place[gi][m] != 0) t++; } } else if(gj == sj){ for(int m = Math.min(gi, si); m <= Math.max(gi, si); m++){ if(place[m][gj] != 0) t++; } } if(t == 1) return true; else return false; } } //兵:不能后退,且过了河才可以左右移动 else if(x == 1||x == 8){ //判断是否过河 if(x == 1){ if(gi >=5){ if(gi - si == 1&&gj == sj) return true; else return false; } else if((gi - si == 1&&sj - gj == 0)||(gi - si == 0&&Math.abs(sj-gj) == 1)) return true; else return false; } else if(x == 8){ if(gi <5){ if(si - gi == 1&&gj == sj) return true; else return false; } else if(((si - gi == 1&&sj - gj == 0))||(gi - si == 0&&Math.abs(sj-gj) == 1)) return true; else return false; } else return false; } return false; }
//判断将是否会面 public boolean meet(){ int jiangi=0, jiangj=0, shuaii=0, shuaij=0, temp=0; for(int i=0; i<10; i++){ for(int j=0; j<9; j++){ if(place[i][j]==7){ shuaii = i; shuaij = j; } else if(place[i][j]==14){ jiangi = i; jiangj = j; } } } if(shuaij == jiangj){ for(int i=jiangi+1; i<shuaii; i++){ if(place[i][shuaij] != 0) temp++; } } else return false;//没会面 if(temp != 0) return false;//没会面 else return true;//会面了 }
장군들이 만날지 여부를 결정하는 별도의 방법을 썼습니다. 왜냐하면 장군들이 만나게 되는 것은 장군들 자신의 움직임뿐만 아니라 다른 체스 말의 이동이므로 동시에만 수행되는 부울 함수입니다. 이전 함수와 이 함수가 얼굴을 반환하지 않는 경우에만 플레이어가 움직일 수 있도록 매개변수를 정의했습니다. 이런 식으로 체스의 규칙이 구현됩니다.
두 점의 값을 교환할 때(또는 조각을 캡처하는 경우) 이전 값을 기록한 다음 액션 리스너가 "Return"을 클릭하는 것을 들을 때 다시 교환해야 합니다.
이동은 한 번에 한 번만 후회할 수 있으며, 체스 말이 처음에 움직이지 않았다면 후회할 수 없습니다.
배경 추가는 체스 말을 그리는 방법과 동일하게 할 수 있으니 체스판이 가려지지 않도록 앞쪽에 그려야 합니다.
이것을 추가하면 또 다른 명백한 문제가 있습니다. 즉, 오른쪽 버튼을 조작할 때마다 사라지고 배경 이미지에 가려진다는 것입니다. 어떻게 해야 합니까?
그래서 세 가지 방법을 요약했습니다.
2. 버튼을 메뉴 형태로 추가합니다.
3. 스크린샷), 다시 그리세요
여기서 count 매개변수를 빌려 리스너에게 전달하고 생성자를 다시 작성합니다.
int count=1; if(listener.count==1){ //画帥 bg.drawImage(chess[6], 708, 322, 50, 50, null); }else if(listener.count==-1){ //画将 bg.drawImage(chess[13], 708, 322, 50, 50, null); }
위 내용은 Java를 사용하여 중국 체스 게임을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!