Java游戏开发——中国象棋联机版

游戏介绍:

中国象棋是起源于中国的一种棋戏,属于二人对抗性游戏的一种,在中国有着悠久的历史。由于规则简单,趣味性强,成为流行极为广泛的棋类游戏。 中国象棋使用方形格状棋盘及红黑二色圆形棋子进行对弈,棋盘上有十条横线、九条竖线共分成90个交叉点;中国象棋的棋子共有32个,每种颜色16个棋子,分为7个兵种,摆放和活动在交叉点上。双方交替行棋,先把对方的将(帅)“将死”的一方获胜。

本篇博文开发了一个基于UDP通信的中国象棋联机版游戏,游戏符合传统中国象棋规则(包括老将见面判法),具备基本的联机和悔棋功能,悔棋需要得到对方同意。运行效果如下:

使用素材文件夹:

素材及完整源码链接:https://pan.baidu.com/s/1m-z1eDGOabN4iLx5VEcZMw 提取码: rpbr

中国象棋介绍:

棋盘

棋子活动的场所叫做“棋盘”,在长方形的平面上,绘有9条平行的竖线和10条平行的横线相交组成,共90个交叉点,棋子摆在这些交叉点上。中间第5根横线和第6根横线之间未画竖线的空白地带,叫做“楚河 汉界”,整个棋盘就以“楚河 汉界”分为相等的两部分;两方将帅坐阵,画有“米”字方格的地方叫做“九宫”。

Ⅱ棋子

象棋的棋子共32个,分为红黑两组,各16个,由对弈双方各执一组,每组兵种是一样的,各分为七种。

红方:帅、仕、相、车、马、炮、兵;

黑方:将、士、象、车、马、炮、卒。

其中帅和将、士和仕、相和象、兵和卒的作用完全相同,仅仅是为了区分红棋和黑棋。

Ⅲ各棋子走法说明

①将或帅

移动范围:它只能在九宫内移动

移动规则:它每一步只可以水平或垂直移动一点

特殊说明:红方帅和黑方将不能直接见面,即帅和将中间必须有其他棋子间隔,否则构成“老将见面”情况;

假如现在是红方执子,此时构成“老将见面”状况,那么玩家可以移动帅直接吃掉对方的将,红方获胜。

②士或仕

移动范围:它只能在九宫内移动

移动规则:它每一步只能沿对角线方向移动一点

③象或相

移动范围:“楚河 汉界”的一侧

移动规则:它每一步只能沿对角线走两点(走田字),另外,移动的对角线方向上一点不能有其他棋子(不能被堵象眼)。

④马

移动范围:任何位置

移动规则:它每一步只能走曰字并且不能被绊马脚(斜着走,横位移量*纵位移量等于2)。

⑤车

移动范围:任何位置

移动规则:它可以水平或垂直方向移动任意个无阻碍的点。

⑥炮

移动范围:任何位置

移动规则:移动跟车很相似,它既可以像车一样水平或垂直方向移动任意无阻碍的点,也可以通过隔一个棋子吃掉对方一个棋子的方式进行移动。

⑦卒或兵

移动范围:过河后可以走过河后的一侧的任何位置,未过河只能走该棋子向上方向的直线区域

移动规则:它每步只能移动一个点,它未过河时只能向前移动,如果它过河了,增加向左向右移动的能力。

Ⅳ胜负说明

对局中,如果一方玩家认输或者该玩家的“将”或“帅”被对方棋子吃掉,该玩家算输,对方算赢。

UDP通信基础

这里涉及到的UDP通信基础可以参考我之前写的一篇博文:https://blog.csdn.net/A1344714150/article/details/85495088

游戏设计思路

Ⅰ棋盘信息存储及显示

前面说过棋盘是有10条横线和9条竖线组成,一共有90个交叉点,棋子必须放置在这些交叉点上。这里可以使用二维数组对棋盘信息进行存储,每个交叉点存储棋子下标索引,如果交叉点上没有棋子存储-1表示它上面没有棋子。为了更容易地计算坐标,这里直接按照二维数组的分布对棋盘进行分割,声明10行9列数组map,行数从0开始到9为止,列数从0开始到8为止;例如,对方第二个兵或卒位于棋盘第3行第2列,所以map[3][2]存储的是对方第二个兵或卒的棋子的下标索引值;

Ⅱ棋子信息存储及显示

棋子设计成对应的类,每种棋子都有自己对应的棋子图案;

中国象棋一共有32个棋子,这里可以将32个棋子对象数组存储到一个棋子对象数组chess。chess[i]中下标i的值如果是0~15表示黑方棋子,16~31表示的是红方棋子;

具体含义如下:

0将  1~2仕  3~4象  5~6马  7~8车  9~10炮  11~15卒;

16帅  17~18士  19~20相  21~22马  23~24车  25~26炮  27~31兵;

棋子初始化时根据玩家执子颜色和棋子上的字获取指定棋子图案,根据x,y的值,将棋子的位置信息初始化到第x行第y列;

游戏开始时根据双方执子颜色初始化棋盘信息(红方和黑方棋子放置位置会不同);

游戏保证了执子方一定处于棋盘下方,判棋规则目前都是基于我方下棋去判断的,如果我方下棋符合下棋规则,先将下棋信息进行坐标转换,然后发送给对方;接收到对方的下棋信息时,直接按照对方下棋信息对棋盘和棋子信息进行变更即可(发送之前坐标已经转换,无需再次转换)。

Ⅲ走棋规则

对于中国象棋来说,有马走日、象走田等一系列规则。

根据不同的棋子,按不同的规则进行走法判断。

判断是否能走棋的算法如下:

①如果棋子为“帅”或“将”,检查是否走直线并且走一步,以及走一步是否超出范围(老将碰面情况需要提前特殊处理)

②如果棋子为“仕”或“士”,检查是否沿斜对角线走一步,以及走一步是否超过范围

③如果棋子为“象”或“象”,检查是否走“田”字,是否被堵象眼,走一步是否超出范围

④如果棋子为“马”,检查是否走“日”字,是否被绊马脚

⑤如果棋子为“车”,检查是否走直线,移动前的位置和移动后的位置中间是否还有其他子

⑥如果棋子为“炮”,检查是否走直线,判断是否吃子,如果吃子判断中间是否只有一个棋子,否则判断中间是否还有其他子

⑦如果棋子为“卒”或“兵”,检查是否走直线,走一步;如果棋子没有过河,判断棋子是否向前走;如果棋子已经过河,判断是否向前、左、右移动

Ⅳ坐标转换

走棋过程中,需要将鼠标点击的像素坐标转换成棋盘坐标,用到analyse方法;

根据鼠标点击的像素坐标去和每个交叉点的小矩形进行匹配,如果该坐标位于矩形内,说明鼠标点击的是该交叉点。

假设点击的交叉点转换成棋盘坐标是(x,y),如果map[x][y]没有棋子索引,返回空,否则返回该棋子索引对应的棋子对象。

Ⅴ通信信息设计

联机版程序的难度在于对方需要通信,这里使用UDP通信;一方玩家输入对方IP和对方端口,点击开始向对方发送联机请求;

发送的通信信息包括以下功能:

①请求联机

格式:join|

②联机成功

格式:conn|

③认输

格式:lose|

④一方退出游戏

格式:quit|

⑤对方棋子移动信息

格式:move|对方移动的棋子下标|移动后所在行数|移动后所在列数|移动前所在行数|移动前所在列数|被吃掉的棋子索引|

如果该步没有吃掉棋子,被吃掉的棋子索引存储信息为-1

⑥请求悔棋

格式:ask|

⑦同意悔棋

格式:agree|

⑧拒绝悔棋

格式:refuse|

⑨游戏结束

格式:succ|黑方赢了 或者 succ|红方赢了 

Ⅵ记录每步棋的信息

自定义数据结构Node类,包含 移动的棋子信息、移动后所在行数、移动后所在列数、移动前所在行数、移动前所在列数、该步棋吃掉了的棋子的索引值;主要作用是为了实现悔棋功能,当然也可以对此进行拓展,完成棋谱记录及按棋谱还原棋局的功能。

游戏具体实现步骤

Ⅰ设计棋子类(Chess.java)

棋子类的成员信息主要包含 棋子所属玩家、棋子类别、棋子所在行数、棋子所在列数、棋子图案的信息;

方法主要包括:

setPos(int x,int y):将棋子放在第x行第y列

ReversePos():将棋子位置进行对调

paint(Graphics g,JPanel i):在指定的JPanel上画棋子

DrawSelectedChess(Graphics g):给选中的棋子画选中框

package 中国象棋;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ImageObserver;

import javax.swing.JPanel;

public class Chess {

	public static final short REDPLAYER = 1;
	public static final short BLACKPLAYER = 0;
	public short player;
	public String typeName;
	public int x,y;//网格地图对应的二维数组的下标
	private Image chessImage;//棋子图案
	private int leftX=28,leftY=20;
	
	public Chess(short player,String typeName,int x,int y){
		this.player = player;
		this.typeName = typeName;
		this.x = x;
		this.y = y;
		if(player == REDPLAYER){
			switch (typeName){
			case "帅":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess7.png");
				break;
			case "仕":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess8.png");
				break;
			case "相":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess9.png");
				break;
			case "马":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess10.png");
				break;
			case "车":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess11.png");
				break;
			case "炮":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess12.png");
				break;
			case "兵":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess13.png");
				break;			
			}
		}else{
			switch(typeName){
			case "将":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess0.png");
				break;
			case "士":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess1.png");
				break;
			case "象":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess2.png");
				break;
			case "马":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess3.png");
				break;
			case "车":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess4.png");
				break;
			case "炮":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess5.png");
				break;
			case "卒":
				chessImage = Toolkit.getDefaultToolkit().getImage("D://Game//ChineseChessGame//chess6.png");
				break;			
			}
		}
	}
	
	public void setPos(int x,int y){
		this.x = x;
		this.y = y;
	}
	
	public void ReversePos(){
		x = 9 - x;
		y = 8 - y;
	}
	
	protected void paint(Graphics g,JPanel i){
		g.drawImage(chessImage, leftX+y*62, leftY+x*57, 40, 40,(ImageObserver)i);
	}
	
	//绘画选中框
	public void DrawSelectedChess(Graphics g){
		g.drawRect(leftX+y*62, leftY+x*57, 40, 40);
	}
	
}

Ⅱ 设计Node类用于记录每步棋的信息(Node.java)

Node.java成员包括:移动的棋子下标index、棋子移动后位于(x,y)、棋子移动前位于(oldX,oldY)、被吃掉的棋子下标eatChessIndex;

package 中国象棋;

//存储棋谱的每一步
public class Node {
	int index;//移动的棋子下标
	int x,y;//棋子移动后位于(x,y)
	int oldX,oldY;//棋子移动前位于(oldX,oldY)
	int eatChessIndex;//被吃掉的棋子下标
	
	//如果棋子移动过程没有吃子,eatChessIndex = -1;
	public Node(int index,int x,int y,int oldX,int oldY,int eatChessIndex){
		this.index = index;
  • 87
    点赞
  • 324
    收藏
    觉得还不错? 一键收藏
  • 22
    评论
Java语言游戏项目实战资源包 内容概览: 这次分享为你带来了丰富的Java语言游戏项目实战资源,让你在实践中深入掌握Java语言,并开启游戏开发之旅。资源包中包括: 游戏项目代码:精心挑选了多个经典的小游戏项目,如猜数字、坦克大战等,每个项目都有完整的代码实现。 项目文档:详细的项目文档,介绍了项目的背景、功能、架构以及实现细节,帮助你更好地理解项目。 操作手册与使用说明:针对每个游戏项目,都准备了详细的操作手册和使用说明,手把手教你如何运行和测试项目。 学习笔记:整理了Java语言在游戏开发中的核心知识点和常用技术,方便你随时查阅和学习。 适用人群: 这份资源包适用于所有对Java游戏开发感兴趣的朋友,无论你是计算机专业的学生,还是希望业余时间尝试游戏开发的爱好者,都可以从中受益。 使用建议: 由浅入深实践:建议先从简单的游戏项目开始,逐步深入,既能增强自信,也能逐步提升技术水平。 结合文档与代码:在实践过程中,结合项目文档和代码,理解每一行代码背后的意义和原理。 持续学习与探索:Java语言和游戏开发技术都在不断更新,建议你在实践中持续学习新的技术和工具,不断提升自己。 Java语言游戏项目实战资源包 内容概览: 这次分享为你带来了丰富的Java语言游戏项目实战资源,让你在实践中深入掌握Java语言,并开启游戏开发之旅。资源包中包括: 游戏项目代码:精心挑选了多个经典的小游戏项目,如猜数字、坦克大战等,每个项目都有完整的代码实现。 项目文档:详细的项目文档,介绍了项目的背景、功能、架构以及实现细节,帮助你更好地理解项目。 操作手册与使用说明:针对每个游戏项目,都准备了详细的操作手册和使用说明,手把手教你如何运行和测试项目。 学习笔记:整理了Java语言在游戏开发中的核心知识点和常用技术,方便你随时查阅和学习。 适用人群: 这份资源包适用于所有对Java游戏开发感兴趣的朋友,无论你是计算机专业的学生,还是希望业余时间尝试游戏开发的爱好者,都可以从中受益。 使用建议: 由浅入深实践:建议先从简单的游戏项目开始,逐步深入,既能增强自信,也能逐步提升技术水平。 结合文档与代码:在实践过程中,结合项目文档和代码,理解每一行代码背后的意义和原理。 持续学习与探索:Java语言和游戏开发技术都在不断更新,建议你在实践中持续学习新的技术和工具,不断提升自己。 Java语言游戏项目实战资源包 内容概览: 这次分享为你带来了丰富的Java语言游戏项目实战资源,让你在实践中深入掌握Java语言,并开启游戏开发之旅。资源包中包括: 游戏项目代码:精心挑选了多个经典的小游戏项目,如猜数字、坦克大战等,每个项目都有完整的代码实现。 项目文档:详细的项目文档,介绍了项目的背景、功能、架构以及实现细节,帮助你更好地理解项目。 操作手册与使用说明:针对每个游戏项目,都准备了详细的操作手册和使用说明,手把手教你如何运行和测试项目。 学习笔记:整理了Java语言在游戏开发中的核心知识点和常用技术,方便你随时查阅和学习。 适用人群: 这份资源包适用于所有对Java游戏开发感兴趣的朋友,无论你是计算机专业的学生,还是希望业余时间尝试游戏开发的爱好者,都可以从中受益。 使用建议: 由浅入深实践:建议先从简单的游戏项目开始,逐步深入,既能增强自信,也能逐步提升技术水平。 结合文档与代码:在实践过程中,结合项目文档和代码,理解每一行代码背后的意义和原理。 持续学习与探索:Java语言和游戏开发技术都在不断更新,建议你在实践中持续学习新的技术和工具,不断提升自己。Java语言游戏项目实战资源包 内容概览: 这次分享为你带来了丰富的Java语言游戏项目实战资源,让你在实践中深入掌握Java语言,并开启游戏开发之旅。资源包中包括: 游戏项目代码:精心挑选了多个经典的小游戏项目,如猜数字、坦克大战等,每个项目都有完整的代码实现。 项目文档:详细的项目文档,介绍了项目的背景、功能、架构以及实现细节,帮助你更好地理解项目。 操作手册与使用说明:针对每个游戏项目,都准备了详细的操作手册和使用说明,手把手教你如何运行和测试项目。 学习笔记:整理了Java语言在游戏开发中的核心知识点和常用技术,方便你随时查阅和学习。 适用人群: 这份资源包适用于所有对Java游戏开发感兴趣的朋友,无论你是计算机专业的学生,还是希望业余时间尝试游戏开发的爱好者,都可以从中受益。 使用建议: 由浅入深实践:建议先从简单的游戏项目开始,逐步深入,既能增强自信,也能逐步提升技术水平。 结合文档与代码:在实践过程中,结合项目文档和代码,理解每一行代码背后的意义和原理。 持续学习与探索:Java语言和游戏开发技术都在不断更新,建议你在实践中持续学习新的技术和工具,不
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值