package org.vv.game.frame;
import java.awt.AWTException;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.Toolkit;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import org.vv.game.util.ExampleFileFilter;
import org.vv.game.util.ImageSelector;
import org.vv.game.util.ImageUtil;
import org.vv.game.vo.ImageSegment;
/**
* @author 俞立全 E-mail:vv_2048@163.com
* @version 创建时间:Feb 21, 2010 9:21:09 PM
* 类说明 拼图游戏
*/
@SuppressWarnings("serial")
// 取得屏幕的宽度
int screenWidth
= Toolkit.
getDefaultToolkit().
getScreenSize().
width;
// 取得屏幕的高度
int screenHeight
= Toolkit.
getDefaultToolkit().
getScreenSize().
height;
// 游戏网格设置
// 设置分割数量 2,3,4,5,6
int size = 3;
// 上边距
int top = 35;
// 左边距
int left = 13;
// 右边距
int right = 220;
// 下边距
int bottom = 13;
// 窗体可变参数,窗体放缩比例
int wSize = 400;
// 窗体的高度
int height = top + bottom + wSize; //400
// 窗体的宽度
int width = left + right + wSize; //510
//游戏区域
int wLength = width - left - right;
int hLength = height - top - bottom;
// 方格的长宽
int xLength = wLength / size;
int yLength = hLength / size;
// 背景图片
private final int smallImageWidth = 200;
private final int smallImageHeight = 200;
// 缩略图片
// 保持拼图板的位置
ImageSegment[][] allImages = new ImageSegment[size][size];
// 保存正确图版的位置
ImageSegment[][] allImagesTmp = new ImageSegment[size][size];
// 保存最多拥有多少时间(秒)
int maxTime = 60;
// 做倒计时的线程类
// 保存剩余时间
int remainingTime = 30;
// 提示
// 图片数量
int bkNum = 11;
// 游戏是否停止
boolean canPlay = true;
// 空白数字设置最后一块
int blankNum = size * size - 1;
// 空白块的数组编号
int blankImageX = 0;
int blankImageY = 0;
// 预设字体
//默认包中的图片
private String imagePackage
= "/image/def/";
//保存选择的图片路径
private String selFilePath
= null;
//判断选择图片还是目录
private boolean isDir = false;
//private String selDirPath = null;
//缩略图放大镜方块
private int magnifierX = 20;
private int magnifierY = 20;
private int magnifierWidth= 200;//smallImageWidth/2;
private int magnifierHeight = 200;//smallImageHeight/2;
private boolean showMagnifier = false;
// Font f2 = new Font("黑体", Font.BOLD, 80);
//private ImageIcon gifImage;
//三个按钮
public NineImageFrame() {
initialize();
}
public void initialize(){
// 设置标题
this.setTitle("拼图 vv_2048@163.com");
// 设置窗体大小
this.setSize(width, height);
// 设置窗体出现位置 居中显示
this.setLocation((screenWidth - width) / 2,
(screenHeight - height) / 2);
// 将窗体设置为大小可改变
//this.setResizable(true);
// 将窗体的关闭方式设置为默认关闭后程序结束
this.
setDefaultCloseOperation(JFrame.
EXIT_ON_CLOSE);
// 为窗体加入鼠标监听器
this.addMouseListener(this);
// 为窗体加入鼠标监听器
this.addMouseMotionListener(this);
// 为窗体加入键盘监听器
this.addKeyListener(this);
//添加 ComponentListener
this.addComponentListener(this);
// 加载背景图片
//String imagePath = "";
try {
bgImage = ImageIO.read(ImageSelector.getInstance().getRandomJarImage(this.getClass(),"/image/background/",12,"","gif"));
//按钮背景
btnImage[0] = ImageIO.read(getClass().getResource("/image/btn1.png"));
btnImage[1] = ImageIO.read(getClass().getResource("/image/btn2.png"));
btnImage[2] = ImageIO.read(getClass().getResource("/image/btn3.png"));
e.printStackTrace();
}
// 加载鼠标光标
/*
* Toolkit tk=Toolkit.getDefaultToolkit(); Image img=new
* ImageIcon(getClass().getResource("/image/point.jpg")).getImage();
* mouse.gif是你的图标 Cursor cu=tk.createCustomCursor(img,new
* Point(10,10),"stick"); this.setCursor(cu);
*/
try {
//随机图片
InputStream is
= ImageSelector.
getInstance().
getRandomJarImage(this.
getClass(),imagePackage,bkNum,
"bk",
"jpg");
// 初始化数据
this.initData(is);
is.close();
e.printStackTrace();
}
//gif动画
//gifImage = new ImageIcon(getClass().getResource("/image/121212.gif"));
// 将窗体显示出来
this.setVisible(true);
// 刷新屏幕,防止开始游戏时出现无法显示的情况.
// this.repaint();
}
height = this.getHeight();
width = this.getWidth();
xLength = (width - left - right) / size;
yLength = (height - top - bottom) / size;
// 双缓冲技术防止屏幕闪烁
g2.
setColor(Color.
BLACK);
// 绘制背景
if (bgImage != null) {
int imageWidth = bgImage.getWidth(this);
int imageHeight = bgImage.getHeight(this);
// 背景图片平铺
for (int ix = 0; ix < width; ix += imageWidth) {
for (int iy = 0; iy < height; iy += imageHeight) {
g2.drawImage(bgImage, ix, iy, this);
}
}
// System.out.println("image");
}
// 输出标题信息
// g2.setFont(new Font("黑体", Font.BOLD, 12));
// g2.drawString("游戏信息:", 130, 60);
// 绘制拼图图片
// g2.drawImage(segmentImage, left, top,200,100,100,100,200,200,this);
// 绘制缩略图
g2.drawImage(smallImage, width - left - right + 20, top,smallImageWidth,smallImageHeight, this);
g2.drawRect(width - left - right + 20, top, smallImageWidth, smallImageHeight);
// 绘制数据
//g2.setFont(f1);
// 获取字符串的高度和宽度
//FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(f1);
//int fh = fm.getHeight();
for (int i = 0; i < allImages.length; i++) {
for (int j = 0; j < allImages.length; j++) {
allImagesCopy[i][j]= ImageUtil.resize(allImages[i][j].getImage(), xLength, yLength,false);
if(allImages[i][j].isShow()){
g2.drawImage(allImagesCopy[i][j], i * xLength + left, j * yLength + top, this);
}
/*int fw = fm.stringWidth(String.valueOf(allImages[i][j].getId()));
g2.drawString(String.valueOf(allImages[i][j].getId()), i *
xLength + xLength / 2 + left - fw / 2, j * yLength + top +
yLength / 2 + fh / 2 - 10);*/
}
}
//重新开始按键区域
g2.drawRect(width - left - right + 20, top+smallImageHeight+10, smallImageWidth, 40);
//选择图片按键区域
g2.drawRect(width - left - right + 20, top+smallImageHeight+60, smallImageWidth, 40);
// 刷新
g2.drawRect(width - left - right + 20, top+smallImageHeight+110, smallImageWidth, 40);
// 绘制按钮
g2.drawImage(this.btnImage[0],width - left - right + 20,top+smallImageHeight+10,this);
g2.drawImage(this.btnImage[1],width - left - right + 20,top+smallImageHeight+60,this);
g2.drawImage(this.btnImage[2],width - left - right + 20,top+smallImageHeight+110,this);
// 在标题中显示剩余时间
this.setTitle("拼图 " + gameMessage);
//绘制放大镜
int wLength = width - left - right;
int hLength = height - top - bottom;
if(this.showMagnifier){
g2.drawRect(this.magnifierX, this.magnifierY, this.magnifierWidth, this.magnifierHeight);
g2.drawImage(this.magnifierBufferedImage, left, top,wLength,hLength, this);
}
// 绘制网格
for (int i = 0; i <= size; i++) {
g2.drawLine(left, top + yLength*i, width - right-1, top + yLength*i);
g2.drawLine(left + xLength * i,top, left + xLength * i, height - bottom-1);
}
//gif 动画测试
/*try {
g2.drawImage(ImageIO.read(getClass().getResource("/image/121212.gif")),50,50,200,200,this);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}*/
//g2.drawImage(gifImage.getImage(), 50,50, 200,200,this);
g.drawImage(bi, 0, 0, this);
}
//鼠标双击
if(e.getClickCount()==2){
}
//检测鼠标右键单击
if(e.isMetaDown()){
}
}
//System.out.println(e.getX());
}
}
@SuppressWarnings("deprecation")
if (canPlay && e.getX() >= left && e.getX() <= width-right && e.getY() >= top
&& e.getY() <= height) {
// 获取窗格相对坐标
int x = e.getX() - left;
int y = e.getY() - top;
// 计算数组序列
int ptX = x / xLength;
int ptY = y / yLength;
// 判断上下左右四个方向是否存在空砖块,假设9为空白。
ImageSegment tmp;
if (allImages[ptX][ptY].getId() != blankNum) {
// 上
if (y - yLength > 0
&& allImages[ptX][ptY - 1].getId() == blankNum) {
tmp = allImages[ptX][ptY];
allImages[ptX][ptY] = allImages[ptX][ptY - 1];
allImages[ptX][ptY - 1] = tmp;
// 保存空白块的位置
blankImageY = blankImageY + 1;
}
// 下
else if (yLength * size - y > yLength
&& allImages[ptX][ptY + 1].getId() == blankNum) {
tmp = allImages[ptX][ptY];
allImages[ptX][ptY] = allImages[ptX][ptY + 1];
allImages[ptX][ptY + 1] = tmp;
blankImageY = blankImageY - 1;
}
// 左
else if (x - xLength > 0
&& allImages[ptX - 1][ptY].getId() == blankNum) {
tmp = allImages[ptX][ptY];
allImages[ptX][ptY] = allImages[ptX - 1][ptY];
allImages[ptX - 1][ptY] = tmp;
blankImageX = blankImageX + 1;
}
// 右
else if (xLength * size - x > xLength
&& allImages[ptX + 1][ptY].getId() == blankNum) {
tmp = allImages[ptX][ptY];
allImages[ptX][ptY] = allImages[ptX + 1][ptY];
allImages[ptX + 1][ptY] = tmp;
blankImageX = blankImageX - 1;
}
// System.out.println(blankImageX + " : " + blankImageY);
}
// System.out.println(x + ":" + y +" "+ptX+" - "+ptY
// +" "+allImages[ptX][ptY]);
// JOptionPane.showMessageDialog(this, x + ":" + y
// +" "+ptX+" - "+ptY +" "+allImages[ptX][ptY]);
this.repaint();
this.verify();
}
int x1 = width - left - right + 20;
int y1 = top+smallImageHeight;
int x2 = x1 + smallImageWidth;
int y2 = y1 + 40;
if (e.getX() > x1 && e.getX() < x2 && e.getY()> y1 + 10 && e.getY() < y2 + 10) {
int result
= JOptionPane.
showConfirmDialog(this,
"是否重新开始游戏?");
if (result == 0) {
//随机图片
/*int num = this.getRandomNumber(bkNum) + 1;
InputStream is = NineImageFrame.class.getResourceAsStream("/image/"
+ "bk" + num + ".jpg");*/
try {
//随机背景
bgImage = ImageIO.read(ImageSelector.getInstance().getRandomJarImage(this.getClass(),"/image/background/",12,"","gif"));
is = ImageSelector.getInstance().getRandomJarImage(this.getClass(),imagePackage,bkNum,"bk","jpg");
this.initData(is);
is.close();
e1.printStackTrace();
}
remainingTime = maxTime;
this.canPlay = true;
this.repaint();
t.resume();
}
}
//自选图像
if (e.getX() > x1 && e.getX() < x2 && e.getY()> y1 + 60 && e.getY() < y2 + 60) {
jf.setDialogTitle("请选择图像文件...");
jf.
setFileSelectionMode(JFileChooser.
FILES_AND_DIRECTORIES);
ExampleFileFilter filter = new ExampleFileFilter();
filter.addExtension("jpg");
filter.addExtension("gif");
filter.addExtension("png");
filter.setDescription("JPG & GIF & PNG Images");
jf.setFileFilter(filter);
if(selFilePath == null || "".equals(selFilePath)){
jf.
setCurrentDirectory(new File("."));//设置当前目录
}else{
jf.
setCurrentDirectory(new File(selFilePath
));//设置之前选择的目录
}
int result = jf.showOpenDialog(this);
jf.setVisible(true);
File selectedFile
= null;
selectedFile = jf.getSelectedFile();
if (selectedFile.exists()) {
//随机背景
try {
bgImage = ImageIO.read(ImageSelector.getInstance().getRandomJarImage(this.getClass(),"/image/background/",12,"","gif"));
e2.printStackTrace();
e2.printStackTrace();
}
if(selectedFile.isDirectory()){
try {
selFilePath = selectedFile.getAbsolutePath();
InputStream is
= ImageSelector.
getInstance().
getRandomImage(selectedFile
);
this.initData(is);
is.close();
e1.printStackTrace();
}
isDir = true;
}
if(selectedFile.isFile()){
try {
selFilePath = selectedFile.getAbsolutePath();
this.initData(is);
is.close();
e1.printStackTrace();
e1.printStackTrace();
}
isDir = false;
}
remainingTime = maxTime;
this.canPlay = true;
this.repaint();
t.resume();
} else {
System.
out.
println("No! You did not select the right file.");
}
System.
out.
println("Cancel button is pushed.");
System.
err.
println("Error when select file.");
}
}
// 刷新
if (e.getX() > x1 && e.getX() < x2 && e.getY()> y1 + 110 && e.getY() < y2 + 110) {
if(isDir){
if(selFilePath!=null && !"".equals(selFilePath)){
int result
= JOptionPane.
showConfirmDialog(this,
"是否更更换拼图?");
if (result == 0) {
try {
//随机背景
bgImage = ImageIO.read(ImageSelector.getInstance().getRandomJarImage(this.getClass(),"/image/background/",12,"","gif"));
is
= ImageSelector.
getInstance().
getRandomImage(new File(selFilePath
));
this.initData(is);
is.close();
remainingTime = maxTime;
this.canPlay = true;
this.repaint();
t.resume();
e1.printStackTrace();
e1.printStackTrace();
}
}
}
else{
}
}else{
}
}
}
if(this.showMagnifier){
this.showMagnifier = false;
repaint();
}
}
/**
* 初始化拼图数组序列
*/
remainingTime = maxTime;
int a = 0;
for (int i = 0; i < allImages.length; i++) {
for (int j = 0; j < allImages.length; j++) {
allImagesTmp[j][i] = new ImageSegment();
allImagesTmp[j][i].setId(a++);
}
}
// 产生随机序列
// i/y 基数递增函数
// i%y 0-y范围循环
int[] rand = ImageSelector.getInstance().getRandoms(size * size);
for (int i = 0; i < rand.length; i++) {
allImages[i / size][i % size] = new ImageSegment();
allImages[i / size][i % size].setId(rand[i] - 1);
// getRandoms 生成的随机数是从1开始的,所有 bis[] 需要减一
allImages[i / size][i % size].setImage(bis[rand[i] - 1]);
// 获取空白的特殊块的信息
if (rand[i]-1 == this.blankNum) {
blankImageX = i / size;
blankImageY = i % size;
allImages[i / size][i % size].setShow(false);
}
}
}
@SuppressWarnings("deprecation")
public void run() {
// 判断是否有时间限制
if (maxTime > 0) {
while (true) {
remainingTime--;
if (remainingTime == 0) {
this.canPlay = false;
t.suspend();
remainingTime = -1;
}
gameMessage = remainingTime / 3600 + ":"
+ (remainingTime / 60 - remainingTime / 3600 * 60)
+ ":" + (remainingTime - remainingTime / 60 * 60);
this.repaint();
if (t.isAlive()) {
try {
e.printStackTrace();
}
}
// System.out.println(remainingTime);
}
}
}
/**
* 判断数组拼图是否正确
*
* @return
*/
@SuppressWarnings("deprecation")
public void verify() {
boolean rt = true;
for (int i = 0; i < allImagesTmp.length; i++) {
for (int j = 0; j < allImagesTmp[i].length; j++) {
if (allImagesTmp[j][i].getId() != allImages[j][i].getId()) {
rt = false;
break;
} else {
rt = true;
}
}
if (!rt) {
break;
}
}
if (rt) {
this.canPlay = false;
allImages[blankImageY][blankImageX].setShow(true);
t.suspend();
}
}
/**
* 把图片分割多少行多少列的
*
* @param imageName
* @param size
* @return
*/
try {
scalesBufferedImage = ImageUtil.resize(ImageIO.read(is), wLength, hLength,false);
// 创建缩略图片
smallImage = scalesBufferedImage;
/*smallImage = ImageUtil.resize(scalesBufferedImage, smallImageWidth,
smallImageHeight,false);*/
e1.printStackTrace();
}
for (int i = 0; i < size * size; i++) {
* yLength , xLength-1, yLength);
//如果图片长700/3,可能出错,xLength-1
bi = scalesBufferedImage.getSubimage(rect.x, rect.y,
rect.width, rect.height);
bis[i] = bi;
}
try {
is.close();
e.printStackTrace();
}
return bis;
}
// 键盘事件
@Override
ImageSegment tmp;
switch (e.getKeyCode()) {
case 37:
// 方向键 左
if (blankImageX < size - 1) {
tmp = allImages[blankImageX][blankImageY];
allImages[blankImageX][blankImageY] = allImages[blankImageX + 1][blankImageY];
allImages[blankImageX + 1][blankImageY] = tmp;
// 保存空白块位置
blankImageX = blankImageX + 1;
// System.out.println(blankImageX + " : " + blankImageY);
}
break;
case 38:
// 方向键 上
if (blankImageY < size - 1) {
tmp = allImages[blankImageX][blankImageY];
allImages[blankImageX][blankImageY] = allImages[blankImageX][blankImageY + 1];
allImages[blankImageX][blankImageY + 1] = tmp;
// 保存空白块位置
blankImageY = blankImageY + 1;
// System.out.println(blankImageX + " : " + blankImageY);
}
break;
case 39:
// 方向键 右
if (blankImageX > 0) {
tmp = allImages[blankImageX][blankImageY];
allImages[blankImageX][blankImageY] = allImages[blankImageX - 1][blankImageY];
allImages[blankImageX - 1][blankImageY] = tmp;
// 保存空白块位置
blankImageX = blankImageX - 1;
// System.out.println(blankImageX + " : " + blankImageY);
}
break;
case 40:
// 方向键 下
if (blankImageY > 0) {
tmp = allImages[blankImageX][blankImageY];
allImages[blankImageX][blankImageY] = allImages[blankImageX][blankImageY - 1];
allImages[blankImageX][blankImageY - 1] = tmp;
// 保存空白块位置
blankImageY = blankImageY - 1;
// System.out.println(blankImageX + " : " + blankImageY);
}
break;
}
this.repaint();
this.verify();
}
@Override
}
@Override
}
/**
* 鼠标拖动
*/
@Override
int x1 = width - left - right + 20;
int y1 = top;
int x2 = x1 + smallImageWidth;
int y2 = y1 + smallImageHeight;
if(e.getX()> x1 && e.getX()< x2 && e.getY()> y1 && e.getY() < y2){
this.magnifierX = e.getX()-magnifierWidth/2;
this.magnifierY = e.getY()-magnifierHeight/2;
try {
// TODO Auto-generated catch block
e1.printStackTrace();
}
this.
magnifierBufferedImage = robot.
createScreenCapture(new Rectangle(e.
getXOnScreen()-magnifierWidth
/2, e.
getYOnScreen()-magnifierHeight
/2, magnifierWidth, magnifierHeight
));
/*this.magnifierBufferedImage = this.smallImage.getSubimage(magnifierX, magnifierY,
magnifierWidth, magnifierHeight);*/
this.showMagnifier = true;
repaint();
}
}
/**
* 鼠标移动
*/
@Override
}
@Override
// TODO Auto-generated method stub
}
@Override
// TODO Auto-generated method stub
}
@Override
int width = e.getComponent().getWidth();
int height = e.getComponent().getHeight();
xLength = (width - left - right) / size;
yLength = (height - top - bottom) / size;
if (xLength < 120 || yLength < 120) {
// 窗体的高度
height = top + bottom + 120*size; //400
// 窗体的宽度
width = left + right + 120*size; //510
}
setSize(width, height);
}
@Override
// TODO Auto-generated method stub
}
}