面向对象程序设计课程设计报告JA V A程序设计课程设计之蜘蛛纸牌学院:年级:班级:指导老师:小组成员:时间:目录第一章课程设计要求 (1)题目名称 (1)题目类型 (1)课程设计目的 (1)实验原理 (1)实验内容 (1)第二章设计概要 (2)2.1 功能设计 (2)2.2 程序流程 (2)2.3功能分析 (3)1. 主要界面: (3)2初始化纸牌及发牌操作: (4)3纸牌移动放置操作: (7)4.回收纸牌操作: (8)5.帮助菜单功能的实现: (9)6.退出功能的实现: (10)第三章调试分析与测试结果 (11)第四章设计总结 (15)第五章参考文献 (16)第一章课程设计要求题目名称:蜘蛛纸牌游戏题目类型:设计型课程设计目的:学会综合运用已学的JAVA知识,用面向对象的技术实现一个小型的应用程序。
实验原理:面向对象程序分析与设计、类的灵活运用、继承技术、多态技术、异常处理、GUI程序设计等。
实验内容:参照windows游戏蜘蛛纸牌,自己编写设计实现其功能,它具有如下一些功能:(1)设计一个游戏界面,包括玩牌区、发牌区和回收区。
(2)纸牌以及其背景的设定。
(3)移动纸牌。
使用鼠标将较小的纸牌拖放到较大的纸牌下方,可以拖动一组纸牌,当要求这组纸牌是同一个花色,并且这一组纸牌从上到下是从大到小排列的,且不间断。
(4)回收纸牌。
当某列出现同一花色,从上到下依次是从K到A的不间组合时,这组纸牌将被回收到回收区中。
(5)发牌。
用鼠标单击发牌区,若发牌区还有剩余的纸牌,则将发出一叠纸牌共10张,依次添加到玩牌区的10列纸牌最下方,但要求这10列纸牌没有空白列。
(6)若玩家不了解游戏规则可以点击帮助获得游戏方法。
(7)级别设定。
点击“游戏”菜单中选取游戏难以级别,有3种级别,分别对应初级、中级、高级。
(8)退出游戏。
第二章设计概要2.1 功能设计编写程序以实现游戏蜘蛛纸牌的功能。
1、设计游戏界面。
2、纸牌以及其背景的设定。
3、移动纸牌。
4、回收纸牌。
5、发牌。
6、若玩家不了解游戏规则可以点击帮助获得游戏方法。
7、级别设定。
8、退出游戏。
2.2 程序流程2.3功能分析1. 主要界面:以下是主菜单界面的主要代码:JMenu jNewGame = new JMenu("游戏");JMenu jHelp = new JMenu("帮助");JMenuItem jItemAbout = new JMenuItem("关于");JMenuItem jItemOpen = new JMenuItem("开始新游戏");JMenuItem jItemDeal = new JMenuItem("发牌");JMenuItem jItemExit = new JMenuItem("退出");JRadioButtonMenuItem jRMItemEasy = new JRadioButtonMenuItem("初级:单花色");//菜单中的可选项按钮JRadioButtonMenuItem jRMItemNormal= new JRadioButtonMenuItem("中级:双花色");JRadioButtonMenuItem jRMItemHard = new JRadioButtonMenuItem("高级:四花色");public SpiderMenuBar(Spider spider) {this.main = spider;jNewGame.add(jItemOpen);jNewGame.add(jItemDeal);jNewGame.addSeparator();//添加划分线jNewGame.add(jRMItemEasy);jNewGame.add(jRMItemNormal);jNewGame.add(jRMItemHard);jNewGame.addSeparator();jNewGame.add(jItemExit);ButtonGroup group = new ButtonGroup();//(用来获取JRadioButtonMenuItem 的值)group.add(jRMItemEasy);group.add(jRMItemNormal);group.add(jRMItemHard);jHelp.add(jItemAbout);this.add(jNewGame);this.add(jHelp);//添加到菜单栏以下是游戏窗口界面初始化的主要代码:pane = this.getContentPane(); // 获得容器pane.setBackground(new Color(0, 112, 26));// 设置背景颜色clickLabel = new JLabel(); // 发牌区的鼠标点击响应区域clickLabel.setBounds(890, 580, 110, 96); // 设置响应区域大小与坐标clickLabel.setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));pane.add(clickLabel); // 将响应区域添加到容器中this.initCards();// 纸牌初始化this.randomCards();// 随机分配纸牌this.setCardsLocation();// 为纸牌设置坐标位置this.deal(); // 从右下角发出一叠纸牌。
游戏刚开始时,需要先发出一叠纸牌。
groundLabel = new JLabel[10];// 创建背景框数组,一共有10个背景框。
int x = 20;// 背景框的x坐标,10个背景框是并排放置的,y坐标相等。
第一个背景框的x坐标为20。
for (int i = 0; i < 10; i++) {// 循环创建背景框,并设置其坐标大小等属性groundLabel[i] = new JLabel();// 创建背景框groundLabel[i].setBorder(javax.swing.BorderFactory.createEtchedBorder(javax.swing.border.EtchedBorder.RAISED));// 为Label设置边框// ,// 形成背景框groundLabel[i].setBounds(x, 25, 71, 96);// 设置背景框的大小与坐标x += 101; // 相邻的背景框的x坐标差值为101。
this.pane.add(groundLabel[i]);// 将背景框添加到容器中}this.setVisible(true);// 显示窗口2初始化纸牌及发牌操作:初始化纸牌的主要代码(包括所有纸牌生成及存入数组,右下角发牌区纸牌初始化以及表面显示纸牌初始化):所有纸牌的生成及存入数组代码:public void initCards() {// 如果纸牌已被赋值,即将其从框架的面板中移去if (cards[0] != null) {for (int i = 0; i < 104; i++) {pane.remove(cards[i]);}}int n = 0;// 通过难度等级,为n赋值if (this.grade == Spider.EASY) {n = 1;} else if (this.grade == Spider.NATURAL) {n = 2;} else {n = 4;}// 为card赋值for (int i = 1; i <= 8; i++) {for (int j = 1; j <= 13; j++) {cards[(i - 1) * 13 + j - 1] = new PKCard((i % n + 1) + "-" + j,this);//当n为1时,i%8的值永远是0,所以i%8+1的值永远是1,因此n为1时,创建的card的名称是1// -1到1-13,全是黑桃。
其他等级类似。
}}}//纸牌随机分配public void randomCards() {// 将纸牌的顺序打乱,否则牌号的将是从A到K的出现规律PKCard temp = null;// 随机生成牌号for (int i = 0; i < 52; i++) {int a = (int) (Math.random() * 104);int b = (int) (Math.random() * 104);temp = cards[a];cards[a] = cards[b];cards[b] = temp;}}右下角发牌区纸牌的初始化代码:int x = 883;// 将坐标定位到右下角发牌区int y = 580;for (int i = 0; i < 6; i++) {// 初始化右下角发牌区的纸牌,共6叠for (int j = 0; j < 10; j++) {int n = i * 10 + j;pane.add(cards[n]);// 将card转向背面cards[n].turnRear();// 将card放在固定的位置上cards[n].moveto(new Point(x, y));// 将card的位置及相关信息存入map.put(new Point(x, y), cards[n]);}x += 10; // 共6叠纸牌,最上面一叠纸牌的x坐标为883,再往下,x依次增加10}表面显示纸牌初始化:x = 20;// 将坐标定位到上方玩牌区的左边起点,也就是第一个背景框的坐标位置y = 45;/** 初始化表面显示的纸牌 */for (int i = 10; i > 5; i--) { // 初始化玩牌区的纸牌,共5行for (int j = 0; j < 10; j++) { // 共10列int n = i * 10 + j; // 生成索引值if (n >= 104) { // 如果索引值超出数组下标continue; // 退出本次循环,执行外层循环}pane.add(cards[n]); // 将索引处的纸牌添加到容器中cards[n].turnRear(); // 将纸牌转向背面cards[n].moveto(new Point(x, y)); // 将纸牌放在固定的位置上map.put(new Point(x, y), cards[n]); // 将纸牌及其坐标值存入map中x += 101; // 每两列之间的x坐标相距101个像素}x = 20; // x坐标回到起点位置y -= 5; // 主坐标向上移5个像素}发牌操作功能代码:public void deal() { // 发牌,指从右下角的发牌区发牌this.setNA();// 判断10列中是否有空列for (int i = 0; i < 10; i++) {if (this.getLastCardLocation(i) == null) {JOptionPane.showMessageDialog(this, "有空位不能发牌!", "提示",JOptionPane.WARNING_MESSAGE);return;}}int x = 20;for (int i = 0; i < 10; i++) {Point lastPoint = this.getLastCardLocation(i);// 这张牌应“背面向上”if (c == 0) {// 当还没有发过牌时,玩牌区的纸牌列中,每两张纸牌之间的y坐标值相差5,// 指的是背面牌与背面牌之间以及背面牌与第一张正面牌之间的y距离lastPoint.y += 5;}// 这张牌应“正面向上”else {// 两张正面牌之间的y距离lastPoint.y += 20;}map.remove(cards[c + i].getLocation());cards[c + i].moveto(lastPoint);map.put(new Point(lastPoint), cards[c + i]);cards[c + i].turnFront();cards[c + i].setCanMove(true);// 将组件card移动到容器中指定的顺序索引。