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();
}
}
运行(鼠标选中人物,利用上下左右键移动):
人物图像和背景音乐自定
原文作者:demons26
原文地址: https://blog.csdn.net/weixin_46098815/article/details/124048752
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
原文地址: https://blog.csdn.net/weixin_46098815/article/details/124048752
本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
相关文章