一、介绍
一共有十六块拼图,一个参考图,玩家在输入玩家名后,进入游戏,然后需按左上的参考图,将左下侧的拼图拖拽到右侧的黑白方块内,然后点击OK键,游戏会返回一个正确或错误的结论,如果玩家想要重玩游戏,点击RESTART键后,再在游戏中任意处拖拽,拼图将复原。
- 效果
图像素材是文森特·梵高在阿尔勒的家(黄楼)-Vincent’s House in Arles (The Yellow House)(1888)。
二、成品操作步骤
(一)操作步骤
- 玩家输入玩家名,点击确认游戏开始,玩家如果点击取消游戏退出;
- 玩家按照参考图将各拼图模块拖拽至左侧黑白区域内;
- 玩家点击OK键查看结果;
- 玩家点击RESTART键,并在游戏区内拖拽实现复位重玩;
- 玩家从菜单栏游戏点击退出即可退出游戏,但游戏结果不保存。
- 玩家可从游戏点击关于查看本游戏信息。
(二)登录
如果玩家选择取消,则退出游戏,如果玩家未输入或输入内容为空,在点确认后,则玩家名默认为player。
(三)拼图错误的情况
在按键OK键后,提示错误,显示玩家名和WEONG。
(四)拼图正确的情况
- 在190秒内,显示玩家名、PERFERCT和用时。
- 超过190秒,显示玩家名、GOOD和用时。
(五)复位
在点击复位键后,再在游戏中任意位置拖拽,图中为(615,241)附近位置拖拽实现复位。
(六)菜单栏的功能介绍
点击关于后即可显示游戏相关信息,如果点击退出则退出游戏。
三、源码
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
/* 拼图 */
class Jigsaw extends JPanel implements ActionListener
{
/* 各模块及初始坐标 */
String[] s = {"imgs\\5.jpg","imgs\\9.jpg","imgs\\1.jpg","imgs\\3.jpg","imgs\\2.jpg","imgs\\8.jpg","imgs\\4.jpg","imgs\\16.jpg",
"imgs\\11.jpg","imgs\\15.jpg","imgs\\13.jpg","imgs\\6.jpg","imgs\\10.jpg","imgs\\12.jpg","imgs\\14.jpg","imgs\\7.jpg"};
private int[] x = {40,40,40,40,40,40,40,40,140,140,140,140,140,140,140,140};
private int[] y = {200,270,340,410,480,550,620,690,200,270,340,410,480,550,620,690};
/* 移动坐标x,y,处理图层冲突机制 */
private int px, py, z[] = new int[100], k = 1;
/* 玩家姓名 */
private String name;
/* 起止时间 */
private long startTime, endTime;
/* 点类 */
private Point point = new Point();
/* 标题 */
JLabel title = new JLabel("拼图·名画");
JLabel reference = new JLabel("参考图");
/* 规则说明文本框 */
JTextField rule1 = new JTextField("Rules:1.请将左侧图块放置到上方黑白方块内;");
JTextField rule2 = new JTextField("2.完成后点击OK;");
JTextField rule3 = new JTextField("3.如果要重置点击RESTART,并在本程序其他位置拖拽下");
/* 确认与重置按键 */
JButton OK = new JButton("OK");
JButton restart = new JButton("RESTART");
/* 玩家信息 */
public void Login()
{
name = JOptionPane.showInputDialog(null,"Enter Your Name","player");
}
/* 选中 */
public boolean isDragged(int px, int py, int x, int y)
{
if ((px <= (x + 50) && px >= (x - 10)) && (py <= (y + 50) && py >= (y - 10)))
{
return true;
}
return false;
}
public Jigsaw()
{
Login();
startTime = System.currentTimeMillis();
add(title);
add(reference);
add(rule1);
add(rule2);
add(rule3);
add(OK);
add(restart);
setLayout(null); //用绝对位置布局
title.setBounds(700,100,400,50);
title.setFont(new Font("楷体",Font.BOLD,40));
reference.setBounds(145,20,40,40);
rule1.setBounds(700,600,400,30);
rule2.setBounds(700,630,400,30);
rule3.setBounds(700,660,400,30);
OK.setBounds(800,550,100,30);
restart.setBounds(940,550,100,30);
rule1.setEditable(false);
rule2.setEditable(false);
rule3.setEditable(false);
OK.addActionListener(this);
restart.addActionListener(this);
/* 鼠标监听 */
addMouseMotionListener(
new MouseAdapter() {
/* 拖拽 */
public void mouseDragged(MouseEvent event)
{
point = event.getPoint();
px = point.x;
py = point.y;
/* 清零机制 */
if (k++ > 95)
{
k = 1;
}
for (int i = 0; i < x.length; i++)
{
if (isDragged(px,py,x[i],y[i]))
{
z[k] = i;
if (z[k] == z[k-1]) //解决图层冲突
{
x[i] = px;
y[i] = py;
}
}
}
repaint();
}
}
);
}
/* 执行动作 */
public void actionPerformed(ActionEvent actionEvent) {
if (actionEvent.getSource() == OK)
{
if (
x[0] >= 698 && x[0] <= 712 && y[0] >= 273 && y[0] <= 287 && //5
// 判断标准略····
//···
//···
)
{
endTime = (System.currentTimeMillis() - startTime) / 1000;
if (endTime < 190)
{
JOptionPane.showMessageDialog(null,name + ", PERFECT, Time cost: " + endTime + "s","成功提示",JOptionPane.PLAIN_MESSAGE);
}
else
{
JOptionPane.showMessageDialog(null,name + ", GOOD, Time cost: " + endTime +"s","成功提示",JOptionPane.PLAIN_MESSAGE);
}
}
else
{
JOptionPane.showMessageDialog(null,name + ", WRONG","错误提示",JOptionPane.ERROR_MESSAGE);
}
}
else if (actionEvent.getSource() == restart)
{
x[0] = x[1] = x[2] = x[3] = x[4] = x[5] = x[6] = x[7] = 40;
// 复位位置略······
//···
//···
/* 起始时间重置 */
startTime = System.currentTimeMillis();
}
}
/* 图像绘制模块 */
public void paintComponent(Graphics g)
{
super.paintComponent(g);
/* 如果玩家姓名为空或无输入,默认为player */
if (name == null)
{
System.exit(0);
}
if (name.length() == 0)
{
name = "player";
}
/* 拖动的位置、玩家和时间信息 */
g.drawString("X: " + px + " Y: " + py + " WELCOME, " + name,5,15);
/* 放置黑白底板模块 */
g.fillRect(700,200,410,290);
g.setColor(Color.WHITE);
int m = 0, wy[] = {205,345,275,415};//白色方块的y坐标
for (int i = 705; i <= 1005; i += 100)
{
for (int j = 0; j < 2; j++)
{
g.fillRect(i,wy[m],100,70);
m++;
}
if (m == 4)
{
m = 0;
}
}
/* 参考图 */
g.drawImage(new ImageIcon("imgs\\pic.jpg").getImage(),50,50,230,130,this);
/* 拼图堆放 */
for (int i = 0; i < x.length; i++)
{
g.drawImage(new ImageIcon(s[i]).getImage(),x[i],y[i],96,60,this);
}
}
}
/* 结合菜单栏 */
public class JigsawGraphics extends JFrame implements ActionListener
{
JMenuBar mb = new JMenuBar();
JMenu game = new JMenu("游戏");
JMenu help = new JMenu("帮助");
JMenuItem exit=new JMenuItem("退出");
JMenuItem about = new JMenuItem("关于");
JMenuItem nohelp = new JMenuItem("没有帮助");
public JigsawGraphics(String title)
{
super(title);
setJMenuBar(mb);
mb.add(game);
mb.add(help);
game.add(exit);
game.add(about);
help.add(nohelp);
exit.addActionListener(this);
about.addActionListener(this);
Jigsaw jg = new Jigsaw();
add(jg);
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
setSize(1200,820);
setVisible(true);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource() == exit)
{
System.exit(0);
}
else if (e.getSource() == about)
{
JOptionPane.showMessageDialog(null, "本游戏开发时间:20200616\n版本号:1.0.1","关于",JOptionPane.PLAIN_MESSAGE);
}
}
public static void main(String[] args)
{
JigsawGraphics JG = new JigsawGraphics("拼图·名画");
}
}