当前位置:   article > 正文

Java实现拼图小游戏

Java实现拼图小游戏

        Java中的图形化界面使用得是比较少的,但是可以用来结合前期学习的面向对象编程的思想,通过图形化的呈现,创造一个拼图小游戏。

        主要用的到的包:

  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;

        类的继承和实现:

public class GameJFrame extends JFrame implements KeyListener, ActionListener

        主要思想:JFrame 、JMenu、JMenuBar、JMenuItem、JLabel、ImageIcon;数组、随机数、面向对象、键盘、鼠标监视、动作监视……

        游戏主体代码:

  1. package GameUI;
  2. import javax.swing.*;
  3. import javax.swing.border.BevelBorder;
  4. import java.awt.event.ActionEvent;
  5. import java.awt.event.ActionListener;
  6. import java.awt.event.KeyEvent;
  7. import java.awt.event.KeyListener;
  8. import java.util.Random;
  9. public class GameJFrame extends JFrame implements KeyListener, ActionListener {
  10. int x = 0; // 用x来记录空白块的数组行标
  11. int y = 0; // 用y来记录空白快数组的列标
  12. int[][] imageArray = new int[4][4];
  13. // 创建胜利数组,当imageArray和胜利数组完全一样的时候,代表游戏胜利
  14. int[][] winArray = new int[][] {
  15. {1,2,3,4},
  16. {5,6,7,8},
  17. {9,10,11,12},
  18. {13,14,15,0}
  19. };
  20. // 用字符串来记录图片的路径,方便修改
  21. String path = "Game\\image\\animal\\animal3\\";
  22. // 用以记录移动步数
  23. int step = 0;
  24. // 创建功能中条目
  25. JMenuItem replayItem = new JMenuItem("重新开始");
  26. JMenuItem reLoginItem = new JMenuItem("重新登录");
  27. JMenuItem closeItem = new JMenuItem("关闭游戏");
  28. // 创建关于制作人员中条目
  29. JMenuItem accountItem = new JMenuItem("Rose");
  30. public GameJFrame() {
  31. // 设置界面
  32. setJFrame();
  33. // 设置菜单
  34. setMenu();
  35. // 初始化数组
  36. initArray();
  37. // 设置图片
  38. setImage();
  39. // 设置界面可见
  40. this.setVisible(true);
  41. }
  42. private void setJFrame() {
  43. // 设置界面大小
  44. this.setSize(603, 680);
  45. // 设置界面标题
  46. this.setTitle("Puzzle version 1.0");
  47. // 设置界面居中
  48. this.setLocationRelativeTo(null);
  49. // 设置界面永远在上
  50. this.setAlwaysOnTop(true);
  51. // 设置界面关闭模式
  52. this.setDefaultCloseOperation(EXIT_ON_CLOSE);
  53. // 取消默认放置(JFrame只是一个框架,真正存放组件的是其中的ContentPanel
  54. // ,必须要取消默认放置的设定才可以自定义坐标放置)
  55. this.setLayout(null);
  56. // 添加键盘监听
  57. this.addKeyListener(this);
  58. }
  59. private void setMenu() {
  60. // 创建整个菜单对象
  61. JMenuBar jMenuBar = new JMenuBar();
  62. // 创建选项功能
  63. JMenu functionJMenu = new JMenu("功能 ");
  64. JMenu aboutJMenu = new JMenu("制作人员");
  65. // 给条目绑定事件
  66. replayItem.addActionListener(this);
  67. reLoginItem.addActionListener(this);
  68. closeItem.addActionListener(this);
  69. accountItem.addActionListener(this);
  70. // 在功能中加入条目
  71. functionJMenu.add(replayItem);
  72. functionJMenu.add(reLoginItem);
  73. functionJMenu.add(closeItem);
  74. // 在关于我们中加入条目
  75. aboutJMenu.add(accountItem);
  76. // 在菜单中加入选项
  77. jMenuBar.add(functionJMenu);
  78. jMenuBar.add(aboutJMenu);
  79. // 在JFrame中创建菜单
  80. this.setJMenuBar(jMenuBar);
  81. }
  82. public void setImage() {
  83. // 清空本来已经出现的图片
  84. this.getContentPane().removeAll();
  85. if (victory()) {
  86. JLabel victoryImage = new JLabel(new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\win.png"));
  87. victoryImage.setBounds(203, 283, 197, 73);
  88. this.getContentPane().add(victoryImage);
  89. }
  90. JLabel stepImage = new JLabel("步数:" + step);
  91. stepImage.setBounds(50, 30, 100, 20);
  92. this.getContentPane().add(stepImage);
  93. for(int i = 0; i < 4; i++) {
  94. for(int j = 0; j < 4; j++) {
  95. int number = imageArray[i][j];
  96. // 创建新的图片对象(构造方法可以传入图片文件的路径)
  97. ImageIcon image = new ImageIcon(path + number + ".jpg");
  98. // JLabel是一个图片容器,可以将ImageIcon创造出来的图片对象加入这个容器
  99. JLabel jLabel = new JLabel(image);
  100. /*设置图片在界面中的显示位置,每个小图片的像素是105*105;通过双重循环
  101. 可以达到将不同的图片,按行列放置到对应位置的效果*/
  102. jLabel.setBounds(105 * j + 83, 105 * i + 134, 105, 105);
  103. // 给每张图片设置一个边框,增强美观性
  104. jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
  105. /*JFrame实际上只是一个框架,真正的组件实际上是“放置”于JFrame中的
  106. ContentPanel中的,可以通过JFrame的getContentPanel方法得到,并且
  107. 在其中添加JLabel对象*/
  108. this.getContentPane().add(jLabel);
  109. }
  110. }
  111. // 添加背景图片
  112. ImageIcon background = new ImageIcon("Game\\image\\background.png");
  113. JLabel bg = new JLabel(background);
  114. bg.setBounds(40, 40, 508, 560);
  115. this.getContentPane().add(bg);
  116. // 刷新界面
  117. this.getContentPane().repaint();
  118. }
  119. public void initArray() {
  120. int[] arr = new int[16];
  121. for (int i = 0; i < arr.length; i++) {
  122. arr[i] = i;
  123. }
  124. Random r = new Random();
  125. int randomNumber;
  126. for (int i = 15; i >= 0; i--) {
  127. randomNumber = r.nextInt(i + 1);
  128. int temp = arr[randomNumber];
  129. arr[randomNumber] = arr[i];
  130. arr[i] = temp;
  131. }
  132. // 初始化时必须将二维数组全部设置为0
  133. // 如果不全部设置为0,上一次的数据会遗留
  134. for (int i = 0; i < imageArray.length; i++) {
  135. for (int j = 0; j < imageArray.length; j++) {
  136. imageArray[i][j] = 0;
  137. }
  138. }
  139. for(int i = 0; i < arr.length; i++) {
  140. if (arr[i] == 0) {
  141. this.x = i / 4;
  142. this.y = i % 4;
  143. } else{
  144. imageArray[i / 4][i % 4] = arr[i];
  145. }
  146. }
  147. }
  148. @Override
  149. public void keyTyped(KeyEvent e) {
  150. }
  151. @Override
  152. public void keyPressed(KeyEvent e) {
  153. int code = e.getKeyCode();
  154. if (code == 65) {
  155. this.getContentPane().removeAll();
  156. JLabel allImage = new JLabel(new ImageIcon(path + "all.jpg"));
  157. allImage.setBounds(83,134,420,420);
  158. this.getContentPane().add(allImage);
  159. // 添加背景图片
  160. ImageIcon background = new ImageIcon("Game\\image\\background.png");
  161. JLabel bg = new JLabel(background);
  162. bg.setBounds(40, 40, 508, 560);
  163. this.getContentPane().add(bg);
  164. // 刷新界面
  165. this.getContentPane().repaint();
  166. }
  167. }
  168. @Override
  169. public void keyReleased(KeyEvent e) {
  170. if (victory()) {
  171. return;
  172. }
  173. int code = e.getKeyCode();
  174. // 左移
  175. if (code == 37) {
  176. if (y == 3) {
  177. return;
  178. } else {
  179. imageArray[x][y] = imageArray[x][y + 1];
  180. imageArray[x][y + 1] = 0;
  181. y++;
  182. step++;
  183. setImage();
  184. }
  185. }
  186. // 上移
  187. else if (code == 38) {
  188. if (x == 3) {
  189. return;
  190. } else {
  191. imageArray[x][y] = imageArray[x + 1][y];
  192. imageArray[x + 1][y] = 0;
  193. x++;
  194. step++;
  195. setImage();
  196. }
  197. }
  198. // 右移
  199. else if (code == 39) {
  200. if (y == 0) {
  201. return;
  202. } else {
  203. imageArray[x][y] = imageArray[x][y - 1];
  204. imageArray[x][y - 1] = 0;
  205. y--;
  206. step++;
  207. setImage();
  208. }
  209. }
  210. // 下移
  211. else if (code == 40) {
  212. if (x == 0) {
  213. return;
  214. } else {
  215. imageArray[x][y] = imageArray[x - 1][y];
  216. imageArray[x - 1][y] = 0;
  217. x--;
  218. step++;
  219. setImage();
  220. }
  221. } else if (code == 65) {
  222. setImage();
  223. } else if (code == 87) {
  224. for (int i = 0; i < imageArray.length* imageArray.length; i++) {
  225. if (i == 15) {
  226. imageArray[3][3] = 0;
  227. break;
  228. }
  229. imageArray[i / 4][i % 4] = i + 1;
  230. }
  231. setImage();
  232. }
  233. }
  234. public boolean victory() {
  235. for (int i = 0; i < imageArray.length; i++) {
  236. for (int j = 0; j < imageArray.length; j++) {
  237. if (imageArray[i][j] != winArray[i][j]) {
  238. return false;
  239. }
  240. }
  241. }
  242. return true;
  243. }
  244. @Override
  245. public void actionPerformed(ActionEvent e) {
  246. Object obj = e.getSource();
  247. if(obj == replayItem) {
  248. // 重开游戏
  249. // 步数清零
  250. step = 0;
  251. // 初始化图片数组
  252. initArray();
  253. // 展示打乱的图片
  254. setImage();
  255. } else if (obj == reLoginItem) {
  256. System.out.println("重新登录(待开发)");
  257. } else if (obj == accountItem) {
  258. // 制作者
  259. System.out.println("rose");
  260. // 创建一个新的JFrame对象
  261. JFrame rose = creatRose();
  262. // 创建玫瑰图像的对象
  263. ImageIcon roseImage = new ImageIcon("D:\\codes\\Java\\PuzzleGame\\Game\\image\\rose.jpg");
  264. // 创建JLabel容器存放玫瑰图像
  265. JLabel roseJB = new JLabel(roseImage);
  266. // 设置图像的位置和大小
  267. roseJB.setBounds(40, 40, 1080, 1080);
  268. // 将图像容器加入JFrame中
  269. rose.getContentPane().add(roseJB);
  270. } else if (obj == closeItem) {
  271. // 退出游戏
  272. // 直接关闭JVM虚拟机
  273. System.exit(0);
  274. }
  275. }
  276. public JFrame creatRose() {
  277. JFrame rose = new JFrame();
  278. // 设置宽高为1080*1080
  279. rose.setSize(1080, 1080);
  280. // 设置窗口可见
  281. rose.setVisible(true);
  282. // 设置窗口标题
  283. rose.setTitle("制作人员");
  284. // 设置窗口默认在屏幕中央
  285. rose.setLocationRelativeTo(null);
  286. // 设置窗口总是在最上层
  287. rose.setAlwaysOnTop(true);
  288. // 设置窗口关闭模式(只关闭当前JFrame窗口(默认关闭的方式))
  289. rose.setDefaultCloseOperation(HIDE_ON_CLOSE);
  290. // 返回JFrame对象
  291. return rose;
  292. }
  293. }

        游戏的测试

  1. import GameUI.GameJFrame;
  2. import GameUI.LoginJFrame;
  3. import GameUI.RegisterJFrame;
  4. public class Application {
  5. public static void main(String[] args) {
  6. // 注册
  7. RegisterJFrame rj = new RegisterJFrame();
  8. // 登录
  9. LoginJFrame lj = new LoginJFrame();
  10. // 游戏
  11. GameJFrame gj = new GameJFrame();
  12. }
  13. }

        还剩下的坑:登录、注册,等到日后有时间再把这个坑填上

  1. package GameUI;
  2. import javax.swing.*;
  3. public class LoginJFrame extends JFrame {
  4. public LoginJFrame() {
  5. // 设置界面大小
  6. this.setSize(488, 430);
  7. // 设置界面标题
  8. this.setTitle("Login");
  9. // 设置界面居中
  10. this.setLocationRelativeTo(null);
  11. // 设置界面永远在上
  12. this.setAlwaysOnTop(true);
  13. // 设置界面关闭模式
  14. this.setDefaultCloseOperation(3);
  15. // 设置界面可见
  16. this.setVisible(true);
  17. }
  18. }
  1. package GameUI;
  2. import javax.swing.*;
  3. public class RegisterJFrame extends JFrame{
  4. public RegisterJFrame() {
  5. // 设置界面大小
  6. this.setSize(488, 500);
  7. // 设置界面标题
  8. this.setTitle("Register");
  9. // 设置界面居中
  10. this.setLocationRelativeTo(null);
  11. // 设置界面永远在上
  12. this.setAlwaysOnTop(true);
  13. // 设置界面关闭模式
  14. this.setDefaultCloseOperation(3);
  15. // 设置界面可见
  16. this.setVisible(true);
  17. }
  18. }

 

 

 

        

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

闽ICP备14008679号