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

📄 gamepanel.java

📁 java版的连连看游戏
💻 JAVA
字号:
package view;

import java.awt.*;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.Line2D;
import java.util.ArrayList;

import javax.swing.JPanel;
import javax.swing.border.BevelBorder;

import model.Model;
/**
 * @author 何晓飞 李强 何明
 * @version 2.0 
 * GamePanel类将游戏界面的图片画出
 * 同时设置了游戏面板的各个参数
 */
public class GamePanel extends JPanel {

	private static final long serialVersionUID = 1L;

	/* 小图片之间的缝隙宽度 */
	private final int borderValue = 1;

	/* 小图片的高度 */
	private final int cellHeight = 40;

	/* 小图片的宽度 */
	private final int cellWidth = 40;

	/* 该类中需要的Model对象 */
	private Model model;

	/* 小图片所在文件的名字 */
	private String pictureFile;

	/**
	 * GamePanel (构造函数)初始化类变量并设置GamePanel属性.
	 * 
	 * @param model
	 *            该类中需要的Model对象.
	 */
	public GamePanel(Model model) {

		this.model = model;
		pictureFile = model.getPictureFile();
		setBackground(new Color(0,0,0));
		setBorder(new BevelBorder(BevelBorder.RAISED));
	}

	/**
	 * 获取 Rectangle 对象的中心坐标,将其生成一个point返回.
	 * 
	 * @param rect
	 *            指定了坐标空间中的一个区域的Rectangle 对象.
	 * 
	 * @return Point 由参数Rectangle对象的中心坐标生成的Point对象.
	 */
	private Point getCenter(Rectangle rect) {
		return new Point(rect.x + rect.width / 2, rect.y + rect.height / 2);
	}

	/**
	 * 通过生成一个Rectangle 对象指定了坐标空间中的一个区域.
	 * 
	 * @param row
	 *            生成Rectangle对象所需要的坐标x = column * cellWidth + borderValue * (col -
	 *            1).
	 * 
	 * @param col
	 *            生成Rectangle对象所需要的坐标y = row * cellHeight + borderValue * (row -
	 *            1).
	 * 
	 * @return Rectangle 返回指定了坐标空间中的一个区域Rectangle 对象
	 */
	public Rectangle matrixToRect(int row, int col) {

		int x = col * cellWidth + borderValue * (col - 1);
		int y = row * cellHeight + borderValue * (row - 1);
		// 通过 Rectangle 对象的左上顶点的坐标(x,y)、宽度和高度定义这个区域并返回该 Rectangle 对象
		return new Rectangle(x, y, cellWidth, cellHeight);

	}

	/**
	 * 通过生成一个Rectangle 对象指定了坐标空间中的一个区域.
	 * 
	 * @param p
	 *            指定生成Rectangle对象的中心坐标.
	 * 
	 * @return Rectangle 返回指定了坐标空间中的一个区域Rectangle 对象
	 */
	public Rectangle matrixToRect(Point p) {
		return matrixToRect(p.x, p.y);
	}

	/**
	 * 根据调用model.getMaps()方法返回的二维数组map[][]画游戏中的小图片
	 * 
	 * @param g
	 *            该类中需要的Graphics对象,通过调用Graphics的drawImages方法画游戏中的小图片
	 */
	public void paint(Graphics g) {
        /*图片区域的大小*/
		setSize(820, 485);
		super.paint(g);
		//绘制背景
		g.drawImage(ImageLoader.getBackGround(), 0, 0, this.getWidth(), this
				.getHeight(), null);
		g.setColor(new Color(118,238,0 ));
		//绘制方格
		for(int col=3;col<17;col++){
			for(int row=1;row<11;row++){
				int x=41*col-2;
				int y=41*row-2;
				g.draw3DRect(x, y,41, 41, true);
			}
		}
		int map[][] = model.getMaps();// 获得Model中保存游戏中存在小图片位置的数组
		for (int i = 0; i < map.length; i++)
			for (int j = 0; j < map[0].length; j++) {
				Rectangle rect = matrixToRect(i, j);// 指定了坐标空间中的一个区域
				// 图片已被消去则跳出本次循环,否则把它画出来
				if (map[i][j] == 0)
					continue;
				g.drawImage(ImageLoader.getImageOf(map[i][j], pictureFile),
						rect.x, rect.y, 40, 40, null);
			}
		// 画出游戏图片被选中时显示的小筐
		if (model.getSltMatrix() != null) {// 图片被选中
			Rectangle rect = matrixToRect(model.getSltMatrix());// 指定图片所在的区域
			Graphics2D g2 = (Graphics2D) g;
			g2.setColor(new Color(148, 0, 211 ));
			float dash[] = { 1f };
			g2.setStroke(new BasicStroke(2.0F, BasicStroke.CAP_SQUARE,
					BasicStroke.JOIN_ROUND, 11.0F, dash, 0.F));// 画出规定样式的小筐
			g2.draw3DRect(rect.x, rect.y, rect.width, rect.height,true);
		}
	}

	/**
	 * 鼠标定位
	 * 
	 * @param Point
	 *            鼠标所点的相关组件源
	 * @return Point 返回所点位置的由图片的行和列组成Point对象
	 */
	public Point PointToMetrix(Point p) {
		int col = 0;
		int row = 0;
		if (p.x <= 40 && p.x >= 0)
			col = 0;
		else if (p.x <= 81 && p.x >= 41)
			col = 1;
		else if (p.x <= 122 && p.x >= 82)
			col = 2;
		else if (p.x <= 163 && p.x >= 123)
			col = 3;
		else if (p.x <= 204 && p.x >= 164)
			col = 4;
		else if (p.x <= 245 && p.x >= 205)
			col = 5;
		else if (p.x <= 286 && p.x >= 246)
			col = 6;
		else if (p.x <= 327 && p.x >= 287)
			col = 7;
		else if (p.x <= 368 && p.x >= 328)
			col = 8;
		else if (p.x <= 409 && p.x >= 369)
			col = 9;
		else if (p.x <= 450 && p.x >= 410)
			col = 10;
		else if (p.x <= 491 && p.x >= 451)
			col = 11;
		else if (p.x <= 532 && p.x >= 492)
			col = 12;
		else if (p.x <= 573 && p.x >= 533)
			col = 13;
		else if (p.x <= 614 && p.x >= 574)
			col = 14;
		else if (p.x <= 655 && p.x >= 615)
			col = 15;
		else if (p.x <= 696 && p.x >= 656)
			col = 16;
		else if (p.x <= 737 && p.x >= 697)
			col = 17;
		else if (p.x <= 778 && p.x >= 738)
			col = 18;
		else if (p.x <= 819 && p.x >= 779)
			col = 19;

		if (p.y <= 40 && p.y >= 0)
			row = 0;
		else if (p.y <= 81 && p.y >= 41)
			row = 1;
		else if (p.y <= 122 && p.y >= 82)
			row = 2;
		else if (p.y <= 163 && p.y >= 123)
			row = 3;
		else if (p.y <= 204 && p.y >= 164)
			row = 4;
		else if (p.y <= 245 && p.y >= 205)
			row = 5;
		else if (p.y <= 286 && p.y >= 246)
			row = 6;
		else if (p.y <= 327 && p.y >= 287)
			row = 7;
		else if (p.y <= 368 && p.y >= 328)
			row = 8;
		else if (p.y <= 409 && p.y >= 369)
			row = 9;
		else if (p.y <= 450 && p.y >= 410)
			row = 10;
		else if (p.y <= 491 && p.y >= 451)
			row = 11;
		return new Point(row, col);
	}

	/**
	 * 画出消去图片时显示的连接路径
	 * 
	 * @param obj
	 *            连接路径中的Point对象集
	 * showPath 方法的原理在于使用线程采集矩形对象画出线框,对符合消去的矩形画出
	 * 路径,同时在指定时间调用repaint 方法将所画线条擦去。
	 * 
	 */
	public void showPath(final Object obj) {

		// 新建一个线程来进行画连接路径的工作,只要你有操作,他就画,还要看你的容器里的东西
		Thread t=new Thread(new Runnable() {

			ArrayList<Point> points = (ArrayList<Point>)obj;

			ArrayList<Shape> shapes = new ArrayList<Shape>();

			int step = 80;

			public void run() {
				// 添加路径起点

				shapes.add(matrixToRect(points.get(0)));
				// 添加路径终点
				shapes.add(matrixToRect(points.get(points.size() - 1)));
				// 添加路线
				for (int i = 1; i < points.size(); i++) {
					Point p1 = getCenter(matrixToRect(points.get(i - 1)));
					Point p2 = getCenter(matrixToRect(points.get(i)));

					if (p1.x == p2.x) {// 画横向的线
						int distance = p2.y - p1.y;// 计算线长
						for (int j = 0; j <= Math.abs(distance); j += step)
							shapes.add(new Line2D.Double(p1, new Point(p1.x,
									p1.y + distance / Math.abs(distance) * j)));// 生成一条线并加到shaps中
					} else if (p1.y == p2.y) {// 画纵向的线
						int distance = p2.x - p1.x;// 计算线长
						for (int j = 0; j <= Math.abs(distance); j += step)
							shapes
									.add(new Line2D.Double(p1, new Point(
											p1.x + distance
													/ Math.abs(distance) * j,
											p1.y)));// 生成一条线并加到shapes中
					}
					shapes.add(new Line2D.Double(p1, p2));// 构造并初始化一个具有坐标 (0,
					// 0) -> (0, 0) 的Line
				}
				Graphics2D g2 = (Graphics2D) getGraphics();
				float dash[] = { 1F };
				g2.setStroke(new BasicStroke(3.0F, BasicStroke.CAP_SQUARE,
						BasicStroke.JOIN_BEVEL, 11.0F, dash, 1.F)); // //画出规定样式的连接路径

				for (int index = 0; index < shapes.size(); index++) {
					for (int pre = 0; pre <= index; pre++) {
						if (pre < 2)
							g2.setColor(new Color(0, 0, 255));// 设置圈图片的颜色
						else
							g2.setColor(new Color(30, 144, 255));// 设置连线的颜色
						g2.draw(shapes.get(pre));// 使用当前 Graphics2D 上下文的设置勾画
					// Shape 的轮廓
					}
				}
				/*2007.6.27,真是开心的一天,我终于把连线有时候不消失的bug给修复了*/
				try {// 延迟300毫秒
				Thread.sleep(300);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
				repaint();
			}
		});
		t.start();
	}
}

⌨️ 快捷键说明

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