课题:魔板游戏
一、课设要求
1.基本功能
(1)游戏规则
一个3×3的魔板,有一个格子是空的,其他格子内随机放置1-8共8个编号的方块,通过单击任意一个与空格子相邻的方块可以把该方块移入空格子,不断的移动方块,直到方块一行一行的按数字顺序排好。
(2)程序功能
三个基本功能:方块移动(键盘鼠标操作皆可)、游戏控制(改变游戏状态)、游戏计时。
(3)程序界面
根据游戏的三种状态有三种界面
2.扩展功能(必须通过菜单命令实现,前两个是必须完成的功能,后两个是选做的功能)
难度设置(更改方块的行列数),放在设置菜单下
魔板设置(更改方块的显示效果,显示为拼图),放在设置菜单下
背景音乐设置(背景音乐开关和音乐选择),放在设置菜单下
玩家排行榜(根据游戏完成时间生成,用数据库或文件存储),放在文件菜单下,退出命令之前
- 课设内容分析——总体设计部分
- 各个类的功能说明
PuzzleGame.java 主类,负责创建魔板游戏的主窗口
PuzzlePad.java 用于创建魔板游戏的方块及其移动
Handleimage.java 将一个图像分解成多个部分并随即排列
Handlemove.java 用于控制鼠标来移动方块
VerifySuccess.java 用于检测是否按照顺序排列
People.java 表示成绩和名字
Record.java 记录名字和成绩到相应的文件中
Block.java 表示方块
Point.java 表示方块的位置
- 各个类的成员变量
(1)PuzzleGame类成员变量
Bar 用来添加菜单
GradeMenu 选择级别菜单
modeMenu 选择模式菜单
resultMenu 查看英雄榜菜单
ChoiceImage 选择图像
OneGrade 初级
TwoGrade 高级
NewImage 选择一幅新图像
digitPlay 数字玩法
imagePlay 图像玩法
- PuzzlePad类成员变量
Point 确定模块中的方块位置
Block 表示模块中的方块
Distance 确定对象之间的距离
Handmove 控制鼠标点击方块
HandleImage 图像分成若干个小图像
VerifySuccess 验证是否排序成功
- HandImage类成员变量
ImageWidth/Height 用来存储图像的宽与高
Tool 用来获取Image对象
- HandleMove类变量成员
Setpoint 用于移动block对象
SetVerifySuccess 用于检验对象是否按要求排列完毕
InitSpendTime 将SpendTime的值设置为0
ActionPerformed 显示用户当前用时
- VerifySuccess类成员变量
Point Point类型的二维数组
Object Object数组,其单元可以存放任何变量
- Record类变量成员
Time 用户用时
YourName 用户用来输入名字的文本框
Enter和Cancel enter可以用来保存成绩,cancel放弃成绩
GradeFile 级别文件
- People类变量成员
Tie 用户用时
Name 用户姓名
- Block类成员变量
Point 确定block对象在魔板中的位置
Object 确定block对象上所显示数字或图像
- Point类成员变量
X Y 表示容器的两个坐标
Haveblock block对象在point对象上的数据是否正确
- 各个类的方法
(1)PuzzleGame类方法
PuzzleGame 完成程序的初始化功能
Main()程序运行的入口方法
- PuzzlePad类方法
PuzzlePad 负责创建PuzzlePad对象
GetHandMove 返回其中的GetHandMove对象
Image 设置Image对象
GetGrade 返回Grade
SetIsDigitplay 将魔板设置为数字玩法
SetIsImageplay 将魔板设置为图像玩法
PaintComponent 对照图
- HandImage类方法
HandImage 负责完成HandImage对象的初始化
GetImages 将那些分解完的小图片放在Image数组中
- HandleMove类方法
HandleMove 创建HandleMove对象
SetPoint 将模板容器中的point对象传递给该类中对象
InitSpendTime 将spendtime值设置为0
Mousepressed 执行鼠标左键对象,根据规则移动Block对象
ActionPerformed 显示用户当前的用时
- VerifySuccess类方法
HandleMove 创建HandleMove对象
SetPoint 将模板容器中的point对象传递给该类中对象
SetPoint 将模板容器中的Interger数组的引用传递给该对象中的Point
IsSuccess 判断程序是否按正确顺序排列
- Record类方法
Record 用来创造Record对象
File 当用户成功是弹出Rcord对话框,将调用SetGradeFile方法将级别文件传递给Record对话框gradefile
SetTime 将记录的用时传递给Record对话框gradeFile
- People类方法
GetTime 返回 time
GetName 返回 name
- Block类方法
SetAtPoint 设置自己所在的点
GetAtPoint 返回自己所在的点
SetObject 设置自己的成员Object
PaintComponent 绘制Image对象
- Point类方法
Point 创建Point对象
IsHaveBlock 如果当前Point对象上有Block对象返回ture
GetX() GetY() 返回X轴坐标和Y坐标
SetBlock 将参数指定的Block对象放在当前Point对象上
GetBlock 返回当前Point对象上的Block对象
四、 课设成果
- 初始界面
- 游戏模式选择(数字与图像)
(1)数字
- 图像
- 用户计时
- 游戏难度选择
- 成功界面
- 排行榜
附录:
代码如下:
PuzzleGame
package mobanyouxi;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;
import javax.swing.filechooser.*;
public class PuzzleGame extends JFrame implements ActionListener{
PuzzlePad puzzlePad;
JMenuBar bar;
JMenu gradeMenu,choiceImage,resultMenu,modeMenu;///
JMenuItem oneGrade,twoGrade,newImage,defaultImage;
JMenuItem oneGradeResult,twoGradeResult;
File fileOneGrade,fileTwoGrade,gradeFile;//
JMenuItem digitPlay,imagePlay;
ButtonGroup group=null;
// Record record=null;
ShowRecordDialog showDiolag=null;///
JButton startButton;
JButton refreshButton;
Image image;
Toolkit tool;
public PuzzleGame(){
fileOneGrade=new File("初级魔板游戏排行榜.txt");//
fileTwoGrade=new File("高级魔板游戏排行榜.txt");//
tool=getToolkit();
bar=new JMenuBar();
modeMenu=new JMenu("选择玩法");
digitPlay=new JMenuItem("数字玩法");
imagePlay=new JMenuItem("图像玩法");
modeMenu.add(digitPlay);
modeMenu.add(imagePlay);
gradeMenu=new JMenu("选择级别");
oneGrade=new JMenuItem("初级");
twoGrade=new JMenuItem("高级");
gradeMenu.add(oneGrade);
gradeMenu.add(twoGrade);
choiceImage=new JMenu("选择图像");
newImage=new JMenuItem("选择一幅新图像");
defaultImage=new JMenuItem("使用默认图像");
choiceImage.add(newImage);
choiceImage.add(defaultImage);
resultMenu=new JMenu("查看英雄榜");/
oneGradeResult=new JMenuItem("初级英雄榜"); /
twoGradeResult=new JMenuItem("高级英雄榜");
resultMenu.add(oneGradeResult);///
resultMenu.add(twoGradeResult);//
bar.add(modeMenu);
bar.add(gradeMenu);
bar.add(choiceImage);
bar.add(resultMenu);
/
setJMenuBar(bar);
oneGrade.addActionListener(this);///
twoGrade.addActionListener(this);//
newImage.addActionListener(this);
defaultImage.addActionListener(this);
oneGradeResult.addActionListener(this);/
twoGradeResult.addActionListener(this);/
digitPlay.addActionListener(this);
imagePlay.addActionListener(this);
startButton=new JButton("刷新数字");
startButton.addActionListener(this);
refreshButton=new JButton("刷新图片");
refreshButton.addActionListener(this);
puzzlePad=new PuzzlePad();
add(puzzlePad,BorderLayout.CENTER);
JPanel pNorth=new JPanel();
pNorth.add(startButton);
pNorth.add(refreshButton);
add(pNorth,BorderLayout.NORTH);
add(puzzlePad.getHandleMove(),BorderLayout.SOUTH);
validate();
setVisible(true);
setBounds(250,50,650,650);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try{
image=tool.createImage(new File("dog.jpg").toURI().toURL());
puzzlePad.setImage(image);
}
catch(Exception exp){}
// imageName=new String[imageNumber];
//for(int i=0;i<imageName.length;i++){
// imageName[i]=new String("car"+i+".jpg");
// }
// m=5;
//n=6;
// gradeFile=fileOneGrade;
//memoryArea.initBlock(m,n,imageName,gradeFile);
// add(memoryArea,BorderLayout.CENTER);
// record=new Record();
// showRead=new ShowRecord();
if(!fileOneGrade.exists()){ /
try { fileOneGrade.createNewFile();/
}/
catch(IOException exp){}/
}
if(!fileTwoGrade.exists()){
try { fileTwoGrade.createNewFile();
}
catch(IOException exp){}/
}
showDiolag=new ShowRecordDialog();/
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==startButton){
puzzlePad.setIsDigitPlay();
}
else if(e.getSource()==refreshButton) {
puzzlePad.setImage(image);
puzzlePad.setIsImagePlay();
}
else if(e.getSource()==digitPlay){
puzzlePad.setIsDigitPlay();
}
else if(e.getSource()==imagePlay){
puzzlePad.setImage(image);
puzzlePad.setIsImagePlay();
}
else if(e.getSource()==oneGrade){
puzzlePad.setGrade(1);
}
else if(e.getSource()==twoGrade){
puzzlePad.setGrade(2);
}
else if(e.getSource()==newImage){
FileNameExtensionFilter filter = new FileNameExtensionFilter(
"JPG & GIF Images", "jpg", "gif");
JFileChooser chooser=new JFileChooser();
chooser.setFileFilter(filter);
int state=chooser.showOpenDialog(null);
File file=chooser.getSelectedFile();
if(file!=null&&state==JFileChooser.APPROVE_OPTION){
try{
image=tool.createImage(file.toURI().toURL());
puzzlePad.setImage(image);
}
catch(Exception exp){}
}
}
else if(e.getSource()==defaultImage){
try{
image=tool.createImage(new File("dog.jpg").toURI().toURL());
puzzlePad.setImage(image);
}
catch(Exception exp){}
}
if(e.getSource()==oneGradeResult){
showDiolag.setGradeFile(fileOneGrade);
showDiolag.showRecord();
showDiolag.setVisible(true);
}
if(e.getSource()==twoGradeResult){/
showDiolag.setGradeFile(fileTwoGrade);/
showDiolag.showRecord();/
showDiolag.setVisible(true);
}//用来生成英雄榜txt文档/
}
public static void main(String args[]){
new PuzzleGame();
}
}
PuzzlePad
package mobanyouxi;
import javax.swing.*;
import java.io.*;
import java.util.*;
import java.awt.*;
public class PuzzlePad extends JPanel{
Point [][] point;
Block [][] block;
int distance=100,grade=1,m=3,n=3;
HandleMove handleMove;
HandleImage handleImage;
VerifySuccess verifySuccess;
Image image;
boolean isDigitPlay;
//Record record;
public PuzzlePad(){
setBackground(Color.gray);
setLayout(null);
handleMove=new HandleMove();
handleMove.initSpendTime();
handleImage=new HandleImage();
verifySuccess=new VerifySuccess();
// record=new Record();
handleMove.setVerifySuccess(verifySuccess);
}
public HandleMove getHandleMove(){
return handleMove;
}
public void setImage(Image image){
this.image=image;
}
public void setGrade(int grade){
this.grade=grade;
handleMove.grade=grade;
if(grade==1){
m=3;
n=3;
}
else if(grade==2){
m=4;
n=4;
}
}
public int getGrade(){
return grade;
}
private void needInit(){
handleMove.initSpendTime();
removeAll();
point=new Point[m][n];
block=new Block[m][n];
int Hspace=distance,Vspace=distance;
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
point[i][j]=new Point(Hspace,Vspace);
Hspace=Hspace+distance;
}
Hspace=distance;
Vspace=Vspace+distance;
}
handleMove.setPoint(point);
verifySuccess.setPoint(point);
handleMove.setVerifySuccess(verifySuccess);
int k=0;
for(int i=0;i<m;i++){
if(i<m-1)
for(int j=0;j<n;j++){
block[i][j]=new Block();
block[i][j].addMouseListener(handleMove);
k++;
}
else
for(int j=0;j<n-1;j++){
block[i][j]=new Block();
block[i][j].addMouseListener(handleMove);
k++;
}
}
for(int i=0;i<m;i++){
if(i<m-1)
for(int j=0;j<n;j++){
add(block[i][j]);
block[i][j].setSize(distance,distance);
block[i][j].setLocation(point[i][j].getX(),point[i][j].getY());
block[i][j].setAtPoint(point[i][j]);
point[i][j].setBlock(block[i][j]);
point[i][j].setHaveBlock(true);
}
else
for(int j=0;j<n-1;j++){
add(block[i][j]);
block[i][j].setSize(distance,distance);
block[i][j].setLocation(point[i][j].getX(),point[i][j].getY());
block[i][j].setAtPoint(point[i][j]);
point[i][j].setBlock(block[i][j]);
point[i][j].setHaveBlock(true);
}
}
}
public void setIsDigitPlay(){
needInit();
isDigitPlay=true;
ArrayList<Integer> numberList=new ArrayList<Integer>();
for(int k=0;k<m*n-1;k++){
numberList.add(k+1);
}
Object []object=numberList.toArray();
verifySuccess.setObject(object);
Collections.shuffle(numberList); //随机排列数字
int k=0;
for(int i=0;i<m;i++){
if(i<m-1)
for(int j=0;j<n;j++){
block[i][j].setObject(numberList.get(k));
k++;
}
else
for(int j=0;j<n-1;j++){
block[i][j].setObject(numberList.get(k));
k++;
}
}
repaint();
}
public void setIsImagePlay(){
needInit();
isDigitPlay=false;
ArrayList<Image> imageList=new ArrayList<Image>();
Image [] blockImage=handleImage.getImages(image,m,n);
for(int k=0;k<blockImage.length-1;k++){
imageList.add(blockImage[k]);
}
Object []object=imageList.toArray();
verifySuccess.setObject(object);
Collections.shuffle(imageList); //随机排列图像
int k=0;
for(int i=0;i<m;i++){
if(i<m-1)
for(int j=0;j<n;j++){
block[i][j].setObject(imageList.get(k));
block[i][j].repaint();
block[i][j].setBorder(null);
k++;
}
else
for(int j=0;j<n-1;j++){
block[i][j].setObject(imageList.get(k));
block[i][j].repaint();
block[i][j].setBorder(null);
k++;
}
}
repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(isDigitPlay==false)
try{
g.drawImage(image,20+distance*(m+1),point[0][0].getY(),
distance*m,distance*n,this);
}
catch(Exception exp){}
}
}
HandleImage
import java.awt.*;
import javax.swing.*;
import java.awt.image.*;
public class HandleImage extends JComponent{
int imageWidth,imageHeight;
Toolkit tool;
HandleImage(){
tool=getToolkit();
}
public Image [] getImages(Image image,int rows,int colums){
Image [] blockImage=new Image[rows*colums];
try{
imageWidth=image.getWidth(this);
imageHeight=image.getHeight(this);
int w=imageWidth/colums;
int h=imageHeight/rows;
int k=0;
PixelGrabber pg=null;
ImageProducer ip=null;
for(int i=0;i<rows;i++){
for(int j=0;j<colums;j++){
int pixels[]= new int[w*h];
pg=new PixelGrabber(image,j*w,i*h,w,h,pixels,0,w);
pg.grabPixels();
ip=new MemoryImageSource(w,h,pixels,0,w);
blockImage[k]=tool.createImage(ip);
k++;
}
}
}
catch(Exception ee){}
return blockImage;
}
}
Block
import javax.swing.*;
import java.awt.*;
public class Block extends JTextField{
Point point;
Object object;
Block(){
setEditable(false);
setHorizontalAlignment(JTextField.CENTER);
setFont(new Font("Arial",Font.BOLD,16));
setForeground(Color.blue);
}
public void setAtPoint(Point p){
point=p;
}
public Point getAtPoint(){
return point;
}
public void setObject(Object object){
this.object=object;
if(object instanceof Integer){
Integer number=(Integer)object;
setText(""+number.intValue());
}
else if(object instanceof Image){
repaint();
}
}
public Object getObject(){
return object;
}
public void paintComponent(Graphics g){
super.paintComponent(g);
int w=getBounds().width;
int h=getBounds().height;
try{
g.drawImage((Image)object,0,0,w,h,this);
}
catch(Exception exp){}
}
}
HandleMove
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.applet.*;
import java.net.*;
public class HandleMove extends JPanel implements MouseListener,ActionListener {
Point [][] point;
int spendTime=0;
int grade=1;///
javax.swing.Timer recordTime;
File fileOneGrade,fileTwoGrade;
///
File musicFile=new File("hello.wav");//
URL url;//
AudioClip clip;
///
JTextField showTime;
VerifySuccess verify;
Record record;
HandleMove(){
try
{
url=musicFile.toURL();
clip=Applet.newAudioClip(url);
}
catch(Exception e)
{}
recordTime=new javax.swing.Timer(1000,this);
showTime=new JTextField(16);
showTime.setEditable(false);
showTime.setHorizontalAlignment(JTextField.CENTER);
showTime.setFont(new Font("楷体_GB2312",Font.BOLD,16));
JLabel hitMess=new JLabel("用鼠标单击方块",JLabel.CENTER);
hitMess.setFont(new Font("楷体_GB2312",Font.BOLD,18));
add(hitMess);
add(showTime);
setBackground(Color.cyan);
fileOneGrade=new File("初级魔板游戏排行榜.txt");///
fileTwoGrade=new File("高级魔板游戏排行榜.txt");///
}
public void setPoint(Point [][] p){
point=p;
}
public void initSpendTime(){
recordTime.stop();
spendTime=0;
showTime.setText(null);
/
/* File musicFile=new File("hello.wav");
URI uri=musicFile.toURI();/
URL url=uri.toURL("E:\chaper6");
AudioClip clip=Applet.newAudioClip(url);*/
/
}
public void setVerifySuccess(VerifySuccess verify){
this.verify=verify;
}
public void mousePressed(MouseEvent e){
recordTime.start();
clip.play();/
Block block=null;
block=(Block)e.getSource();
int w=block.getBounds().width;
int h=block.getBounds().height;
int startI=-1,startJ=-1,endI=-1,endJ=-1;
Point startPoint=block.getAtPoint();
Point endPoint=null;
for(int i=0;i<point.length;i++){
for(int j=0;j<point[0].length;j++)
if(point[i][j].equals(startPoint)){
startI=i;
startJ=j;
break;
}
}
for(int i=0;i<point.length;i++){
for(int j=0;j<point[0].length;j++)
if(point[i][j].isHaveBlock()==false){
endI=i;
endJ=j;
endPoint=point[i][j];
break;
}
}
boolean moveCondition1=Math.abs(endI-startI)==1&&endJ==startJ;
boolean moveCondition2=Math.abs(endJ-startJ)==1&&endI==startI;
if(moveCondition1||moveCondition2){
block.setLocation(endPoint.getX(),endPoint.getY());
block.setAtPoint(endPoint);
endPoint.setBlock(block);
endPoint.setHaveBlock(true);
startPoint.setHaveBlock(false);
}
}
public void actionPerformed(ActionEvent e){
spendTime++;
showTime.setText("您的用时:"+spendTime+"秒");
}
public void mouseReleased(MouseEvent e){
if(verify.isSuccess()){
recordTime.stop();
record=new Record();
switch(grade){///
case 1:record.setGradeFile(fileOneGrade);///
break;///
case 2:record.setGradeFile(fileTwoGrade);///
break;///
}///
record.setTime(spendTime);///
record.setVisible(true);
JOptionPane.showMessageDialog(this,"您成功了!","消息框",
JOptionPane.INFORMATION_MESSAGE );
/*record.setTime(spendTime);
record.setGradeFile(gradeFile);
record.setVisible(true);//记录英雄榜*/
}
}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseClicked(MouseEvent e){
/* record.setTime(spendTime);
record.setGradeFile(gradeFile);
record.setVisible(true);//记录英雄榜*/
}
}
People
import java.io.*;
public class People implements Serializable,Comparable{
String name=null;
int time=0;
public People(String name,int t){
this.name=name;
time=t;
}
public int getTime(){
return time;
}
public String getName(){
return name;
}
public int compareTo(Object b){
People p=(People)b;
if((this.time-p.time)==0)
return 1;
else
return (this.time-p.time);
}
}
Point
public class Point{
int x,y;
boolean haveBlock;
Block block=null;
public Point(int x,int y){
this.x=x;
this.y=y;
}
public boolean isHaveBlock(){
return haveBlock;
}
public void setHaveBlock(boolean boo){
haveBlock=boo;
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public boolean equals(Point p){
if(p.getX()==this.getX()&&p.getY()==this.getY())
return true;
else
return false;
}
public void setBlock(Block block){
this.block=block;
}
public Block getBlock(){
return block;
}
}
Record
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Record extends JDialog implements ActionListener{
int time=0;
JTextField yourName;
JLabel label=null;
JButton enter,cancel;
File gradeFile=null;
public Record(){
setBounds(100,50,550,380);
setResizable(false);
setModal(true);
setVisible(false);
enter=new JButton("确定");
cancel=new JButton("取消");
yourName=new JTextField(8);
yourName.setText("匿名");
enter.addActionListener(this);
cancel.addActionListener(this);
setLayout(new GridLayout(2,1));
label=new JLabel();
add(label);
JPanel p=new JPanel();
p.add(yourName);
p.add(enter);
p.add(cancel);
add(p);
}
public void setGradeFile(File f){
gradeFile=f;
setTitle("保存成绩到"+gradeFile.getName());
label.setText("保存成绩到"+gradeFile.getName());
validate();
}
public void setTime(int time){
this.time=time;
}
public void actionPerformed(ActionEvent e){
if(e.getSource()==enter){
LinkedList<People> list=new LinkedList<People>();
try{
RandomAccessFile out=new RandomAccessFile(gradeFile,"rw");
out.seek(out.length());
out.writeUTF(yourName.getText());
out.writeInt(time);
out.close();
}
catch(Exception event) {
System.out.println("error");///
}
setVisible(false);
}
if(e.getSource()==cancel){
setVisible(false);
}
}
}
VerifySuccess
public class VerifySuccess{
Point [][] point;
Object [] object;
public void setPoint(Point [][] point){
this.point=point;
}
public void setObject(Object [] object){
this.object=object;
}
public boolean isSuccess(){
boolean boo=true;
int k=0;
for(int i=0;i<point.length;i++){
if(i<point.length-1){
for(int j=0;j<point[i].length;j++){
if(!(point[i][j].getBlock().getObject()==object[k])){
boo=false;
break;
}
k++;
}
}
else{
for(int j=0;j<point[i].length-1;j++){
if(!(point[i][j].getBlock().getObject()==object[k])){
boo=false;
break;
}
k++;
}
}
}
return boo;
}
}