本次课程训练选题为:拼图游戏
通过课程设计,进一步巩固、加深我们所学专业课《JAVA面向对象程序设计》的基本理论知识,理论联系实际,进一步培养我们的综合分析问题,解决问题的能力;全面考核我们所掌握基本理论知识及其实际业务能力,从而达到提高学生素质的最终目的;利用所学知识,开发小型应用系统,掌握运用JAVA语言编写调试应用系统程序,训练独立开发应用系统,进行数据处理的综合能力;对于给定的设计题目,如何进行分析,理清思路,并给出相应的数学模型。
熟练掌握JAVA语言灵活运用各种类库,为今后从事实际工作打下坚实的基础。通过该课程设计,全面系统的理解JAVA语言的一般原理和基本实现方法.
此次实训设计实现了一个基于Java编程语言的一个小游戏——拼图。
拼图游戏是一款益智游戏,该游戏的形式:是由16个无序的小图像组成,最终人们在将其恢复至最原始的序列而形成完整的排列,会充分考验玩家的智商,是人们休闲娱乐时可供选择的消遣工具。
本次项目用到了二维数组,图形界面,键盘监听等知识点。
游戏的面板是由4*4的界面构成,把4*4的界面平均分成16个格子,在前15个格子里随机放置15个编号为 1~15的方块(数组中为0~14),最后一个格子是未放置方块的空格子。
用键盘中的上下左右键控制图片与空格子水平或垂直相邻的方块交换位置,当前方块移动之前所在的格子成为空格子。通过不断地移动方块可以将方块一行一行地按数字顺序排好。
三、设计实训过程
拼图游戏内容由若干小图像块组成的,通过鼠标点击图像块上下左右移动,完成图像的拼凑。
创建一个initJFrame的方法来实现游戏主界面。由于主类继承JFrame类,调用Size方法控制界面的大小;调用LocationRelativeTo方法控制界面在显示屏的位置,选择null控制界面居中。
public void initJFrame(){
//创建一个游戏主界面
//设置宽高
setSize(603,680);
//设置界面标题
setTitle("拼图游戏");
//设置界面置顶
setAlwaysOnTop(true);//永远在顶部
//设置界面居中
setLocationRelativeTo(null);
//设置游戏模式关闭
setDefaultCloseOperation(3);//定义在一个接口中,四种状态(0,1,2,3)
//取消默认的居中放置,只有取消了才会按照xy轴的形式添加组件
setLayout(null);
//给整个界面添加键盘监听事件
addKeyListener(this);//执行本类里面的方法
}
由于16个图片需要放在4*4的界面中,所以需要定义一个二维数组,同时定义一个游戏步数的变量和游戏中空白格的位置为(0,0)。
//定义空白位置
int x,y = 0;
//定义一个二维数组,储存正确的数据
int [][] win = {
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,0}
};
//定义一个步数变量
int step = 0;
//加载图片的时候,会根据二维数组进行加载
//创建二维数组
int[] [] data = new int[4] [4];
16张图片需要4*4的格子中,打印照片时用两层for循环进行打印,每一行打印四次,共打印四行。给每一个图片创建ImageIcon的对象,再将这个对象放入由JLabel的对象(管理容器)中,图片默认放在正中央。每次添加完图片后,需要把管理容器添加到界面中。同样的方法,添加游戏胜利的图标和背景图片。
public void initImage(){
//删除原本已经出现的所有图片
getContentPane().removeAll();
//注意,先加载的照片在上方,后加载的图片在下面。
//打印照片
for (int i = 0; i < 4; i++) {//每一行打印四次
for (int j = 0; j < 4; j++) {
int num = data[i][j];
//先打印一行
//创建一个图片ImageIcon的对象
ImageIcon icon1 = new ImageIcon("untitled\\untitled5\\im\\"+num +".jpg");
//创建一个JLabel的对象(管理容器)//图片默认放在正中央
JLabel jLabel1 = new JLabel(icon1);
//指定图片位置
jLabel1.setBounds(105 * j + 83,105 * i + 134,105,105);//宽高为像素
//给图片添加边框
BevelBorder bevelBorder = new BevelBorder(1);
jLabel1.setBorder(bevelBorder);
//把管理容器添加到界面中
//add(jLabel);
getContentPane().add(jLabel1);//为隐藏容器,需要调用再添加到里面
//number++;
}
}
//添加背景图片
}
先定义一个一维数组,将0~15个数录入。产生随机数 Random rand=new Random();随机数可以打乱原有图片的位置,用有序数组和产生的随机数进行一一交换。再将交换的完的一维数组添加到已经定义好的二维数组中。
public void initDate(){
//定义一个数组
int[] tempArr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
Random random = new Random();
for (int i = 0; i < tempArr.length ; i++) {
int index = random.nextInt(tempArr.length);
//用遍历的每一个数据,和随机索引上的数据进行交换
int temp = tempArr[i];
tempArr[i] = tempArr[index];
tempArr[index] = temp;
}
//二维数组添加数据
for (int i = 0; i < tempArr.length; i++) {
if(tempArr[i] == 0){
x = i / 4;
y = i % 4;
} else {
data[i / 4][i % 4] = tempArr[i];
}
}
}
这里我们使用keyReleased()来实现添加键盘监听的功能,public void keyReleased(KeyEvent e):松开。
因为键盘上有很多键,所以每一个键都对应一个编号,但是这个编号与ASCLL码无关,分别是左:37,上:38,右:39,下:40。
注意:需要在初始化界面时要绑定键盘监听事件。
这里以监听上键和下键为例。
@Override
public void keyReleased(KeyEvent e) {
//判断游戏是否胜利,如果胜利,将直接结束,不执行下面的移动代码
if(victory()){
//结束方法
return;
}
//对上,下,左,右进行判断
//左:37,上:38,右:39,下:40
int code = e.getKeyCode();
if(code == 37){
System.out.println("向左移动");
if(y == 3){
//表示空白方块已经在最右方了,他的下面没有图片再能移动
return;
}
data[x][y] = data[x ][y + 1];
data[x][y + 1] = 0;
y++;
//每移动一次,计数器就自增一次
step ++;
initImage();
} else if (code == 38) {
System.out.println("向上移动");
//把空白方块下方的数字向上移
//x,y表示空白方块
//x + 1,y 表示空白方块下面的数字
if(x == 3){
//表示空白方块已经在最下方了,他的下面没有图片再能移动
return;
}
判断data数组中的数据是否跟win数组中相同。
如果全部相同,返回true;否则,返回false。
public boolean victory(){
for (int i = 0; i < data.length; i++) {
//i依次表示二维数组data里面的索引
//data【i】:依次表示每一个一维数组
for (int j = 0; j < data.length; j++) {
if(data[i][j] != win[i][j]){
//只要一个不正确,返回false。
return false;
}
}
}
return true;
}
public GameJFrame(){
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化数据(打乱图片)
initDate();
//初始化图片
initImage();
//显示主界面
//show();
setVisible(true);
}
package ui;
public class Jframe {
public static void main(String[] arg){
new GameJFrame();
}
}
在界面中显示已经打乱的16张图片,且其中一个格子为空白
通过点击键盘(上下左右)来控制空白格和图片的交换位置,同时也会在终端上打印出来。
当我们点击键盘右键时,空白格就会和他左边的图片进行交换位置。如图:
左图为移动前,右图为移动后。
当我们把每一个图片归回原位时,会调用victory方法,来判断两个数组是否相同。如果相同,则显示胜利。
(1)步数
在原有代码的基础上,添加了步数显示;当玩家每点一次键盘时,步数自加一次。
int step = 0;
//在界面打印步数
JLabel stepCount = new JLabel("步数" + step);
stepCount.setBounds(50,30,100,20);
getContentPane().add(stepCount);
//每移动一次,计数器就自增一次
step ++;
(2)菜单
为了游戏有更多的选择性,添加了菜单
public void initJMenuBar(){
//初始化菜单
//创建整个的菜单对象
JMenuBar jMenuBar = new JMenuBar();
//创建菜单上面的两个选项的对象(功能,关于我们)
JMenu functionJMnu = new JMenu("功能");
//创建选项下面的条目对象
JMenuItem replayItem = new JMenuItem("重新游戏");
JMenuItem reLoginItem = new JMenuItem("重新登录");
//将每一个选项下面的条目添加到选项中
functionJMnu.add(replayItem);
functionJMnu.add(reLoginItem);
//给整个界面设置菜单
setJMenuBar(jMenuBar);
}
(1)玩家无法查看原始的图片,导致拼图无从下手,于是选择添加原始图片。
通过查阅百度书籍后,我们选择用键盘监听的方式来显示图片。只有玩家点击大写A时,原始图片就会覆盖在拼图上面出现,为了使游戏能继续进行,我们选择了用keyPressed(KeyEvent e)来监听,只要松开按键就会回到游戏中。
@Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == 65){
//把界面中所有的图片全部删除
getContentPane().removeAll();
//加载第一张完整的照片
ImageIcon iconAll = new ImageIcon(“\\image\\animal\\animal1\\all.jpg");
JLabel jLabelAll = new JLabel(iconAll);
jLabelAll .setBounds(83,134,420,420);
getContentPane().add(jLabelAll);
//加载背景图片
//添加背景图片
ImageIcon icon2 = new ImageIcon("untitled5\\image\\background.png");
JLabel jLabel2 = new JLabel(icon2);
jLabel2.setBounds(40,40,508,560);
//把背景图片添加到界面当中
getContentPane().add(jLabel2);
//刷新界面
getContentPane().repaint();
}
}
1.总结:
1.把学过的JAVA的知识强化,能够把课堂上学的知识通过自己设计的程序表示出来,加深了对理论知识的理解。
2.在设计的过程中了解到自己的知识还是比较有限,更肯定了自己再以后学习编程的道路上的坚定不移,同时也让我懂得组合作的重要性。
3.同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过这次之后,一定把以前所学的知识重新温故,提升自己的能力。