Java华容道小程序设计

华容道游戏取自著名的三国故事,曹操在赤壁大战中被刘备和孙权的“苦肉计”、“火烧连营”打败,被迫退逃到华容道,又遇上诸葛亮的伏兵,关羽为了报答曹操对他的恩情,明逼实让,终于帮助曹操逃出了华容道。

要求:1.本程序主要练习使用布局管理器设计一个华容道游戏界面,并练习使用事件监听器(鼠标事件、键盘事件和焦点事件)实现按钮的移动。

2.编写一个按钮的子类,使用该子类创建的对象代表华容道中的人物。通过焦点事件控制人物颜色,当人物获得焦点时颜色为红色,当失去焦点时颜色为黄色。

3.通过键盘事件和鼠标事件来实现曹操、关羽等人物的移动。当人物上发生鼠标事件或键盘事件时,如果鼠标指针的位置是在人物的下方(也就是组件的下半部分)或按下键盘的“↓“键,该人物向下移动。向左、向右和向上的移动原理类似。

4.点击“重新开始”可以使各个按钮复位,重新开始游戏。

Hua_Rong_Road类:

package 华容道;

import javazoom.jl.player.Player;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;

public class Hua_Rong_Road extends JFrame implements ActionListener, MouseListener, KeyListener {

    Person[] person = new Person[10]; // 10个人
    JButton left, right, above, below;// 边界
    JButton restart = new JButton("重新开始");
    JButton about = new JButton("游戏背景");
    JButton help = new JButton("游戏帮助");
    int i = 0;
    JLabel jLabel = new JLabel();//标签
    public Hua_Rong_Road() {
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//隐藏并释放窗体,dispose(),当最后一个窗口被释放后,则程序也随之运行结束
        setBounds(450, 0, 425, 700);//设置边框的大小
        setVisible(true);//设置视野可见
        validate();//使用插件时的初始化方法
    }

    public void init() {
        setResizable(false);//生成的窗体大小是由程序员决定的,用户不可以自由改变该窗体的大小。
        setDefaultCloseOperation(3);//直接关闭应用程序,System.exit(0)。
        i = 0;//记录步数
        setLayout(null);//流式布局绝对布局
        add(restart);//重新开始按钮
        restart.setBounds(140, 540, 120, 40);
        restart.addActionListener(this);
        add(about);//游戏背景按钮
        about.setBounds(10, 540, 120, 40);
        about.addActionListener(this);//事件监听对象,this指本身这个对象,这个类会实现监听器接口
        add(help);//游戏帮助按钮
        help.setBounds(270, 540, 120, 40);
        help.addActionListener(this);//事件监听对象,this指本身这个对象,这个类会实现监听器接口
        String[] name = {"曹操", "关羽", "马超", "黄忠", "张飞", "赵云", "兵", "兵", "兵", "兵"};
        for (int k = 0; k < name.length; k++) {
            person[k] = new Person(k, name[k]);
            person[k].addMouseListener(this);//为人物对象添加鼠标监听器
            person[k].addKeyListener(this);//为人物对象添加键盘监听器
            add(person[k]);
        }

        jLabel.setText("当前走了" + i + "步");
        person[0].setBounds(105, 5, 200, 200); //曹操
        person[1].setBounds(105, 205, 200, 100);// 关羽
        person[2].setBounds(5, 205, 100, 200);//马超"
        person[3].setBounds(305, 205, 100, 200);//黄忠
        person[4].setBounds(5, 5, 100, 200);//张飞
        person[5].setBounds(305, 5, 100, 200);//赵云
        person[6].setBounds(5, 405, 100, 100);//兵
        person[7].setBounds(305, 405, 100, 100);//兵
        person[8].setBounds(105, 305, 100, 100);//兵
        person[9].setBounds(205, 305, 100, 100);//兵
        left = new JButton();
        right = new JButton();
        above = new JButton();
        below = new JButton();
        add(jLabel);
        add(left);
        add(right);
        add(above);
        add(below);
        left.setBounds(0, 0, 5, 505);
        right.setBounds(405, 0, 5, 505);
        above.setBounds(0, 0, 410, 5);
        below.setBounds(0, 505, 410, 5);
        jLabel.setBounds(166, 600, 100, 20);

        validate();//使用validate方法是容器再次布置其组件,确保布局有效

        new Thread(() -> {
            try {
                File file = new File("src\\music\\三国 - 黎允文.mp3");
                FileInputStream fis = null;
                fis = new FileInputStream(file);
                BufferedInputStream stream = new BufferedInputStream(fis);
                Player player = new Player(stream);
                player.play();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();

    }

    @Override//键盘按键的控制
    public void keyPressed(KeyEvent e) {
        Person man = (Person) e.getSource();
        if (e.getKeyCode() == KeyEvent.VK_DOWN) {
            go(man, below);
        }
        if (e.getKeyCode() == KeyEvent.VK_UP) {
            go(man, above);
        }
        if (e.getKeyCode() == KeyEvent.VK_LEFT) {
            go(man, left);
        }
        if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
            go(man, right);
        }

    }

    public void keyReleased(KeyEvent e) {
    }

    public void keyTyped(KeyEvent e) {
    }


    public void mousePressed(MouseEvent e) {

    }

    public void mouseClicked(MouseEvent e) {
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }
    //判断是否可以进行移动

    public void go(Person man, JButton direction) {

        boolean move = true;
        Rectangle manRect = man.getBounds();
        int x = man.getBounds().x;
        int y = man.getBounds().y;
        if (direction == below)
            y = y + 100;
        else if (direction == above)
            y = y - 100;
        else if (direction == left)
            x = x - 100;
        else if (direction == right)
            x = x + 100;
        manRect.setLocation(x, y);
        Rectangle dirctionRect = direction.getBounds();
        for (int k = 0; k < 10; k++) {
            Rectangle personRect = person[k].getBounds();
            if ((manRect.intersects(personRect)) && (man.number != k))
                move = false;
        }
        if (manRect.intersects(dirctionRect))
            move = false;
        if (move == true) {
            i++;
            jLabel.setText("当前走了" + i + "步");
            man.setLocation(x, y);
            if (man.name == "曹操") {
                if (man.getLocation().x == 105 && man.getLocation().y == 305) {
                    JOptionPane.showMessageDialog(this, "游戏成功,按确定重新开始", "游戏成功", JOptionPane.INFORMATION_MESSAGE);
                    dispose();//刷新界面
                    new Hua_Rong_Road().init();//初始化界面
                }
            }
        }

    }

    //重新开始新的一局游戏
    @Override
    public void actionPerformed(ActionEvent e) {
        JButton b = (JButton) e.getSource();
        if (b == restart) {
            dispose();
            new Hua_Rong_Road().init();
        }
        if (b == about) {
            JOptionPane.showMessageDialog(this, "华容道游戏取自著名的三国故事,曹操在赤壁大战中被\n"
                    + "刘备和孙权的“苦肉计”、“火烧连营”打败,被迫退逃到华容道,又遇上诸葛亮的伏兵,\n"
                    + "关羽为了报答曹操对他的恩情,明逼实让,终于帮助曹操逃出了华容道。\n"
                    + "曹操逃出华容道的最大障碍是关羽,关羽立马华容道,一夫当关,万夫莫开。\n"
                    + "关羽与曹操当然是解开这一游戏的关键。\n"
                    + "四个刘备军兵是最灵活的,也最容易对付,如何发挥他们的作用也要充分考虑周全。\n"
                    + "“华容道”有一个带二十个小方格的棋盘,代表华容道。\n"
                    + "棋盘下方有一个两方格边长的出口,是供曹操逃走的。", "背景", JOptionPane.INFORMATION_MESSAGE);
        }
        if (b == help) {
            JOptionPane.showMessageDialog(this, "胜利条件:曹操到达地图中下方位置。\n"
                    + "操作方式:用鼠标选中角色后,使用键盘上下左右方向键控制角色移动", "帮助", JOptionPane.WARNING_MESSAGE);
        }
    }

}

Data类

package 华容道;

import javax.swing.*;
import java.net.URL;

public class Data {
    static URL CaoCaoURL= Data.class.getResource("caocao.png");
    public static ImageIcon CaoCaoIcon = new ImageIcon(CaoCaoURL);

    static URL ZhaoYunURL= Data.class.getResource("zhaoyun.jpg");
    public static ImageIcon ZhaoYun = new ImageIcon(ZhaoYunURL);

    static URL ZhangFeiURL= Data.class.getResource("zhangfei.png");
    public static ImageIcon ZhangFei = new ImageIcon(ZhangFeiURL);

    static URL GuanYuURL= Data.class.getResource("guanyu.jpg");
    public static ImageIcon GuanYu = new ImageIcon(GuanYuURL);

    static URL MaChaoURL= Data.class.getResource("machao.jpg");
    public static ImageIcon MaChao = new ImageIcon(MaChaoURL);

    static URL HuangZhouURL= Data.class.getResource("huangzhong.png");
    public static ImageIcon HuangZhou = new ImageIcon(HuangZhouURL);

    static URL BingURL= Data.class.getResource("bing.jpg");
    public static ImageIcon Bing = new ImageIcon(BingURL);
}

人物定义 Person.java

package 华容道;

import javax.swing.*;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;

public class Person extends JButton implements FocusListener {
    int number;
    String name;
    Font font = new Font("宋体", Font.BOLD, 16);
    Color c;
    Person(int number,String s) {
        name=s;
        setFont(font);
        this.number = number;
        c = getBackground();
        addFocusListener(this);
    }

    @Override
    protected void paintComponent(Graphics g) {
        if (name=="曹操"){
            Data.CaoCaoIcon.paintIcon(this,g,0,0);
        }else if (name=="赵云"){
            Data.ZhaoYun.paintIcon(this,g,0,0);
        }else if (name=="关羽"){
            Data.GuanYu.paintIcon(this,g,0,0);
        }else if (name=="马超"){
            Data.MaChao.paintIcon(this,g,0,0);
        }else if (name=="黄忠"){
            Data.HuangZhou.paintIcon(this,g,0,0);
        }else if (name=="张飞"){
            Data.ZhangFei.paintIcon(this,g,0,0);
        }else if (name=="兵"){
            Data.Bing.paintIcon(this,g,0,0);
        }

    }

    @Override
    public void focusGained(FocusEvent arg0) {
        setBackground(Color.blue);
    }

    @Override
    public void focusLost(FocusEvent arg0) {
        setBackground(Color.gray);
    }

}

测试主类

package 华容道;

public class MainClass {
    public static void main(String[] args) {
        new Hua_Rong_Road().init();
    }
}

运行(鼠标选中人物,利用上下左右键移动):

《Java华容道小程序设计》

 人物图像和背景音乐自定

    原文作者:demons26
    原文地址: https://blog.csdn.net/weixin_46098815/article/details/124048752
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。

相关文章