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

📄 mainframe.java

📁 比较好的用java实现的俄罗斯方块 写的比较详细 功能基本完善
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
	public void pauseGame() {
		if (shape == null)
			return;
		shape.setPause(true);
		for (GameListener l : listeners)
			l.gamePause();
	}

	/**
	 * 继续游戏
	 */
	public void continueGame() {
		shape.setPause(false);
		for (GameListener l : listeners)
			l.gameContinue();
	}

	/**
	 * 游戏是否是在暂停状态
	 */
	public boolean isPausingGame() {
		return shape.isPause();
	}

	/**
	 * 获得游戏的最新提示信息
	 * 
	 * @return
	 */
	public String getNewInfo() {
		if (!playing || ground.isFull())
			return " ";// "提示: 按 Y 开始新游戏";
		else
			return new StringBuffer().append("提示: ").append(" 速度 ").append(
					shape.getSpeed()).append("毫秒/格").toString();
	}

	public ShapeFactory getShapeFactory() {
		return shapeFactory;
	}

	public void setShapeFactory(ShapeFactory shapeFactory) {
		this.shapeFactory = shapeFactory;
	}

	public Ground getGround() {
		return ground;
	}

	public void setGround(Ground ground) {
		this.ground = ground;
	}

	public GamePanel getGamePanel() {
		return gamePanel;
	}

	public void setGamePanel(GamePanel gamePanel) {
		this.gamePanel = gamePanel;
	}

	/**
	 * 处理Ground 触发的 beforeDeleteFullLine 事件将会改变满行的颜色并暂停一段时间
	 */
	public void beforeDeleteFullLine(Ground ground, int lineNum) {
		// TODO Auto-generated method stub
		ground.changeFullLineColor(lineNum);
		gamePanel.redisplay(ground, shape);
		try {
			Thread.sleep(Global.STAY_TIME);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 处理Ground 触发的 fullLineDeleted 事件, 这个方法什么也没做, 只是打印了一句话
	 */
	public void fullLineDeleted(Ground ground, int deletedLineCount) {
		// TODO Auto-generated method stub
		System.out.println("消了 " + deletedLineCount + " 行");
	}

	/**
	 * 是否正在游戏中
	 * 
	 * @return
	 */
	public boolean isPlaying() {
		if (playing && !ground.isFull())
			return true;
		return false;
	}

	/**
	 * 得到显示提示信息的组件
	 * 
	 * @return
	 */
	public JLabel getGameInfoLabel() {
		return gameInfoLabel;
	}

	/**
	 * 设置
	 * 
	 * @param gameInfoLabel
	 */
	public void setGameInfoLabel(JLabel gameInfoLabel) {
		this.gameInfoLabel = gameInfoLabel;
		this.gameInfoLabel.setSize(Global.WIDTH * Global.CELL_WIDTH, 20);
		this.gameInfoLabel.setFont(new Font("宋体", Font.PLAIN, 12));
		gameInfoLabel.setText(this.getNewInfo());
	}

	/**
	 * 处理Ground 的 groundIsFull() 事件, 将触发游戏结束事件
	 */
	public void groundIsFull(Ground ground) {
		// TODO Auto-generated method stub
		if (playing) {
			playing = false;
			for (GameListener l : listeners)
				l.gameOver();
		}
	}

	/**
	 * 添加监听器, 可添加多个
	 * 
	 * @param l
	 */
	public void addGameListener(GameListener l) {
		if (l != null)
			this.listeners.add(l);
	}

	/**
	 * 移除监听器
	 * 
	 * @param l
	 */
	public void removeGameListener(GameListener l) {
		if (l != null)
			this.listeners.remove(l);
	}

}
/**
 * 
 * 
 * 工具类<BR>
 * <BR>
 * 此类中存放了其他类中用到的一些常量<BR>
 * 并且支持配置文件<BR>
 * 配置文件的路径为游戏运行的目录, 文件名为 tetris.ini<BR>
 * <BR>
 * 配置文件的写法请参见字段的注释<BR>
 * <BR>
 * 配置文件中设置项可以只写需要配置的, 没有写的设置项默认为缺省值<BR>
 * 各配置项的缺省值请参见字段的注释<BR>
 * <BR>
 * 每个配置项都有设置值范围, 超出范围(无效)的设置值将不起作用<BR>
 * 设置值的范围请参见字段的注释<BR>
 * 
 * @version 1.0, 08/01/08
 * 
 * @author 汤阳光
 * 
 */
 class Global {

	private static Properties properties = new Properties();

	/**
	 * 配置文件的路径(默认为当前目录下的 snake.ini文件)
	 */
	private static String CONFIG_FILE = "tetris.ini";

	/**
	 * 一个格子的宽度, 单位:像素 <BR>
	 * 对应的配置文件中的关键字为: cell_width, 或用 cell_size指定<BR>
	 * 范围1 至 100<BR>
	 * 缺省值为 23
	 */
	public static final int CELL_WIDTH;

	/**
	 * 一个格子的高度, 单位:像素 <BR>
	 * 对应的配置文件中的关键字为: cell_width, 或用 cell_size指定<BR>
	 * 范围1 至 100<BR>
	 * 缺省值为 23
	 */
	public static final int CELL_HEIGHT;
	/**
	 * 用格子表示的宽度, (宽度为多少个格子) 单位:格 <BR>
	 * 对应的配置文件中的关键字为: width<BR>
	 * 范围10 至 80<BR>
	 * 缺省值为 15
	 */
	public static final int WIDTH;

	/**
	 * 用格子表示的高度, (高度为多少个格子), 单位:格<BR>
	 * 对应的配置文件中的关键字为: height<BR>
	 * 范围10 至 60<BR>
	 * 缺省值为20
	 */
	public static final int HEIGHT;

	/**
	 * 图形下落的初始速度 (单位: 毫秒/格)<BR>
	 * 对应的配置文件中的关键字为: speed<BR>
	 * 范围10 至 无限大<BR>
	 * 缺省值为 200
	 */
	public static final int DEFAULT_SPEED;

	/**
	 * 保存当前游戏中图形的下落速度
	 */
	public static int CURRENT_SPEED;

	/**
	 * 图形快速下落的速度 (单位: 毫秒/格)<BR>
	 * 对应的配置文件中的关键字为: swift_speed<BR>
	 * 范围0 至 无限大<BR>
	 * 缺省值为 15
	 */
	public static final int SWIFT_SPEED;

	/**
	 * 每次加速或减速的幅度 (单位: 毫秒/格)<BR>
	 * 对应的配置文件的关键字为: speed_step<BR>
	 * 范围1 至 无限大<BR>
	 * 缺省值为 25
	 */
	public static final int SPEED_STEP;

	/**
	 * 消除满行前暂停效果的时间(单位: 毫秒)<BR>
	 * 对应的配置文件的关键字为: stay_time<BR>
	 * 范围0 至 无限大<BR>
	 * 缺省值为 200
	 */
	public static final int DEFAULT_STAY_TIME;

	/**
	 * 消除满行前暂停效果的时间
	 */
	public static int STAY_TIME;

	private static Random random = new Random();

	public static final String TITLE_LABEL_TEXT;

	public static final String INFO_LABEL_TEXT;

	private static final Color[] DEFAULT_COLORS = new Color[] {
			new Color(0x990066), new Color(0x990099), new Color(0x330099),
			new Color(0x663300), new Color(0x009966), new Color(0x003333) };

	public static final List<Color> COMMON_COLORS;

	/**
	 * 返回一个随机的颜色
	 * 
	 * @return
	 */
	public static Color getRandomColor() {
		return DEFAULT_COLORS[random.nextInt(DEFAULT_COLORS.length)];
	}

	/**
	 * 默认的构造器, 私有的, 不能生成这个类的实例
	 */
	private Global() {
	}

	/**
	 * 初始化常量
	 */
	static {
		InputStream inputStream = null;

		try {
			inputStream = new FileInputStream(CONFIG_FILE);
			properties.load(inputStream);
		} catch (FileNotFoundException e) {
			System.out.println("没有配置文件");
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (inputStream != null)
					inputStream.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		Integer temp = null;
		WIDTH = (temp = getIntValue("width")) != null && temp <= 80
				&& temp >= 10 ? temp : 15;
		HEIGHT = (temp = getIntValue("height")) != null && temp <= 60
				&& temp >= 10 ? temp : 20;
		DEFAULT_SPEED = CURRENT_SPEED = (temp = getIntValue("speed")) != null
				&& temp >= 10 ? temp : 300;
		SWIFT_SPEED = (temp = getIntValue("swift_speed")) != null && temp >= 0 ? temp
				: 15;
		SPEED_STEP = (temp = getIntValue("speed_step")) != null && temp >= 1 ? temp
				: 25;
		DEFAULT_STAY_TIME = STAY_TIME = (temp = getIntValue("stay_time")) != null
				&& temp >= 0 ? temp : 200;
		int defaultCellSize = (temp = getIntValue("cell_size")) != null
				&& temp > 0 && temp <= 100 ? temp : 23;
		CELL_WIDTH = (temp = getIntValue("cell_width")) != null && temp > 0
				&& temp <= 100 ? temp : defaultCellSize;
		CELL_HEIGHT = (temp = getIntValue("cell_height")) != null && temp > 0
				&& temp <= 100 ? temp : defaultCellSize;

		String tempStr = null;
		TITLE_LABEL_TEXT = (tempStr = getValue("title")) == null ? "说明:"
				: tempStr;
		INFO_LABEL_TEXT = (tempStr = getValue("info")) == null ? "方向键控制方向, 回车键暂停/继续\nPAGE UP, PAGE DOWN 加速或减速\n\n更多请看 www.itcast.cn "
				: tempStr;

		COMMON_COLORS = loadColors();
	}

	/**
	 * 要考虑多种情况<BR>
	 * 1. 没有这个key和value<BR>
	 * 2 有key 没有 value
	 */
	private static Integer getIntValue(String key) {
		if (key == null)
			throw new RuntimeException("key 不能为空");
		try {
			return new Integer(properties.getProperty(key));
		} catch (NumberFormatException e) {
			return null;
		}
	}

	private static String getValue(String key) {
		try {
			return new String(properties.getProperty(key).getBytes("iso8859-1"));
		} catch (Exception e) {
			return null;
		}
	}

	@SuppressWarnings("unchecked")
	private static List<Color> loadColors() {

		List<Color> l = new ArrayList<Color>(7);
		for (int i = 0; i < 7; i++)
			l.add(null);

		Set set = properties.keySet();
		Iterator iter = set.iterator();
		while (iter.hasNext()) {
			String key = (String) iter.next();
			if ("1".equals(key.trim()))
				addColor(l, 0, getValue(key));
			else if ("2".equals(key.trim()))
				addColor(l, 1, getValue(key));
			else if ("3".equals(key.trim()))
				addColor(l, 2, getValue(key));
			else if ("4".equals(key.trim()))
				addColor(l, 3, getValue(key));
			else if ("5".equals(key.trim()))
				addColor(l, 4, getValue(key));
			else if ("6".equals(key.trim()))
				addColor(l, 5, getValue(key));
			else if ("7".equals(key.trim()))
				addColor(l, 6, getValue(key));
		}

		for (int i = 0; i < 7; i++) {
			l.remove(null);
		}

		if (l.size() < 1) {
			for (int i = 0; i < DEFAULT_COLORS.length; i++) {
				l.add(DEFAULT_COLORS[i]);
			}
		} else {
			if (l.size() != 7)
				System.out.println("您一共设置了 " + l.size() + " 种有效颜色, 建议设置七种");

			return l.subList(0, l.size() > 7 ? 7 : l.size());
		}
		return l;
	}

	@SuppressWarnings("unchecked")
	private static void addColor(List l, int index, String str) {
		str = str.trim();
		if (!str.startsWith("0x") || str.length() < 3) {
			System.out.println("颜色设置有误,请检查 : " + str + " (key)");
			return;
		}

		try {
			String strRGB = str.substring(2, str.length() >= 8 ? 8 : str
					.length());
			int rgb = Integer.valueOf(strRGB, 16);
			Color c = new Color(rgb);
			if (c != null) {
				l.add(index, c);
			}
		} catch (Exception e) {
			System.out.println("(e)颜色设置有误,请检查:" + str + "(key)");
			e.printStackTrace();
			return;
		}
	}

}
/**
 * 游戏的显示界面<BR>
 * 可以用 setBackgroundColor() 设置游戏的背景色
 * 
 * @version 1.0, 01/01/08
 * 
 * @author 汤阳光
 * 
 * 
 * 
 */
class GamePanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private Image oimg;

	private Graphics og;

	public static final Color DEFAULT_BACKGROUND_COLOR = new Color(0xcfcfcf);
	/**
	 * 背景颜色
	 */
	protected Color backgroundColor = DEFAULT_BACKGROUND_COLOR;

	public GamePanel() {
		/* 设置大小和布局 */
		this.setSize(Global.WIDTH * Global.CELL_WIDTH, Global.HEIGHT
				* Global.CELL_HEIGHT);
		this.setBorder(new EtchedBorder(EtchedBorder.LOWERED));
		this.setFocusable(true);
	}

	/**
	 * 重新显示 Ground, Shape
	 * 
	 * @param ground
	 * @param shape
	 */
	public synchronized void redisplay(Ground ground, Shape shape) {

		/* 重新显示 */
		if (og == null) {
			oimg = createImage(getSize().width, getSize().height);
			if (oimg != null)
				og = oimg.getGraphics();
		}
		if (og != null) {
			og.setColor(backgroundColor);
			og.fillRect(0, 0, Global.WIDTH * Global.CELL_WIDTH, Global.HEIGHT
					* Global.CELL_HEIGHT);
			ground.drawMe(og);
			if (shape != null)
				shape.drawMe(og);
			this.paint(this.getGraphics());
		}
	}

	@Override
	public void paint(Graphics g) {
		g.drawImage(oimg, 0, 0, this);
	}

	/**
	 * 得到当前的背景颜色
	 * 
	 * @return
	 */
	public Color getBackgroundColor() {
		return backgroundColor;
	}

	/**
	 * 设置当前的背景颜色
	 * 
	 * @param backgroundColor
	 */
	public void setBackgroundColor(Color backgroundColor) {
		this.backgroundColor = backgroundColor;
	}

}
/**
 * 可以叫做地形, 或地面<BR>
 * 维护障碍物的信息<BR>
 * 可以使用提供的 addObstacle(int, int) 和 addStubbornObstacle(int ,int) 方法添加障碍物。<BR>
 * <BR>
 * 可以通过setObstacleColor(), setStubbornObstacleColor() 或
 * setGriddingColor()方法更改障碍物或网格的颜色<BR>
 * 通过setDrawGridding() 方法设置是否画空白(网格)<BR>
 * 用 setColorfulSupport() 方法设置是否支持彩色显示<BR>
 * <BR>
 * 覆盖 drawObstacle(Graphics, int, int, int, int) 方法可以改变障碍物的显示方式<BR>
 * 覆盖 drawStubbornObstacle(Graphics, int, int, int, int) 方法可以改变不可消除的障碍物的显示方式<BR>
 * <BR>
 * 
 * @version 1.0, 01/01/08
 * 
 * @author 汤阳光
 * 
 */
class Ground {

	/**
	 * 监听器
	 */
	protected Set<GroundListener> listeners = new HashSet<GroundListener>();

	/**
	 * 容器

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -