⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mainpanel.java

📁 实现人和人对战的五子棋
💻 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 + -