public static final int FRAME_TITLE_PANEL_HEIGHT = 65;
public static int FRAME_MENU_PANEL_HEIGHT = 65;
public static final int RECTANGLE_STANDARD_ROWS = 4; public static final int RECTANGLE_STANDARD_COLS = 4; public static final String STRING_FONT = "Courier New";
public static int blockWidth = 10;
public static int blockHeight = 10;
private static HashMap<String,String> parametersMap = new HashMap<String,String>();
public static int blockCountOfX = 10; public static int blockCountOfY = 20;
public static int initSpeed = 30;
/** * */ public static HashMap<String,String> readConfigFile(String configFileName) { HashMap<String,String> parametersMap = new HashMap<String,String>(); BufferedReader fileReader = null; try { fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(configFileName)));
String line = fileReader.readLine(); int lineIndex = 1;
while (line != null) { line = line.trim(); // 略过注释 if (!line.equals("") && !line.startsWith("//") && !line.startsWith("#")) { int equalPos = line.indexOf("="); String name = line; String value = line; if (equalPos != -1) { name = line.substring(0,equalPos).trim(); value = line.substring(equalPos + 1).trim();
if (value != null && !value.equals("")) { parametersMap.put(name, value); } } lineIndex++; } line = fileReader.readLine(); }
innerX = x; innerY = y; innerWidth = width; innerHeight = height; } /** * @return the height */ public int getHeight() { return height; } /** * @param height the height to set */ public void setHeight(int height) { this.height = height; } /** * @return the width */ public int getWidth() { return width; } /** * @param width the width to set */ public void setWidth(int width) { this.width = width; } /** * @return the x */ public int getX() { return x; } /** * @param x the x to set */ public void setX(int x) { this.x = x; } /** * @return the y */ public int getY() { return y; } /** * @param y the y to set */ public void setY(int y) { this.y = y; } /** * @param graph */ public void drawArea(Graphics graph) { graph.setColor(areaColor ); graph.drawRect(x,y,width,height); drawed = true; } /** * @param graph */ public void clearArea(Graphics graph) { graph.clearRect(innerX,innerY,innerWidth,innerHeight); } }package cross.pauliuyou.block.graph;import java.awt.Component; import java.util.Date; import java.util.HashMap;import javax.swing.JOptionPane;/** * 弹出报警窗口.同一标题的窗口只能弹出一次,关闭以后才可以再弹出 * @author 刘优 * @version 1.0 */ public class MsgBox {
private static HashMap<String,Boolean> isWindowShowingMap = new HashMap<String,Boolean>();
package cross.pauliuyou.block.graph;import java.awt.Dimension; import java.awt.Frame; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.Window; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.lang.reflect.Method;import javax.swing.JDialog; import javax.swing.JFrame;/** * 窗口显示调整工具 * @author 刘优 * @version 1.0 */public class WindowUtil { /** * Positions the specified frame in the middle of the screen. * * @param frame the frame to be centered on the screen. */ public static void centerFrameOnScreen(final Window frame) { positionFrameOnScreen(frame, 0.5, 0.5); } /** * Positions the specified frame at a relative position in the screen, where 50% is considered * to be the center of the screen. * * @param frame the frame. * @param horizontalPercent the relative horizontal position of the frame (0.0 to 1.0, * where 0.5 is the center of the screen). * @param verticalPercent the relative vertical position of the frame (0.0 to 1.0, where * 0.5 is the center of the screen). */ public static void positionFrameOnScreen(final Window frame, final double horizontalPercent, final double verticalPercent) { final Rectangle s = getMaximumWindowBounds(); final Dimension f = frame.getSize(); final int w = Math.max(s.width - f.width, 0); final int h = Math.max(s.height - f.height, 0); final int x = (int) (horizontalPercent * w) + s.x; final int y = (int) (verticalPercent * h) + s.y; frame.setBounds(x, y, f.width, f.height); }
/** * Computes the maximum bounds of the current screen device. If this method is called on JDK 1.4, Xinerama-aware * results are returned. (See Sun-Bug-ID 4463949 for details). * * @return the maximum bounds of the current screen. */ public static Rectangle getMaximumWindowBounds () { final GraphicsEnvironment localGraphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment(); try { final Method method = GraphicsEnvironment.class.getMethod("getMaximumWindowBounds", (Class[]) null); return (Rectangle) method.invoke(localGraphicsEnvironment, (Object[]) null); } catch(Exception e) { // ignore ... will fail if this is not a JDK 1.4 .. }
final Dimension s = Toolkit.getDefaultToolkit().getScreenSize(); return new Rectangle (0, 0, s.width, s.height); } public static void fullScreenFrame(Window window) { java.awt.Dimension dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize(); window.setSize(dimension.width, dimension.height - 30); if (window instanceof Frame) ((Frame)window).setExtendedState(Frame.MAXIMIZED_BOTH); window.setLocation(0, 0); }
/** * 居中显示窗口 * @param w */ public static void doView(Window w) {
/** * 居中显示窗口 * @param w * @param width * @param height */ public static void doView(Window w,int width,int height) { w.setSize(width,height); int width2 = w.getToolkit().getScreenSize().width; width2 = (width2 - w.getWidth()) / 2; int height2 = w.getToolkit().getScreenSize().height; height2 = (height2 - w.getHeight()) / 2; w.setLocation(width2,height2); w.setVisible(true); if (w.getClass() == JFrame.class) { ((JFrame)w).setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ((JFrame)w).setResizable(false); } /* if (w.getClass() == JDialog.class) { ((JDialog)w).setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE); ((JDialog)w).setResizable(false); } */ } /** * 设置窗口关闭 * @param w 窗口 */ public static void doClose(Window w) { final Window w2 = w; w.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent we) { w2.dispose(); } }); } }
/** * */ package cross.pauliuyou.block.graph;import java.awt.Color; import java.awt.Graphics;import cross.pauliuyou.block.api.Drawable; import cross.pauliuyou.block.api.Movable; import cross.pauliuyou.block.common.ConfigUtil; import cross.pauliuyou.block.common.RandomProducer;/** * 方块类, 是组成矩阵的基本元素,每个方块都可以移动并自我绘制 * @author 刘优 * */ public class Block implements Drawable,Movable { /** * 方块宽度 */ public static final int BLOCK_WIDTH = ConfigUtil.blockWidth;
/** * 方块高度 */ public static final int BLOCK_HEIGHT = ConfigUtil.blockHeight;
/** * 向上移动 */ public static final int MOVE_UP = 0;
/** * 向下移动 */ public static final int MOVE_DOWN = 1; public static final int MOVE_LEFT = 2; public static final int MOVE_RIGHT = 3;
protected static int defaultXStep = BLOCK_WIDTH; protected static int defaultYStep = BLOCK_HEIGHT;
protected int x; protected int y;
protected Graphics graphics; protected Color blockColor; protected Color displayColor; protected WorkArea workArea;
protected RandomProducer countRandom = new RandomProducer(8,3); protected RandomProducer directionRandom = new RandomProducer(4); protected int stepCount; protected int moveDirection;
} /* (non-Javadoc) * @see cross.pauliuyou.block.api.Movable#moveAngle(int, double) */ public void moveAngle(int step, double angle) { // TODO Auto-generated method stub
}
/** * @return the blockColor */ public Color getBlockColor() { return blockColor; } /** * @param blockColor the blockColor to set */ public void setBlockColor(Color blockColor) { this.blockColor = blockColor; } /** * @return the graphics */ public Graphics getGraphics() { return graphics; } /** * @param graphics the graphics to set */ public void setGraphics(Graphics graphics) { this.graphics = graphics; } /** * @return the workArea */ public WorkArea getWorkArea() { return workArea; } /** * @param workArea the workArea to set */ public void setWorkArea(WorkArea workArea) { this.workArea = workArea; } /** * @return the x */ public int getX() { return x; } /** * @param x the x to set */ public void setX(int x) { this.x = x; } /** * @return the y */ public int getY() { return y; } /** * @param y the y to set */ public void setY(int y) { this.y = y; } /** * @return the displayColor */ public Color getDisplayColor() { return displayColor; } /** * @param displayColor the displayColor to set */ public void setDisplayColor(Color displayColor) { this.displayColor = displayColor; } /** * @return the moveDirection */ public int getMoveDirection() { return moveDirection; } /** * @param moveDirection the moveDirection to set */ public void setMoveDirection(int moveDirection) { this.moveDirection = moveDirection; } /** * @return the stepCount */ public int getStepCount() { return stepCount; } /** * @param stepCount the stepCount to set */ public void setStepCount(int stepCount) { this.stepCount = stepCount; } /** * @return the tableIndexes */ public int[] getTableIndexes() { return tableIndex; } /** * @param tableIndexes the tableIndexes to set */ public void setTableIndexes(int[] tableIndexes) { this.tableIndex = tableIndexes; } /** * @return the toMoveDown */ public boolean isToMoveDown() { return toMoveDown; } /** * @param toMoveDown the toMoveDown to set */ public void setToMoveDown(boolean toMoveDown) { this.toMoveDown = toMoveDown; } /** * @return the toMoveLeft */ public boolean isToMoveLeft() { return toMoveLeft; } /** * @param toMoveLeft the toMoveLeft to set */ public void setToMoveLeft(boolean toMoveLeft) { this.toMoveLeft = toMoveLeft; } /** * @return the toMoveRight */ public boolean isToMoveRight() { return toMoveRight; } /** * @param toMoveRight the toMoveRight to set */ public void setToMoveRight(boolean toMoveRight) { this.toMoveRight = toMoveRight; } /** * @return the toMoveUp */ public boolean isToMoveUp() { return toMoveUp; } /** * @param toMoveUp the toMoveUp to set */ public void setToMoveUp(boolean toMoveUp) { this.toMoveUp = toMoveUp; } /** * @return the owner */ public BlockMartix getOwner() { return owner; } /** * @param owner the owner to set */ public void setOwner(BlockMartix owner) { this.owner = owner; } }
/** * */ package cross.pauliuyou.block.graph;import java.awt.Color; import java.awt.Graphics;/** * @author Administrator * */ public class RectangleBlock extends Block { /** * @param graphics * @param workArea * @param blockColor * @param x * @param y */ public RectangleBlock(Graphics graphics, WorkArea workArea, Color blockColor, int x, int y) { super(graphics, workArea, blockColor, x, y); } /* (non-Javadoc) * @see cross.pauliuyou.block.api.Drawable#drawMe() */ @Override public void drawMeNoRect() { if (visible) { graphics.setColor(displayColor); graphics.fillRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT); } }
/* (non-Javadoc) * @see cross.pauliuyou.block.api.Drawable#drawMe() */ public void drawMe() { if (visible) { graphics.setColor(Color.gray); graphics.drawRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT); graphics.setColor(displayColor); graphics.fillRect(x + 1, y + 1, BLOCK_WIDTH - 1, BLOCK_HEIGHT - 1); } } }
/** * */ package cross.pauliuyou.block.graph;import java.awt.Color; import java.awt.Graphics;import cross.pauliuyou.block.api.Drawable; import cross.pauliuyou.block.api.Movable; import cross.pauliuyou.block.api.Rotatable; import cross.pauliuyou.block.common.ConfigUtil; import cross.pauliuyou.block.common.RandomProducer;/** * @author 刘优 * */ public class BlockMartix implements Movable,Drawable,Rotatable { protected int rows = ConfigUtil.RECTANGLE_STANDARD_ROWS; protected int cols = ConfigUtil.RECTANGLE_STANDARD_COLS;
protected Block[][] blockTable = new Block[rows][cols];
private RandomProducer random0 = new RandomProducer(230,5);
private RandomProducer random1 = new RandomProducer(8,5);
private RandomProducer random2 = new RandomProducer(4);
protected WorkArea workArea;
protected Color color;
protected int stepCount; protected int moveDirection; protected int initX; protected int initY; protected Block leftTopBlock; protected Graphics graphics;
/** * */ protected void createMatrix(Color color) { int x = initX; int y = initY;
int blue = 10; int green = 10; int red = 10; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { Color tmpColor = color; if (color == null) { tmpColor = new Color(red,green,blue); } Block block = new RectangleBlock(graphics,workArea,tmpColor,x,y); block.setOwner(this); block.tableIndex = new int[]{i,j};
blockTable[i][j] = block;
blue = random0.getInt(); green = random0.getInt(); red = random0.getInt();
x += Block.BLOCK_WIDTH; } x = initX; y += Block.BLOCK_HEIGHT; } leftTopBlock = blockTable[0][0]; } /* (non-Javadoc) * @see cross.pauliuyou.block.api.Movable#moveUp() */ public void moveUp() { moveUp(Block.defaultYStep);
/**
*
*/
package cross.pauliuyou.block.api;/**
* @author 刘优
*
*/
public interface Drawable
{
public void clearMe();
public void drawMe();
}/**
*
*/
package cross.pauliuyou.block.api;/**
* @author 刘优
*
*/
public interface Movable
{
public void moveUp();
public void moveDown();
public void moveLeft();
public void moveRight();
public void moveUp(int step);
public void moveDown(int step);
public void moveLeft(int step);
public void moveRight(int step);
public void moveAngle(double angle);
public void moveAngle(int step,double angle);
public void wander();
}/**
*
*/
package cross.pauliuyou.block.api;/**
* @author 刘优
*
*/
public interface Rotatable
{
public void clockRotate();
public void deClockRotate();
}/**
*
*/
package cross.pauliuyou.block.common;import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;import cross.pauliuyou.block.graph.MsgBox;/**
* @author 刘优
*
*/
public class ConfigUtil
{
private static final String CONFIG_FILE_NAME = "BlockConfig";
public static final int FRAME_TITLE_PANEL_HEIGHT = 65;
public static int FRAME_MENU_PANEL_HEIGHT = 65;
public static final int RECTANGLE_STANDARD_ROWS = 4; public static final int RECTANGLE_STANDARD_COLS = 4; public static final String STRING_FONT = "Courier New";
public static int blockWidth = 10;
public static int blockHeight = 10;
private static HashMap<String,String> parametersMap = new HashMap<String,String>();
public static int blockCountOfX = 10; public static int blockCountOfY = 20;
public static int initSpeed = 30;
/**
*
*/
public static HashMap<String,String> readConfigFile(String configFileName)
{
HashMap<String,String> parametersMap = new HashMap<String,String>();
BufferedReader fileReader = null;
try
{
fileReader = new BufferedReader(new InputStreamReader(new FileInputStream(configFileName)));
String line = fileReader.readLine();
int lineIndex = 1;
while (line != null)
{
line = line.trim();
// 略过注释 if (!line.equals("") && !line.startsWith("//") && !line.startsWith("#"))
{
int equalPos = line.indexOf("=");
String name = line;
String value = line;
if (equalPos != -1)
{
name = line.substring(0,equalPos).trim();
value = line.substring(equalPos + 1).trim();
if (value != null && !value.equals(""))
{
parametersMap.put(name, value);
}
}
lineIndex++;
}
line = fileReader.readLine();
}
fileReader.close();
}
catch (Exception e)
{
MsgBox.error("未找到配置文件[" + configFileName + "]!");
}
return parametersMap;
} /**
* @param configFileName
* @param parametersMap
*/
public static void writeConfigFile(String configFileName, HashMap<String, String> parametersMap)
{
if (parametersMap == null)
{
return;
}
try
{
PrintWriter fileWriter = new PrintWriter(new OutputStreamWriter(new FileOutputStream(configFileName)));
Iterator<String> it = parametersMap.keySet().iterator();
while (it.hasNext())
{
String key = it.next();
String value = parametersMap.get(key);
if (value == null)
{
value = "";
}
fileWriter.println(key + " = " + value);
}
fileWriter.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
/**
*
*/
public static void config()
{
File configFile = new File(CONFIG_FILE_NAME);
if (!configFile.exists() || configFile.length() == 0)
{
try
{
configFile.createNewFile();
String name = "blockCountOfX";
parametersMap.put(name,blockCountOfX + "");
name = "blockCountOfY";
parametersMap.put(name,blockCountOfY + "");
name = "initSpeed";
parametersMap.put(name,initSpeed + "");
name = "blockWidth";
parametersMap.put(name,blockWidth + "");
blockHeight = 10;
name = "blockHeight";
parametersMap.put(name,blockHeight + "");
writeConfigFile(CONFIG_FILE_NAME,parametersMap);
}
catch (IOException e)
{
e.printStackTrace();
}
}
else
{
parametersMap = readConfigFile(CONFIG_FILE_NAME);
String name = "blockCountOfX";
try
{
blockCountOfX = Integer.parseInt(parametersMap.get(name));
}
catch (Exception ex)
{
MsgBox.alert("配置文件中的参数[" + name + "]应该为整数");
}
name = "blockCountOfY";
try
{
blockCountOfY = Integer.parseInt(parametersMap.get(name));
}
catch (Exception ex)
{
MsgBox.alert("配置文件中的参数[" + name + "]应该为整数");
}
name = "initSpeed";
try
{
initSpeed = Integer.parseInt(parametersMap.get(name));
}
catch (Exception ex)
{
MsgBox.alert("配置文件中的参数[" + name + "]应该为整数");
}
name = "blockWidth";
try
{
blockWidth = Integer.parseInt(parametersMap.get(name));
}
catch (Exception ex)
{
MsgBox.alert("配置文件中的参数[" + name + "]应该为整数");
}
name = "blockHeight";
try
{
blockHeight = Integer.parseInt(parametersMap.get(name));
}
catch (Exception ex)
{
MsgBox.alert("配置文件中的参数[" + name + "]应该为整数");
}
}
}
}
/**
*
*/
package cross.pauliuyou.block.common;import java.util.Random;/**
* @author 刘优
*
*/
public class RandomProducer
{
private static long seed = System.currentTimeMillis();
private Random random;
private int max;
private int begin;
public RandomProducer(int max)
{
this(max,0);
}
public RandomProducer(int max,int begin)
{
this.max = max;
this.begin = begin;
random = new Random(++seed);
}
/**
* @param i
* @return
*/
public int getInt()
{
int randNum = random.nextInt() % (max - begin) + begin;
if (randNum < 0)
{
randNum *= -1;
}
return randNum;
}
public double getDouble()
{
int randNum = (int)(random.nextDouble() * (max + begin) * 100);
double rs = randNum / 100d + begin;
if (rs < 0)
{
rs *= -1;
}
return rs;
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.Color;
import java.awt.Graphics;/**
* @author 刘优
*
*/
public class WorkArea
{
private static Color areaColor = Color.black;
protected int x;
protected int y;
protected int width;
protected int height;
protected int innerX;
protected int innerY;
protected int innerWidth;
protected int innerHeight; public boolean drawed;
public WorkArea(int x,int y,int width,int height)
{
this.x = x;
this.y = y;
this.width = width;
this.height = height;
innerX = x;
innerY = y;
innerWidth = width;
innerHeight = height;
}
/**
* @return the height
*/
public int getHeight()
{
return height;
}
/**
* @param height the height to set
*/
public void setHeight(int height)
{
this.height = height;
}
/**
* @return the width
*/
public int getWidth()
{
return width;
}
/**
* @param width the width to set
*/
public void setWidth(int width)
{
this.width = width;
}
/**
* @return the x
*/
public int getX()
{
return x;
}
/**
* @param x the x to set
*/
public void setX(int x)
{
this.x = x;
}
/**
* @return the y
*/
public int getY()
{
return y;
}
/**
* @param y the y to set
*/
public void setY(int y)
{
this.y = y;
}
/**
* @param graph
*/
public void drawArea(Graphics graph)
{
graph.setColor(areaColor );
graph.drawRect(x,y,width,height);
drawed = true;
}
/**
* @param graph
*/
public void clearArea(Graphics graph)
{
graph.clearRect(innerX,innerY,innerWidth,innerHeight);
}
}package cross.pauliuyou.block.graph;import java.awt.Component;
import java.util.Date;
import java.util.HashMap;import javax.swing.JOptionPane;/**
* 弹出报警窗口.同一标题的窗口只能弹出一次,关闭以后才可以再弹出
* @author 刘优
* @version 1.0
*/
public class MsgBox {
private static HashMap<String,Boolean> isWindowShowingMap = new HashMap<String,Boolean>();
public static String msgBoxTitleHead = "";
/**
* 弹出消息窗口
* @param msgBody 消息体
*/
public static void msg(Object msgBody)
{
show(null,msgBody,"消息窗口",1,false);
}
/**
* 弹出消息窗口
* @param msgBody 消息体
*/
public static void msg(Object msgBody,boolean create)
{
show(null,msgBody,"消息窗口",1,false);
}
/**
* 弹出消息窗口
* @param msgBody 消息体
*/
public static void msg(Component parentWindow,String msgBody)
{
show(parentWindow,msgBody,"消息窗口",1,false);
}
/**
* 弹出消息窗口
* @param msgBody 消息体
*/
public static void msg(Component parentWindow,String msgBody,boolean createNew)
{
show(parentWindow,msgBody,"消息窗口",1,createNew);
}
/**
* 弹出消息窗口
* @param msgBody 消息体
* @param title 消息标题
*/
public static void msg(String msgBody,String title)
{
show(null,msgBody,title,1,false);
}
/**
* 弹出消息窗口
* @param msgBody 消息体
* @param title 消息标题
*/
public static void msg(String msgBody,String title,boolean createNew)
{
show(null,msgBody,title,1,createNew);
}
public static void msg(Component parentWindow,String msgBody,String title)
{
show(parentWindow,msgBody,title,1,false);
}
public static void msg(Component parentWindow,String msgBody,String title,boolean createNew)
{
show(parentWindow,msgBody,title,1,createNew);
}
/**
* 弹出警告窗口
* @param msgBody 警告消息
*/
public static void alert(Object msgBody)
{
show(null,msgBody,"警告窗口",2,false);
}
public static void alert(Object msgBody,boolean createNew)
{
show(null,msgBody,"警告窗口",2,createNew);
}
/**
* 弹出警告窗口
* @param msgBody 警告消息
*/
public static void alert(Component parentWindow,String msgBody)
{
show(parentWindow,msgBody,"警告窗口",2,false);
}
public static void alert(Component parentWindow,String msgBody,boolean createNew)
{
show(parentWindow,msgBody,"警告窗口",2,createNew);
}
/**
* 弹出警告窗口
* @param msgBody 警告消息体
* @param title 警告标题
*/
public static void alert(String msgBody,String title)
{
show(null,msgBody,title,2,false);
}
public static void alert(String msgBody,String title,boolean createNew)
{
show(null,msgBody,title,2,createNew);
}
/**
* 弹出警告窗口
* @param msgBody 警告消息体
* @param title 警告标题
*/
public static void alert(Component parentWindow,Object msgBody,String title)
{
show(parentWindow,msgBody,title,2,false);
}
public static void alert(Component parentWindow,Object msgBody,String title,boolean createNew)
{
show(parentWindow,msgBody,title,2,createNew);
}
/**
* 弹出问题窗口
* @param msgBody 问题消息体
*/
public static void question(Object msgBody)
{
show(null,msgBody,"问题窗口",3,false);
}
public static void question(Object msgBody,boolean createNew)
{
show(null,msgBody,"问题窗口",3,createNew);
}
/**
* 弹出问题窗口
* @param msgBody 问题消息体
*/
public static void question(Component parentWindow,String msgBody)
{
show(parentWindow,msgBody,"问题窗口",3,false);
}
public static void question(Component parentWindow,String msgBody,boolean createNew)
{
show(parentWindow,msgBody,"问题窗口",3,createNew);
}
/**
* 弹出问题窗口
* @param msgBody 问题消息体
* @param title 问题标题
*/
public static void question(String msgBody,String title)
{
show(null,msgBody,title,3,false);
}
public static void question(String msgBody,String title,boolean createNew)
{
show(null,msgBody,title,3,createNew);
}
/**
* 弹出问题窗口
* @param msgBody 问题消息体
* @param title 问题标题
*/
public static void question(Component parentWindow,String msgBody,String title)
{
show(parentWindow,msgBody,title,3,false);
}
public static void question(Component parentWindow,String msgBody,String title,boolean createNew)
{
show(parentWindow,msgBody,title,3,createNew);
}
/**
* 弹出错误窗口
* @param msgBody 误消息体
*/
public static void error(Object msgBody)
{
show(null,msgBody,"错误窗口",0,false);
}
public static void error(Object msgBody,boolean createNew)
{
show(null,msgBody,"错误窗口",0,createNew);
}
/**
* 弹出错误窗口
* @param msgBody 误消息体
*/
public static void error(Component parentWindow,String msgBody)
{
show(parentWindow,msgBody,"错误窗口",0,false);
}
public static void error(Component parentWindow,String msgBody,boolean createNew)
{
show(parentWindow,msgBody,"错误窗口",0,createNew);
}
/**
* 弹出错误窗口
* @param msgBody 错误消息体
* @param title 错误标题
*/
public static void error(String msgBody,String title)
{
show(null,msgBody,title,0,false);
}
public static void error(String msgBody,String title,boolean createNew)
{
show(null,msgBody,title,0,createNew);
}
/**
* 弹出错误窗口
* @param msgBody 错误消息体
* @param title 错误标题
*/
public static void error(Component parentWindow,String msgBody,String title)
{
show(parentWindow,msgBody,title,0,false);
}
public static void error(Component parentWindow,String msgBody,String title,boolean createNew)
{
show(parentWindow,msgBody,title,0,createNew);
}
/**
* 弹出提示窗口
* @param msgBody 提示消息体
* @param title 提示标题
* @param windowType 提示窗口类型(3-问题窗口,2-警告窗口,1-消息窗口,0-错误窗口)
*/
public static void show(Component parentWindow,Object msgBody,String title,int windowType,boolean createNew)
{
String titleInfor = msgBoxTitleHead + title;
boolean isShowing = false;
Object obj = isWindowShowingMap.get(titleInfor);
if (obj != null)
{
isShowing = (Boolean)obj;
}
if (!isShowing || createNew)
{
new ShowBoxThread(parentWindow,msgBody,title,windowType,createNew).start();
}
}
private static class ShowBoxThread extends Thread
{
private Component parentWindow;
private String infor;
private String titleInfor;
private int theType;
private boolean createNew;
public ShowBoxThread(Component parentWindow,Object msgBody,String title,int windowType,boolean createNew)
{
this.parentWindow = parentWindow;
this.infor = msgBody.toString();
this.titleInfor = msgBoxTitleHead + title;
this.theType = windowType;
this.createNew = createNew;
}
public void run()
{
setName("MsgBox<" + titleInfor + ">");
if (!createNew)
{
isWindowShowingMap.put(titleInfor,true);
try
{
JOptionPane.showMessageDialog(parentWindow,new Date() + " > " + infor,titleInfor,theType);
}
catch (Exception e)
{
error("消息窗口的类型参数不正确.(3-问题窗口,2-警告窗口,1-消息窗口,0-错误窗口)");
}
isWindowShowingMap.put(titleInfor,false);
}
else
{
try
{
JOptionPane.showMessageDialog(parentWindow,new Date() + " > " + infor,titleInfor,theType);
}
catch (Exception e)
{
error("消息窗口的类型参数不正确.(3-问题窗口,2-警告窗口,1-消息窗口,0-错误窗口)");
}
}
}
}
}
package cross.pauliuyou.block.graph;import java.awt.Dimension;
import java.awt.Frame;
import java.awt.GraphicsEnvironment;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.reflect.Method;import javax.swing.JDialog;
import javax.swing.JFrame;/**
* 窗口显示调整工具
* @author 刘优
* @version 1.0
*/public class WindowUtil {
/**
* Positions the specified frame in the middle of the screen.
*
* @param frame the frame to be centered on the screen.
*/
public static void centerFrameOnScreen(final Window frame) {
positionFrameOnScreen(frame, 0.5, 0.5);
} /**
* Positions the specified frame at a relative position in the screen, where 50% is considered
* to be the center of the screen.
*
* @param frame the frame.
* @param horizontalPercent the relative horizontal position of the frame (0.0 to 1.0,
* where 0.5 is the center of the screen).
* @param verticalPercent the relative vertical position of the frame (0.0 to 1.0, where
* 0.5 is the center of the screen).
*/
public static void positionFrameOnScreen(final Window frame,
final double horizontalPercent,
final double verticalPercent) { final Rectangle s = getMaximumWindowBounds();
final Dimension f = frame.getSize();
final int w = Math.max(s.width - f.width, 0);
final int h = Math.max(s.height - f.height, 0);
final int x = (int) (horizontalPercent * w) + s.x;
final int y = (int) (verticalPercent * h) + s.y;
frame.setBounds(x, y, f.width, f.height); }
/**
* Computes the maximum bounds of the current screen device. If this method is called on JDK 1.4, Xinerama-aware
* results are returned. (See Sun-Bug-ID 4463949 for details).
*
* @return the maximum bounds of the current screen.
*/
public static Rectangle getMaximumWindowBounds ()
{
final GraphicsEnvironment localGraphicsEnvironment = GraphicsEnvironment.getLocalGraphicsEnvironment();
try
{
final Method method = GraphicsEnvironment.class.getMethod("getMaximumWindowBounds", (Class[]) null);
return (Rectangle) method.invoke(localGraphicsEnvironment, (Object[]) null);
}
catch(Exception e)
{
// ignore ... will fail if this is not a JDK 1.4 ..
}
final Dimension s = Toolkit.getDefaultToolkit().getScreenSize();
return new Rectangle (0, 0, s.width, s.height);
} public static void fullScreenFrame(Window window)
{
java.awt.Dimension dimension = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
window.setSize(dimension.width, dimension.height - 30);
if (window instanceof Frame)
((Frame)window).setExtendedState(Frame.MAXIMIZED_BOTH);
window.setLocation(0, 0);
}
/**
* 居中显示窗口
* @param w
*/
public static void doView(Window w) {
w.setSize(w.getToolkit().getScreenSize().width,w.getToolkit().getScreenSize().height - 40);
w.setLocation(0,0);
w.setVisible(true);
if (w.getClass() == JFrame.class) {
((JFrame)w).setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
((JFrame)w).setResizable(false);
}
if (w.getClass() == JDialog.class) {
((JDialog)w).setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
((JDialog)w).setResizable(false);
}
}
/**
* 居中显示窗口
* @param w
* @param width
* @param height
*/
public static void doView(Window w,int width,int height) {
w.setSize(width,height);
int width2 = w.getToolkit().getScreenSize().width;
width2 = (width2 - w.getWidth()) / 2;
int height2 = w.getToolkit().getScreenSize().height;
height2 = (height2 - w.getHeight()) / 2;
w.setLocation(width2,height2);
w.setVisible(true);
if (w.getClass() == JFrame.class) {
((JFrame)w).setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
((JFrame)w).setResizable(false);
}
/*
if (w.getClass() == JDialog.class) {
((JDialog)w).setDefaultCloseOperation(JDialog.EXIT_ON_CLOSE);
((JDialog)w).setResizable(false);
}
*/
}
/**
* 设置窗口关闭
* @param w 窗口
*/
public static void doClose(Window w) {
final Window w2 = w;
w.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
w2.dispose();
}
});
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.Color;
import java.awt.Graphics;import cross.pauliuyou.block.api.Drawable;
import cross.pauliuyou.block.api.Movable;
import cross.pauliuyou.block.common.ConfigUtil;
import cross.pauliuyou.block.common.RandomProducer;/**
* 方块类, 是组成矩阵的基本元素,每个方块都可以移动并自我绘制
* @author 刘优
*
*/
public class Block implements Drawable,Movable
{
/**
* 方块宽度
*/
public static final int BLOCK_WIDTH = ConfigUtil.blockWidth;
/**
* 方块高度
*/
public static final int BLOCK_HEIGHT = ConfigUtil.blockHeight;
/**
* 向上移动
*/
public static final int MOVE_UP = 0;
/**
* 向下移动
*/
public static final int MOVE_DOWN = 1;
public static final int MOVE_LEFT = 2;
public static final int MOVE_RIGHT = 3;
protected static int defaultXStep = BLOCK_WIDTH;
protected static int defaultYStep = BLOCK_HEIGHT;
protected int x;
protected int y;
protected Graphics graphics;
protected Color blockColor;
protected Color displayColor;
protected WorkArea workArea;
protected RandomProducer countRandom = new RandomProducer(8,3);
protected RandomProducer directionRandom = new RandomProducer(4);
protected int stepCount;
protected int moveDirection;
protected int[] tableIndex;
protected boolean visible = true;
protected boolean toMoveUp = true;
protected boolean toMoveDown = true;
protected boolean toMoveLeft = true;
protected boolean toMoveRight = true;
private int upStep = defaultXStep;
private int downStep = defaultXStep;
private int leftStep = defaultYStep;
private int rightStep = defaultYStep;
private int top;
private int buttom;
private int left;
private int right;
private BlockMartix owner;
public void setBlockTableIndexes(int[] tableIndexes)
{
this.tableIndex = tableIndexes;
}
public Block(Graphics graphics,WorkArea workArea,Color blockColor,int x,int y)
{
this.blockColor = blockColor;
displayColor = blockColor;
this.graphics = graphics;
this.workArea = workArea;
this.x = x;
this.y = y;
top = workArea.y + 2;
buttom = workArea.height - 2 - BLOCK_HEIGHT + ConfigUtil.FRAME_TITLE_PANEL_HEIGHT;
left = workArea.x + 2;
right = workArea.x + workArea.width - 2 - BLOCK_WIDTH;
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#clearMe()
*/
public void clearMe()
{
if (visible)
{
//graphics.clearRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
}
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#drawMe()
*/
public void drawMeNoRect()
{
if (visible)
{
graphics.setColor(displayColor);
graphics.fillRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
}
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#drawMe()
*/
public void drawMe()
{
if (visible)
{
graphics.setColor(Color.gray);
graphics.drawRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
graphics.setColor(displayColor);
graphics.fillRect(x + 1, y + 1, BLOCK_WIDTH - 1, BLOCK_HEIGHT - 1);
}
}
public void setVisible(boolean visible)
{
this.visible = visible;
if (visible)
{
displayColor = blockColor;
}
else
{
displayColor = null;
}
}
public boolean isVisible()
{
return visible;
}
public void moveUp()
{
moveUp(defaultYStep);
}
public void moveDown()
{
moveDown(defaultYStep);
}
public void moveLeft()
{
moveLeft(defaultXStep);
}
public void moveRight()
{
moveRight(defaultXStep);
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveUp(int)
*/
public void moveUp(int step)
{
if (!toMoveUp)
{
toMoveDown = true;
return;
}
upStep = step;
clearMe();
if (willOverTop())
{
y = buttom;
}
else
{
y -= step;
}
drawMe();
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveDown(int)
*/
public void moveDown(int step)
{
if (!toMoveDown)
{
toMoveUp = true;
return;
}
downStep = step;
clearMe();
if (willOverButtom())
{
y = top;
}
else
{
y += step;
}
drawMe();
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveLeft(int)
*/
public void moveLeft(int step)
{
if (!toMoveLeft)
{
toMoveRight = true;
return;
}
leftStep = step;
clearMe();
if (willOverLeft())
{
x = right;
}
else
{
x -= step;
}
drawMe();
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveRight(int)
*/
public void moveRight(int step)
{
if (!toMoveRight)
{
toMoveLeft = true;
return;
}
rightStep = step;
clearMe();
if (willOverRight())
{
x = left;
}
else
{
x += step;
}
drawMe();
}
public boolean willOverTop()
{
if (y - upStep < workArea.y - 2)
{
return true;
}
return false;
}
public boolean willOverButtom()
{
if (y + downStep > workArea.height + ConfigUtil.FRAME_TITLE_PANEL_HEIGHT - BLOCK_HEIGHT)
{
return true;
}
return false;
}
public boolean willOverLeft()
{
if (x - leftStep < workArea.x + 2)
{
return true;
}
return false;
}
public boolean willOverRight()
{
if (x + rightStep > workArea.x + workArea.width - 2 - BLOCK_WIDTH)
{
return true;
}
return false;
} public void wander()
{
int theCount = countRandom.getInt();
if (stepCount++ >= theCount)
{
moveDirection = directionRandom.getInt();
stepCount = 0;
}
//System.out.println(moveDirection);
switch (moveDirection)
{
case MOVE_UP :
if (willOverTop())
{
moveDirection = MOVE_DOWN;
moveDown();
}
else
{
moveUp();
}
break;
case MOVE_DOWN :
if (willOverButtom())
{
moveDirection = MOVE_UP;
moveUp();
}
else
{
moveDown();
}
break;
case MOVE_LEFT :
if (willOverLeft())
{
moveDirection = MOVE_RIGHT;
moveRight();
}
else
{
moveLeft();
}
break;
case MOVE_RIGHT:
if (willOverRight())
{
moveDirection = MOVE_LEFT;
moveLeft();
}
else
{
moveRight();
}
break;
}
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
public void moveAngle(double angle)
{
moveAngle(defaultXStep,angle);
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
public void moveAngle(int step, double angle)
{
// TODO Auto-generated method stub
}
/**
* @return the blockColor
*/
public Color getBlockColor()
{
return blockColor;
} /**
* @param blockColor the blockColor to set
*/
public void setBlockColor(Color blockColor)
{
this.blockColor = blockColor;
} /**
* @return the graphics
*/
public Graphics getGraphics()
{
return graphics;
} /**
* @param graphics the graphics to set
*/
public void setGraphics(Graphics graphics)
{
this.graphics = graphics;
} /**
* @return the workArea
*/
public WorkArea getWorkArea()
{
return workArea;
} /**
* @param workArea the workArea to set
*/
public void setWorkArea(WorkArea workArea)
{
this.workArea = workArea;
} /**
* @return the x
*/
public int getX()
{
return x;
} /**
* @param x the x to set
*/
public void setX(int x)
{
this.x = x;
} /**
* @return the y
*/
public int getY()
{
return y;
} /**
* @param y the y to set
*/
public void setY(int y)
{
this.y = y;
} /**
* @return the displayColor
*/
public Color getDisplayColor()
{
return displayColor;
} /**
* @param displayColor the displayColor to set
*/
public void setDisplayColor(Color displayColor)
{
this.displayColor = displayColor;
} /**
* @return the moveDirection
*/
public int getMoveDirection()
{
return moveDirection;
} /**
* @param moveDirection the moveDirection to set
*/
public void setMoveDirection(int moveDirection)
{
this.moveDirection = moveDirection;
} /**
* @return the stepCount
*/
public int getStepCount()
{
return stepCount;
} /**
* @param stepCount the stepCount to set
*/
public void setStepCount(int stepCount)
{
this.stepCount = stepCount;
} /**
* @return the tableIndexes
*/
public int[] getTableIndexes()
{
return tableIndex;
} /**
* @param tableIndexes the tableIndexes to set
*/
public void setTableIndexes(int[] tableIndexes)
{
this.tableIndex = tableIndexes;
} /**
* @return the toMoveDown
*/
public boolean isToMoveDown()
{
return toMoveDown;
} /**
* @param toMoveDown the toMoveDown to set
*/
public void setToMoveDown(boolean toMoveDown)
{
this.toMoveDown = toMoveDown;
} /**
* @return the toMoveLeft
*/
public boolean isToMoveLeft()
{
return toMoveLeft;
} /**
* @param toMoveLeft the toMoveLeft to set
*/
public void setToMoveLeft(boolean toMoveLeft)
{
this.toMoveLeft = toMoveLeft;
} /**
* @return the toMoveRight
*/
public boolean isToMoveRight()
{
return toMoveRight;
} /**
* @param toMoveRight the toMoveRight to set
*/
public void setToMoveRight(boolean toMoveRight)
{
this.toMoveRight = toMoveRight;
} /**
* @return the toMoveUp
*/
public boolean isToMoveUp()
{
return toMoveUp;
} /**
* @param toMoveUp the toMoveUp to set
*/
public void setToMoveUp(boolean toMoveUp)
{
this.toMoveUp = toMoveUp;
} /**
* @return the owner
*/
public BlockMartix getOwner()
{
return owner;
} /**
* @param owner the owner to set
*/
public void setOwner(BlockMartix owner)
{
this.owner = owner;
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.Color;
import java.awt.Graphics;/**
* @author Administrator
*
*/
public class RectangleBlock extends Block
{
/**
* @param graphics
* @param workArea
* @param blockColor
* @param x
* @param y
*/
public RectangleBlock(Graphics graphics, WorkArea workArea, Color blockColor, int x, int y)
{
super(graphics, workArea, blockColor, x, y);
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#drawMe()
*/
@Override
public void drawMeNoRect()
{
if (visible)
{
graphics.setColor(displayColor);
graphics.fillRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
}
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#drawMe()
*/
public void drawMe()
{
if (visible)
{
graphics.setColor(Color.gray);
graphics.drawRect(x, y, BLOCK_WIDTH, BLOCK_HEIGHT);
graphics.setColor(displayColor);
graphics.fillRect(x + 1, y + 1, BLOCK_WIDTH - 1, BLOCK_HEIGHT - 1);
}
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.Color;
import java.awt.Graphics;import cross.pauliuyou.block.api.Drawable;
import cross.pauliuyou.block.api.Movable;
import cross.pauliuyou.block.api.Rotatable;
import cross.pauliuyou.block.common.ConfigUtil;
import cross.pauliuyou.block.common.RandomProducer;/**
* @author 刘优
*
*/
public class BlockMartix implements Movable,Drawable,Rotatable
{
protected int rows = ConfigUtil.RECTANGLE_STANDARD_ROWS;
protected int cols = ConfigUtil.RECTANGLE_STANDARD_COLS;
protected Block[][] blockTable = new Block[rows][cols];
private RandomProducer random0 = new RandomProducer(230,5);
private RandomProducer random1 = new RandomProducer(8,5);
private RandomProducer random2 = new RandomProducer(4);
protected WorkArea workArea;
protected Color color;
protected int stepCount;
protected int moveDirection; protected int initX;
protected int initY;
protected Block leftTopBlock;
protected Graphics graphics;
protected static Color[] colors = {Color.red,Color.green,Color.blue,Color.black,Color.gray,Color.yellow};
protected boolean stopped;
public BlockMartix(Graphics graphics,WorkArea workArea)
{
this(graphics,workArea,null);
}
public BlockMartix(Graphics graphics,WorkArea workArea,Color color)
{
this.graphics = graphics;
this.workArea = workArea;
this.color = color;
initX = workArea.x + ((workArea.width / 2) - ((cols / 2) * Block.BLOCK_WIDTH));
initY = workArea.y + 2;
createMatrix(color);
}
/**
*
*/
protected void createMatrix(Color color)
{
int x = initX;
int y = initY;
int blue = 10;
int green = 10;
int red = 10;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
Color tmpColor = color;
if (color == null)
{
tmpColor = new Color(red,green,blue);
}
Block block = new RectangleBlock(graphics,workArea,tmpColor,x,y);
block.setOwner(this);
block.tableIndex = new int[]{i,j};
blockTable[i][j] = block;
blue = random0.getInt();
green = random0.getInt();
red = random0.getInt();
x += Block.BLOCK_WIDTH;
}
x = initX;
y += Block.BLOCK_HEIGHT;
}
leftTopBlock = blockTable[0][0];
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveUp()
*/
public void moveUp()
{
moveUp(Block.defaultYStep);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveDown()
*/
public void moveDown()
{
moveDown(Block.defaultYStep);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveLeft()
*/
public void moveLeft()
{
moveLeft(Block.defaultXStep);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveRight()
*/
public void moveRight()
{
moveRight(Block.defaultXStep);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveUp(int)
*/
public void moveUp(int step)
{
if (stopped)
{
return;
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].moveUp(step);
}
}
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveDown(int)
*/
public void moveDown(int step)
{
if (stopped)
{
return;
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].moveDown(step);
}
}
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveLeft(int)
*/
public void moveLeft(int step)
{
if (stopped)
{
return;
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].moveLeft(step);
}
}
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveRight(int)
*/
public void moveRight(int step)
{
if (stopped)
{
return;
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].moveRight(step);
}
}
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
public void moveAngle(double angle)
{
moveAngle(Block.defaultXStep,angle);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
public void moveAngle(int step, double angle)
{
if (stopped)
{
return;
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].moveAngle(step,angle);
}
}
}
}
public void wander()
{
if (stopped)
{
return;
}
int theCount = random1.getInt();
if (stepCount++ >= theCount)
{
moveDirection = random2.getInt();
stepCount = 0;
}
//System.out.println(moveDirection);
switch (moveDirection)
{
case Block.MOVE_UP :
if (blockTable[0][0].willOverTop())
{
moveDirection = Block.MOVE_DOWN;
moveDown();
}
else
{
moveUp();
}
break;
case Block.MOVE_DOWN :
if (blockTable[rows - 1][0].willOverButtom())
{
moveDirection = Block.MOVE_UP;
moveUp();
}
else
{
moveDown();
}
break;
case Block.MOVE_LEFT :
if (blockTable[0][0].willOverLeft())
{
moveDirection = Block.MOVE_RIGHT;
moveRight();
}
else
{
moveLeft();
}
break;
case Block.MOVE_RIGHT:
if (blockTable[0][cols - 1].willOverRight())
{
moveDirection = Block.MOVE_LEFT;
moveLeft();
}
else
{
moveRight();
}
break;
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#drawMe()
*/
public void drawMe()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].drawMe();
}
}
}
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Drawable#clearMe()
*/
public void clearMe()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j] != null)
{
blockTable[i][j].clearMe();
}
}
}
}
* @see cross.pauliuyou.block.api.Rotatable#clockRotate()
*/
public void clockRotate()
{
if (stopped)
{
return;
}
Block[][] tempTable = new Block[cols][rows];
int headX = blockTable[0][0].x;
int headY = blockTable[0][0].y;
for (int i = 0; i < cols; i++)
{
Block[] newXLine = new Block[rows];
for (int j = 0; j < rows; j++)
{
newXLine[j] = blockTable[rows - 1 - j][i];
}
tempTable[i] = newXLine;
}
int temp = rows;
rows = cols;
cols = temp;
int x = headX;
int y = headY;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
tempTable[i][j].tableIndex = new int[]{i,j};
tempTable[i][j].x = x;
tempTable[i][j].y = y;
x += Block.BLOCK_WIDTH;
}
y += Block.BLOCK_HEIGHT;
x = headX;
}
blockTable = tempTable;
drawMe();
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Rotatable#deClockRotate()
*/
public void deClockRotate()
{
if (stopped)
{
return;
}
Block[][] tempTable = new Block[cols][rows];
int headX = blockTable[0][0].x;
int headY = blockTable[0][0].y;
for (int i = 0; i < cols; i++)
{
Block[] newXLine = new Block[rows];
for (int j = 0; j < rows; j++)
{
newXLine[j] = blockTable[j][cols - 1 - i];
}
tempTable[i] = newXLine;
}
int temp = rows;
rows = cols;
cols = temp;
int x = headX;
int y = headY;
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
tempTable[i][j].tableIndex = new int[]{i,j};
tempTable[i][j].x = x;
tempTable[i][j].y = y;
x += Block.BLOCK_WIDTH;
}
y += Block.BLOCK_HEIGHT;
x = headX;
}
blockTable = tempTable;
drawMe();
}
public int getX()
{
return this.leftTopBlock.x;
}
public int getY()
{
return this.leftTopBlock.y;
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.Color;
import java.awt.Graphics;
import java.util.Vector;/**
* @author 刘优
*
*/
public class Shape extends BlockMartix
{
private byte[][] shapeDesc;
private Block topBlock;
private Block buttomBlock;
private Block leftBlock;
private Block rightBlock;
private boolean atTop;
private boolean atButtom;
private boolean atLeft;
private boolean atRight;
private boolean moved;
private Vector<Block> visibleBlocks = new Vector<Block>();
/**
* @return the atButtom
*/
public boolean isAtButtom()
{
return atButtom;
} /**
* @return the atLeft
*/
public boolean isAtLeft()
{
return atLeft;
} /**
* @return the atRight
*/
public boolean isAtRight()
{
return atRight;
} /**
* @return the atTop
*/
public boolean isAtTop()
{
return atTop;
} /**
* @param window
* @param color
*/
public Shape(Graphics graphics,WorkArea workArea,Color color,byte[][]shapeDesc)
{
super(graphics,workArea, color);
this.shapeDesc = shapeDesc;
rebuildShape();
this.shapeDesc = new byte[shapeDesc.length][shapeDesc[0].length];
for (int i = 0; i < shapeDesc.length; i++)
{
for (int j = 0; j < shapeDesc[i].length; j++)
{
this.shapeDesc[i][j] = shapeDesc[i][j];
}
}
}
protected void rebuildShape()
{
for (int i = 0; i < shapeDesc.length; i++)
{
if (i < super.blockTable.length)
{
for (int j = 0; j < shapeDesc[i].length; j++)
{
if (j < super.blockTable[i].length)
{
if (shapeDesc[i][j] == 0)
{
super.blockTable[i][j].setVisible(false);
}
else
{
visibleBlocks.add(blockTable[i][j]);
}
}
}
}
}
findEdge();
}
private void findEdge()
{
topBlock = null;
int lx = shapeDesc.length - 1;
int ly = shapeDesc.length - 1;
int rx = 0;
int ry = 0;
int bx = 0;
int by = 0;
for (int i = 0; i < blockTable.length; i++)
{
for (int j = 0; j < blockTable[i].length; j++)
{
if (blockTable[i][j].isVisible())
{
if (topBlock == null)
{
topBlock = blockTable[i][j];
}
if (j < ly)
{
lx = i;
ly = j;
}
if (j > ry)
{
rx = i;
ry = j;
}
if (i > bx)
{
bx = i;
by = j;
}
}
}
}
buttomBlock = blockTable[bx][by];
leftBlock = blockTable[lx][ly];
rightBlock = blockTable[rx][ry];
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveUp(int)
*/
@Override
public void moveUp(int step)
{
if (!topBlock.willOverTop())
{
super.moveUp(step);
moved = true;
}
else
{
atTop = true;
drawMe();
}
atButtom = false;
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveDown(int)
*/
@Override
public void moveDown(int step)
{
if (!buttomBlock.willOverButtom())
{
super.moveDown(step);
moved = true;
}
else
{
atButtom = true;
drawMe();
}
atTop = false;
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveLeft(int)
*/
@Override
public void moveLeft(int step)
{
if (!leftBlock.willOverLeft())
{
super.moveLeft(step);
moved = true;
}
else
{
atLeft = true;
drawMe();
}
atRight = false;
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveRight(int)
*/
@Override
public void moveRight(int step)
{
if (!rightBlock.willOverRight())
{
super.moveRight(step);
moved = true;
}
else
{
atRight = true;
drawMe();
}
atLeft = false;
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
@Override
public void moveAngle(double angle)
{
moveAngle(Block.defaultXStep,angle);
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Movable#moveAngle(int, double)
*/
@Override
public void moveAngle(int step, double angle)
{
super.moveAngle(step,angle);
moved = true;
}
/* (non-Javadoc)
* @see cross.pauliuyou.block.api.Rotatable#clockRotate()
*/
@Override
public void clockRotate()
{
super.clockRotate();
int oldRow = shapeDesc.length;
int oldCol = shapeDesc[0].length;
byte[][] tempDesc = new byte[oldCol][oldRow];
for (int i = 0; i < oldCol; i++)
{
byte[] newXLine = new byte[oldRow];
for (int j = 0; j < oldRow; j++)
{
newXLine[j] = shapeDesc[oldRow - 1 - j][i];
}
tempDesc[i] = newXLine;
}
shapeDesc = tempDesc;
findEdge();
/*
Block tmp = topBlock;
topBlock = leftBlock;
leftBlock = buttomBlock;
buttomBlock = rightBlock;
rightBlock = tmp;
*/
} /* (non-Javadoc)
* @see cross.pauliuyou.block.api.Rotatable#deClockRotate()
*/
@Override
public void deClockRotate()
{
super.deClockRotate();
int oldRow = shapeDesc.length;
int oldCol = shapeDesc[0].length;
byte[][] tempDesc = new byte[oldCol][oldRow];
for (int i = 0; i < oldCol; i++)
{
byte[] newXLine = new byte[oldRow];
for (int j = 0; j < oldRow; j++)
{
newXLine[j] = shapeDesc[j][oldCol - 1 - i];
}
tempDesc[i] = newXLine;
}
shapeDesc = tempDesc;
findEdge();
/*
Block tmp = topBlock;
topBlock = rightBlock;
rightBlock = buttomBlock;
buttomBlock = leftBlock;
leftBlock = tmp;
*/
} /**
* @return the buttomBlock
*/
public Block getButtomBlock()
{
return buttomBlock;
} /**
* @return the leftBlock
*/
public Block getLeftBlock()
{
return leftBlock;
} /**
* @return the rightBlock
*/
public Block getRightBlock()
{
return rightBlock;
} /**
* @return the topBlock
*/
public Block getTopBlock()
{
return topBlock;
} /**
* @return
*/
public boolean isAllInvisible()
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j].isVisible())
{
return false;
}
}
}
return true;
}
/**
* @param currentLeftBlock
* @return
*/
public boolean blockTouchedMe(Block block)
{
for (int i = visibleBlocks.size() - 1; i >= 0; i--)
{
Block theBlock = visibleBlocks.get(i);
if (theBlock.isVisible() && theBlock.x == block.x && (block.y + Block.BLOCK_HEIGHT == theBlock.y))
{
return true;
}
}
return false;
}
public boolean isMoved()
{
return moved;
}
public boolean notMoved()
{
int x = getX();
int y = getY();
return (x == initX && y == initY);
} /**
* @param y1
*/
public void moveDownBlocksUponAtY(int y)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
if (blockTable[i][j].y >= y)
{
break;
}
blockTable[i][j].moveDown();
}
}
}
/**
* @param blockToClean
*/
public void cleanBlock(Block blockToClean)
{
blockToClean.visible = false;
visibleBlocks.remove(blockToClean);
int[] indexOfTable = blockToClean.tableIndex;
shapeDesc[indexOfTable[0]][indexOfTable[1]] = 0;
}
/**
* @param x1
* @return
*/
public Vector<Block> getAllBlocksAtY(int y)
{
Vector<Block> blocks = new Vector<Block>();
for (int i = 0; i < visibleBlocks.size(); i++)
{
Block theBlock = visibleBlocks.get(i);
if (theBlock.y == y)
{
blocks.add(theBlock);
}
}
return blocks;
}
/**
* @param currentShape
* @return
*/
public boolean otherShapeAboveOnMe(Shape otherShape)
{
for (int i = otherShape.visibleBlocks.size() - 1; i >= 0; i--)
{
Block otherBlock = otherShape.visibleBlocks.get(i);
for (int j = 0; j < visibleBlocks.size(); j++)
{
Block thisBlock = visibleBlocks.get(j);
if (thisBlock.x == otherBlock.x && (otherBlock.y + Block.BLOCK_HEIGHT == thisBlock.y))
{
return true;
}
}
}
return false;
}
/**
* @param currentShape
* @return
*/
public boolean otherShapeUnderMe(Shape otherShape)
{
for (int i = 0; i < otherShape.visibleBlocks.size(); i++)
{
Block otherBlock = otherShape.visibleBlocks.get(i);
for (int j = 0; j < visibleBlocks.size(); j++)
{
Block thisBlock = visibleBlocks.get(j);
if (thisBlock.x == otherBlock.x && (otherBlock.y - Block.BLOCK_HEIGHT == thisBlock.y))
{
return true;
}
}
}
return false;
}
/**
* @param currentShape
* @return
*/
public boolean otherShapeLeftSideByMe(Shape otherShape)
{
for (int i = otherShape.visibleBlocks.size() - 1; i >= 0; i--)
{
Block otherBlock = otherShape.visibleBlocks.get(i);
for (int j = 0; j < visibleBlocks.size(); j++)
{
Block thisBlock = visibleBlocks.get(j);
if (thisBlock.y == otherBlock.y && (otherBlock.x + Block.BLOCK_WIDTH == thisBlock.x))
{
return true;
}
}
}
return false;
}
/**
* @param currentShape
* @return
*/
public boolean otherShapeRightSideByMe(Shape otherShape)
{
for (int i = otherShape.visibleBlocks.size() - 1; i >= 0; i--)
{
Block otherBlock = otherShape.visibleBlocks.get(i);
for (int j = 0; j < visibleBlocks.size(); j++)
{
Block thisBlock = visibleBlocks.get(j);
if (thisBlock.y == otherBlock.y && (otherBlock.x - Block.BLOCK_WIDTH == thisBlock.x))
{
return true;
}
}
}
return false;
} /**
*
*/
public int getYDistanceWithOtherShape(Shape otherShape)
{
int minValue = abs(buttomBlock.y - otherShape.buttomBlock.y);
boolean hasSameX = false;
for (int i = otherShape.visibleBlocks.size() - 1; i >= 0; i--)
{
Block otherBlock = otherShape.visibleBlocks.get(i);
for (int j = 0; j < visibleBlocks.size(); j++)
{
Block thisBlock = visibleBlocks.get(j);
if (thisBlock.x == otherBlock.x)
{
hasSameX = true;
int tmp = abs(thisBlock.y - otherBlock.y);
if (tmp < minValue)
{
minValue = tmp;
}
}
}
}
if (hasSameX)
{
return minValue - Block.BLOCK_HEIGHT;
}
return -1;
} /**
* @param i
* @return
*/
private static int abs(int i)
{
return i < 0 ? -i : i;
}
}
/**
*
*/
package cross.pauliuyou.block.graph;import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.KeyStroke;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;import cross.pauliuyou.block.common.ConfigUtil;
import cross.pauliuyou.block.common.RandomProducer;/**
* @author 刘优
*
*/
public class BlockFrame extends JFrame implements ActionListener,
Runnable,
KeyListener,
MouseListener,
ChangeListener,
MouseMotionListener
{ public WorkArea workArea; private static final long serialVersionUID = 1L;
public static final int TITLE_PANEL_HEIGHT = ConfigUtil.FRAME_TITLE_PANEL_HEIGHT;
public static final int MENU_PANEL_HEIGHT = ConfigUtil.FRAME_MENU_PANEL_HEIGHT;
private static byte[][] desc1 = {{1,1,1,1},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}};
private static byte[][] desc2 = {{1,1,0,0},
{1,1,0,0},
{0,0,0,0},
{0,0,0,0}};
private static byte[][] desc3 = {{1,0,0,0},
{1,1,0,0},
{0,1,0,0},
{0,0,0,0}};
private static byte[][] desc4 = {{0,1,0,0},
{1,1,0,0},
{1,0,0,0},
{0,0,0,0}};
private static byte[][] desc5 = {{0,1,0,0},
{1,1,1,0},
{0,0,0,0},
{0,0,0,0}};
private static byte[][] desc6 = {{1,1,0,0},
{0,1,0,0},
{0,1,0,0},
{0,0,0,0}};
private static byte[][] desc7 = {{1,1,0,0},
{1,0,0,0},
{1,0,0,0},
{0,0,0,0}};
private static byte[][][] allShapes = {desc1,desc2,desc3,desc4,desc5,desc6,desc7};
private static Color[] allColors = {Color.red,Color.yellow,Color.blue,Color.green,Color.orange,Color.magenta,Color.pink};
private RandomProducer shapeRandom = new RandomProducer(7);
Graphics graph;
private static final String STRING_FONT = ConfigUtil.STRING_FONT; private boolean gameThreadRunFlag; private Thread gameThread; private int frameWidth;
private int frameHeight;
private int blockInitX = 10;
private int blockCountOfX = ConfigUtil.blockCountOfX; private int blockCountOfY = ConfigUtil.blockCountOfY;
private int speed = ConfigUtil.initSpeed;
private JSlider speedSlider;
private JLabel speedLabel;
private Shape currentShape;
private Vector<Shape> stoppedShapes = new Vector<Shape>(); private boolean gameOver; private boolean gamePause; private WorkArea workArea1; private WorkArea workArea2; private int currentShapeIndex;
private int nextShapeIndex1; private int nextShapeIndex2; private Shape nextShape1; private Shape nextShape2; private boolean currentShapeTouched; private int moveDownCount;
private int score; private boolean producing; private int previousScore = 1; private boolean gameThreadOver; private static int gapSize = 4; /**
*/
public BlockFrame()
{
super("方块");
getMenu();
speedSlider = new JSlider();
speedSlider.setMinimum(0);
speedSlider.setMaximum(1000);
speedSlider.setValue(speed);
speedSlider.addChangeListener(this);
speedLabel = new JLabel("" + speed);
JPanel southPanel = new JPanel(new BorderLayout());
southPanel.add(new JLabel("速度: "),"West");
southPanel.add(speedLabel,"East");
southPanel.add(speedSlider);
//add(southPanel,"South");
addKeyListener(this);
thisFrameInit();
} /**
*
*/
private void thisFrameInit()
{
workArea = new WorkArea(blockInitX - gapSize / 2,
TITLE_PANEL_HEIGHT,
Block.BLOCK_WIDTH * blockCountOfX + gapSize ,
Block.BLOCK_HEIGHT * blockCountOfY + gapSize);
frameWidth = workArea.width + Block.BLOCK_WIDTH * ConfigUtil.RECTANGLE_STANDARD_ROWS + gapSize * 15;
frameHeight = workArea.height + TITLE_PANEL_HEIGHT + gapSize * 15;
workArea1 = new WorkArea(workArea.x + workArea.width + gapSize,
TITLE_PANEL_HEIGHT,
Block.BLOCK_WIDTH * ConfigUtil.RECTANGLE_STANDARD_ROWS + gapSize,
Block.BLOCK_WIDTH * ConfigUtil.RECTANGLE_STANDARD_COLS + gapSize);
workArea2 = new WorkArea(workArea.x + workArea.width + gapSize,
workArea1.y + workArea1.height + gapSize,
Block.BLOCK_WIDTH * ConfigUtil.RECTANGLE_STANDARD_ROWS + gapSize,
Block.BLOCK_WIDTH * ConfigUtil.RECTANGLE_STANDARD_COLS + gapSize);
setSize(frameWidth,frameHeight);
WindowUtil.centerFrameOnScreen(this);
setVisible(true);
graph = getGraphics();
setResizable(false);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we)
{
shutdown();
}
});
newGame();
} /**
*
*/
protected void shutdown()
{
gameThreadRunFlag = false;
gameThread.interrupt();
this.dispose();
}
/**
*
*/
private void newGame()
{
stoppedShapes.clear();
if (gameThread != null)
{
gameThreadRunFlag = false;
gameThread.interrupt();
while (!gameThreadOver)
{
}
}
previousScore = 1;
score = 0;
int randShapeIndex = shapeRandom.getInt();
currentShape = new Shape(graph,workArea,allColors[randShapeIndex],allShapes[randShapeIndex]);
currentShape.drawMe();
nextShapeIndex1 = shapeRandom.getInt();
nextShapeIndex2 = shapeRandom.getInt();
printNextTwoShapes(true);
if (gamePause)
{
resume();
}
gameOver = false;
gamePause = false;
currentShapeTouched = false;
gameThread = new Thread(this);
gameThread.setName("GameThread");
gameThreadOver = false;
gameThreadRunFlag = true;
gameThread.start();
} /* (non-Javadoc)
* @see java.lang.Runnable#run()
*/
public void run()
{
while (gameThreadRunFlag)
{
if (speed > 0)
{
if (!currentShape.stopped)
{
repaintWorkArea();
judgeCurrentShapeAbovedOther();
}
if (currentShape.isAtButtom() || currentShapeTouched || currentShape.stopped)
{
if (stoppedShapes.size() >= 2)
{
judgeCleanedBlock();
}
produceNextShape();
}
currentShape.moveDown();
++moveDownCount;
try
{
Thread.sleep(speedToSleepTime());
}
catch (InterruptedException e)
{
}
if (moveDownCount == 1)
{
judgeCurrentShapeAbovedOther();
if (currentShapeTouched || currentShape.stopped)
{
gameOver();
break;
}
}
}
else
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
}
}
}
gameThreadOver = true;
}
/**
*
*/
private void judgeCleanedBlock()
{
if (producing)
{
return;
}
Block topBlock = currentShape.getTopBlock();
Block buttomBlock = currentShape.getButtomBlock();
int cleanedLayers = 0;
for (int y = topBlock.y; y <= buttomBlock.y; y += Block.BLOCK_HEIGHT)
{
Vector<Block> totalLineBlocks = currentShape.getAllBlocksAtY(y);
for (int i = stoppedShapes.size() - 1; i >= 0; i--)
{
Shape shape = stoppedShapes.get(i);
Vector<Block> blocks = shape.getAllBlocksAtY(y);
if (blocks.size() > 0)
{
totalLineBlocks.addAll(blocks);
}
}
if (totalLineBlocks.size() == this.blockCountOfX)
{
for (int i = 0; i < totalLineBlocks.size(); i++)
{
Block blockToClean = totalLineBlocks.get(i);
((Shape)blockToClean.getOwner()).cleanBlock(blockToClean);
}
currentShape.moveDownBlocksUponAtY(y);
for (int j = 0; j < stoppedShapes.size(); j++)
{
Shape shape = stoppedShapes.get(j);
shape.moveDownBlocksUponAtY(y);
}
++cleanedLayers;
}
}
calculateScore(cleanedLayers);
if (cleanedLayers > 0)
{
outer:
while(true)
{
for (int i = 0; i < stoppedShapes.size(); i++)
{
Shape shape = stoppedShapes.get(i);
if (shape.isAllInvisible())
{
stoppedShapes.remove(i);
continue outer;
}
}
break;
}
}
}
/**
* @param cleanLayer
*/
private void calculateScore(int cleanLayer)
{
score += cleanLayer;
} /**
*
*/
private void produceNextShape()
{
if (producing)
{
//return;
}
//System.out.println("next1["+ nextShapeIndex1 + "],next2[" + nextShapeIndex2 + "]\n");
stoppedShapes.add(currentShape);
this.repaintWorkArea();
producing = true;
currentShapeIndex = nextShapeIndex1;
currentShape = new Shape(graph,workArea,allColors[currentShapeIndex],allShapes[currentShapeIndex]);
currentShapeTouched = false;
nextShapeIndex1 = nextShapeIndex2;
nextShapeIndex2 = shapeRandom.getInt();
printNextTwoShapes(true);
moveDownCount = 0;
producing = false;
this.repaintWorkArea();
//System.out.println("current[" + currentShapeIndex + "],next1["+ nextShapeIndex1 + "],next2[" + nextShapeIndex2 + "]\n");
}
/**
*
*/
private void judgeCurrentShapeAbovedOther()
{
for (int i = stoppedShapes.size() - 1; i >= 0; i--)
{
Shape shape = stoppedShapes.get(i);
if (shape.otherShapeAboveOnMe(currentShape))
{
currentShapeTouched = true;
currentShape.stopped = true;
break;
}
}
}
/**
*
*/
public boolean judgeCurrentShapeUnderedOther()
{
for (int i = stoppedShapes.size() - 1; i >= 0; i--)
{
Shape shape = stoppedShapes.get(i);
if (shape.otherShapeUnderMe(currentShape))
{
return true;
}
}
return false;
}
/**
*
*/
private boolean judgeCurrentShapeLeftSideOther()
{
for (int i = stoppedShapes.size() - 1; i >= 0; i--)
{
Shape shape = stoppedShapes.get(i);
if (shape.otherShapeLeftSideByMe(currentShape))
{
return true;
}
}
return false;
}
/**
*
*/
private boolean judgeCurrentShapeRightSideOther()
{
for (int i = stoppedShapes.size() - 1; i >= 0; i--)
{
Shape shape = stoppedShapes.get(i);
if (shape.otherShapeRightSideByMe(currentShape))
{
return true;
}
}
return false;
}
/**
* @param refresh
*/
private void printNextTwoShapes(boolean refresh)
{
if (refresh)
{
//System.out.println("printNextShapes["+nextShapeIndex1+"]["+nextShapeIndex2+"]");
workArea1.clearArea(graph);
workArea2.clearArea(graph);
nextShape1 = new Shape(graph,workArea1,allColors[nextShapeIndex1],allShapes[nextShapeIndex1]);
nextShape2 = new Shape(graph,workArea2,allColors[nextShapeIndex2],allShapes[nextShapeIndex2]);
}
//workArea1.clearArea(graph);
//workArea2.clearArea(graph);
//workArea1.drawArea(graph);
//workArea2.drawArea(graph);
if (nextShape1 != null && nextShape2 != null)
{
nextShape1.drawMe();
nextShape2.drawMe();
}
}
private void printInfors()
{
if (previousScore == score)
{
//return;
}
int x = workArea2.x + Block.BLOCK_WIDTH / 10;
int y = workArea2.y + workArea2.height + Block.BLOCK_HEIGHT;
// not work. strange!!
//graph.clearRect(x,y, getWidth(), getHeight());
graph.setColor(Color.black);
graph.setFont(new Font(STRING_FONT,Block.BLOCK_WIDTH,Block.BLOCK_WIDTH));
graph.drawString("Score:" + score, x, y);
graph.drawString("Speed:" + speed, x, y + Block.BLOCK_WIDTH * 2);
previousScore = score;
}
/**
* 重要方法, 用来重绘窗口
*/
@Override
public void paint(Graphics graph)
{
super.paint(graph);
repaintWorkArea();
}
/**
*
*/
private void repaintWorkArea()
{
graph.clearRect(0,TITLE_PANEL_HEIGHT, getWidth(), getHeight());
workArea.drawArea(graph);
for (int i = 0; i < stoppedShapes.size(); i++)
{
stoppedShapes.get(i).drawMe();
}
if (gameOver)
{
gameOver();
}
if (gamePause)
{
pause();
}
printInfors();
printNextTwoShapes(false);
}
private void pause()
{
if (gameOver || gamePause)
{
return;
}
graph.setColor(Color.green);
graph.setFont(new Font(STRING_FONT,22,22));
graph.drawString("Pause", workArea.x + workArea.width / 2 - 20, workArea.height / 2);
speed = 0;
gamePause = true;
currentShape.drawMe();
}
private void resume()
{
speed = speedSlider.getValue();
gamePause = false;
gameThread.interrupt();
}
/**
*
*/
private void gameOver()
{
graph.setColor(Color.red);
graph.setFont(new Font(STRING_FONT,20,20));
graph.drawString("GameOver", workArea.x + workArea.width / 2 - 20, workArea.height / 2);
gameOver = true;
moveDownCount = 0;
currentShapeTouched = false;
}
/**
* @return
*/
private long speedToSleepTime()
{
return (long)((5.0 / speed) * 1000);
}
/**
* @return
*/
public WorkArea getWorkArea()
{
return workArea;
} /* (non-Javadoc)
* @see java.awt.event.KeyListener#keyPressed(java.awt.event.KeyEvent)
*/
public void keyPressed(KeyEvent event)
{
if (currentShape == null ||
gameOver ||
gamePause ||
currentShape.stopped)
{
return;
}
//System.out.println("keyPressed:" + event.getKeyCode());
int keyCode = event.getKeyCode();
if (keyCode >= 37 && keyCode <= 40 || keyCode == 32 || keyCode == 10)
{
repaintWorkArea();
}
// space
if (keyCode == 32)
{
currentShape.clockRotate();
}
// enter
else if (keyCode == 10)
{
currentShape.deClockRotate();
}
// up
else if (keyCode == 38)
{
currentShape.moveUp();
}
// down
else if (keyCode == 40)
{
moveToButtom();
//currentShape.moveDown();
}
// left
else if (keyCode == 37)
{
if (!judgeCurrentShapeRightSideOther())
{
currentShape.moveLeft();
}
}
// right
else if (keyCode == 39)
{
if (!judgeCurrentShapeLeftSideOther())
{
currentShape.moveRight();
}
}
judgeCurrentShapeAbovedOther();
}
/**
*
*/
private void moveToButtom()
{
currentShapeTouched = true;
int distanceOfY = (workArea.y + workArea.height) - (currentShape.getButtomBlock().y + Block.BLOCK_HEIGHT) - gapSize / 2;
System.out.println("begin y distance : " + distanceOfY);
for (int i = 0; i < stoppedShapes.size(); i++)
{
Shape shape = stoppedShapes.get(i);
if (shape.getRightBlock().x < currentShape.getLeftBlock().x ||
shape.getLeftBlock().x > currentShape.getRightBlock().x)
{
continue;
}
int tmp = shape.getYDistanceWithOtherShape(currentShape);
if (tmp != -1 && tmp < distanceOfY)
{
distanceOfY = tmp;
}
}
System.out.println("final y distance : " + distanceOfY);
currentShape.moveDown(distanceOfY);
currentShape.stopped = true;
this.judgeCleanedBlock();
this.produceNextShape();
}
/* (non-Javadoc)
* @see java.awt.event.KeyListener#keyReleased(java.awt.event.KeyEvent)
*/
public void keyReleased(KeyEvent event)
{
//System.out.println("keyReleased:" + event.getKeyCode());
} /* (non-Javadoc)
* @see java.awt.event.KeyListener#keyTyped(java.awt.event.KeyEvent)
*/
public void keyTyped(KeyEvent event)
{
//System.out.println("keyTyped:" + event.getKeyCode());
} /* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent)
*/
public void mouseClicked(MouseEvent arg0)
{
//System.out.println("mouseClicked");
//pause();
//repaintWorkArea();
} /* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent)
*/
public void mouseEntered(MouseEvent arg0)
{
} /* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent)
*/
public void mouseExited(MouseEvent arg0)
{
} /* (non-Javadoc)
* @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
*/
public void mousePressed(MouseEvent arg0)
{
//System.out.println("mousePressed");
//pause();
//repaintWorkArea();
} /* (non-Javadoc)
* @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent)
*/
public void mouseReleased(MouseEvent arg0)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
*/
public void stateChanged(ChangeEvent arg0)
{
speed = speedSlider.getValue();
gameThread.interrupt();
speedLabel.setText(speedSlider.getValue() + "");
}
/**
* 初始化菜单
*
*/
private void getMenu()
{
JMenuBar menuBar = new JMenuBar();
menuBar.addMouseMotionListener(this);
JMenu fileMenu = new JMenu("文 件 (F) ");
fileMenu.setMnemonic(KeyEvent.VK_F);
fileMenu.setActionCommand("filemenu");
fileMenu.addMouseListener(this);
JMenu gameMenu = new JMenu("游 戏 (G) ");
gameMenu.setMnemonic(KeyEvent.VK_G);
JMenuItem openMenuItem = new JMenuItem("打 开... (O)", KeyEvent.VK_O);
KeyStroke ctrlOKeyStroke = KeyStroke.getKeyStroke("control O");
openMenuItem.setAccelerator(ctrlOKeyStroke);
JMenuItem saveMenuItem = new JMenuItem("保 存 (S)", KeyEvent.VK_S);
KeyStroke ctrlSKeyStroke = KeyStroke.getKeyStroke("control S");
saveMenuItem.setAccelerator(ctrlSKeyStroke);
JMenuItem aboutMenuItem = new JMenuItem("关于本程序", KeyEvent.VK_A);
aboutMenuItem.addActionListener(this);
aboutMenuItem.setActionCommand("about");
JMenuItem exitMenuItem = new JMenuItem("退出游戏 (X)", KeyEvent.VK_X);
openMenuItem.addActionListener(this);
openMenuItem.setActionCommand("opengame");
saveMenuItem.addActionListener(this);
saveMenuItem.setActionCommand("savegame");
exitMenuItem.addActionListener(this);
exitMenuItem.setActionCommand("exitgame");
fileMenu.add(openMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.addSeparator();
fileMenu.add(aboutMenuItem);
fileMenu.addSeparator();
fileMenu.add(exitMenuItem);
// /////////////
JMenuItem newGameItem = new JMenuItem("新游戏 (N)", KeyEvent.VK_N);
newGameItem.addActionListener(this);
newGameItem.setActionCommand("newgame");
KeyStroke ctrlZKeyStroke = KeyStroke.getKeyStroke("control N");
newGameItem.setAccelerator(ctrlZKeyStroke);
gameMenu.add(newGameItem);
JMenuItem pauseGameItem = new JMenuItem("暂 停 (P)", KeyEvent.VK_P);
pauseGameItem.addActionListener(this);
pauseGameItem.setActionCommand("pausegame");
KeyStroke ctrlYKeyStroke = KeyStroke.getKeyStroke("control P");
pauseGameItem.setAccelerator(ctrlYKeyStroke);
gameMenu.add(pauseGameItem);
JMenuItem resumeGameItem = new JMenuItem("继 续 (C)", KeyEvent.VK_C);
resumeGameItem.addActionListener(this);
resumeGameItem.setActionCommand("resumegame");
KeyStroke ctrlCKeyStroke = KeyStroke.getKeyStroke("control C");
resumeGameItem.setAccelerator(ctrlCKeyStroke);
gameMenu.add(resumeGameItem);
JMenuItem optionGameItem = new JMenuItem("选 项 (O)", KeyEvent.VK_O);
optionGameItem.addActionListener(this);
optionGameItem.setActionCommand("option");
KeyStroke ctrlPKeyStroke = KeyStroke.getKeyStroke("control O");
optionGameItem.setAccelerator(ctrlPKeyStroke);
gameMenu.addSeparator();
gameMenu.add(optionGameItem);
// ///////////////
menuBar.add(fileMenu);
menuBar.add(gameMenu);
this.setJMenuBar(menuBar);
}
/* (non-Javadoc)
* @see java.awt.event.MouseMotionListener#mouseDragged(java.awt.event.MouseEvent)
*/
public void mouseDragged(MouseEvent arg0)
{
// TODO Auto-generated method stub
}
/* (non-Javadoc)
* @see java.awt.event.MouseMotionListener#mouseMoved(java.awt.event.MouseEvent)
*/
public void mouseMoved(MouseEvent arg0)
{
if (gameOver || gamePause)
{
return;
}
pause();
}
/* (non-Javadoc)
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
*/
public void actionPerformed(ActionEvent event)
{
String cmd = event.getActionCommand();
if (cmd.equals("exitgame"))
{
shutdown();
}
else if (cmd.equals("newgame"))
{
newGame();
}
else if (cmd.equals("pausegame"))
{
pause();
}
else if (cmd.equals("resumegame"))
{
resume();
}
// 未处理的命令部分.提示开发人员
else
{
MsgBox.alert("您还未在actionPerformed()方法中完成处理命令[" + cmd + "]的响应代码");
}
repaintWorkArea();
}
public static void main(String[] args)
{
ConfigUtil.config();
new BlockFrame();
}
}
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package lesson54;import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.LineBorder;/**
*
* @author scj
*/
/**
* 运行该文件
*/
public class Matrix extends JPanel { private JLabel matrix[][];
public static final int ROW = 20;
public static final int COLUMN = 15;
private MatrixModel model; public Matrix() {
this.setLayout(new GridLayout(ROW, COLUMN));
init();
Dimension size = new Dimension(COLUMN * 20, ROW * 20);
this.setPreferredSize(size);
this.setMinimumSize(size);
this.setMaximumSize(size);
this.addKeyListener(new MyKeyListener());
this.setFocusable(true);
model = new MatrixModel(this);
} public void start() {
model.start();
} private void init() {
matrix = new JLabel[ROW][COLUMN];
JLabel label = null;
for (int i = 0; i < ROW; i++) {
for (int j = 0; j < COLUMN; j++) {
label = new JLabel(" ");
label.setBorder(new LineBorder(Color.GRAY));
label.setOpaque(true);
matrix[i][j] = label;
add(matrix[i][j]);
}
}
} public void displayState(int[][] state) {
for (int i = 0; i < state.length; i++) {
for (int j = 0; j < state[i].length; j++) {
if (state[i][j] == 1) {
matrix[i][j].setBackground(Color.red);
} else {
matrix[i][j].setBackground(Color.black);
}
}
}
} class MyKeyListener extends KeyAdapter { public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
model.moveLeft();
} else if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
model.moveRight();
} else if (e.getKeyCode() == KeyEvent.VK_DOWN) {
model.down();
} else if (e.getKeyCode() == KeyEvent.VK_UP) {
model.rotateSharp();
}
}
} public static void main(String arg[]) {
JFrame frame = new JFrame();
Matrix matrix = new Matrix();
matrix.start();
frame.add(new JScrollPane(matrix));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
/*
* int i[][] = {{10,20}, {11, 21}, {21, 31}}; int j[][] = new int[3][2];
* System.arraycopy(i, 0, j, 0, i.length); for(int x=0; x<j.length;
* x++){ for(int y=0; y<j[x].length; y++){ System.out.print(j[x][y]+"
* "); } System.out.println(); }
*/
}
}
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package lesson54;import java.util.*;/**
*
* @author scj
*/
public class MatrixModel { private int model[][];
private int sharp[][];
private int state[][];
private int currentX, currentY;
private Matrix myParent;
private RunThread runThread;
private int currentIndex; public MatrixModel(Matrix parent) {
myParent = parent;
model = new int[Matrix.ROW][Matrix.COLUMN];
state = new int[Matrix.ROW][Matrix.COLUMN];
newSharp();
} public void start() {
runThread = new RunThread();
runThread.start();
} private int[][] randomSharp() {
currentIndex = (int) (MatrixSharp.NUMBER * Math.random());
return MatrixSharp.sharp[currentIndex];
} private synchronized boolean isMoveAvaliable(int currentX, int currentY) {
if (currentX > Matrix.COLUMN - 1) {
return false;
}
if (currentX < 0) {
for (int i = 0; i < 4; i++) {
for (int j = 0; j < Math.abs(currentX); j++) {
if (sharp[i][j] != 0) {
return false;
}
}
}
}
if (currentY < 0 || currentY > Matrix.ROW - 1) {
return false;
}
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if (currentX + x > -1 && currentX + x < Matrix.COLUMN && currentY + y < Matrix.ROW) {
if ((sharp[y][x] & model[currentY + y][currentX + x]) != 0) {
return false;
}
} else {
if (currentX + x >= Matrix.COLUMN) {
if (sharp[y][x] != 0) {
return false;
}
} else if (currentY + y >= Matrix.ROW) {
if (sharp[y][x] != 0) {
return false;
}
}
}
}
}
return true;
} private synchronized void moveTo(int x, int y) {
for (int i = 0; i < Matrix.ROW; i++) {
for (int j = 0; j < Matrix.COLUMN; j++) {
state[i][j] = model[i][j];
}
}
for (int c = 0; c < 4; c++) {
for (int r = 0; r < 4; r++) {
if (currentX + c > -1 && currentX + c < Matrix.COLUMN && currentY + r < Matrix.ROW) {
state[currentY + r][currentX + c] |= sharp[r][c];
}
}
}
myParent.displayState(state);
} public void over() {
System.out.println("game over");
runThread.end();
} public synchronized void moveLeft() {
if (isMoveAvaliable(currentX - 1, currentY)) {
currentX -= 1;
moveTo(currentX, currentY);
}
} public synchronized void moveRight() {
if (isMoveAvaliable(currentX + 1, currentY)) {
currentX += 1;
moveTo(currentX, currentY);
}
} private boolean isOver() {
if (currentY == 0) {
return false;
}
return false;
} private synchronized void resetState() {
state = new int[Matrix.ROW][Matrix.COLUMN];
moveTo(currentX, currentY);
} public synchronized void down() {
if (isMoveAvaliable(currentX, currentY + 1)) {
currentY += 1;
moveTo(currentX, currentY);
} else {
if (isOver()) {
over();
return;
}
model = state;
check();
resetState();
newSharp();
}
} public synchronized void check() {
Vector clearVector = new Vector();
for (int i = Matrix.ROW - 1; i > 0; i--) {
int j = 0;
for (; j < Matrix.COLUMN; j++) {
if (model[i][j] == 0) {
break;
}
}
if (j == Matrix.COLUMN) {
clearVector.add(new Integer(i));
}
}
clearRows(clearVector);
} private synchronized void clearRows(Vector clearVector) { for (int i = clearVector.size(); i > 0; i--) {
int row = ((Integer) clearVector.get(i - 1)).intValue();
for (int j = 0; j < Matrix.COLUMN; j++) {
for (int k = row; k >= 0; k--) {
if (k == 0) {
model[k][j] = 0;
} else {
model[k][j] = model[k - 1][j];
}
}
}
}
} public synchronized void rotateSharp() {
int tmpIndex = currentIndex++;
if (currentIndex % 4 == 0) {
currentIndex -= 4;
}
int[][] tmpSharp = MatrixSharp.sharp[currentIndex];
if (isRotateAble(tmpSharp)) {
sharp = MatrixSharp.sharp[currentIndex];
moveTo(currentX, currentY);
} else {
currentIndex = tmpIndex;
}
} private synchronized boolean isRotateAble(int sharp[][]) {
for (int x = 0; x < 4; x++) {
for (int y = 0; y < 4; y++) {
if ((currentX + x < 0 || currentX + x >= Matrix.COLUMN) || (currentY + y < 0 || currentY + y >= Matrix.ROW)) {
if (sharp[y][x] != 0) {
return false;
}
}
}
}
return isMoveAvaliable(currentX, currentY);
} private synchronized void newSharp() {
currentX = Matrix.COLUMN / 2;
currentY = 0;
sharp = randomSharp();
} class RunThread extends Thread { boolean isRun = true; public void end() {
isRun = false;
} public void run() {
while (isRun) {
down();
try {
sleep(500);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}interface MatrixSharp { static int sharp[][][] = new int[][][]{
{{0, 0, 1, 0}, {0, 0, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 1}, {0, 0, 0, 0}},
{{0, 1, 1, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {1, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}},
{{1, 1, 1, 1}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 0}, {0, 0, 1, 1}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 1, 1, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 0, 1, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}, {0, 0, 0, 0}},
{{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 0, 1, 0}, {1, 1, 1, 0}, {0, 0, 0, 0}},
{{0, 1, 1, 0}, {0, 0, 1, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}},
{{0, 0, 0, 0}, {0, 1, 1, 1}, {0, 1, 0, 0}, {0, 0, 0, 0}}};
static int NUMBER = sharp.length;
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Terris extends JFrame implements Runnable, KeyListener {
private short isPlaying=0/*是否游戏,声明*/,xOffSet = 3/*当前方块的横坐标*/, yOffSet = 0/*当前方块的纵坐标*/, blockType = (short) Math.round(Math.random() * 6)/*随即初始方块类型*/, blockRotation = 0/*初始方块旋转角度*/, blockColor = (short) Math.round(Math.random() * 5)/*随即初始方块颜色*/;
private short matrix[][] = new short[21][10];/*整个画布21*10的矩阵*/
private short block[][][][] = {{{{ 0, 1, 0, 0 },{ 0, 1, 0, 0 },{ 0, 1, 0, 0 },{ 0, 1, 0, 0 }},/* l */{{ 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 },{ 0, 0, 0, 0 } } },/*-*/{{ { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 },{ 0, 0, 0, 0 } },/* z */{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 },{ 0, 1, 0, 0 } } },/* z| */{{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 },{ 0, 0, 0, 0 } },/* xz */{ { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 },{ 0, 0, 0, 0 } } },/* xz| */{ { { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } } },/** []*/{{ { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 1, 0 },{ 0, 0, 0, 0 } },{ { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 1, 1, 0, 0 },{ 0, 0, 0, 0 } },{ { 1, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 },{ 0, 0, 0, 0 } } },/* f */{{ { 1, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 0, 1, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 },{ 0, 0, 0, 0 } },{ { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 1, 0, 0, 0 },{ 0, 0, 0, 0 } } },/* xf */ {{ { 0, 1, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 0 } },{ { 0, 1, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 0, 0 },{ 0, 0, 0, 0 } } } };/* t *//*保存所有方块的4维矩阵,分别是:方块类型、方块旋转、方块x坐标、方块y坐标*/
private Image[] images = {new ImageIcon("D:/Java/eclipse/workspace/Terris/src/img/Red.gif").getImage(),new ImageIcon("D:/Java/eclipse/workspace/Terris/src/img/Blue.gif").getImage(),new ImageIcon(("D:/Java/eclipse/workspace/Terris/src/img/Pink.gif")).getImage(),new ImageIcon(("D:/Java/eclipse/workspace/Terris/src/img/BBlue.gif")).getImage(),new ImageIcon(("D:/Java/eclipse/workspace/Terris/src/img/Orange.gif")).getImage(),new ImageIcon(("D:/Java/eclipse/workspace/Terris/src/img/Green.gif")).getImage(),new ImageIcon("D:/Java/eclipse/workspace/Terris/src/img/Red.gif").getImage()};/*各种颜色方块图片*/
public Terris() {
setSize(160, 335);/*窗口大小*/
setVisible(true);/*可视*/
createBufferStrategy(2);/*对当前窗口创建双缓冲*/
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);/*设置关闭按钮事件*/
addKeyListener(this);/*添加按键响应*/
}
public void paint(Graphics g) {
Graphics tg = this.getBufferStrategy().getDrawGraphics();/*获取后台缓冲画布*/
tg.fillRect(5, 30, 150, 340);/*涂黑背景*/
for (int i = 0; i < 21; i++)
for (int j = 0; j < 10; j++) {
if (matrix[i][j] != 0)
tg.drawImage(images[matrix[i][j]], j * 15 + 5, i * 15 + 15,null);/*根据后台背景的矩阵绘制已经固定的各方块*/
if (i < 4 && j < 4&& block[blockType][blockRotation][i][j] != 0)
tg.drawImage(images[blockColor + 1],((j + xOffSet) * 15) + 5,((i + yOffSet) * 15) + 15, null);/*绘制当前能控制的方块*/
}
this.getBufferStrategy().show();/*切换后台画布到前台显示*/
}
public static void main(String[] args) {
new Thread(new Terris()).start();//初始化界面并创建启动游戏线程
}
public void run() {
while (isPlaying==0)/*当游戏正在进行 不断下落*/
try {
if (check(0, 0, 0, 1))/*最后一个参数1 是下落 表示下落一格 其他参数见下面的注释*/
yOffSet += 1;/*如果能下落 y坐标+1*/
else {/*如不能下落 说明到底了*/
if (yOffSet == 0) {/*如果当前是第一个方块 游戏结束*/
isPlaying = 1;
continue;/*不再循环*/
}
freezeAndNew();/*将当前控制的方块合并到背景矩阵中 并初始化新的方块*/
}
repaint();/*重绘画布*/
Thread.sleep(600);/*线程sleep 可以修改作为难度*/
} catch (InterruptedException e) {/*无用*/
}
}
private boolean check(int left, int right, int up, int down) {/*判断方块是否可以左右移动、下落、旋转 都合并到一个方法中了 四个参数分别代表要判断左移、右移、旋转、下落 如果对应方向有动作 则传入1 没有动作传入0 在判断时直接计算参数值即可 而不考虑传入的具体值是1还是0*/
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
if (((xOffSet + j - left + right < 0 || xOffSet + j - left+ right >= 10) && block[blockType][((blockRotation + up) >= block[blockType].length ? 0: (blockRotation + up))][i][j] != 0)|| ((yOffSet + i + down >= 21) && block[blockType][((blockRotation + up) >= block[blockType].length ? 0: (blockRotation + up))][i][j] != 0)|| (block[blockType][((blockRotation + up) >= block[blockType].length ? 0: (blockRotation + up))][i][j] != 0 && matrix[yOffSet+ i + down][xOffSet + j - left + right] != 0))
return false;
return true;
}
private synchronized void freezeAndNew() {/*方块到底 固定到背景矩阵 并初始化新方块*/
boolean[] clear = new boolean[]{false,false,false,false};/*是否可以消行的数组 每个方块4*4 只需判断方块所在的4行即可*/
for (int i = 0; i < 4; i++){
for (int j = 0; j < 4; j++)
if (block[blockType][blockRotation][i][j] != 0)/*循环将方块的1赋值到背景的矩阵中 方块4*4中的0 没有方块的地方不复制*/
matrix[i + yOffSet][j + xOffSet] = (short) (blockColor + 1);/*根据当前方块颜色复制到背景 可修改为灰色*/
clear[i]=i + yOffSet>=matrix.length?false:(matrix[i + yOffSet][0]!=0&&matrix[i + yOffSet][1]!=0&&matrix[i + yOffSet][2]!=0&&matrix[i + yOffSet][3]!=0&&matrix[i + yOffSet][4]!=0&&matrix[i + yOffSet][5]!=0&&matrix[i + yOffSet][6]!=0&&matrix[i + yOffSet][7]!=0&&matrix[i + yOffSet][8]!=0&&matrix[i + yOffSet][9]!=0);/*一次判断一行0~9个方块是否有值 有值 复制到消行数组为true*/
}
for(int i=0;i<clear.length;i++)
if(clear[i])/*如果消行*/
for(int j=yOffSet+i;j>0;j--)
System.arraycopy(matrix[j-1],0,matrix[j],0,10);/*循环从当前行依次把上面一行复制下来 下落效果*/
yOffSet = blockRotation = 0;/*消行结束 下面几行是初始化新方块 xy方块类型 旋转 颜色*/
xOffSet = 3;
blockType = (short) Math.round(Math.random() * 6);
blockRotation = (short) Math.round((Math.random() * (block[blockType].length - 1)));
blockColor = (short) Math.round(Math.random() * 5);
}
public void keyPressed(KeyEvent e) {// 38-上 40-下 37-左 39-右
if ((e.getKeyCode() == 65 || e.getKeyCode() == 37) && check(1, 0, 0, 0)&&isPlaying==0) {// left/*左移 传入判断方块是否能移动的方法 第一个参数传1 其他传0*/
xOffSet--;/*能左移 x减1*/
} else if ((e.getKeyCode() == 68 || e.getKeyCode() == 39)&& check(0, 1, 0, 0)&&isPlaying==0) {// right/*类似上面 右移第二个参数传1 其他0*/
xOffSet++;/*能右移 x加1*/
} else if ((e.getKeyCode() == 87 || e.getKeyCode() == 38)&& check(0, 0, 1, 0)&&isPlaying==0) {// up
blockRotation = (short) ((blockRotation + 1) >= block[blockType].length ? 0: (blockRotation + 1));/*能旋转 根据当前方块类型进行旋转 如果到最后一个角度 回到0 继续旋转*/
} else if ((e.getKeyCode() == 83 || e.getKeyCode() == 40)&& check(0, 0, 0, 1)&&isPlaying==0) {// down
yOffSet += 1;/*能下落 y加1*/
} else if((e.getKeyCode() == 83 || e.getKeyCode() == 40)&& isPlaying==0)
freezeAndNew();/*不能下落 固定 并消行 新方块*/
repaint();/*移动事件触发重绘*/
}
public void keyReleased(KeyEvent arg0) {/*无用*/
}
public void keyTyped(KeyEvent arg0) {/*无用*/
}
}
//作者:http://wireless.javaeye.com/blog/595321