用Java swing写一个简单象棋程序的心里历程(3)

前言

抛去一些复杂的功能的话,不知不觉基本上已经写完啦,其实也没那么难。(当然现在程序中还有一些bug和一些必须要扩展的功能)。这次接着上次的,记录一下遇到的问题和解决的办法吧,

车和炮带来的问题

其实车和炮的走子规则有点类似的,就是在吃敌方的子时会有不同。程序在走子时,其实就是用setLocation 函数直接把代表各个棋子的component闪电式的在另外的位置显示出来。如下图:
在这里插入图片描述
直接这样走肯定不行嘛,中间还隔了个“兵”哥哥呢,怎么可以无视他。所以在走子的时候肯定要知道棋子的起始位置和终点位置之间是否有其他棋子(炮也是这样)。怎么办呢?我是在Data类中通过一个静态9X10的二维数组来记录整个棋盘各个位置的状态的,如果某一个位置有棋子就在二维数组对应的位置1,这个数组在后面别马脚和象脚的判断中也起到了很重要的作用。如下图最开始初始化时,碰到了一点小问题,本来是先new出一个二维数组,然后在Data的构造函数中初始化数组的,然而好像并不可以。在构造函数中通过“=”给数组每个位置赋值后,并没有效果,调试时好像根本不会进入到构造函数中去,感觉是因为只有在new Data这个class时才会进入到构造函数。(基础没学好。。)所以我就想下面这样初始化啦,

package com.myChess;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JButton;

public class Data {
	public static Boolean sFlag = false;
	public static ChessPiece selectPiece = null;
	public static ChessPiece lastSelectPiece = null;
	public static final int chessWidth = 41;
	public static final int chessHeigth = 41;
	public static Boolean BorRRun = true;//被选中的是黑子还是红字,黑子为true
	public static int panelArray[][]= {	{1, 0, 0, 1, 0, 0, 1, 0, 0,1}, 
										{1, 0, 1, 0, 0, 0, 0, 1, 0,1},
										{1, 0, 0, 1, 0, 0, 1, 0, 0,1},
										{1, 0, 0, 0, 0, 0, 0, 0, 0,1},
										{1, 0, 0, 1, 0, 0, 1, 0, 0,1}, 
										{1, 0, 0, 0, 0, 0, 0, 0, 0,1}, 
										{1, 0, 0, 1, 0, 0, 1, 0, 0,1}, //列代表X,行代表Y
										{1, 0, 1, 0, 0, 0, 0, 1, 0,1},				
										{1, 0, 0, 1, 0, 0, 1, 0, 0,1}};//用来表示棋盘上每个位置是否有棋子	

除了初始化时,在方法外面好像不能通过“=”赋值
在这里插入图片描述

关于红字走完黑子走的问题

先不管那么多,先在Data类里来个public static Boolean BorRRun = true;//用来代表该哪一方走了。然后在每个棋子的鼠标点击事件中加入判断语句:
if (c == MouseEvent.BUTTON1 && Data.BorRRun == false)// 推断是鼠标左键按下
如果Data.BorRRun 变成该你走了的状态(这里false是黑子走,true红子),才会去选中你那种颜色的棋子。否则的话,你更本选不中你的棋子。

关于吃敌方棋子的操作

如果棋子被吃了,直接把它的visible设成false,我们看不见它不就好了。但是怎么样才能知道棋子被吃了呢?首先,别人如果想要吃你的棋子,肯定要满足各个棋子的走子规则,马走日,象走田…前面我们已经通过在每个棋子里重写setLocation方法,并加上适当的判断语句,就实现了各个棋子应该有的走子规则了。(下次详细的说说各个棋子的走子规则的判断语句)这里可以这样想,假如轮到敌方走了,却点到了己方的子,不就说明敌方想吃你嘛。所以可以在己方子的点击事件中做文章。

@Override
	public void mouseClicked(MouseEvent var1) {
		// TODO Auto-generated method stub
		int c = var1.getButton();// 得到按下的鼠标键
		String mouseInfo = null;// 接收信息
		if (c == MouseEvent.BUTTON1 && Data.BorRRun == false)// 这个是正常选择棋子的操作,下面主要是对棋子的选中状态进行更改,应该可以简化
		{
			if(Data.lastSelectPiece!=this && Data.lastSelectPiece!=null) {
				Data.lastSelectPiece.setIconSelect(false);
				Data.selectPiece = this;				
				this.setIconSelect(true);
				Data.lastSelectPiece = this;
				
			}
			else if(Data.lastSelectPiece == this ) {
				this.setIconSelect(false);			
				Data.lastSelectPiece = null;				
			}else {
				Data.selectPiece = this;
				this.setIconSelect(true);
				Data.lastSelectPiece = this;
			}
			
		}
		else if (c==MouseEvent.BUTTON1 && Data.BorRRun == true) {//这个算是吃子时的操作,当该敌方走子时点到了己方的棋子就是想吃了你呗,当然得满足规则才能让它吃
			Data.lastSelectPiece.setLocation(CurrentsimX, CurrentsimY);
			if(Data.BorRRun == false)//setLocation执行则满足规则,执行时会将BorRRun取反,所以BorRRun与开始相反时就说明子被吃了,
				this.setVisible(false);//把visible设为false代表子被吃了
		}
	}

上面就是棋子点击时要做的操作,Data.BorRRun == false时是正常走子,Data.BorRRun == true时就是吃子啦。无非就是调了一下setLocation函数,当然这里需要传进去的X和Y就是当前棋子的坐标啦,是别人吃你额。另外setLocation方法里会将代表该哪一方走子的标志Data.BorRRun取反。所以如果满足了地方的棋子满足了自己setLocation里的走子规则的话就会顺利执行setLocation方法啦(好像前面有的地方说成函数啦。。。)然后判断Data.BorRRun是不是变了,这里是如果从true变成了false就代表你被吃了额。赶快通过setVisible方法消失吧。
基本上就是这些了吧,难一点感觉还是“炮”的走子规则和吃子,想的我脑壳疼。但也都解决啦,下一次分析每个棋子的走子规则并演示吧。

bug

(1)偶尔会出现下面的情况。这可能是因为paint函数重画的问题,不清楚,慢慢研究吧。
在这里插入图片描述
(2)当一个子吃另一个子时会报异常,那个记录整个棋盘状态的Data.panelArray数组大小会超出边界,其实就是CurrentX和CurrentY变成了几百多。再看吧,有些bug写程序写着写着自己就没了。。

在这里插入图片描述(3)我还用了try catch捕捉异常啦。在GamePanel中的鼠标点击事件中,会把选定的棋子置到你鼠标点击的位置,可是如果我没选中棋子呢,这个时候Data.selectPiece的引用会是null所以会报异常,我就是catch了一下而已。。不知道有没有必要,就是Console栏里不会报红了而已。
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值