当前位置:   article > 正文

用Java实现拼图小游戏_导入图片拼图游戏

导入图片拼图游戏

用JAVA实现拼图小游戏

目录

一、项目简介

          用JAVA的JFrame,JButton等工具实现拼图小游戏,包括拼图功能,更换图片功能,重新开始功能等等。

一、界面搭建和菜单搭建

          首先创建一个名为GameJframe的类,通过setSize()方法以及setTitle()等方法来初始化一个JFrame窗口,并设置标题为“拼图单机版”,通过setAlwaysOnTop()方法设置窗口置顶,并通过setLocationRelativeTo()方法设置窗口居中,而为使玩家可以通过关闭游戏窗口而关闭整个进程,我们则需设置默认关闭模式,当setDefaultCloseOperation()中参数为3即可。

  1. //设置窗口宽、高
  2. this.setSize(603, 680);
  3. //设置窗口标题
  4. this.setTitle("拼图单机版");
  5. //设置窗口置顶
  6. this.setAlwaysOnTop(true);
  7. //设置窗口置中
  8. this.setLocationRelativeTo(null);
  9. //设置窗口关闭模式
  10. /*
  11. setDefaultCloseOperation()里的参数为0时,窗口不可关闭
  12. 为1时,则为默认关闭模式
  13. 为2时,则需关闭所有窗口才可完全关闭虚拟机
  14. 为3时,则只需关闭一个窗口即可完全关闭虚拟机
  15. */
  16. this.setDefaultCloseOperation(3);

          为搭建菜单,需通过创建JMenuBarJMenu对象实现,通过其中的add()方法将需要的菜单选项添加到窗口中即可。

  1. //创建整个菜单对象
  2. JMenuBar jmb = new JMenuBar();
  3. //创建菜单下三个选项对象
  4. JMenu functionjm = new JMenu("菜单");
  5. JMenu aboutjm = new JMenu("关于我");
  6. JMenu changeimage = new JMenu("更换图片");

二、添加和打乱图片

        拼图游戏自然要有图片以供我们拼接,为此我们需准备好相应的图片资源,并复制粘贴至项目所在的文件夹中,通过创建JLabel对象和ImageIcon对象来管理图片,通过其中的成员方法setBounds()来设置图片大小以及setBorder()方法来设置图片格式,方法中参数为0时表示让图片凸出来,参数为1则表示让图片凹进去,为美观,我们选择将参数设为1,然后通过getContentpane()方法来添加进去。

  1. //创建一个JLabel管理容器
  2. JLabel jl = new JLabel(new ImageIcon(path+temppath+temp+"\\"+count+".jpg"));
  3. //设置图片位置以及大小
  4. jl.setBounds(105*j+83,105*i+134,105,105);
  5. //给图片设置边框
  6. //参数为0时表示让图片凸出来
  7. //参数为1时表示让图片凹进去
  8. jl.setBorder(new BevelBorder(1));
  9. this.getContentPane().add(jl);

        在添加完图片后,为打乱图片,我们可以将图片分为16份,15份索引和一份空白图片,所以我们只需创建一个如下的4行4列的二维数组,将随机打乱后的位置索引存储进去,在添加图片时按照打乱后的索引进行添加即可。

111154
31059
8267
0121413

  1. //存储打乱后的索引
  2. private int[][] data = new int[4][4];
  3. int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  4. //数组随机索引
  5. int temp = 0;
  6. Random r = new Random();
  7. //打乱数组元素
  8. for (int i = 0; i < arr.length; i++) {
  9. int index = r.nextInt(arr.length);
  10. temp = arr[i];
  11. arr[i] = arr[index];
  12. arr[index] = temp;
  13. }
  14. //给二位数组添加打乱后的元素
  15. for (int i = 0; i < arr.length; i++) {
  16. //若当前元素为空白元素,则令x和y为当前元素的位置
  17. if (arr[i] == 0){
  18. x = i / 4;
  19. y = i % 4;
  20. }
  21. data[i / 4][i % 4] = arr[i];
  22. }

三、添加事件和美化图片

        在我们玩游戏时,需要对图片进行操作,这时候就需要用到监听这个接口了,比如在编写图片移动功能时,我们就要对键盘进行监听,当我们按到w键或者上箭头时,空白格子下方的图片就会向上移动一格,所以我们要实现KeyListener接口,并重写keyRelease()方法即可。

  1. if (code == 37 || code == 65){
  2. System.out.println("向左移动");
  3. //实现空白图片右方的图片向左移动
  4. if (y == 3){
  5. return;
  6. }
  7. data[x][y] = data[x][y+1];
  8. data[x][y+1] = 0;
  9. y++;
  10. step++;
  11. //调用方法按照最新的数字加载图片
  12. initimage();
  13. }

        为美化图片,使玩家获得更好游戏体验,只需为图片添加一个背景即可。

  1. //添加背景图片
  2. JLabel jb = new JLabel(new ImageIcon("image\\background.png"));
  3. jb.setBounds(40,40,508,560);
  4. this.getContentPane().add(jb);

四、计步和菜单业务实现

        为了实现计步功能,只需定义一个成员变量来储存步数,当移动一次时,步数加一,当选择重新开始游戏或者更换图片时,步数清零即可。而菜单业务则与上文的移动功能类似,也需实现监听接口,当鼠标点击该功能按钮时,就要进行相应的操作。

  1. Object obj = e.getSource();
  2. if (obj == restartjmi){
  3. System.out.println("重新游戏");
  4. //计步器清零
  5. step = 0;
  6. //初始化数据
  7. initdata();
  8. //初始化图片
  9. initimage();
  10. }
  11. else if(obj == closejmi){
  12. System.out.println("关闭游戏");
  13. //关闭虚拟机
  14. System.exit(0);
  15. }else if(obj == accountjmi){
  16. System.out.println("名片");
  17. JDialog jdi = new JDialog();
  18. JLabel jb = new JLabel(new ImageIcon("image\\mingpian.jpg"));
  19. //设置位置
  20. jb.setBounds(0,0,300,299);
  21. jdi.getContentPane().add(jb);
  22. //设置弹框大小
  23. jdi.setSize(344,344);
  24. //设置弹框置顶
  25. jdi.setAlwaysOnTop(true);
  26. //设置弹框居中
  27. jdi.setLocationRelativeTo(null);
  28. //设置弹框不关闭无法继续
  29. jdi.setModal(true);
  30. //设置弹框可视化
  31. jdi.setVisible(true);
  32. }else if (obj == girl) {
  33. System.out.println("更换美女图片");
  34. //计步器清零
  35. step = 0;
  36. //初始化数据
  37. initdata();
  38. //随机图片库
  39. temppath = "\\girl\\girl";
  40. changei();
  41. }else if (obj == animal) {
  42. System.out.println("更换动物图片");
  43. //计步器清零
  44. step = 0;
  45. //初始化数据
  46. initdata();
  47. //随机图片库
  48. temppath = "\\animal\\animal";
  49. changei();
  50. }else if (obj == sport) {
  51. System.out.println("更换运动图片");
  52. //计步器清零
  53. step = 0;
  54. //初始化数据
  55. initdata();
  56. //随机图片库
  57. temppath = "\\sport\\sport";
  58. changei();
  59. }

五、最终代码实现以及结果展示

 完整代码:

  1. import javax.swing.*;
  2. import javax.swing.border.BevelBorder;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. import java.awt.event.KeyEvent;
  6. import java.awt.event.KeyListener;
  7. import java.util.Random;
  8. public class GameJFrame extends JFrame implements KeyListener, ActionListener {
  9. //存储打乱后的索引
  10. private int[][] data = new int[4][4];
  11. //创建选项下的条目对象
  12. JMenuItem restartjmi = new JMenuItem("重新开始");
  13. //JMenuItem relogjmi = new JMenuItem("重新登录");
  14. JMenuItem closejmi = new JMenuItem("关闭游戏");
  15. JMenuItem girl = new JMenuItem("美女");
  16. JMenuItem animal = new JMenuItem("动物");
  17. JMenuItem sport = new JMenuItem("运动");
  18. JMenuItem accountjmi = new JMenuItem("名片");
  19. //记录空白图片在二维数组中的位置
  20. private int x = 0;
  21. private int y = 0;
  22. //定义路径
  23. String path = "image";
  24. String temppath = "\\girl\\girl";
  25. int temp = 1;
  26. //String path = "image";
  27. //定义一个胜利数组
  28. private int[][] win = new int[][]{
  29. {1,2,3,4},
  30. {5,6,7,8},
  31. {9,10,11,12},
  32. {13,14,15,0}
  33. };
  34. //定义变量来统计步数
  35. private int step = 0;
  36. //判断data数组中的值是否跟win数组中的值完全相同
  37. //相同则胜利,返回true。不同则继续,返回false
  38. public boolean victory(){
  39. //判断data数组元素与win数组元素是否全部相同
  40. for (int i = 0; i < data.length; i++) {
  41. for (int j = 0; j < data[i].length; j++) {
  42. if (data[i][j] != win[i][j]){
  43. return false;
  44. }
  45. }
  46. }
  47. //遍历结束,全部相同返回true
  48. return true;
  49. }
  50. public GameJFrame() {
  51. //初始化窗口
  52. initjf();
  53. //初始化菜单
  54. initjmbar();
  55. //初始化数据
  56. initdata();
  57. //初始化图片
  58. initimage();
  59. //设置窗口可视化
  60. this.setVisible(true);
  61. }
  62. private void initdata() {
  63. int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
  64. //数组随机索引
  65. int temp = 0;
  66. Random r = new Random();
  67. //打乱数组元素
  68. for (int i = 0; i < arr.length; i++) {
  69. int index = r.nextInt(arr.length);
  70. temp = arr[i];
  71. arr[i] = arr[index];
  72. arr[index] = temp;
  73. }
  74. //给二维数组添加打乱后的索引
  75. // int index = 0;
  76. // for (int i = 0; i < 4; i++) {
  77. // for (int j = 0; j < 4; j++) {
  78. // data[i][j] = arr[index];
  79. // index++;
  80. // }
  81. // }
  82. //给二位数组添加打乱后的元素
  83. for (int i = 0; i < arr.length; i++) {
  84. //若当前元素为空白元素,则令x和y为当前元素的位置
  85. if (arr[i] == 0){
  86. x = i / 4;
  87. y = i % 4;
  88. }
  89. data[i / 4][i % 4] = arr[i];
  90. }
  91. }
  92. private void initimage(){
  93. //删除所有图片
  94. this.getContentPane().removeAll();
  95. //调用victory方法判断是否胜利
  96. if (victory()) {
  97. JLabel win = new JLabel(new ImageIcon("image\\win.png"));
  98. //JLabel win = new JLabel(new ImageIcon("image\\win.png"));
  99. win.setBounds(203,283,197,73);
  100. this.getContentPane().add(win);
  101. }
  102. JLabel jbstep = new JLabel("步数: "+step);
  103. jbstep.setBounds(50,30,100,20);
  104. this.getContentPane().add(jbstep);
  105. for (int i = 0; i < data.length; i++) {
  106. for (int j = 0; j < data[i].length; j++) {
  107. int count = data[i][j];
  108. //创建一个JLabel管理容器
  109. JLabel jl = new JLabel(new ImageIcon(path+temppath+temp+"\\"+count+".jpg"));
  110. //设置图片位置以及大小
  111. jl.setBounds(105*j+83,105*i+134,105,105);
  112. //给图片设置边框
  113. //参数为0时表示让图片凸出来
  114. //参数为1时表示让图片凹进去
  115. jl.setBorder(new BevelBorder(1));
  116. this.getContentPane().add(jl);
  117. }
  118. }
  119. //添加背景图片
  120. JLabel jb = new JLabel(new ImageIcon("image\\background.png"));
  121. jb.setBounds(40,40,508,560);
  122. this.getContentPane().add(jb);
  123. //刷新加载图片
  124. this.getContentPane().repaint();
  125. }
  126. private void changei(){
  127. Random r = new Random();
  128. if ((path+temppath).equals("image\\girl\\girl")){
  129. temp = r.nextInt(13)+1;
  130. initimage();
  131. }else if((path+temppath).equals("image\\animal\\animal")){
  132. temp = r.nextInt(8)+1;
  133. initimage();
  134. }else if((path+temppath).equals("image\\sport\\sport")){
  135. temp = r.nextInt(10)+1;
  136. initimage();
  137. }
  138. }
  139. private void initjmbar() {
  140. //创建整个菜单对象
  141. JMenuBar jmb = new JMenuBar();
  142. //创建菜单下三个选项对象
  143. JMenu functionjm = new JMenu("菜单");
  144. JMenu aboutjm = new JMenu("关于我");
  145. JMenu changeimage = new JMenu("更换图片");
  146. //添加条目对象到选项对象中
  147. functionjm.add(changeimage);
  148. functionjm.add(restartjmi);
  149. //functionjm.add(relogjmi);
  150. functionjm.add(closejmi);
  151. aboutjm.add(accountjmi);
  152. changeimage.add(girl);
  153. changeimage.add(animal);
  154. changeimage.add(sport);
  155. //给条目绑定事件
  156. restartjmi.addActionListener(this);
  157. //relogjmi.addActionListener(this);
  158. closejmi.addActionListener(this);
  159. accountjmi.addActionListener(this);
  160. girl.addActionListener(this);
  161. animal.addActionListener(this);
  162. sport.addActionListener(this);
  163. //将选项对象添加到菜单对象中
  164. jmb.add(functionjm);
  165. jmb.add(aboutjm);
  166. //给整个界面设置菜单
  167. this.setJMenuBar(jmb);
  168. }
  169. private void initjf(){
  170. //设置窗口宽、高
  171. this.setSize(603, 680);
  172. //设置窗口标题
  173. this.setTitle("拼图单机版");
  174. //设置窗口置顶
  175. this.setAlwaysOnTop(true);
  176. //设置窗口置中
  177. this.setLocationRelativeTo(null);
  178. //设置窗口关闭模式
  179. /*
  180. setDefaultCloseOperation()里的参数为0时,窗口不可关闭
  181. 为1时,则为默认关闭模式
  182. 为2时,则需关闭所有窗口才可完全关闭虚拟机
  183. 为3时,则只需关闭一个窗口即可完全关闭虚拟机
  184. */
  185. this.setDefaultCloseOperation(3);
  186. //添加键盘监听指针
  187. this.addKeyListener(this);
  188. //只有取消居中,才可以将图片放到指定位置
  189. this.setLayout(null);
  190. }
  191. @Override
  192. public void keyTyped(KeyEvent e) {
  193. }
  194. //按下A键不松开时会调用此方法实现图片还原功能
  195. @Override
  196. public void keyPressed(KeyEvent e) {
  197. int code = e.getKeyCode();
  198. if (code == 73){
  199. //将界面中的图片全部删除
  200. this.getContentPane().removeAll();
  201. //加载一张完整图片
  202. JLabel jb = new JLabel(new ImageIcon(path+temppath+temp+"\\"+"all.jpg"));
  203. jb.setBounds(83,134,420,420);
  204. this.getContentPane().add(jb);
  205. //加载背景图片
  206. JLabel jb1 = new JLabel(new ImageIcon("image\\background.png"));
  207. jb1.setBounds(40,40,508,560);
  208. this.getContentPane().add(jb1);
  209. //刷新界面
  210. this.getContentPane().repaint();
  211. }
  212. }
  213. @Override
  214. public void keyReleased(KeyEvent e) {
  215. int code = e.getKeyCode();
  216. //判断游戏是否胜利,胜利则直接结束,不用执行下面的代码
  217. if (victory()) {
  218. return;
  219. }
  220. if (code == 37 || code == 65){
  221. System.out.println("向左移动");
  222. //实现空白图片右方的图片向左移动
  223. if (y == 3){
  224. return;
  225. }
  226. data[x][y] = data[x][y+1];
  227. data[x][y+1] = 0;
  228. y++;
  229. step++;
  230. //调用方法按照最新的数字加载图片
  231. initimage();
  232. }else if(code == 38 || code == 87){
  233. System.out.println("向上移动");
  234. //实现空白图片下方的图片向上移动
  235. if (x == 3){
  236. return;
  237. }
  238. data[x][y] = data[x+1][y];
  239. data[x+1][y] = 0;
  240. x++;
  241. step++;
  242. //调用方法按照最新的数字加载图片
  243. initimage();
  244. }else if(code == 39 || code == 68)
  245. {
  246. System.out.println("向右移动");
  247. //实现空白图片左方的图片向右移动
  248. if (y == 0){
  249. return;
  250. }
  251. data[x][y] = data[x][y-1];
  252. data[x][y-1] = 0;
  253. y--;
  254. step++;
  255. //调用方法按照最新的数字加载图片
  256. initimage();
  257. }else if(code == 40 || code == 83){
  258. System.out.println("向下移动");
  259. //实现空白图片上方的图片向下移动
  260. if (x == 0){
  261. return;
  262. }
  263. data[x][y] = data[x-1][y];
  264. data[x-1][y] = 0;
  265. x--;
  266. step++;
  267. //调用方法按照最新的数字加载图片
  268. initimage();
  269. }else if(code == 73){
  270. //当松开I键时,初始化界面
  271. initimage();
  272. }else if(code == 66){
  273. //当按下键为B时,作弊
  274. data = new int[][]{
  275. {1,2,3,4},
  276. {5,6,7,8},
  277. {9,10,11,12},
  278. {13,14,15,0}
  279. };
  280. initimage();
  281. }
  282. }
  283. @Override
  284. public void actionPerformed(ActionEvent e) {
  285. Object obj = e.getSource();
  286. if (obj == restartjmi){
  287. System.out.println("重新游戏");
  288. //计步器清零
  289. step = 0;
  290. //初始化数据
  291. initdata();
  292. //初始化图片
  293. initimage();
  294. }
  295. // else if(obj == relogjmi){
  296. // System.out.println("重新登录");
  297. // //关闭当前游戏界面
  298. // this.setVisible(false);
  299. // //打开登陆界面
  300. // new LoginJFrame();
  301. // }
  302. else if(obj == closejmi){
  303. System.out.println("关闭游戏");
  304. //关闭虚拟机
  305. System.exit(0);
  306. }else if(obj == accountjmi){
  307. System.out.println("名片");
  308. JDialog jdi = new JDialog();
  309. JLabel jb = new JLabel(new ImageIcon("image\\mingpian.jpg"));
  310. //设置位置
  311. jb.setBounds(0,0,300,299);
  312. jdi.getContentPane().add(jb);
  313. //设置弹框大小
  314. jdi.setSize(344,344);
  315. //设置弹框置顶
  316. jdi.setAlwaysOnTop(true);
  317. //设置弹框居中
  318. jdi.setLocationRelativeTo(null);
  319. //设置弹框不关闭无法继续
  320. jdi.setModal(true);
  321. //设置弹框可视化
  322. jdi.setVisible(true);
  323. }else if (obj == girl) {
  324. System.out.println("更换美女图片");
  325. //计步器清零
  326. step = 0;
  327. //初始化数据
  328. initdata();
  329. //随机图片库
  330. temppath = "\\girl\\girl";
  331. changei();
  332. }else if (obj == animal) {
  333. System.out.println("更换动物图片");
  334. //计步器清零
  335. step = 0;
  336. //初始化数据
  337. initdata();
  338. //随机图片库
  339. temppath = "\\animal\\animal";
  340. changei();
  341. }else if (obj == sport) {
  342. System.out.println("更换运动图片");
  343. //计步器清零
  344. step = 0;
  345. //初始化数据
  346. initdata();
  347. //随机图片库
  348. temppath = "\\sport\\sport";
  349. changei();
  350. }
  351. }
  352. }

成品展示:

 

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

闽ICP备14008679号