📄 mainpanel.java
字号:
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.EventObject;
import java.awt.event.KeyEvent;
import javax.swing.*;
import sun.audio.AudioPlayer;
import sun.audio.AudioStream;
//有关与长宽都是正方形
public class MainPanel extends JPanel implements FiveChessConstants{
private int[][] occupyTable;
private int squareNum;
private int baseX;
private boolean keyEnable = false;
//多线程判断是否赢了时用到
private Chess blick;
private Chess mouseChess;
private int currentbaseX,currentbaseY;
//当前的棋子的坐标
private int currentXTable,currentYTable;
//胜利时候显示闪烁
private int[][]fiveChess;
private GameInfoPane info;
public MainPanel()
{
this.buildGUI();
}
private void hookEvent()
{
this.addMouseListener(new MouseAdapter(){
public void mouseClicked( MouseEvent e)
{
if(!MainPanel.this.keyEnable)
{
int x = e.getPoint().x;
int y = e.getPoint().y;
int rightLimit = HORI_SPACE+PANEL_WIDTH+CHESS_SQUARE/2;
if(x < baseX || x > rightLimit
|| y < baseX || y > rightLimit)
{
//JOptionPane.showMessageDialog(null,"out of space");
return;
}
//保存当前棋子的坐标,便于键盘事件的处理
currentXTable = ((int)x - HORI_SPACE + CHESS_SQUARE/2) / CHESS_SQUARE;
currentYTable = ((int)y - HORI_SPACE + CHESS_SQUARE/2) / CHESS_SQUARE;
//计算要画的棋子的左顶点
currentbaseX = HORI_SPACE - CHESS_SQUARE/2 +
currentXTable*CHESS_SQUARE + OFFSET;
currentbaseY = HORI_SPACE - CHESS_SQUARE/2 +
currentYTable*CHESS_SQUARE + OFFSET;
//保存当前鼠标下的棋子在数组中的位置,当作键盘下棋的起点
if(occupyTable[currentXTable][currentYTable] == EMPTY)
{
occupyTable[currentXTable][currentYTable] = RED;
drawChess(RED,currentbaseX,currentbaseY);
if(isWinner())
{
playSound(true,false);
winnerConfirm(false);
return ;
}
playSound(false,false);
MainPanel.this.drawBlickChess(BLACK,currentbaseX,currentbaseY);
info.changeInfo("键", "盘");
MainPanel.this.keyEnable = true;
}
}
}
});
this.addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e)
{
if(!MainPanel.this.keyEnable)
return;
boolean isDirection = true;
int keyType = e.getKeyCode();
switch(keyType)
{
case KeyEvent.VK_UP:
dealUp();
break;
case KeyEvent.VK_DOWN:
dealDown();
break;
case KeyEvent.VK_RIGHT:
dealRight();
break;
case KeyEvent.VK_LEFT:
dealLeft();
break;
case KeyEvent.VK_ENTER:
dealEnter();
isDirection = false;
break;
default:
isDirection = false;
break;
}
//公开操作 闪烁的棋子前进
if(isDirection)
if(blick != null)
blick.setLocation(currentbaseX, currentbaseY);
}
});
}
private void dealEnter()
{
int index = this.occupyTable[this.currentXTable][this.currentYTable];
if(index == EMPTY)
{
this.occupyTable[this.currentXTable][this.currentYTable] = BLACK;
if(blick != null)
blick.stopBlick();
if(isWinner())
{
this.playSound(true, true);
JOptionPane.showMessageDialog(this,"黑方赢了!");
this.winnerConfirm(true);
return ;
}
//鼠标事件能发生
this.playSound(false,false);
this.info.changeInfo("鼠", "标");
this.keyEnable = false;
}
}
private void dealUp()
{
int temp = this.currentYTable-1;
if(temp < 0)
return;
//画当前的棋子
//空则清除背景
this.dealOverPaint();
this.currentYTable--;
this.currentbaseY -= CHESS_SQUARE;
}
private void dealDown()
{
int temp = this.currentYTable + 1;
if(temp > squareNum)
return;
//画当前的棋子
//空则清除背景
this.dealOverPaint();
this.currentYTable++;
this.currentbaseY += CHESS_SQUARE;
}
private void dealRight()
{
int temp = this.currentXTable+1;
if(temp > squareNum)
return;
//画当前的棋子
//空则清除背景
this.dealOverPaint();
this.currentXTable++;
this.currentbaseX += CHESS_SQUARE;
}
private void dealLeft()
{
int temp = this.currentXTable-1;
if(temp < 0)
return;
//画当前的棋子
//空则清除背景
this.dealOverPaint();
this.currentXTable--;
this.currentbaseX -= CHESS_SQUARE;
}
//画当前的棋子
//空则清除背景
private void dealOverPaint()
{
if(this.occupyTable[this.currentXTable][this.currentYTable] != EMPTY)
{
int kind = this.occupyTable[this.currentXTable][this.currentYTable];
// 重画被覆盖的不闪烁的棋子
new Chess(kind,this).draw(this.currentbaseX,this.currentbaseY,false);
}
else
new Chess(RED,this).draw(this.currentbaseX,this.currentbaseY,true);
}
private void drawChess(int kind,int px,int py)
{
this.mouseChess = new Chess(kind,this);
this.mouseChess.draw(px,py,false);
//看清楚鼠标下的棋子
try{
Thread.sleep(250);
}catch(InterruptedException e)
{}
}
private void drawBlickChess(int kind,int px,int py)
{
blick = new Chess(kind,this);
blick.setLocation(px,py);
blick.drawBlick();
}
private void buildGUI()
{
this.setSize(700,700);
this.setBackground(Color.LIGHT_GRAY);
//能处理键盘事件
this.setVisible(true);
squareNum = PANEL_WIDTH/CHESS_SQUARE;
//初始化为0 为空表
this.occupyTable = new int[squareNum+1][squareNum+1];
this.baseX = HORI_SPACE - CHESS_SQUARE/4;
//显示信息面板
info = new GameInfoPane();
}
public GameInfoPane getInfoPane()
{
return this.info;
}
private boolean isWinner()
{
//检测横行
int steps = 0;
StringBuffer str = new StringBuffer();
int x = this.currentXTable;
int y = this.currentYTable;
int heng_Check_Index = x-4>=0?x-4:0;
while(steps < 10)
{
int index = heng_Check_Index+steps;
//越界限了
if(index > squareNum)
break;
int kind = this.occupyTable[index][y];
str.append(kind);
if(str.toString().contains("22222")
||str.toString().contains("11111"))
{
return true;
}
++steps;
}
//检测竖列
int shu_Check_Index = y-4>=0?y-4:0;
steps = 0;
str = new StringBuffer();
while(steps < 10)
{
int index = shu_Check_Index+steps;
//越界限了
if(index > squareNum)
break;
int kind = this.occupyTable[x][index];
str.append(kind);
if(str.toString().contains("22222")
||str.toString().contains("11111"))
{
return true;
}
++steps;
}
//检测米字的撇画
//for循环5次,说明偏移4
int offsetIndex =4;
steps = 0;
str = new StringBuffer();
for(int i =0; i < 5;++i)
{
if(x + i < squareNum && y-i >0)
continue;
offsetIndex = i;
break;
}
while(steps < 10)
{
int pieX_Check_Index = x + offsetIndex - steps;
int pieY_Check_Index = y - offsetIndex + steps;
//越界限了
if(pieX_Check_Index < 0 || pieY_Check_Index >squareNum)
break;
int kind = this.occupyTable[pieX_Check_Index][pieY_Check_Index];
str.append(kind);
if(str.toString().contains("22222")
||str.toString().contains("11111"))
{
// if(this.fiveChess == null)
// this.fiveChess = new int[2][5];
return true;
}
++steps;
}
//检测米字的捺画
offsetIndex =4;
steps = 0;
str = new StringBuffer();
for(int i =0; i < 5;++i)
{
if(x-i >0 && y-i >0)
continue;
offsetIndex = i;
break;
}
while(steps < 10)
{
int laX_Check_Index = x - offsetIndex + steps;
int laY_Check_Index = y - offsetIndex + steps;
//越界限了
if(laX_Check_Index >squareNum || laY_Check_Index >squareNum)
break;
int kind = this.occupyTable[laX_Check_Index][laY_Check_Index];
str.append(kind);
if(str.toString().contains("22222")
||str.toString().contains("11111"))
{
return true;
}
++steps;
}
return false;
}
private void playSound(boolean isWinner,boolean isBlack)
{
String fileName;
if(isWinner)
fileName = isBlack?BLACK_WIN:RED_WIN;
else
fileName = !this.keyEnable?RED_TURN:BLACK_TURN;
try{
InputStream in = new FileInputStream (new File(fileName));
AudioStream as = new AudioStream (in);
AudioPlayer.player.start(as);
}catch(Exception e)
{}
}
private void winnerConfirm(Boolean isBlack)
{
String name = isBlack?"黑":"红";
if(JOptionPane.YES_OPTION ==
JOptionPane.showConfirmDialog(this,name+
"方赢了!\n再来一局?","胜利了!",
JOptionPane.YES_NO_OPTION))
reStart();
else
{
this.info.changeInfo("启","动");
this.setEnabled(false);
}
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.RED);
for(int i =0; i <= this.squareNum; ++i)
{
int x = HORI_SPACE + i*CHESS_SQUARE;
g.drawLine(x, HORI_SPACE-CHESS_SIZE/2, x, HORI_SPACE+PANEL_WIDTH+CHESS_SIZE/2);
g.drawLine(HORI_SPACE-CHESS_SIZE/2,x,HORI_SPACE+PANEL_WIDTH+CHESS_SIZE/2,x);
}
g.dispose();
}
public void startGame()
{
this.setEnabled(true);
//键盘事件必需的设置
this.requestFocus();
info.changeInfo("鼠","标");
if(this.getKeyListeners().length == 0)
this.hookEvent();
this.reStart();
}
public void reStart()
{
//清空表格
this.occupyTable = new int[squareNum+1][squareNum+1];
//防止还在闪烁就重新开始啦
if(this.blick != null)
{
this.blick.stopBlick();
try{
Thread.sleep(250);
}catch(InterruptedException e)
{}
}
this.repaint();
this.keyEnable = false;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -