一、双缓冲
当数据量很大时,绘图可能需要几秒钟甚至更长的时间,而且有时还会出现闪烁现象,为了解决这些问题,可采用双缓冲技术来绘图。
双缓冲即在内存中创建一个与屏幕绘图区域一致的对象,先将图形绘制到内存中的这个对象上,再一次性将这个对象上的图形拷贝到屏幕上,这样能大大加快绘图的速度。
BufferImage为image的直接子类,增加了缓冲功能。BufferedImage生成的图片在内存里有一个图像缓冲区,利用这个缓冲区我们可以很方便的操作这个图片,通常用来做图片修改操作如大小变换、图片变灰、设置图片透明或不透明等。
BufferedImage bufferedImage = ImageIO.read(new FileInputStream(filePath));
二、 代码实现
package org.like.game.frame;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
public class FiveChessFrame extends JFrame implements MouseListener
{
int width = Toolkit.getDefaultToolkit().getScreenSize().width;
int height = Toolkit.getDefaultToolkit().getScreenSize().height;
BufferedImage bgImage = null;
int x = 0;
int y = 0;
int[][] allChess = new int[19][19];
boolean isBlack = true;
boolean canPlay = true;
String message = "黑方先行";//提示信息
public FiveChessFrame()
{
this.setTitle("五子棋");
this.setSize(500,500);
this.setLocation((width-500)/2,(height-500)/2);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.addMouseListener(this);
try
{
bgImage = ImageIO.read(new File("F:/mypicture/java/background.jpg"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
public void paint(Graphics g)
{//建立一个缓冲图对象,选择RGB模式
BufferedImage bi = new BufferedImage(500, 500, BufferedImage.TYPE_INT_RGB);
Graphics g2 = bi.createGraphics();//通过bi实例化Graphics类
g2.setColor(Color.BLACK);//设置颜色
g2.drawImage(bgImage,3,20,this);//以下都是把内容先画到bi的缓冲区中
g2.setFont(new Font("黑体",Font.BOLD,20));
g2.drawString("游戏信息:"+message, 150, 50);//提示该哪边下棋
g2.setFont(new Font("宋体",0,14));
g2.drawString("黑方时间:无限制", 45, 470);
g2.drawString("白方时间:无限制", 260, 470);
for(int i=0;i<19;i++)
{
g2.drawLine(13, 70+20*i, 372, 70+20*i);
g2.drawLine(13+20*i,70,13+20*i,430);
}
g2.fillOval(71, 128, 4, 4);
g2.fillOval(311, 128, 4, 4);
g2.fillOval(311, 368, 4, 4);
g2.fillOval(71, 368, 4, 4);
g2.fillOval(311, 248, 4, 4);
g2.fillOval(191, 128, 4, 4);
g2.fillOval(71, 248, 4, 4);
g2.fillOval(191, 368, 4, 4);
g2.fillOval(191, 248, 4, 4);
for(int i=0;i<19;i++)
{
for(int j=0;j<19;j++)
{
if(allChess[i][j] == 1)
{
x = i * 20 + 13;
y = j * 20 + 70;
g2.fillOval(x-7, y-7, 14, 14);
}
if(allChess[i][j] == 2)
{
x = i * 20 + 13;
y = j * 20 + 70;
g2.setColor(Color.WHITE);
g2.fillOval(x-7, y-7, 14, 14);
g2.setColor(Color.BLACK);
g2.drawOval(x-7, y-7, 14, 14);
}
}
}
g.drawImage(bi, 0, 0, this);//将bi缓冲区中的内容一次性画到(this)当前窗口
}
@Override
public void mouseClicked(MouseEvent e)
{
}
@Override
public void mousePressed(MouseEvent e)
{
if(canPlay == true)
{
x = e.getX();
y = e.getY();
if(x >= 13 && x <= 372 && y >= 70 && y <= 430)
{
x = (x - 13) / 20;
y = (y - 70) / 20;
if(allChess[x][y] == 0)
{
if(isBlack)
{
allChess[x][y] = 1;
isBlack = false;
message = "轮到白方下棋";
}
else
{
allChess[x][y] = 2;
isBlack = true;
message = "轮到黑方下棋";
}
this.repaint();
boolean winFlag = this.checkWin();
if(winFlag == true)
{
JOptionPane.showMessageDialog(this, "游戏结束"+(allChess[x][y] == 1?"黑方":"白棋")+"获胜!");
canPlay = false;
}
}
else
{
JOptionPane.showMessageDialog(this, "当前位置已经有棋子了,请重新落子!");
}
}
}
}
@Override
public void mouseReleased(MouseEvent e)
{
}
@Override
public void mouseEntered(MouseEvent e)
{
}
@Override
public void mouseExited(MouseEvent e)
{
}
public static void main(String[] args)
{
FiveChessFrame ff = new FiveChessFrame();
}
private boolean checkWin()
{
boolean flag = false;
int count = 1;
int color = allChess[x][y];
count = this.checkCount(1, 0, color);
if (count >= 5)
{
flag = true;
}
else
{
// 判断纵向
count = this.checkCount(0, 1, color);
if (count >= 5)
{
flag = true;
}
else
{
// 判断右上、左下
count = this.checkCount(1, -1, color);
if (count >= 5)
{
flag = true;
}
else
{
// 判断右下、左上
count = this.checkCount(1, 1, color);
if (count >= 5)
{
flag = true;
}
}
}
}
return flag;
}
private int checkCount(int xChange, int yChange, int color)
{
int count = 1;
int tempX = xChange;
int tempY = yChange;
while (x + xChange >= 0 && x + xChange <= 18 && y + yChange >= 0&& y + yChange <= 18
&& color == allChess[x + xChange][y + yChange])
{
count++;
if (xChange != 0)
xChange++;
if (yChange != 0) {
if (yChange > 0)
yChange++;
else {
yChange--;
}
}
}
xChange = tempX;
yChange = tempY;
while (x - xChange >= 0 && x - xChange <= 18 && y - yChange >= 0&& y - yChange <= 18
&& color == allChess[x - xChange][y - yChange])
{
count++;
if (xChange != 0)
xChange++;
if (yChange != 0) {
if (yChange > 0)
yChange++;
else {
yChange--;
}
}
}
return count;
}
}
三、
效果展示