中国象棋Java,基于java的中国象棋游戏设计
00-1010一、接口二。按钮三。添加棋子四。实现棋子的移动v .判断胜负VI。实现按钮“开始游戏”和“重新开始”七。增加规则八。第九轮。为象棋道歉x .背景及提示本例用Java分享中国象棋对弈的具体代码,供大家参考。具体内容如下
要实现一个小游戏,需要知道从哪里入手,一步一步去实现和完善。对于中国象棋的一个小游戏,我们可以这样开始:
首先要准备好00-1010棋盘,这是一个大小合适,比例合适,位置合适的界面。然后,在表单上画(没错,drawLine的那种画图)N条直线和对角线。具体值根据您的接口大小设置。这样画出来的界面整洁美观~
public void paint(图形g){ super . paint(g);//重写绘图函数Font f=new Font(微软雅黑,Font。粗体,30);g . set font(f);g.drawRect(60,50,500,560);//外环g.drawRect(70,60,480,540);//内环//水平部分int length=60for(int I=0;i9;i ){ g.drawLine(70,长度,550,长度);长度=60;}//中间汉字g.drawString(初和,160,340);g .拉带(“韩杰”,400,340);//竖线部分长度=130;for(int I=0;i7;I ){ //上垂直线G. Drawline(长度,60,长度,300);//下方竖线g.drawline(长度,360,长度,600);长度=60;}//九宫格斜线g.drawLine的上半部分(250,60,370,180);g .拉线(370,60,250,180);//九宫格对角线的下半部分g.drawLine(250,480,370,600);g .拉线(250,600,370,480);}
00-1010画好棋盘后,添加功能按钮。这个时候功能暂时不考虑,喜欢的可以添加。这里建议将按钮类型设置为数组,方便及时添加和删除。
//添加到面板String[] type={ 开始游戏,重新开始,输了,后悔棋 };for(int I=0;itype.lengthi ){ Button btn=新按钮(类型[I]);btn.setPreferredSize(新维度(150,50));anniu . add(BTN);}
这时候你会发现加按钮的地方很紧凑。我的解决方案是在这个面板上再加一个面板,设置成白色覆盖,这样按钮就会根据面板的流式布局下移。调整空白面板的宽度可以改变按钮的位置。
00-1010将找到的棋子图片添加到棋盘的十字位置,是给棋盘注入灵魂的方式。把十四种图片全部加到包里,这样程序以后就可以在其他电脑上运行了(这里推荐png格式,jpg格式会有方形边框)。接下来,有三个步骤。
1.创建一个10行9列的整数数组来存储每个位置的数据;2.创建一个长度为14的图像数组,用来对应棋子类型;3.遍历整数数组,画出对应的棋子;
这是棋盘的直观视图,这是我们的整数数组的初始值:
将图像与棋子图片匹配:
//初始化每个棋的定义(int k=0;k14k ){ chess[k]=新的ImageIcon(this.getClass()。getResource((k 1)。png’))。通用电气公司
tImage(); }遍历画图:
//根据棋盘布局 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);
五、判断胜负
率先吃掉对方帥或将的队伍获胜,写一个函数判断谁胜谁负显示胜局,同时将数据初始化为0,准备再来一局:(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; }
这里的init函数是给整数二维数组初始化为开局后遍历可以加上棋子的状态。
七、加规则
//规定各个棋子的移动规则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 == 3x == 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 == 4x == 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 == 5x == 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 == 6x == 13){ if(Math.abs(gj-sj)==1&&Math.abs(gi-si)==1){ if(x == 6&&si >= 7&&sj >= 3&&sj <= 5) return true; &n
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。