赞
踩
用JAVA的JFrame,JButton等工具实现拼图小游戏,包括拼图功能,更换图片功能,重新开始功能等等。
首先创建一个名为GameJframe的类,通过setSize()方法以及setTitle()等方法来初始化一个JFrame窗口,并设置标题为“拼图单机版”,通过setAlwaysOnTop()方法设置窗口置顶,并通过setLocationRelativeTo()方法设置窗口居中,而为使玩家可以通过关闭游戏窗口而关闭整个进程,我们则需设置默认关闭模式,当setDefaultCloseOperation()中参数为3即可。
- //设置窗口宽、高
- this.setSize(603, 680);
- //设置窗口标题
- this.setTitle("拼图单机版");
- //设置窗口置顶
- this.setAlwaysOnTop(true);
- //设置窗口置中
- this.setLocationRelativeTo(null);
- //设置窗口关闭模式
- /*
- setDefaultCloseOperation()里的参数为0时,窗口不可关闭
- 为1时,则为默认关闭模式
- 为2时,则需关闭所有窗口才可完全关闭虚拟机
- 为3时,则只需关闭一个窗口即可完全关闭虚拟机
- */
- this.setDefaultCloseOperation(3);
为搭建菜单,需通过创建JMenuBar和JMenu对象实现,通过其中的add()方法将需要的菜单选项添加到窗口中即可。
- //创建整个菜单对象
- JMenuBar jmb = new JMenuBar();
-
- //创建菜单下三个选项对象
- JMenu functionjm = new JMenu("菜单");
- JMenu aboutjm = new JMenu("关于我");
-
- JMenu changeimage = new JMenu("更换图片");
拼图游戏自然要有图片以供我们拼接,为此我们需准备好相应的图片资源,并复制粘贴至项目所在的文件夹中,通过创建JLabel对象和ImageIcon对象来管理图片,通过其中的成员方法setBounds()来设置图片大小以及setBorder()方法来设置图片格式,方法中参数为0时表示让图片凸出来,参数为1则表示让图片凹进去,为美观,我们选择将参数设为1,然后通过getContentpane()方法来添加进去。
- //创建一个JLabel管理容器
- JLabel jl = new JLabel(new ImageIcon(path+temppath+temp+"\\"+count+".jpg"));
- //设置图片位置以及大小
- jl.setBounds(105*j+83,105*i+134,105,105);
- //给图片设置边框
- //参数为0时表示让图片凸出来
- //参数为1时表示让图片凹进去
- jl.setBorder(new BevelBorder(1));
- this.getContentPane().add(jl);
在添加完图片后,为打乱图片,我们可以将图片分为16份,15份索引和一份空白图片,所以我们只需创建一个如下的4行4列的二维数组,将随机打乱后的位置索引存储进去,在添加图片时按照打乱后的索引进行添加即可。
11 | 1 | 15 | 4 |
3 | 10 | 5 | 9 |
8 | 2 | 6 | 7 |
0 | 12 | 14 | 13 |
- //存储打乱后的索引
- private int[][] data = new int[4][4];
- int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- //数组随机索引
- int temp = 0;
- Random r = new Random();
- //打乱数组元素
- for (int i = 0; i < arr.length; i++) {
- int index = r.nextInt(arr.length);
- temp = arr[i];
- arr[i] = arr[index];
- arr[index] = temp;
- }
- //给二位数组添加打乱后的元素
- for (int i = 0; i < arr.length; i++) {
- //若当前元素为空白元素,则令x和y为当前元素的位置
- if (arr[i] == 0){
- x = i / 4;
- y = i % 4;
- }
- data[i / 4][i % 4] = arr[i];
- }
在我们玩游戏时,需要对图片进行操作,这时候就需要用到监听这个接口了,比如在编写图片移动功能时,我们就要对键盘进行监听,当我们按到w键或者上箭头时,空白格子下方的图片就会向上移动一格,所以我们要实现KeyListener接口,并重写keyRelease()方法即可。
- if (code == 37 || code == 65){
- System.out.println("向左移动");
- //实现空白图片右方的图片向左移动
- if (y == 3){
- return;
- }
- data[x][y] = data[x][y+1];
- data[x][y+1] = 0;
- y++;
- step++;
- //调用方法按照最新的数字加载图片
- initimage();
- }
为美化图片,使玩家获得更好游戏体验,只需为图片添加一个背景即可。
- //添加背景图片
- JLabel jb = new JLabel(new ImageIcon("image\\background.png"));
- jb.setBounds(40,40,508,560);
- this.getContentPane().add(jb);
为了实现计步功能,只需定义一个成员变量来储存步数,当移动一次时,步数加一,当选择重新开始游戏或者更换图片时,步数清零即可。而菜单业务则与上文的移动功能类似,也需实现监听接口,当鼠标点击该功能按钮时,就要进行相应的操作。
- Object obj = e.getSource();
- if (obj == restartjmi){
- System.out.println("重新游戏");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //初始化图片
- initimage();
- }
- else if(obj == closejmi){
- System.out.println("关闭游戏");
- //关闭虚拟机
- System.exit(0);
- }else if(obj == accountjmi){
- System.out.println("名片");
-
- JDialog jdi = new JDialog();
- JLabel jb = new JLabel(new ImageIcon("image\\mingpian.jpg"));
- //设置位置
- jb.setBounds(0,0,300,299);
- jdi.getContentPane().add(jb);
- //设置弹框大小
- jdi.setSize(344,344);
- //设置弹框置顶
- jdi.setAlwaysOnTop(true);
- //设置弹框居中
- jdi.setLocationRelativeTo(null);
- //设置弹框不关闭无法继续
- jdi.setModal(true);
- //设置弹框可视化
- jdi.setVisible(true);
- }else if (obj == girl) {
- System.out.println("更换美女图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\girl\\girl";
- changei();
- }else if (obj == animal) {
- System.out.println("更换动物图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\animal\\animal";
- changei();
- }else if (obj == sport) {
- System.out.println("更换运动图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\sport\\sport";
- changei();
- }
完整代码:
- import javax.swing.*;
- import javax.swing.border.BevelBorder;
- import java.awt.event.ActionEvent;
- import java.awt.event.ActionListener;
- import java.awt.event.KeyEvent;
- import java.awt.event.KeyListener;
- import java.util.Random;
-
- public class GameJFrame extends JFrame implements KeyListener, ActionListener {
- //存储打乱后的索引
- private int[][] data = new int[4][4];
- //创建选项下的条目对象
- JMenuItem restartjmi = new JMenuItem("重新开始");
- //JMenuItem relogjmi = new JMenuItem("重新登录");
- JMenuItem closejmi = new JMenuItem("关闭游戏");
- JMenuItem girl = new JMenuItem("美女");
- JMenuItem animal = new JMenuItem("动物");
- JMenuItem sport = new JMenuItem("运动");
- JMenuItem accountjmi = new JMenuItem("名片");
- //记录空白图片在二维数组中的位置
- private int x = 0;
- private int y = 0;
- //定义路径
- String path = "image";
- String temppath = "\\girl\\girl";
-
- int temp = 1;
-
- //String path = "image";
- //定义一个胜利数组
- private int[][] win = new int[][]{
- {1,2,3,4},
- {5,6,7,8},
- {9,10,11,12},
- {13,14,15,0}
- };
- //定义变量来统计步数
- private int step = 0;
-
- //判断data数组中的值是否跟win数组中的值完全相同
- //相同则胜利,返回true。不同则继续,返回false
- public boolean victory(){
- //判断data数组元素与win数组元素是否全部相同
- for (int i = 0; i < data.length; i++) {
- for (int j = 0; j < data[i].length; j++) {
- if (data[i][j] != win[i][j]){
- return false;
- }
- }
- }
- //遍历结束,全部相同返回true
- return true;
- }
-
- public GameJFrame() {
- //初始化窗口
- initjf();
-
- //初始化菜单
- initjmbar();
-
- //初始化数据
- initdata();
-
- //初始化图片
- initimage();
-
-
-
-
-
-
-
- //设置窗口可视化
- this.setVisible(true);
- }
-
- private void initdata() {
- int[] arr = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
- //数组随机索引
- int temp = 0;
- Random r = new Random();
- //打乱数组元素
- for (int i = 0; i < arr.length; i++) {
- int index = r.nextInt(arr.length);
- temp = arr[i];
- arr[i] = arr[index];
- arr[index] = temp;
- }
- //给二维数组添加打乱后的索引
- // int index = 0;
- // for (int i = 0; i < 4; i++) {
- // for (int j = 0; j < 4; j++) {
- // data[i][j] = arr[index];
- // index++;
- // }
- // }
- //给二位数组添加打乱后的元素
- for (int i = 0; i < arr.length; i++) {
- //若当前元素为空白元素,则令x和y为当前元素的位置
- if (arr[i] == 0){
- x = i / 4;
- y = i % 4;
- }
- data[i / 4][i % 4] = arr[i];
- }
- }
-
- private void initimage(){
- //删除所有图片
- this.getContentPane().removeAll();
-
- //调用victory方法判断是否胜利
- if (victory()) {
- JLabel win = new JLabel(new ImageIcon("image\\win.png"));
- //JLabel win = new JLabel(new ImageIcon("image\\win.png"));
- win.setBounds(203,283,197,73);
- this.getContentPane().add(win);
- }
-
- JLabel jbstep = new JLabel("步数: "+step);
- jbstep.setBounds(50,30,100,20);
- this.getContentPane().add(jbstep);
-
-
-
- for (int i = 0; i < data.length; i++) {
- for (int j = 0; j < data[i].length; j++) {
- int count = data[i][j];
- //创建一个JLabel管理容器
- JLabel jl = new JLabel(new ImageIcon(path+temppath+temp+"\\"+count+".jpg"));
- //设置图片位置以及大小
- jl.setBounds(105*j+83,105*i+134,105,105);
- //给图片设置边框
- //参数为0时表示让图片凸出来
- //参数为1时表示让图片凹进去
- jl.setBorder(new BevelBorder(1));
- this.getContentPane().add(jl);
- }
- }
-
- //添加背景图片
- JLabel jb = new JLabel(new ImageIcon("image\\background.png"));
- jb.setBounds(40,40,508,560);
- this.getContentPane().add(jb);
-
- //刷新加载图片
- this.getContentPane().repaint();
- }
-
- private void changei(){
-
- Random r = new Random();
-
- if ((path+temppath).equals("image\\girl\\girl")){
- temp = r.nextInt(13)+1;
- initimage();
- }else if((path+temppath).equals("image\\animal\\animal")){
- temp = r.nextInt(8)+1;
- initimage();
- }else if((path+temppath).equals("image\\sport\\sport")){
- temp = r.nextInt(10)+1;
- initimage();
- }
-
- }
-
- private void initjmbar() {
-
- //创建整个菜单对象
- JMenuBar jmb = new JMenuBar();
-
- //创建菜单下三个选项对象
- JMenu functionjm = new JMenu("菜单");
- JMenu aboutjm = new JMenu("关于我");
-
- JMenu changeimage = new JMenu("更换图片");
-
- //添加条目对象到选项对象中
- functionjm.add(changeimage);
- functionjm.add(restartjmi);
- //functionjm.add(relogjmi);
- functionjm.add(closejmi);
- aboutjm.add(accountjmi);
-
- changeimage.add(girl);
- changeimage.add(animal);
- changeimage.add(sport);
-
- //给条目绑定事件
- restartjmi.addActionListener(this);
- //relogjmi.addActionListener(this);
- closejmi.addActionListener(this);
- accountjmi.addActionListener(this);
- girl.addActionListener(this);
- animal.addActionListener(this);
- sport.addActionListener(this);
-
- //将选项对象添加到菜单对象中
- jmb.add(functionjm);
- jmb.add(aboutjm);
-
- //给整个界面设置菜单
- this.setJMenuBar(jmb);
- }
-
- private void initjf(){
- //设置窗口宽、高
- this.setSize(603, 680);
-
- //设置窗口标题
- this.setTitle("拼图单机版");
-
- //设置窗口置顶
- this.setAlwaysOnTop(true);
-
- //设置窗口置中
- this.setLocationRelativeTo(null);
-
- //设置窗口关闭模式
- /*
- setDefaultCloseOperation()里的参数为0时,窗口不可关闭
- 为1时,则为默认关闭模式
- 为2时,则需关闭所有窗口才可完全关闭虚拟机
- 为3时,则只需关闭一个窗口即可完全关闭虚拟机
- */
- this.setDefaultCloseOperation(3);
-
- //添加键盘监听指针
- this.addKeyListener(this);
-
- //只有取消居中,才可以将图片放到指定位置
- this.setLayout(null);
- }
-
- @Override
- public void keyTyped(KeyEvent e) {
-
- }
-
- //按下A键不松开时会调用此方法实现图片还原功能
- @Override
- public void keyPressed(KeyEvent e) {
- int code = e.getKeyCode();
- if (code == 73){
- //将界面中的图片全部删除
- this.getContentPane().removeAll();
- //加载一张完整图片
- JLabel jb = new JLabel(new ImageIcon(path+temppath+temp+"\\"+"all.jpg"));
- jb.setBounds(83,134,420,420);
- this.getContentPane().add(jb);
- //加载背景图片
- JLabel jb1 = new JLabel(new ImageIcon("image\\background.png"));
- jb1.setBounds(40,40,508,560);
- this.getContentPane().add(jb1);
- //刷新界面
- this.getContentPane().repaint();
- }
- }
-
- @Override
- public void keyReleased(KeyEvent e) {
- int code = e.getKeyCode();
- //判断游戏是否胜利,胜利则直接结束,不用执行下面的代码
- if (victory()) {
- return;
- }
- if (code == 37 || code == 65){
- System.out.println("向左移动");
- //实现空白图片右方的图片向左移动
- if (y == 3){
- return;
- }
- data[x][y] = data[x][y+1];
- data[x][y+1] = 0;
- y++;
- step++;
- //调用方法按照最新的数字加载图片
- initimage();
- }else if(code == 38 || code == 87){
- System.out.println("向上移动");
- //实现空白图片下方的图片向上移动
- if (x == 3){
- return;
- }
- data[x][y] = data[x+1][y];
- data[x+1][y] = 0;
- x++;
- step++;
- //调用方法按照最新的数字加载图片
- initimage();
- }else if(code == 39 || code == 68)
- {
- System.out.println("向右移动");
- //实现空白图片左方的图片向右移动
- if (y == 0){
- return;
- }
- data[x][y] = data[x][y-1];
- data[x][y-1] = 0;
- y--;
- step++;
- //调用方法按照最新的数字加载图片
- initimage();
- }else if(code == 40 || code == 83){
- System.out.println("向下移动");
- //实现空白图片上方的图片向下移动
- if (x == 0){
- return;
- }
- data[x][y] = data[x-1][y];
- data[x-1][y] = 0;
- x--;
- step++;
- //调用方法按照最新的数字加载图片
- initimage();
- }else if(code == 73){
- //当松开I键时,初始化界面
- initimage();
- }else if(code == 66){
- //当按下键为B时,作弊
- data = new int[][]{
- {1,2,3,4},
- {5,6,7,8},
- {9,10,11,12},
- {13,14,15,0}
- };
- initimage();
- }
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- Object obj = e.getSource();
- if (obj == restartjmi){
- System.out.println("重新游戏");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //初始化图片
- initimage();
- }
- // else if(obj == relogjmi){
- // System.out.println("重新登录");
- // //关闭当前游戏界面
- // this.setVisible(false);
- // //打开登陆界面
- // new LoginJFrame();
- // }
- else if(obj == closejmi){
- System.out.println("关闭游戏");
- //关闭虚拟机
- System.exit(0);
- }else if(obj == accountjmi){
- System.out.println("名片");
-
- JDialog jdi = new JDialog();
- JLabel jb = new JLabel(new ImageIcon("image\\mingpian.jpg"));
- //设置位置
- jb.setBounds(0,0,300,299);
- jdi.getContentPane().add(jb);
- //设置弹框大小
- jdi.setSize(344,344);
- //设置弹框置顶
- jdi.setAlwaysOnTop(true);
- //设置弹框居中
- jdi.setLocationRelativeTo(null);
- //设置弹框不关闭无法继续
- jdi.setModal(true);
- //设置弹框可视化
- jdi.setVisible(true);
- }else if (obj == girl) {
- System.out.println("更换美女图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\girl\\girl";
- changei();
- }else if (obj == animal) {
- System.out.println("更换动物图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\animal\\animal";
- changei();
- }else if (obj == sport) {
- System.out.println("更换运动图片");
- //计步器清零
- step = 0;
- //初始化数据
- initdata();
- //随机图片库
- temppath = "\\sport\\sport";
- changei();
- }
- }
- }
成品展示:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。