课题:魔板游戏
一、课设要求
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 图像玩法
Point 确定模块中的方块位置
Block 表示模块中的方块
Distance 确定对象之间的距离
Handmove 控制鼠标点击方块
HandleImage 图像分成若干个小图像
VerifySuccess 验证是否排序成功
ImageWidth/Height 用来存储图像的宽与高
Tool 用来获取Image对象
Setpoint 用于移动block对象
SetVerifySuccess 用于检验对象是否按要求排列完毕
InitSpendTime 将SpendTime的值设置为0
ActionPerformed 显示用户当前用时
Point Point类型的二维数组
Object Object数组,其单元可以存放任何变量
Time 用户用时
YourName 用户用来输入名字的文本框
Enter和Cancel enter可以用来保存成绩,cancel放弃成绩
GradeFile 级别文件
Tie 用户用时
Name 用户姓名
Point 确定block对象在魔板中的位置
Object 确定block对象上所显示数字或图像
X Y 表示容器的两个坐标
Haveblock block对象在point对象上的数据是否正确
(1)PuzzleGame类方法
PuzzleGame 完成程序的初始化功能
Main()程序运行的入口方法
PuzzlePad 负责创建PuzzlePad对象
GetHandMove 返回其中的GetHandMove对象
Image 设置Image对象
GetGrade 返回Grade
SetIsDigitplay 将魔板设置为数字玩法
SetIsImageplay 将魔板设置为图像玩法
PaintComponent 对照图
HandImage 负责完成HandImage对象的初始化
GetImages 将那些分解完的小图片放在Image数组中
HandleMove 创建HandleMove对象
SetPoint 将模板容器中的point对象传递给该类中对象
InitSpendTime 将spendtime值设置为0
Mousepressed 执行鼠标左键对象,根据规则移动Block对象
ActionPerformed 显示用户当前的用时
HandleMove 创建HandleMove对象
SetPoint 将模板容器中的point对象传递给该类中对象
SetPoint 将模板容器中的Interger数组的引用传递给该对象中的Point
IsSuccess 判断程序是否按正确顺序排列
Record 用来创造Record对象
File 当用户成功是弹出Rcord对话框,将调用SetGradeFile方法将级别文件传递给Record对话框gradefile
SetTime 将记录的用时传递给Record对话框gradeFile
GetTime 返回 time
GetName 返回 name
SetAtPoint 设置自己所在的点
GetAtPoint 返回自己所在的点
SetObject 设置自己的成员Object
PaintComponent 绘制Image对象
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[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
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 [] 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 for(int j=0;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 for(int j=0;j if(point[i][j].equals(startPoint)){ startI=i; startJ=j; break; } } for(int i=0;i for(int j=0;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 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 if(i for(int j=0;j if(!(point[i][j].getBlock().getObject()==object[k])){ boo=false; break; } k++; } } else{ for(int j=0;j if(!(point[i][j].getBlock().getObject()==object[k])){ boo=false; break; } k++; } } } return boo; } }