基于Java实现的拼图小游戏,代码与图片素材来自b站up主黑马程序员的Java教学视频。
main方法
import ui.LoginJframe;
public class App {
public static void main(String[] args) {
new LoginJframe(); //创建登陆界面
}
}
登录界面
package ui;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
//游戏登录界面
public class LoginJframe extends JFrame implements MouseListener {
//创建全集一个用户集合用于登录判断
static ArrayList<User> list=new ArrayList<>();
static String userName;
//添加用户集合成员,用于登录操作判断
static{
list.add(new User("wuhu","yahu"));
}
//切换验证码按键
JButton Switch_Captcha=new JButton();
//设置注册按钮
JButton enrollJButton=new JButton();
//设置登录按钮
JButton loginJButton = new JButton();
//getCaptcha为验证码获取方法,传递的数据为需要返回的验证码的长度
String str_Captcha=getCaptcha(5);
/*登录与注册按钮的图片文件位置*/
String Image_enroll="untitled/image/login/注册按钮.png";
String Image_login="untitled/image/login/登录按钮.png";
//显示用户名输入框
JTextField NameFrame=new JTextField();
//添加验证码文本框
JTextField FrameCaptcha=new JTextField();
//密码输入显示框
JTextField PasswordFrame=new JTextField();
//创建一个弹框对象
JDialog Error;
//登录界面的空参构造
public LoginJframe(){
initJFrame(); //界面初始化项目
initView(); //界面元素添加
//绑定监听
enrollJButton.addMouseListener(this);
loginJButton.addMouseListener(this);
Switch_Captcha.addMouseListener(this);
//将界面状态设置为显示
this.setVisible(true);
}
//界面初始化类
public void initView(){
//清空界面
this.getContentPane().removeAll();
//显示用户名
JLabel UsrtName = new JLabel(new ImageIcon("untitled/image/login/用户名.png"));
UsrtName.setBounds(100,105,47,17);
this.getContentPane().add(UsrtName);
//配置用户名输入框
NameFrame.setBounds(160,100,200,30);
this.getContentPane().add(NameFrame);
//显示密码
JLabel UsrtPassword=new JLabel(new ImageIcon("untitled/image/login/密码.png"));
UsrtPassword.setBounds(100,155,47,17);
this.getContentPane().add(UsrtPassword);
//配置密码框参数
PasswordFrame.setBounds(160,150,200,30);
this.getContentPane().add(PasswordFrame);
//添加验证码
JLabel CaptchaTxT=new JLabel(new ImageIcon("untitled/image/login/验证码.png"));
CaptchaTxT.setBounds(100,215,47,17);
this.getContentPane().add(CaptchaTxT);
//配置验证码文本框参数
FrameCaptcha.setBounds(160,210,100,30);
this.getContentPane().add(FrameCaptcha);
//验证码显示
System.out.println(str_Captcha);
JLabel Captcha=new JLabel(str_Captcha);
Captcha.setBounds(280,215,50,20);
this.getContentPane().add(Captcha);
//设置验证码按钮
Switch_Captcha.setBounds(275,215,50,20);
Switch_Captcha.setBorderPainted(false);
Switch_Captcha.setContentAreaFilled(false);
this.getContentPane().add(Switch_Captcha);
//配置登录按钮
loginJButton.setIcon(new ImageIcon(Image_login));
loginJButton.setBorderPainted(false); //去除按钮的默认边框
loginJButton.setContentAreaFilled(false); //去除按钮的默认背景
loginJButton.setBounds(123,310,128,47); //设置位置与大小
this.getContentPane().add(loginJButton);
//配置注册按钮
enrollJButton.setIcon(new ImageIcon(Image_enroll));
enrollJButton.setBorderPainted(false); //去除按钮的默认边框
enrollJButton.setContentAreaFilled(false); //去除按钮的默认背景
enrollJButton.setBounds(270,310,128,47); //设置位置与大小
this.getContentPane().add(enrollJButton);
// 添加背景图片
//设置一个JLabel对象进行管理图片
JLabel background_JLabel=new JLabel(new ImageIcon("untitled/image/register/background.png"));
//设置图片的位置与宽高
background_JLabel.setBounds(0,0,470,390);
//将容器添加到界面当中
this.getContentPane().add(background_JLabel);
//刷新界面
this.getContentPane().repaint();
}
//获取验证码方法 n 为需要返回的验证码长度
public static String getCaptcha(int len){
Random r=new Random(); //设置随机方法种子
StringBuilder str=new StringBuilder();
for (int i = 0; i < len-1; i++) {
int num=r.nextInt(58)+65; //字母范围的数值
//跳过ascii表中的其他字符
if(num > 90 && num < 97){
num+=7;
}
str.append((char)num); //将数值强制转换为字母并添加到字符串中
}
//将数字添加到字符串中
int number=r.nextInt(10);
str.append(number);
//转换为字符数组更好进行乱序的操作
char []arr= str.toString().toCharArray();
//将其数组元素顺序打乱
for (int i = 0; i < arr.length; i++) {
int index=r.nextInt(arr.length);
char temp=arr[i];
arr[i]=arr[index];
arr[index]=temp;
}
//将完成的验证码转换为字符串将其返回
return new String(arr);
}
//注册界面初始化方法
public void initJFrame(){
//设置界面的宽高
this.setSize(488,430);
//设置界面的标题
this.setTitle(" 登录界面 ");
//设置界面为图层顶置
this.setAlwaysOnTop(true);
//设置界面为初始化居中显示
this.setLocationRelativeTo(null);
//设置关闭模式 3 代表当前界面被关闭后程序结束
this.setDefaultCloseOperation(3);
}
/*事件监听*/
//鼠标松开后执行
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("松开后");
Object obj=e.getSource(); //获取点击是哪一个按键
//登录按钮点击后的操作
if(loginJButton == obj){
Image_login=("untitled/image/login/登录按钮.png");
initView();//界面显示方法
//获取用户名、密码、验证码框内的内容
String getName=NameFrame.getText();
String getPasswodr=PasswordFrame.getText();
String getCaptcha=FrameCaptcha.getText();
//判断三个文本框内是否都有输入数据
if((0 == getName.length()) || (0 == getPasswodr.length()) || (0 == getCaptcha.length())){
showJDialog("输入有误,请检查是否已全部输入");
return;
}
else if(!(str_Captcha.equals(getCaptcha))){
showJDialog("验证码错误,请正确输入");
str_Captcha=getCaptcha(5);
initView();//界面显示方法
}
/*judgmentUser方法作用为判断输入的用户名与密码是否为正确的
* 返回值为 bool类型,正确返回true,错误返回false
* */
else if ( judgmentUser(getName,getPasswodr) ){
showJDialog("登录成功!欢迎进入游戏");
this.dispose(); //关闭当前界面
userName=getName;
new GameJframe(); //打开游戏界面
}
else {
showJDialog("用户名或密码错误");
return;
}
}
//注册按钮点击后的操作
else if (enrollJButton == obj) {
Image_enroll=("untitled/image/login/注册按钮.png");
showJDialog("功能未完善,敬请期待。");
}
//验证码显示范围地区被点击后
else if (Switch_Captcha == obj) {
str_Captcha=getCaptcha(5); //传入的形参为返回的长度
initView();//界面显示方法
}
/*判断整个弹窗对象是否被点击*/
else if (Error == obj) {
//将生成的弹窗关闭
Error.dispose();
} else {
;
}
}
//按键按着不松时
@Override
public void mousePressed(MouseEvent e) {
/*主要作用为当按键松开后,将按钮恢复为初始状态*/
Object obj=e.getSource(); //获取点击是哪一个按键
if(loginJButton == obj){
Image_login=("untitled/image/login/登录按下.png");
//界面显示方法
initView();
} else if (enrollJButton == obj) {
Image_enroll=("untitled/image/login/注册按下.png");
//界面显示方法
initView();
}else {
;
}
}
//鼠标点击后松开执行
@Override
public void mouseReleased(MouseEvent e) {
}
//鼠标滑入监听
@Override
public void mouseEntered(MouseEvent e) {
}
//鼠标滑出监听
@Override
public void mouseExited(MouseEvent e) {
}
//判断用户名与密码是否相等方法
public boolean judgmentUser(String strName,String strPassword){
for (int i = 0; i < list.size(); i++) {
if( list.get(i).getName().equals(strName) ){
if( list.get(i).getPassword().equals(strPassword) ){
return true;
}
return false;
}
}
return false;
}
//弹框显示
public void showJDialog(String display){
//创建一个弹框的对象,显示形参display
Error=new JDialog();
//设置弹框的大小
Error.setSize(200,150);
JLabel data=new JLabel(display);
data.setBounds(0,0,200,150);
Error.getContentPane().add(data);
Error.setTitle("提示");
//将弹框设置为界面顶置
Error.setAlwaysOnTop(true);
//初始位置为居中显示
Error.setLocationRelativeTo(null);
//将弹框设置为不关闭弹框无法操作其他界面
Error.setModal(true);
//绑定监听
Error.addMouseListener(this);
//将弹框显示方式设置为显示
Error.setVisible(true);
}
}
游戏主界面
package ui;
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 {
int [][] PosArr=new int[4][4];
int [][] win=new int[][]{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,0}
};
String path="untitled\\image\\animal\\animal3\\";
int step=0; //计步器
//记录空白方块在二维数组中的位置
int x=0,y=0;
//条目
JMenuItem accountItem=new JMenuItem("支持我们(手动狗头)");
JMenuItem prompt=new JMenuItem("提示");
JMenuItem replayItem=new JMenuItem("重新游戏");
JMenuItem reLoginItem=new JMenuItem("重新登录");
JMenuItem closeItem=new JMenuItem("关闭游戏");
JMenuItem BeautyPi=new JMenuItem("美女");
JMenuItem AnimalPi=new JMenuItem("动物");
JMenuItem MotionPi=new JMenuItem("运动");
JMenuItem AboutUser=new JMenuItem("关于用户");
//创建一个主界面
public GameJframe(){
//初始化界面
initJFrame();
//初始化菜单
initJMenuBar();
//初始化并打乱二维数组中的下标
ArrRandom();
//初始化图片
initImage();
//将界面状态设置为显示
this.setVisible(true);
}
//初始化图片
private void initImage() {
//清空所有图片
this.getContentPane().removeAll();
JLabel stepJlbel=new JLabel("步数:"+step);
stepJlbel.setBounds(50,30,100,20);
this.getContentPane().add(stepJlbel);
//判断数组是否顺序相同,相同则代表图片位置同意一样
if(OrderJudgment())
{
JLabel winJlabel=new JLabel(new ImageIcon("untitled/image/win.png"));
winJlabel.setBounds(203,283,197,73);
this.getContentPane().add(winJlabel);
}
for(int i=0; i<4; i++)
{
for(int j=0; j<4; j++)
{
int index=PosArr[i][j];
ImageIcon icon = new ImageIcon(path+(index)+".jpg");
JLabel jLabel = new JLabel(icon);
jLabel.setBounds(105*j+83,105*i+134,105,105);
jLabel.setBorder(new BevelBorder(BevelBorder.LOWERED));
this.getContentPane().add(jLabel);
}
}
//添加背景
ImageIcon background=new ImageIcon("untitled\\image\\background.png");
JLabel dataJlabel=new JLabel(background);
dataJlabel.setBounds(40,40,508,560);
this.getContentPane().add(dataJlabel);
//刷新界面
this.getContentPane().repaint();
}
//数组随机
public void ArrRandom() {
Random r=new Random();
int []tmparr={1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0};
for (int i = 0; i < tmparr.length; i++) {
int index=r.nextInt(tmparr.length);
int temp=tmparr[index];
tmparr[index]=tmparr[i];
tmparr[i]=temp;
}
for (int i = 0; i < tmparr.length; i++) {
if(tmparr[i] == 0)
{
x=i/4;
y=i%4;
}
PosArr[i/4][i%4]=tmparr[i];
}
}
//菜单设置
private void initJMenuBar() {
//初始化菜单
JMenuBar jMenuBar = new JMenuBar();
JMenu functionJMenu=new JMenu("功能");
JMenu handoffPi=new JMenu("切换图片");
JMenu aboutJMenu=new JMenu("关于");
//添加
functionJMenu.add(handoffPi);
functionJMenu.add(replayItem);
functionJMenu.add(reLoginItem);
functionJMenu.add(closeItem);
//将功能添加进切换图片这个项当中
handoffPi.add(BeautyPi);
handoffPi.add(AnimalPi);
handoffPi.add(MotionPi);
//关于此项添加
aboutJMenu.add(accountItem);
//给条目绑定事件
//重新游戏
replayItem.addActionListener(this);
//重新登录
reLoginItem.addActionListener(this);
//关闭游戏
closeItem.addActionListener(this);
//关于我们
accountItem.addActionListener(this);
//提示
prompt.addActionListener(this);
//关于用户
AboutUser.addActionListener(this);
//更换图片功能绑定条目
//美女、动物、运动
BeautyPi.addActionListener(this);
AnimalPi.addActionListener(this);
MotionPi.addActionListener(this);
//将其添加到大菜单当中
jMenuBar.add(functionJMenu);
jMenuBar.add(aboutJMenu);
jMenuBar.add(prompt);
jMenuBar.add(AboutUser);
this.setJMenuBar(jMenuBar); //给界面设置菜单
}
//界面初始化
private void initJFrame() {
//设置界面长宽
this.setSize(603,680);
this.setTitle("拼图游戏单机版 V1.0");
this.setAlwaysOnTop(true);
this.setLocationRelativeTo(null);
//设置关闭模式
this.setDefaultCloseOperation(3);
this.setLayout(null);
//给整个界面添加键盘监听
this.addKeyListener(this);
}
//判断两个数组数据是否相同
public boolean OrderJudgment(){
for (int i = 0; i < PosArr.length; i++) {
for (int j = 0; j < PosArr[i].length; j++) {
if(PosArr[i][j] != win[i][j]){
return false;
}
}
}
return true;
}
//无内容
@Override
public void keyTyped(KeyEvent e) {
}
//按键按着不松时执行
@Override
public void keyPressed(KeyEvent e) {
//获取当前按键的键值
int code =e.getKeyCode();
//判断是否 X 按键被按下 x的键盘值就是88
if (code == 88) {
//清空图片
this.getContentPane().removeAll();
//显示完整图片
ImageIcon Fullmap=new ImageIcon(path+"\\all.jpg");
JLabel dataJlabel=new JLabel(Fullmap);
dataJlabel.setBounds(83,134,420,420);
this.getContentPane().add(dataJlabel);
//添加背景
JLabel all=new JLabel(new ImageIcon("untitled\\image\\background.png"));
all.setBounds(40,40,508,560);
this.getContentPane().add(all);
//刷新界面
this.getContentPane().repaint();
}
}
//按键松开时执行
@Override
public void keyReleased(KeyEvent e) {
//对 上 下 左 右 的操作进行判断
// 38 40 37 39
int code=e.getKeyCode(); //获取键盘按键的键值
if(code == 37 && y != 0){
PosArr[x][y]=PosArr[x][y-1];
PosArr[x][y-1]=0;
y--;
//初始化图片
initImage();
System.out.println("向左移动");
step++;
}
else if (code == 38 && x != 0) {
PosArr[x][y]=PosArr[x-1][y];
PosArr[x-1][y]=0;
x--;
//初始化图片
initImage();
System.out.println("向上移动");
step++;
}
else if (code == 39 && y != 3) {
PosArr[x][y]=PosArr[x][y+1];
PosArr[x][y+1]=0;
y++;
//初始化图片
initImage();
System.out.println("向右移动");
step++;
}
else if (code == 40 && x!= 3) {
PosArr[x][y]=PosArr[x+1][y];
PosArr[x+1][y]=0;
x++;
//初始化图片
initImage();
System.out.println("向下移动");
step++;
}
//按下 X 显示全图
else if (code == 88) {
//初始化图片
initImage();
}
//按下 A 键则执行一键通关
else if (code == 65) {
PosArr= new int[][]{
{1,2,3,4},
{5,6,7,8},
{9,10,11,12},
{13,14,15,0},
};
x=y=3; //将空白位置的坐标记录下来
//初始化图片
initImage();
}
//按下 C 键图片重新打乱,重新游戏
else if (code == 67) {
step=0; //计步器归零
//将二维数组重新打乱以达到重新将图片打乱的效果
ArrRandom();
//初始化图片
initImage();
System.out.println("重新游戏");
}
else{
return;
}
}
//鼠标动作监听
@Override
public void actionPerformed(ActionEvent e) {
Object obj=e.getSource();
//重新游戏
if(obj == replayItem){
step=0; //计步器归零
//将二维数组重新打乱以达到重新将图片打乱的效果
ArrRandom();
//初始化图片
initImage();
System.out.println("重新游戏");
}
//重新登录
else if (obj == reLoginItem) {
this.dispose(); //关闭当前界面
new LoginJframe(); //打开登录界面
System.out.println("重新登录");
}
//关闭游戏
else if (obj == closeItem) {
//关闭虚拟机已到达退出游戏的效果
System.exit(0);
System.out.println("关闭游戏");
}
//收款码弹窗显示
else if(obj == accountItem){
//创建一个弹框对象
JDialog jDialog =new JDialog();
//创建一个图片对象并将其添加到管理容器当中
JLabel jLabel=new JLabel(new ImageIcon("untitled\\image\\收款码.png"));
//设置图片的位置与宽高
jLabel.setBounds(0,0,516,506);
//将管理容器添加到弹框中
jDialog.getContentPane().add(jLabel);
//设置弹框的大小
jDialog.setSize(600,600);
//设置弹框为界面顶置
jDialog.setAlwaysOnTop(true);
//设置弹框为初始居中显示
jDialog.setLocationRelativeTo(null);
//将弹框设置为未关闭则无法操作其他界面
jDialog.setModal(true);
//将弹框设置为显示
jDialog.setVisible(true);
System.out.println("关于我们");
}
//美女、动物、与运动等图片的切换
else if (obj == BeautyPi) {
System.out.println("美女图片");
Random r=new Random();
int index=r.nextInt(10)+1;//随机图片下标
path=new String("untitled\\image\\girl\\girl"+(index)+"\\");
step=0; //计步器归零
ArrRandom();
//生成图片
initImage();
} else if (obj == AnimalPi) {
System.out.println("动物图片");
Random r=new Random();
int index=r.nextInt(8)+1;//随机图片下标
path=new String("untitled/image/animal/animal"+(index)+"\\");
step=0; //计步器归零
ArrRandom(); //数组乱序
initImage(); //生成图片
} else if (obj == MotionPi) {
System.out.println("运动图片");
Random r=new Random();
int index=r.nextInt(10)+1; //随机图片下标
path=new String("untitled/image/sport/sport"+(index)+"\\");
step=0; //计步器归零
ArrRandom(); //数组乱序
initImage(); //生成图片
}
//提示弹框创建
else if (obj == prompt) {
showJDialog("x :显示全图; c :重新游戏;");
}
//关于用户动作监听
else if (obj == AboutUser) {
showJDialog("那年"+LoginJframe.userName+"双手插兜, 被我们打的不知如何还手");
}
else {
return;
}
}
public void showJDialog(String display){
//创建一个弹框的对象,显示形参display
JDialog Error=new JDialog();
//设置弹框的大小
Error.setSize(300,300);
JLabel data=new JLabel(display);
data.setBounds(0,0,200,150);
Error.getContentPane().add(data);
Error.setTitle("提示");
//将弹框设置为界面顶置
Error.setAlwaysOnTop(true);
//初始位置为居中显示
Error.setLocationRelativeTo(null);
//将弹框设置为不关闭弹框无法操作其他界面
Error.setModal(true);
//将弹框显示方式设置为显示
Error.setVisible(true);
}
}
User类
package ui;
//用户类
public class User {
private String Name;
private String password;
public User() {
}
public User(String name, String password) {
this.Name = name;
this.password = password;
}
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
图片素材获取方式
方式1:访问黑马官网可下载:www.itheima.com?bz
方式2:关注黑马程序员公众号,回复关键词:领取资源02