一、目的和意义
1.制作一个五子棋小游戏。
2.通过参与此次游戏制作,巩固复习学习的java知识,并且将学习到的知识运用到实际的应用中。而且也学习到了一些新的java知识。
二、功能模块划分
1.用户登录
UI_Login.java文件
2.游戏运行
UI_Main.java文件
三.功能展示
1.Swing窗体的创建
运用JFame,JLable,JTextField,JButton;setLayout,setTitle,setBounds,setVisible等功能创建了窗体
JFrame login=new JFrame();
login.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
login.setLayout(null);//绝对定位
login.setTitle("这是一个登录窗体");
login.setBounds(400,100,600,400);
//文字标签
JLabel title=new JLabel("欢迎使用-豪富-五子棋");
title.setBounds(200, 50, 200, 20);
//将标签添加到窗体中
login.add(title);
JLabel jl_uname=new JLabel("用户名:");
jl_uname.setBounds(50, 100, 50, 20);
login.add(jl_uname);
JLabel jl_password=new JLabel("密码:");
jl_password.setBounds(50, 140, 50, 20);
login.add(jl_password);
//文本框
JTextField txt_username=new JTextField();
txt_username.setBounds(120, 100, 200, 20);
login.add(txt_username);
final JPasswordField txt_password=new JPasswordField();
txt_password.setBounds(120, 140, 200, 20);
login.add(txt_password);
final JButton ok=new JButton(" 登 录 ");
ok.setBounds(80, 200, 90, 30);
login.add(ok);
final JButton result=new JButton(" 重 置 ");
result.setBounds(220, 200, 90, 30);
login.add(result);
2.窗体登录
MouseListener,MouseEvent进行鼠标事件
//鼠标事件
ok.addMouseListener(new MouseAdapter() {
//鼠标按下事件
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下");
String uname=txt_username.getText();
String password=txt_password.getText();
System.out.println(uname+"\t"+password);
if("cyh".equals(uname) && "123456".equals(password)){
JOptionPane.showMessageDialog(null, "恭喜你,登录成功!","登录提示",JOptionPane.WARNING_MESSAGE);
login.setVisible(false);
UI_Main main=new UI_Main();
main.setVisible(true);
}else{
JOptionPane.showMessageDialog(null, "用户名或密码错误!","登录提示",JOptionPane.ERROR_MESSAGE);
}
}
});
result.addMouseListener(new MouseAdapter() {
//鼠标按下事件2
public void mousePressed(MouseEvent e) {
System.out.println("鼠标按下2");
String uname=txt_username.getText();
String password=txt_password.getText();
uname="";
password="";
JOptionPane.showMessageDialog(null, "恭喜你,重置成功");
}
});
login.setVisible(true);
3.棋盘和棋子的绘制(棋盘绘制,窗体的事件处理,棋子的绘制及美化,记录棋子位置以及控制棋子的下至相应位置)
//无参构造
private Image image;//设置窗体背景图片
private int mouseX;//获取鼠标在窗体的x坐标
private int mouseY;//获取鼠标在窗体的y坐标
private int index_x=0;
private int index_y=0;
//控制是否可以在棋盘上面下棋
private boolean start=false;
//记录棋子颜色
private boolean isBlack=false;
//二维数组 0 无棋子 1白 2 黑
int [][]allChess=new int[10][10];
Robot robot=new Robot();
//创建一个变量,存储下棋的棋子
int [] xpoint=new int[100];
int [] ypoint=new int[100];
//记下棋的次数步数
int count;
private Image black;
private Image white;
private Image rim;
//获取下棋的记录,将棋盘上的位置设置为0
public UI_Main() {
try {
black=ImageIO.read(new File("src/resource/black.png"));
white=ImageIO.read(new File("src/resource/white.png"));
rim = ImageIO.read(new File("src/resource/rim.png"));
} catch (IOException e) {
e.printStackTrace();
}
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("豪富专用---五子棋");
//获取屏幕分辨率
Dimension dimension=getToolkit().getDefaultToolkit().getScreenSize();
int width=dimension.width;
int height=dimension.height;
int win_width=800;
int win_height=600;
setBounds(width/2-win_width/2, height/2-win_height/2, win_width, win_height);
//设置背景图
//File类代表系统中的文件对象
File file=new File("src/resource/p1.jpg");
try {
image=ImageIO.read(file);
}catch (IOException e) {
e.printStackTrace();
}
//注册事件
this.addMouseListener(this);
//设置布局方式
this.setLayout(null);
//将jlable标签添加到窗体中,放置到指定位置,单击是将中间变量设置开始(true)
JLabel startGame=new JLabel();
startGame.setBounds(620, 215, 120, 50);
JLabel overGame=new JLabel();
overGame.setBounds(620, 480, 120, 50);
JLabel people=new JLabel();
people.setBounds(620, 281, 120, 50);
JLabel hqJLabel=new JLabel();
hqJLabel.setBounds(620, 350, 120, 50);
startGame.addMouseListener(new MouseListenerAwat() {
@Override
public void mousePressed(MouseEvent e) {
JOptionPane.showMessageDialog(null, "可以与人机进行对战了");
//内部类访问外部类的属性
UI_Main.this.start=true;
}
});
//将组件添加到窗体中
this.add(startGame);
this.add(overGame);
this.add(people);
this.add(hqJLabel);
4.与人机进行对战
将Robot代码引入UI_Main代码中,实现人机对战
// --------------人机对战----------------
robot.autoPlay(allChess);//将棋盘给机器人
int rb_x=robot.row;
int rb_y=robot.col;
this.allChess[rb_x][rb_y]=2;
allChess[index_x][index_y]=1;
this.index_x=rb_x;
this.index_y=rb_y;
this.xpoint[count]=index_x;
this.ypoint[count]=index_y;
count++;
5.如何判断输赢
五子棋获胜方式:横,纵五子,左右斜五子
public boolean checkWin() {
//当前下棋位置
//获取当前下棋颜色
int color=this.allChess[this.index_x][this.index_y];
int count=1;//储存当前棋子数量
int num=1;//记录坐标位置数量
// ------------水平 start---------------
while (this.index_x-num>=0&&color==this.allChess[this.index_x-num][this.index_y]) {
count++;
num++;
}
num=1;
while (this.index_x+num<10&&color==this.allChess[this.index_x+num][this.index_y]) {
count++;
num++;
}
if (count>=5) {
return true;
}
// ------------水平 end--------------
// ------------纵轴 start--------------
count=1;
num=1;
while (this.index_x+num<10&&color==this.allChess[this.index_x][this.index_y+num]) {
count++;
num++;
}
num=1;
while (this.index_x+num>=0&&color==this.allChess[this.index_x][this.index_y-num]) {
count++;
num++;
}
if (count>=5) {
return true;
}
// ------------纵轴 end--------------
// ------------左斜 start--------------
count=1;
num=1;
while (this.index_x+num<10&&this.index_y+num<10&&color==this.allChess[this.index_x+num][this.index_y+num]) {
count++;
num++;
}
num=1;
while (this.index_x+num>=0&& this.index_y-num>=0 &&color==this.allChess[this.index_x-num][this.index_y-num]) {
count++;
num++;
}
if (count>=5) {
return true;
}
// ------------左斜 end--------------
// ------------右斜 start--------------
count=1;
num=1;
while (this.index_x-num>=0&&this.index_y+num <10 &&color==this.allChess[this.index_x-num][this.index_y+num]) {
count++;
num++;
}
num=1;
while (this.index_x+num<10&& this.index_y-num>=0&&color==this.allChess[this.index_x+num][this.index_y+num]) {
count++;
num++;
}
if (count>=5) {
return true;
}
// ------------右斜 end--------------
return false;
}
主要使用if语句进行判断输赢
if (allChess[index_x][index_y]==0) {
allChess[index_x][index_y]=1;//已经下的棋子坐标
this.xpoint[count]=index_x;
this.ypoint[count]=index_y;
count++;
//判断是否获胜
if (checkWin()) {
JOptionPane.showMessageDialog(null, "恭喜臭宝儿,你获得胜利了");
}
//判断是否获胜
if (checkWin()) {
JOptionPane.showMessageDialog(null, "电脑赢了,你个傻der");
}
}else {
JOptionPane.showMessageDialog(null, "这有棋子啦");
}
System.out.println(index_x+"\t"+index_y);
//调节鼠标重绘功能
this.repaint();
}
6.添加棋子点击音乐和背景音乐
// 点击音乐
public void playMusic() {
new Thread() {
public void run() {
URL url=MusicDemo.class.getClass().getResource("src/resource/shake.wav");
AudioClip clip=Applet.newAudioClip(url);
clip.play();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
};
}.start();
}
// BGM 背景音乐
new Thread(){
public void run() {
URL url = MusicDemo.class.getClass().getResource("src/resource/kj.mp3");
AudioClip clip = Applet.newAudioClip(url);
clip.loop();
};
}.start();
}
7.悔棋
this.add(hqJLabel);
//悔棋
JLabel hp=new JLabel("悔棋");
hp.setBounds(620, 350, 120, 50);
hp.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (count==0) {
JOptionPane.showMessageDialog(null, "傻孩儿,你已无棋可悔");
return;
}
int x=xpoint[count-1];
int y=ypoint[count-1];
allChess[x][y]=0;
count--;
x=xpoint[count-1];
y=ypoint[count-1];
allChess[x][y]=0;
count--;
//调整窗体重绘功能
UI_Main.this.repaint();
}
});
this.add(hp);
}
四、项目演示
1.窗体登录
2.多人对战
3.人机对战
4.悔棋
五、遇到的问题和解决措施
1.棋子可以被覆盖的解决方法:
解决思路:用if语句判断,有棋子给出提示。
2.棋子在棋盘外显示的解决方法:
解决思路:设置边界坐标,点击边界外弹出窗体并提示且不会有棋子落下。
3.只能下一个棋子,无法储存棋子的解决方法:
解决思路:通过建立一个二维数组,二维数组元素默认值为0,下过棋子的用1赋值标记,然后对棋盘进行重绘。
4.悔棋的解决方法:
解决思路:引入新的变量记录棋子,一次悔棋悔两个棋子。
5.棋子在边缘处系统报错的解决方法:
解决思路:设置界限>=0或者<10方可落子
六、总结
1、计划做一个五子棋游戏小项目,旨在培养、增强中玩家进行五子棋游戏进行陶冶情操。项目的主要功能为登录、人机对战、多人游戏、悔棋。
2、对项目所用开发工具有了一定的了解,例如,二维数组的运用,for循环,if判断语句,面向对象,以及面向对象的全局变量和局部变量。
对项目所用开发工具和关键字符有了一定的了解,如:电脑的快捷键,以及eclipse快捷键的配置和使用。同时也学会了添加背景图片,配置背景音乐,打包,封装文件。