当前位置:   article > 正文

用java实现拼图小游戏_java拼图游戏记载步数

java拼图游戏记载步数

1、了解拼图游戏基本功能:

拼图游戏内容由若干小图像块组成的,通过鼠标点击图像块上下左右移动,完成图像的拼凑。

2、拼图游戏交互界面设计与开发:

通过创建窗体类、菜单、中间面板和左右面板完成设计拼图的交互界面 ,实现拼图游戏的基本功能。

3、图片的加载与分割:

使用Image类实现图片的缩放,ImageIO类实现图片的读写加载,通过接口类Icon,BufferedImage类获取BufferedImage类的对象实现图片分割。

4、图片随机打乱和交换:

产生随机数 Random rand=new Random();

           rand.nextInt(hs*ls)------[0,8]

具体操作:生成两个随机数表示数组下标,互换两个数组元素的位置,按钮的方法getX和getY可以获取按钮的坐标,利用按钮的单击事件的处理ActionListener可以使其图片交换。

5、判赢:

当用户移动按钮后进行判断,代码写在监听器的actionPerformed方法中,判断拼图是否成功,主要取决于每一个按钮通过索引下标获取的位置值,与当前按钮的位置值是否相同。

6、计时和计数功能的实现:

计时功能的实现主要是线程的设计,线程的定义方法:第一:继承Thread类,第二:实现Runnable接口,创建带实现接口的子类对象的Thread对象,MainJFrame实现Runnable接口,重写run方法;而计数则在主窗体中通过rp.times实现对变量的使用来计数。

7、游戏记录的保存:

当用户拼图成功后,记录当前信息到文件中,FileWriter追加写信息,FileReader完成读取数据。

  1. import java.awt.Color;
  2. import java.awt.Font;
  3. import java.awt.GridLayout;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import javax.swing.JButton;
  7. import javax.swing.JFrame;
  8. import javax.swing.JLabel;
  9. import javax.swing.JOptionPane;
  10. import javax.swing.JPasswordField;
  11. import javax.swing.JTextField;
  12. public class LoginPintu extends JFrame{
  13. JLabel jl1,jl2,jl3,jl4;
  14. JTextField jtf;//文本框
  15. JPasswordField jpf;//密码
  16. JButton jb1,jb2;
  17. public LoginPintu() {
  18. this.setTitle("拼图游戏");
  19. setBounds(400,350,500,400);
  20. //设置窗体为流式布局
  21. setLayout(new GridLayout(20,1));
  22. //空布局
  23. setLayout(null);
  24. init();
  25. setVisible(true);
  26. setDefaultCloseOperation(EXIT_ON_CLOSE);
  27. jb1.addActionListener(new ActionListener(){
  28. public void actionPerformed(ActionEvent e) {
  29. if(jtf.getText().trim().equals("admin")&&
  30. new String(jpf.getPassword()).trim().equals("123"))
  31. {JOptionPane.showMessageDialog(null, "欢迎进入游戏!");
  32. new MainJFrame();}
  33. else if(jtf.getText().trim().length()==0||
  34. new String(jpf.getPassword()).trim().length()==0)
  35. {JOptionPane.showMessageDialog(null, "用户名或密码不能为空!");}
  36. else {JOptionPane.showMessageDialog(null, "用户名或密码错误!");}
  37. }
  38. });
  39. jb2.addActionListener(new ActionListener() {
  40. public void actionPerformed(ActionEvent e) {
  41. // System.exit(0);
  42. //获取事件源对象
  43. JButton jb=(JButton)e.getSource();
  44. jtf.setText(jb.getText());
  45. }
  46. });
  47. }
  48. public void init() {
  49. jl1=new JLabel("拼图游戏登录窗口");
  50. jl2=new JLabel("用户名:");
  51. jl3=new JLabel("密码:");
  52. jtf=new JTextField(10);
  53. jpf=new JPasswordField(10);
  54. jb1=new JButton("登录");
  55. jb2=new JButton("取消");
  56. jl1.setBounds(150,30,200,60);
  57. jl2.setBounds(100, 120, 180, 30);
  58. jtf.setBounds(200, 120, 180, 30);
  59. jl3.setBounds(100, 180, 180, 30);
  60. jpf.setBounds(200, 180, 180, 30);
  61. jb1.setBounds(100, 260, 100, 30);
  62. jb2.setBounds(220, 260, 100, 30);
  63. Font font = new Font("楷体",Font.PLAIN,25);
  64. jl1.setFont(font);
  65. jl1.setForeground(Color.red);
  66. add(jl1);
  67. add(jl2);
  68. add(jtf);
  69. add(jl3);
  70. add(jpf);
  71. add(jb1);
  72. add(jb2);
  73. }
  74. public static void main(String[] args) {
  75. new LoginPintu();
  76. }
  77. }


  1. import java.awt.Image;
  2. import java.awt.event.ActionEvent;
  3. import java.awt.event.ActionListener;
  4. import java.awt.image.BufferedImage;
  5. import java.io.FileInputStream;
  6. import java.io.FileWriter;
  7. import java.io.IOException;
  8. import java.net.URL;
  9. import java.util.Random;
  10. import javax.imageio.ImageIO;
  11. import javax.swing.ImageIcon;
  12. import javax.swing.JButton;
  13. import javax.swing.JOptionPane;
  14. import javax.swing.JPanel;
  15. import jdk.jfr.events.FileWriteEvent;
  16. //右面板实现ActionListener接口,右面板也就成为了监听器
  17. public class RightJPanel extends JPanel implements ActionListener{
  18. //面板的大小
  19. int width=700;
  20. int height=700;
  21. //定义按钮数组
  22. JButton[] jbs;
  23. //设置分割的行列数
  24. int hs=2,ls=2;
  25. //按钮的宽度和高度,指定是小图图片缩放的尺寸
  26. int widthbut,heightbut;
  27. //图片原始高度宽度
  28. int widthtp,heighttp;
  29. //小图的原始宽度高度
  30. int widthxt,heightxt;
  31. //实现步数计算的变量
  32. int times;
  33. //空白按钮
  34. JButton kb;
  35. public RightJPanel(){
  36. //面板布局是空布局
  37. setLayout(null);
  38. setSize(width,height);
  39. //init();
  40. }
  41. //创建按钮,并放置到右面板
  42. public void init(URL url) {
  43. //面板组件初始化前,先清除所有已有的组件
  44. this.removeAll();
  45. //创建按钮数组
  46. jbs=new JButton[hs*ls];
  47. //为每一个按钮实现初始化
  48. //计算按钮的宽度和高度
  49. //面板是700*700,拆分成3*39个区域
  50. //每一块区域的宽度 700/3
  51. //每一块区域的高度 700/3
  52. widthbut=width/ls;
  53. heightbut=height/hs;
  54. BufferedImage buf=null;
  55. try {
  56. buf = ImageIO.read(url);
  57. //获取原图的宽度、高度
  58. widthtp=buf.getWidth();
  59. heighttp=buf.getHeight();
  60. //获取小图的宽度和高度
  61. widthxt=widthtp/ls;
  62. heightxt=heighttp/hs;
  63. //每一块按钮的坐标位置确定
  64. for(int i=0;i<jbs.length;i++){
  65. jbs[i]=new JButton();
  66. jbs[i].setSize(widthbut,heightbut);
  67. //jbs[i].setText(i+"");
  68. //添加按钮前要确定坐标位置
  69. //横坐标 i=0 0 i=1 233 i=2 466
  70. //i=3 0 i=4 233
  71. //纵坐标 i=3
  72. jbs[i].setLocation((i%ls)*widthbut, i/ls*heightbut);
  73. //jbs[i].setIcon(null);
  74. //小图的获取
  75. BufferedImage subimage = buf.getSubimage(i%ls*widthxt, i/ls*heightxt, widthxt, heightxt);
  76. //小图的缩放
  77. Image image = subimage.getScaledInstance(widthbut, heightbut, 1);
  78. //将小图图片放置到按钮上
  79. jbs[i].setIcon(new ImageIcon(image));
  80. //添加按钮到右面板
  81. add(jbs[i]);
  82. //设置按钮不可用
  83. jbs[i].setEnabled(false);
  84. //设置按钮的监听,当按钮被单击,会到右面板中找actionPerformed方法执行
  85. jbs[i].addActionListener(this);
  86. }
  87. jbs[hs*ls-1].setIcon(null);
  88. kb=jbs[hs*ls-1];
  89. } catch (IOException e) {
  90. // TODO Auto-generated catch block
  91. e.printStackTrace();
  92. }
  93. }
  94. //打乱按钮在面板中显示的顺序
  95. public void randomOrder(){
  96. //创建随机数对象
  97. Random rand=new Random();
  98. //打乱多次
  99. for(int i=0;i<hs*ls;i++){
  100. //随机索引
  101. int index1=rand.nextInt(hs*ls);
  102. int index2=rand.nextInt(hs*ls);
  103. int x1=jbs[index1].getX();
  104. int y1=jbs[index1].getY();
  105. int x2=jbs[index2].getX();
  106. int y2=jbs[index2].getY();
  107. jbs[index1].setLocation(x2, y2);
  108. jbs[index2].setLocation(x1, y1);
  109. jbs[i].setEnabled(true);
  110. }
  111. }
  112. //按钮的单击事件执行的代码
  113. @Override
  114. public void actionPerformed(ActionEvent e) {
  115. // 判断单击按钮和空白按钮是否相邻,如果相邻,则位置互换
  116. //获取用户单击的按钮 ,通过ActionEvent e的方法gerSource获取事件源
  117. JButton jb=(JButton)(e.getSource());
  118. //获取单击按钮和空白按钮的坐标
  119. int x1=jb.getX();
  120. int y1=jb.getY();
  121. int x2=kb.getX();
  122. int y2=kb.getY();
  123. //判断是否可以移动
  124. //Math.abs(x1-x2)/widthbut + Math.abs(y1-y2)/heightbut==1
  125. if (Math.abs(x1-x2)/widthbut + Math.abs(y1-y2)/heightbut==1){
  126. jb.setLocation(x2, y2);
  127. kb.setLocation(x1, y1);
  128. times++;
  129. }
  130. //判断是否拼图成功
  131. if (isWin()){
  132. JOptionPane.showMessageDialog(null, "恭喜你,拼图成功");
  133. //使得按钮不可用
  134. for(int i=0;i<jbs.length;i++){
  135. jbs[i].setEnabled(false);
  136. }
  137. //提示用户输入名称
  138. //使用输入对话框
  139. String name = JOptionPane.showInputDialog("请输入你的姓名:");
  140. String info = hs+"*"+ls+"拼图记录:"+name+"的步数是:"+times+"\r\n";
  141. JOptionPane.showMessageDialog(null, hs+"*"+ls+"拼图记录:"+name+"的步数是:"+times+"\r\n");
  142. try {
  143. FileWriter fw = new FileWriter("D:\\游戏记录.dat",true);
  144. fw.write(info);
  145. fw.close();
  146. }catch (IOException e1) {
  147. e1.printStackTrace();
  148. }
  149. }
  150. }
  151. //判断是否拼图成功
  152. public boolean isWin() {
  153. //获取每一个按钮的坐标
  154. for(int i=0;i<jbs.length;i++){
  155. //jbs[i].setLocation((i%ls)*widthbut, i/ls*heightbut);由之前坐标设置给出下面的x,y
  156. int x=jbs[i].getX()/widthbut;
  157. int y=jbs[i].getY()/heightbut;
  158. //判断,通过下标值,也可以获取按钮的坐标 横坐标 i%ls 纵坐标 i/ls
  159. if (i%ls!=x || i/ls!=y ){
  160. return false;
  161. }
  162. }
  163. return true;
  164. }
  165. }

  1. import java.awt.Color;
  2. import java.awt.GridLayout;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. import java.io.File;
  6. import java.io.FileReader;
  7. import java.io.IOException;
  8. import java.net.MalformedURLException;
  9. import java.net.URL;
  10. import javax.swing.ButtonGroup;
  11. import javax.swing.JFileChooser;
  12. import javax.swing.JFrame;
  13. import javax.swing.JLabel;
  14. import javax.swing.JMenu;
  15. import javax.swing.JMenuBar;
  16. import javax.swing.JMenuItem;
  17. import javax.swing.JOptionPane;
  18. import javax.swing.JPanel;
  19. import javax.swing.JRadioButtonMenuItem;
  20. import javax.swing.filechooser.FileNameExtensionFilter;
  21. public class MainJFrame extends JFrame implements Runnable{
  22. //菜单
  23. //菜单栏
  24. JMenuBar jmenubar;
  25. //菜单 菜单、等级、帮助
  26. JMenu menu,menuclass,menuhelp;
  27. //菜单项 开始、退出、图片更换、关于游戏、游戏记录、清空记录
  28. JMenuItem itembegin,itemend,itemchange,itemabout,itemrecord,itemclear;
  29. //单选菜单项 简单、一般、困难
  30. JRadioButtonMenuItem itemeasy,itemnormal,itemhard;
  31. //中间面板
  32. JPanel jp;
  33. //左面板
  34. LeftJPanel lp;
  35. //右面板
  36. RightJPanel rp;
  37. //访问的图片
  38. URL url;
  39. //显示计时标签
  40. JLabel total_time;
  41. //起止时间
  42. long startTime,endTime;
  43. //创建线程对象,实现计时功能
  44. Thread th;
  45. //显示步数的标签
  46. JLabel total_count;
  47. //构造方法
  48. public MainJFrame(){
  49. //标题设置
  50. setTitle("拼图游戏");
  51. //窗体大小
  52. setSize(1440, 780);
  53. //窗体位置在容器/屏幕的正中间
  54. setLocationRelativeTo(null);
  55. //窗体大小不可变
  56. setResizable(false);
  57. //实现界面菜单初始化
  58. //创建一个线程对象
  59. th=new Thread(this);
  60. //界面菜单初始化
  61. menuinit();
  62. //各面板的初始化
  63. init();
  64. setDefaultCloseOperation(EXIT_ON_CLOSE);
  65. setVisible(true);
  66. //开始菜单
  67. itembegin.addActionListener(new ActionListener() {
  68. @Override
  69. public void actionPerformed(ActionEvent e) {
  70. //启动线程
  71. //如果线程没有启动,则调用start方法启动
  72. if(!th.isAlive()) th.start();
  73. startTime=System.currentTimeMillis();
  74. rp.times=0;
  75. rp.randomOrder();
  76. }
  77. });
  78. //结束游戏
  79. itemend.addActionListener(new ActionListener() {
  80. @Override
  81. public void actionPerformed(ActionEvent e) {
  82. System.exit(1);
  83. }
  84. });
  85. //选择难易度itemeasy,itemnormal,itemhard
  86. itemeasy.addActionListener(new ActionListener() {
  87. @Override
  88. public void actionPerformed(ActionEvent e) {
  89. //第一,传递2*2到右面板
  90. rp.hs=2;
  91. rp.ls=2;
  92. //第二,调用右面板组件初始化的方法
  93. rp.init(url);
  94. }
  95. });
  96. itemnormal.addActionListener(new ActionListener() {
  97. @Override
  98. public void actionPerformed(ActionEvent e) {
  99. //第一,传递3*3到右面板
  100. rp.hs=3;
  101. rp.ls=3;
  102. //第二,调用右面板组件初始化的方法
  103. rp.init(url);
  104. }
  105. });
  106. itemhard.addActionListener(new ActionListener() {
  107. @Override
  108. public void actionPerformed(ActionEvent e) {
  109. //第一,传递4*4到右面板
  110. rp.hs=4;
  111. rp.ls=4;
  112. //第二,调用右面板组件初始化的方法
  113. rp.init(url);
  114. }
  115. });
  116. //游戏记录显示
  117. itemrecord.addActionListener(new ActionListener() {
  118. @Override
  119. public void actionPerformed(ActionEvent e) {
  120. //info存储要显示的内容
  121. String info="";
  122. try {
  123. //判断文件是否存在
  124. File f = new File("D:\\游戏记录.dat");
  125. if(f.exists()) {
  126. //创建指向***的文件字符输入流对象
  127. FileReader fr = new FileReader("D:\\游戏记录.dat");
  128. //读取数据
  129. char[] chs = new char[1024];
  130. int len;
  131. while((len=fr.read(chs))!=-1) {
  132. //读取的结果放在info中
  133. info+=new String(chs,0,len);
  134. }
  135. fr.close();
  136. //通过消息框显示结果
  137. JOptionPane.showMessageDialog(null, info);
  138. }else {
  139. JOptionPane.showMessageDialog(null, "游戏记录为空!");
  140. }
  141. }catch (IOException e1) {
  142. e1.printStackTrace();
  143. }
  144. }
  145. });
  146. //关于游戏
  147. itemabout.addActionListener(new ActionListener() {
  148. @Override
  149. public void actionPerformed(ActionEvent e) {
  150. JOptionPane.showMessageDialog(null, "关于拼图游戏\r\n版本:v2.0\r\n作者:LWL\r\n欢迎进入游戏!");
  151. }
  152. });
  153. //清空记录
  154. itemclear.addActionListener(new ActionListener() {
  155. @Override
  156. public void actionPerformed(ActionEvent e) {
  157. File f = new File("D:\\游戏记录.dat");
  158. if(f.exists()) {
  159. f.delete();
  160. }
  161. }
  162. });
  163. //实现图片的更换
  164. itemchange.addActionListener(new ActionListener() {
  165. @Override
  166. public void actionPerformed(ActionEvent e) {
  167. //显示一个打开对话框,选择一个图片文件,将文件转换成url对象,调用左右面板的相应方法
  168. JFileChooser jfc=new JFileChooser();
  169. //设置文件的扩展名
  170. jfc.setFileFilter(new FileNameExtensionFilter("图片格式(jpg|png|gif|jpeg)", "jpg","png","gif","jpeg"));
  171. //弹出打开对话框
  172. int sd = jfc.showOpenDialog(MainJFrame.this);
  173. if (sd==jfc.APPROVE_OPTION)//如果用户选择了打开按钮
  174. {
  175. //获取用户选择的文件完整名称
  176. String file=jfc.getSelectedFile().getAbsolutePath();
  177. try {
  178. url=new URL("file:\\"+file);
  179. //更新两个面板的图片
  180. lp.init(url);
  181. rp.init(url);
  182. } catch (MalformedURLException e1) {
  183. // TODO Auto-generated catch block
  184. e1.printStackTrace();
  185. }
  186. }
  187. }
  188. });
  189. }
  190. public void init() {
  191. jp=new JPanel();
  192. //设置中间面板的布局方式
  193. jp.setLayout(new GridLayout(1,2));
  194. //提供左右面板的图片
  195. url=this.getClass().getResource("小狗.jpg");
  196. //创建左面板
  197. lp=new LeftJPanel();
  198. //对标签初始化
  199. lp.init(url);
  200. //将左面板添加到中间面板
  201. jp.add(lp);
  202. //创建右面板
  203. rp=new RightJPanel();
  204. //右面板的按钮初始化
  205. rp.init(url);
  206. //将右面板添加到中间面板
  207. jp.add(rp);
  208. //将中间面板添加到窗体
  209. add(jp);
  210. }
  211. public void menuinit() {
  212. jmenubar=new JMenuBar();
  213. menu=new JMenu("菜单");
  214. menuclass=new JMenu("等级");
  215. menuhelp=new JMenu("帮助");
  216. itembegin=new JMenuItem("开始游戏");
  217. itemend=new JMenuItem("结束游戏");
  218. itemchange=new JMenuItem("更换图片");
  219. itemabout=new JMenuItem("关于游戏");
  220. itemrecord=new JMenuItem("游戏记录");
  221. itemclear=new JMenuItem("清空记录");
  222. itemeasy=new JRadioButtonMenuItem("简单");
  223. itemnormal=new JRadioButtonMenuItem("一般");
  224. itemhard=new JRadioButtonMenuItem("困难");
  225. //为单选菜单分组,实现多选一
  226. ButtonGroup bg=new ButtonGroup();
  227. bg.add(itemeasy);
  228. bg.add(itemnormal);
  229. bg.add(itemhard);
  230. //添加菜单
  231. menu.add(itembegin);
  232. menu.add(itemend);
  233. menu.add(itemchange);
  234. menuclass.add(itemeasy);
  235. menuclass.add(itemnormal);
  236. menuclass.add(itemhard);
  237. menuhelp.add(itemabout);
  238. menuhelp.add(itemrecord);
  239. menuhelp.add(itemclear);
  240. jmenubar.add(menu);
  241. jmenubar.add(menuclass);
  242. jmenubar.add(menuhelp);
  243. //菜单栏添加到窗体
  244. this.setJMenuBar(jmenubar);
  245. itemeasy.setSelected(true);
  246. //创建一个线程对象
  247. th=new Thread(this);
  248. total_time=new JLabel("用时:");
  249. total_time.setForeground(Color.red);
  250. jmenubar.add(new JLabel(" "));
  251. jmenubar.add(total_time);
  252. total_count=new JLabel("步数:");
  253. total_count.setForeground(Color.red);
  254. jmenubar.add(new JLabel(" "));
  255. jmenubar.add(total_count);
  256. }
  257. public static void main(String[] args) {
  258. new MainJFrame();
  259. }
  260. //实现计时并定时显示的run()方法
  261. @Override
  262. public void run() {
  263. while(true) {
  264. endTime=System.currentTimeMillis();
  265. total_time.setText("用时:"+(endTime-startTime)/1000+"秒");
  266. total_count.setText("步数:第"+rp.times+"步");
  267. try {
  268. Thread.sleep(500);
  269. }catch (InterruptedException e) {
  270. e.printStackTrace();
  271. }
  272. }
  273. }
  274. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/从前慢现在也慢/article/detail/584414
推荐阅读
相关标签
  

闽ICP备14008679号