还是承接着上次的OX游戏,这次老师提的要求奇奇怪怪的,说实话真的挺费解的,但多读几遍以后要抓住几个关键点,“左上角”、“绘制”。看刚好学了paint嘛,所以,十有八九就是用paint()写啦。注意:paint()是自动执行的!!!也就是说你不用去调用它,它就会在你运行程序时自动在所在类的图层上画图!!
PS:本来还想把按钮改成保持数字不变的,但改起来太麻烦了,就没搞了。
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TestOXGame {
public static void main(String[] args) {
MyOXGame myoxgame=new MyOXGame();
}
}
class MyOXGame extends JFrame implements ActionListener {
//主体部分,绘制GUI,编辑有关响应
JButton[] button;//对象数组,表示棋盘上的九个格子
ChessPanel[] chessPanel;//小方格,放棋子的panel
JButton restart;//重置键
JLabel judgement;//裁判,用来显示游戏的结果
JPanel chessboard,basicPanel;//棋盘,棋盘下部区域
int player=0;//显示当前玩家编号
boolean gameOverFlag=false;//记录游戏是否结束,如果结束值为true,停止对事件的响应
MyOXGame(){//生成函数,生成游戏
setTitle("MY OXGAME");
setBounds(400,400,340,360);//窗体基本设置
button=new JButton[10];
chessPanel=new ChessPanel[10];
restart=new JButton("Restart");
chessboard=new JPanel();
basicPanel=new JPanel();
judgement=new JLabel("");
chessboard.setLayout(new GridLayout(3,3));
basicPanel.setLayout(new FlowLayout());//组件初始化设置
add(chessboard,BorderLayout.CENTER);
add(basicPanel,BorderLayout.SOUTH);
basicPanel.add(restart);
basicPanel.add(judgement);//布局设置
initChessboard();//初始化棋盘,使九个按钮按顺序加上1-9的标签,
addChessToChessboard(chessboard);//将九个按钮添加至chessboard
restart.addActionListener(this);//添加监听器
buttonListener();//为按钮添加监听器
setVisible(true);//设置可视化
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);//使关闭键有用
}
private void addChessToChessboard(JPanel chessboard){
//添加按钮至小方格
for(int i=1;i<=9;i++) {
chessboard.add(chessPanel[i]);
}
}
private void initChessboard(){
//使棋子按钮初始化为1-9
for(int i=1;i<=9;i++){
button[i]=new JButton( ""+i);
button[i].setSize(45,45);
chessPanel[i]=new ChessPanel();
chessPanel[i].setLayout(null);
chessPanel[i].setBorder(BorderFactory.createLineBorder(Color.black, 1));
chessPanel[i].add(button[i]);
}
}
private void buttonListener(){
//为棋子按钮添加监听器
for(int i=1;i<=9;i++)
{
button[i].addActionListener(this);
}
}
private void restartTheGame(){
//重置游戏
chessboard.removeAll();//必须于repaint和updateUI一起用不然要不啥都没有,要不没有改动
//必须注意removll会清空布局
chessboard.setLayout(new GridLayout(3,3));
initChessboard();
addChessToChessboard(chessboard);
buttonListener();
chessboard.updateUI();
chessboard.repaint();
judgement.setText("");
gameOverFlag=false;
}
private boolean checkDogfall(char[] chess){
//检查是否被填满,填满即为平局
for(int i=1;i='1'&&chess[i]<='9')
return false;
}
return true;
}
private int checkWinner(int playerNow) {
//检查当前游戏状态,-2表示没有决出胜负,-1表示平局。0表示O玩家胜利,1表示X玩家胜利
char[] chess=new char[10];
for(int i=1;i<=9;i++){
chess[i]=button[i].getLabel().charAt(0);
}
if( (chess[1]==chess[2]&&chess[2]==chess[3])||
(chess[4]==chess[5]&&chess[5]==chess[6])||
(chess[7]==chess[8]&&chess[8]==chess[9])||
(chess[1]==chess[5]&&chess[5]==chess[9])||
(chess[7]==chess[5]&&chess[5]==chess[3])||
(chess[1]==chess[4]&&chess[4]==chess[7])||
(chess[2]==chess[5]&&chess[5]==chess[8])||
(chess[3]==chess[6]&&chess[6]==chess[9])){
//判断当前玩家是否为赢家
return playerNow;
}
else if(checkDogfall(chess))
return -1;
return -2;
}
public class ChessPanel extends JPanel{
int paintCode=-1;//状态码,用来设置可见性及类型,-1表示不可见,0表示圈圈,1表示叉叉
public void paint(Graphics g) {
super.paint(g);
if(paintCode==0){
Graphics2D g_2D=(Graphics2D)g;
g_2D.setStroke(new BasicStroke(6.0f));
g.drawOval(43,43,23,23);//用笔画
//Image oo = new ImageIcon("src/oo.png").getImage();
//g.drawImage(oo,40,40,40,40,this);//用图画
}
else if(paintCode==1){
Image xx = new ImageIcon("src/xx.png").getImage();
g.drawImage(xx,43,43,25,25,this);//用图画
//g.drawLine(50,50,60,60);
//g.drawLine(50,60,60,50);//用笔画
}
}
}
@Override
public void actionPerformed(ActionEvent actionEvent) {
//对监听的事件进行响应
int statueCode;
int id;
JButton buttonSource=(JButton)actionEvent.getSource();
if(buttonSource==restart){
//判断是否使restart键,如果是,重置游戏
restartTheGame();
}
if (gameOverFlag==true) return;
String buttonMark=buttonSource.getLabel();
id=(int)(buttonMark.charAt(0)-'0');
if(buttonMark.matches("[0-9]")){
if(player==0){
//绘制o
buttonSource.setLabel("O");
chessPanel[id].paintCode=0;//更改状态码
repaint();//使所有chessPanel重绘
}
else{
//绘制x
buttonSource.setLabel("X");
chessPanel[id].paintCode=1;
repaint();
}
statueCode=checkWinner(player);
if(statueCode==0){
judgement.setText("Player O wins the game! ");
gameOverFlag=true;
}
else if(statueCode==1){
judgement.setText("Player X wins the game!");
gameOverFlag=true;
}
else if(statueCode==-1){
judgement.setText("The game a draw!");
}
player=(player+1)%2;//更换玩家
}
}
}
后记
本着互联网精神和大家交流一下经验啦,希望大家还是自己写一写,不要直接copy交作业影响我也影响你(你再怎么的把变量名改改嘛),这次的其他两个作业都挺好做的就不讲了!这道题废了不少时间,我查了好久才明白不能点一下直接画一个,找了半天绘制的坐标的原点是哪一个,走了不少绕路,相信大家看了我这篇博客可以省下不少时间吧。可以的话点个赞支持我一下?有问题可以评论哦~