import com.madou.uml.components.FruitObject;
			import com.madou.uml.util.ReadResourceUtil;
			import com.sun.media.jfxmedia.AudioClip;

			import javax.swing.*;
			import javax.swing.border.EmptyBorder;
			import java.awt.*;
			import java.awt.event.MouseListener;
			import java.util.List;
			import java.util.*;
			import java.util.stream.Collectors;


			/**
			 * 验卡区
			 * @author miukoo
			 * @see  
			 * @see  
			 */
			public class CardSlotCantainer extends JPanel {

			static AudioClip audioClip;
			static AudioClip failClip;
			static {
				try {
					audioClip = AudioClip.load(ReadResourceUtil.readAudio("win.wav").toURI());
				} catch (Exception e) {
					e.printStackTrace();
				}
				try {
					failClip = AudioClip.load(ReadResourceUtil.readAudio("fail.wav").toURI());
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
			// 卡片间隔
			int step = 5;
			// 内外底色的间隔
			int borderSize = 10;
			// 卡片最大数
			int solt = 7;
			// 是否结束
			boolean isOver = false;

			Color bgColor = new Color(157,97,27);
			Color borderColor = new Color(198,128,48);
			// 圆角幅度
			int arc = 15;
			List slot = new ArrayList<>();
			int initX;
			int initY;
			public CardSlotCantainer(ImageCantainer imageCantainer,int initX, int initY){
				initY+=20;
				initX+=-borderSize;
				this.setBorder(new EmptyBorder(0,0,0,0));
				this.setOpaque(false);
				this.setFocusable(true);
				this.setLayout(new FlowLayout());
				this.initY = initY;
				this.initX = initX;
				setBounds(initX,initY,FruitObject.defaultWidht*solt+step*2+borderSize*2,FruitObject.defaultHeight+step*2+borderSize*2);
				imageCantainer.add(this);
			}

			// 点击添加
			public void addSlot(FruitObject object){
				if(isOver){
					return;
				}
				slot.add(object);
				// 验卡区的卡片删除点击事件
				object.removeImageCantainer();
				MouseListener[] mouseListeners = object.getFruits().getMouseListeners();
				if(mouseListeners!=null){
					for (MouseListener mouseListener : mouseListeners) {
						object.getFruits().removeMouseListener(mouseListener);
					}
				}
				// 排序验卡区中的图片
				slot.sort(Comparator.comparing(FruitObject::getImageName));
				// 3张图片的判断,如果有直接消除,思路是:分组后看每组数量是否超过3张如果超过则消除
				Map> map = slot.stream().collect(Collectors.groupingBy(FruitObject::getImageName));
				Set keys = map.keySet();
				for (String key : keys) {
					List objects = map.get(key);
					if(objects.size()==3){
						if(audioClip!=null){
							audioClip.play();
						}
						// 消除的元素直接从集合中删除
						for (FruitObject fruitObject : objects) {
							fruitObject.removeCardSlotCantainer();
						}
						slot.removeAll(objects);
					}
				}
				// 新添加的卡片,显示到验卡区
				redraw();
				// 判断游戏是否结束
				if(slot.size()==solt){
					isOver = true;
					failClip.play();
					JOptionPane.showMessageDialog(this.getParent(), "Game Over:槽满了","Tip",JOptionPane.ERROR_MESSAGE);
				}
			}

			public void redraw(){
				this.removeAll();
				for (int i = 0; i < slot.size(); i++) {
					FruitObject fruitObject = slot.get(i);
					int pointX =  step+i*FruitObject.defaultWidht+borderSize/2;
					fruitObject.getFruits().setBounds(pointX,borderSize,FruitObject.defaultWidht,FruitObject.defaultHeight+step);
					this.add(fruitObject.getFruits());
				}
				repaint();
			}

			@Override
			protected void paintComponent(Graphics g) {
				Graphics2D g2d = (Graphics2D) g;
				g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
				BasicStroke basicStroke = new BasicStroke(borderSize);
				g2d.setStroke(basicStroke);
				// 绘制第1层底色
				g2d.setColor(bgColor);
				g2d.fillRoundRect(0, 0, (int) (getSize().width - borderSize), (int) (getSize().height - borderSize),arc,arc);
				// 绘制第2层底色
				g2d.setColor(borderColor);
				g2d.fillRoundRect(borderSize, borderSize, (int) (getSize().width - 1-borderSize*3), (int) (getSize().height - 1-borderSize*3),arc,arc);
				super.paintComponent(g);
			}
			}
				
			
				
			import javax.swing.*;
			import javax.swing.border.EmptyBorder;
			import java.awt.*;
			import java.awt.geom.AffineTransform;
			import java.util.Random;

			/**
			 * 游戏背景区
			 * @author miukoo
			 * @see  project home
			 * @see  athor website
			 */
			public class ImageCantainer extends JPanel implements ScaleFunction  {

				// 背景颜色
				Color backgroudColor = Color.WHITE;
				// 间距距
				int step = 20;
				// 缩放比例,每走一格+-5
				int scale = 100;

				public ImageCantainer(){
					this.setLayout(null);
					this.setBorder(new EmptyBorder(20,20,20,20));
					this.setBackground(Color.RED);
					this.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR));
				}

				// 背景色
				Color bgColor = new Color(195,254,139);
				// 背景图标色
				Color grassColor = new Color(95,154,39);
				Random random =  new Random();

				public void drawX(Graphics g){
					int size = 20;
					int width = (int) (this.getWidth()/(scale/100F));
					int height = (int) (this.getHeight()/(scale/100F));
					int skip = (int) (step*scale/100F);
					Graphics2D graphics = (Graphics2D)g;
					graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
					// 背景色
					graphics.setColor(bgColor);
					graphics.fillRect(0,0,width,height);
					// 设置画笔颜色或大小
					graphics.setColor(grassColor);
					BasicStroke basicStroke = new BasicStroke(2);
					graphics.setStroke(basicStroke);
					// 随机绘制各种大小图形
					for (int i = 0; i < width; i+=skip) {
						graphics.drawRect(random.nextInt(width),random.nextInt(height),random.nextInt(size),random.nextInt(size));
						graphics.drawArc(random.nextInt(width),random.nextInt(height),random.nextInt(size),random.nextInt(size),random.nextInt(360),random.nextInt(360));
						graphics.drawOval(random.nextInt(width),random.nextInt(height),random.nextInt(size),random.nextInt(size));
						graphics.drawRoundRect(random.nextInt(width),random.nextInt(height),random.nextInt(size),random.nextInt(size),random.nextInt(360),random.nextInt(360));
					}
				}

				@Override
				protected void paintComponent(Graphics graphics) {
					Graphics2D g = (Graphics2D)graphics;
					clearPane(g);
					AffineTransform transform = new AffineTransform(g.getTransform());
					g.setTransform(transform);
					g.scale(scale/100F,scale/100F);
					graphics.setColor(backgroudColor);
					graphics.fillRect(0,0,getWidth(),getHeight());
					drawX(graphics);
					transform.concatenate(g.getTransform());
				}

				// 清空背景
				private void clearPane(Graphics2D g) {
					g.clearRect(0, 0, getWidth(), getHeight());
				}

				/**
				 * 重置大小
				 */
				@Override
				public void reset(){
					scale=100;
					scale(0);
				}

				/**
				 * 放大或者缩写
				 * @param step
				 */
				@Override
				public void scale(int step){
					scale+=step;
					if(scale<20){
						scale=20;
					}
					if(scale>500){
						scale=500;
					}
					applyZoom();
				}

				private void applyZoom() {
					setPreferredSize(new Dimension((int) (scale/100F * getWidth()), (int) (scale/100F * getHeight())));
					validate();
					repaint();
				}
			}
				
			
				
			public interface ScaleFunction {
			/**
			 * 缩放一步,可以是负数
			 * @param step
			 */
			public void scale(int step);

			/**
			 * 重置样式为100
			 */
			public void reset();
			}
				
			
				
			import com.madou.uml.cantainer.CardSlotCantainer;
			import com.madou.uml.cantainer.ImageCantainer;
			import com.madou.uml.util.ReadResourceUtil;
			import com.sun.media.jfxmedia.AudioClip;

			import java.awt.*;
			import java.awt.event.MouseAdapter;
			import java.awt.event.MouseEvent;
			import java.util.Random;

			/**
			 * 卡片对象放置位置对象:记录卡片放在那个位置
			 * @author miukoo
			 * @see  project home
			 * @see  athor website
			 */
			public class FruitObject  {

				// 卡片默认宽度
				public static final int defaultWidht = 100;
				// 卡片默认高度
				public static final int defaultHeight = 100;
				static Random RANDOM = new Random();
				// 点击卡片的声音
				static AudioClip audioClip;
				static {
					try {
						audioClip = AudioClip.load(ReadResourceUtil.readAudio("click.wav").toURI());
					} catch (Exception e) {
						e.printStackTrace();
					}
				}

				// 存放的卡片
				Fruits fruits;
				// 所在层的x序号
				int x;
				// 所在层的y序号
				int y;
				// 所在层序号
				int level;
				// 卡片名称,有点重复了,后续优化
				String imageName;//名称,非常重要,安装名称来判断是否为同一类型
				boolean flag = true;//是否可以点击
				boolean leftFold = false;// 是否为遮挡元素
				boolean rightFold = false;// 是否为遮挡元素
				ImageCantainer imageCantainer;
				CardSlotCantainer cardSlotCantainer;

				public FruitObject(CardSlotCantainer cardSlotCantainer,Fruits fruits, int x, int y, int level) {
					this.fruits = fruits;
					this.x = x;
					this.y = y;
					this.level = level;
					this.imageName = fruits.getImageName();
					this.cardSlotCantainer = cardSlotCantainer;
				}

				public Fruits getFruits() {
					return fruits;
				}

				public void setX(int x) {
					this.x = x;
				}

				public void setY(int y) {
					this.y = y;
				}

				public int getLevel() {
					return level;
				}

				public void setLevel(int level) {
					this.level = level;
				}

				public String getImageName() {
					return imageName;
				}

				/**
				 * 添加到叠卡区
				 * @param imageCantainer
				 * @param initX
				 * @param initY
				 */
				public void show(ImageCantainer imageCantainer, int initX, int initY) {
					this.imageCantainer = imageCantainer;
					// 随机生成开始坐标偏移量,实现上下层错落有致的视觉感
					boolean ranDomWidth = RANDOM.nextInt(10)%2==0;
					boolean ranDomHeight = RANDOM.nextInt(10)%2==0;
					int pointX = initX + x*defaultWidht+(ranDomWidth?defaultWidht/2:0);
					int pointY = initY + y*defaultHeight+(ranDomHeight?defaultHeight/2:0);
					// 设置卡片显示在背景面板中位置
					fruits.setBounds(pointX,pointY,defaultWidht,defaultHeight);
					// 记录卡片的空间信息
					SpaceManager.rectangle(this);
					imageCantainer.add(fruits,0);
					addClick();
				}

				/**
				 * 添加到翻牌区
				 * @param imageCantainer
				 * @param initX
				 * @param initY
				 * @param offset
				 * @param isLeft
				 */
				public void showFold(ImageCantainer imageCantainer, int initX, int initY, int offset,boolean isLeft) {
					this.imageCantainer = imageCantainer;
					// 随机生成开始坐标偏移量,实现上下层错落有致的视觉感
					int pointX = initX + x*defaultWidht+offset;
					int pointY = initY + y*defaultHeight-defaultHeight/4;
					if(isLeft){
						this.leftFold = true;
					}else{
						this.rightFold= true;
					}
					// 设置卡片显示在背景面板中位置
					fruits.setBounds(pointX,pointY,defaultWidht,defaultHeight);
					// 记录卡片的空间信息
					SpaceManager.rectangle(this);
					imageCantainer.add(fruits,0);
					addClick();
				}

				/**
				 * 卡片点击事件:点击后添加到验卡区
				 */
				public void addClick(){
					fruits.addMouseListener(new MouseAdapter() {
						@Override
						public void mouseClicked(MouseEvent e) {
							if(flag) {
								if (audioClip != null) {
									audioClip.play();
								}
								cardSlotCantainer.addSlot(FruitObject.this);
							}
						}
					});
				}

				public void removeImageCantainer() {
					Rectangle visibleRect = fruits.getVisibleRect();
					SpaceManager.removeCompontFlag(this);
					imageCantainer.remove(fruits);
					imageCantainer.repaint(visibleRect);
				}

				public void removeCardSlotCantainer() {
					cardSlotCantainer.remove(fruits);
				}

				public boolean isLeftFold() {
					return leftFold;
				}

				public boolean isRightFold() {
					return rightFold;
				}

				/**
				 * 设置
				 * @param flag=false 不可以用
				 */
				public void setFlag(boolean flag) {
					if(this.flag!=flag){//需要更新透明度
						getFruits().setAlpha(flag?1:0.65f);
					}
					this.flag = flag;
				}
			}
				
			
				
			import com.madou.uml.drager.ShapeDrager;

			import javax.swing.*;
			import java.awt.*;

			/**
			 * 卡片对象
			 * @author miukoo
			 * @see  project home
			 * @see  athor website
			 */
			public class Fruits extends ShapeDrager {

			// 卡片上放置的图形
			Image image = null;
			// 卡片名称
			String imageName;

			// 卡片圆角边框
			int arc = 10;
			// 透明度
			float alpha = 1;
			Color bgColor = new Color(138,158,58);
			public Fruits(JPanel parent,Image image,String imageName){
				super(parent);
				this.image = image;
				this.imageName = imageName;
			}

			@Override
			protected void paintComponent(Graphics g) {
			Graphics2D g2d = (Graphics2D) g;
			g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
			BasicStroke basicStroke = new BasicStroke(2);
			g2d.setStroke(basicStroke);
			if(alpha<1) {
				g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
			}
			g2d.rotate(getRotation(),getWidth()/2,getHeight()/2);
			// 绘制底色
			g2d.setColor(bgColor);
			g2d.fillRoundRect(0, 0, (int) (getSize().width - 1), (int) (getSize().height - 1),arc,arc);
			// 绘制白色
			g2d.setColor(Color.WHITE);
			g2d.fillRoundRect(0, 0, (int) (getSize().width - 1), (int) (getSize().height - 1-5),arc,arc);
			// 绘制外边框
			g2d.setColor(bgColor);
			g2d.drawRoundRect(0, 0, (int) (getSize().width - 1), (int) (getSize().height - 1),arc,arc);
			// 绘制图片
			if(image!=null) {
				int imageWidth = image.getWidth(null);
				int imageHeight = image.getHeight(null);
				int x = (getWidth()-imageWidth)/2;
				int y = (getHeight()-5-imageHeight)/2;
				g2d.drawImage(image,x,y,imageWidth,imageHeight,null);
			}
			super.paintComponent(g);
			}

			public String getImageName() {
				return imageName;
			}

			public void setAlpha(float alpha) {
				this.alpha = alpha;
				repaint();
			}
			}
				
			
				
			import java.awt.*;
			import java.util.ArrayList;
			import java.util.HashMap;
			import java.util.List;
			import java.util.Map;

			/**
			 * 记录每层卡片的空间信息,用于实现上下层是否可点击的动态刷新
			 * @author miukoo
			 * @see  project home
			 * @see  athor website
			 */
			public class SpaceManager {
				// Map>>
				static Map>> LEAVL_DATA_X1 = new HashMap<>();
				static Map>> LEAVL_DATA_X2 = new HashMap<>();
				static Map>> LEAVL_DATA_X3 = new HashMap<>();
				static Map>> LEAVL_DATA_Y1 = new HashMap<>();
				static Map>> LEAVL_DATA_Y2 = new HashMap<>();
				static Map>> LEAVL_DATA_Y3 = new HashMap<>();

				/**
				 * 记录组件坐标重叠数据
				 */
				public static void rectangle(FruitObject fruitObject){
					Rectangle bounds  = fruitObject.fruits.getBounds();
					if(fruitObject.isLeftFold()){
						bounds.x=0;bounds.y=0;
					}
					if(fruitObject.isRightFold()){
						bounds.x=1;bounds.y=1;
					}
					int x1 = bounds.x;
					int x2 = bounds.x+FruitObject.defaultWidht/2;
					int x3 = bounds.x+FruitObject.defaultHeight;
					int y1 = bounds.y;
					int y2 = bounds.y+FruitObject.defaultHeight/2;
					int y3 = bounds.y+FruitObject.defaultHeight;
					putToCache(x1,fruitObject,LEAVL_DATA_X1);
					putToCache(x2,fruitObject,LEAVL_DATA_X2);
					putToCache(x3,fruitObject,LEAVL_DATA_X3);
					putToCache(y1,fruitObject,LEAVL_DATA_Y1);
					putToCache(y2,fruitObject,LEAVL_DATA_Y2);
					putToCache(y3,fruitObject,LEAVL_DATA_Y3);
					updateCompontFlag(fruitObject,false,bounds);
				}

				private static void putToCache(int point,FruitObject fruitObject,Map>> LEAVL_DATA){
					Map> hashLevel = LEAVL_DATA.get(fruitObject.level);
					if(hashLevel==null){
						hashLevel = new HashMap<>();
					}
					List objects = hashLevel.get(point);
					if(objects==null){
						objects = new ArrayList<>();
					}
					objects.add(fruitObject);
					hashLevel.put(point,objects);
					LEAVL_DATA.put(fruitObject.level,hashLevel);
				}

				/**
				 * 消除卡片时,计算下一层点亮的卡片
				 * @param fruitObject
				 */
				public static void removeCompontFlag(FruitObject fruitObject){
					Rectangle bounds  = fruitObject.fruits.getBounds();
					if(fruitObject.isLeftFold()){
						bounds.x=0;bounds.y=0;
					}
					if(fruitObject.isRightFold()){
						bounds.x=1;bounds.y=1;
					}
					int x1 = bounds.x;
					int x2 = bounds.x+FruitObject.defaultWidht/2;
					int x3 = bounds.x+FruitObject.defaultHeight;
					int y1 = bounds.y;
					int y2 = bounds.y+FruitObject.defaultHeight/2;
					int y3 = bounds.y+FruitObject.defaultHeight;
					deleteLevelFlag(x1,fruitObject,LEAVL_DATA_X1);
					deleteLevelFlag(x2,fruitObject,LEAVL_DATA_X2);
					deleteLevelFlag(x3,fruitObject,LEAVL_DATA_X3);
					deleteLevelFlag(y1,fruitObject,LEAVL_DATA_Y1);
					deleteLevelFlag(y2,fruitObject,LEAVL_DATA_Y2);
					deleteLevelFlag(y3,fruitObject,LEAVL_DATA_Y3);
					updateCompontFlag(fruitObject,true,bounds);
				}

				private static void deleteLevelFlag(int point,FruitObject fruitObject,Map>> LEAVL_DATA){
					Map> hashLevel = LEAVL_DATA.get(fruitObject.getLevel());
					if(hashLevel==null){
						return;
					}
					List objects = hashLevel.get(point);//删除对应层次对应点的坐标
					if(objects==null){
						hashLevel.remove(point);
						if(hashLevel.size()==0){
							LEAVL_DATA.remove(fruitObject.getLevel());
						}else {
							LEAVL_DATA.put(fruitObject.getLevel(), hashLevel);
						}
						return;
					}
					objects.remove(fruitObject);//删除对应层次对应点的坐标
					if(objects.isEmpty()){
						hashLevel.remove(point);
						if(hashLevel.size()==0){
							LEAVL_DATA.remove(fruitObject.getLevel());
						}else {
							LEAVL_DATA.put(fruitObject.getLevel(), hashLevel);
						}
					}
				}

				/**
				 * 更新底层节点的状态,false修改为不可点,反之可点
				 * @param fruitObject
				 */
				private static void updateCompontFlag(FruitObject fruitObject,boolean flag,Rectangle bounds){
					int level = fruitObject.getLevel();
					int x1 = bounds.x;
					int x2 = bounds.x+FruitObject.defaultWidht/2;
					int x3 = bounds.x+FruitObject.defaultHeight;
					int y1 = bounds.y;
					int y2 = bounds.y+FruitObject.defaultHeight/2;
					int y3 = bounds.y+FruitObject.defaultHeight;
					for (int i = 0; i>> LEAVL_DATA,boolean flag){
					Map> hashLevel = LEAVL_DATA.get(level);
					if(hashLevel==null){
						return;
					}
					List objects = hashLevel.get(point);
					if(objects==null){
						return;
					}
					if(flag) {// 当更新的时候需要强制检查
						flag = !LEAVL_DATA.containsKey(level + 1);//上一层都没了,可以点击
					}
					//上一层存在,但是没有遮挡可以点击
					if(!flag){
						flag = !(isExsit(x1,level+1,LEAVL_DATA_X1)
								&& isExsit(x2,level+1,LEAVL_DATA_X2)
								&& isExsit(x3,level+1,LEAVL_DATA_X3)
								&& isExsit(y1,level+1,LEAVL_DATA_Y1)
								&& isExsit(y2,level+1,LEAVL_DATA_Y2)
								&& isExsit(y3,level+1,LEAVL_DATA_Y3));
					}
					for (FruitObject object : objects) {
						object.setFlag(flag);
					}
				}

				private static boolean isExsit(int point,int level,Map>> LEAVL_DATA){
					Map> hashLevel = LEAVL_DATA.get(level);
					if(hashLevel==null){
						return false;
					}
					List objects = hashLevel.get(point);
					if(objects==null||objects.isEmpty()){
						return false;
					}
					return true;
				}

			}
				
			
				
			import javax.swing.*;
		import java.awt.*;

		/**
		 * 卡片超类
		 * @author miukoo
		 * @see  
		 * @see  
		 */
		public abstract class ShapeDrager extends JPanel {
			// 旋转的角度
			double rotation = 0;
			// 是否图标模式
			boolean iconType = false;

			public ShapeDrager(JComponent parent){
				this(parent,false);
			}

			public ShapeDrager(JComponent parent, boolean iconType){
				this.iconType = iconType;
				this.setFocusable(true);
				if(!iconType) {
					this.setCursor(new Cursor(Cursor.MOVE_CURSOR));
				}else{
					this.setCursor(new Cursor(Cursor.HAND_CURSOR));
				}
				initShape();
			}

			private void initShape(){
				this.setOpaque(false);
				this.setLayout(new BorderLayout());
			}

			public double getRotation() {
				return rotation;
			}
			}
				
			
				
			import java.io.File;
			import java.io.UnsupportedEncodingException;
			import java.net.MalformedURLException;
			import java.net.URISyntaxException;
			import java.net.URL;
			import java.util.ArrayList;
			import java.util.Enumeration;
			import java.util.List;
			import java.util.Random;
			import java.util.jar.JarEntry;
			import java.util.jar.JarFile;

			/**
			 * 外部资源加载类,可以从jar中读取内容
			 * @author miukoo
			 * @see 
			 */
			public class ReadResourceUtil {

				static Random random = new Random();
				static File jarFile;

				static {
					try {
						jarFile = new File(java.net.URLDecoder.decode(ReadResourceUtil.class.getProtectionDomain().getCodeSource().getLocation().getFile(), "UTF-8"));
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
				}

				/**
				 * 读取音频
				 */
				public static URL readAudio(String name){
					return getUri("/static/audio/wav" +random.nextInt(2)+"/"+name);
				}

				public static URL getUri(String name){
					URL resource = ReadResourceUtil.class.getResource(name);
					if(resource==null){
						try {
							File file = new File(jarFile.getParentFile(), "static");
							System.out.println(file.getAbsolutePath()+"\t"+file.exists());
							if(file.exists()) {
								resource = new File(jarFile.getParentFile(), name).toURL();
							}else{
								resource = new File(jarFile.getParentFile().getParentFile(), name).toURL();
							}
						} catch (MalformedURLException e) {
							e.printStackTrace();
						}
					}
					return resource;
				}

				/**
				 * 读取图片
				 */
				private static String readSkinPath(boolean isRandom){
					if(isRandom){
						return "/static/skins/a" +random.nextInt(109);
					}else{
						return "/static/skins/a108";
					}
				}

				/**
				 * 读取图片
				 */
				public static List readSkin(boolean isRandom){
					String path = readSkinPath(isRandom);
					List list = new ArrayList<>();
					try {
						URL url = getUri("/" + path);
						if (url != null) {
							try {
								final File apps = new File(url.toURI());
								for (File app : apps.listFiles()) {
									list.add(path+"/"+app.getName());
								}
							} catch (URISyntaxException ex) {
								ex.printStackTrace();
							}
						}
					}catch (Exception e){
						e.printStackTrace();
					}
					return list;
				}

			}
				
			
				
			import com.madou.uml.cantainer.CardSlotCantainer;
			import com.madou.uml.cantainer.ImageCantainer;
			import com.madou.uml.components.FruitObject;
			import com.madou.uml.components.Fruits;
			import com.madou.uml.util.ReadResourceUtil;

			import javax.imageio.ImageIO;
			import javax.swing.*;
			import java.awt.*;
			import java.awt.event.ComponentAdapter;
			import java.awt.event.ComponentEvent;
			import java.awt.image.BufferedImage;
			import java.io.IOException;
			import java.util.ArrayList;
			import java.util.List;
			import java.util.Random;

			/**
			 * 游戏主程序
			 * @author miukoo
			 * @see  project home
			 * @see  athor website
			 */
			public class UmlPanel extends JPanel {
				ImageCantainer imageCantainer = new ImageCantainer();
				public UmlPanel(){
					this.setLayout(null);
					this.add(imageCantainer);
					this.addComponentListener(new ComponentAdapter() {
						@Override
						public void componentResized(ComponentEvent e) {
							reDrawImagePanel();
						}
					});
					initContent();
				}

			public void initContent(){
			int maxLevel = 10;//多少层
			int maxWidth = 6;// 跨度个数
			int maxHeight = 5;// 最大宽度
			int maxFlop = 60;//翻牌数量;
			Random random = new Random();
			// 如果需要随机皮肤,修改为true即可
			List list = ReadResourceUtil.readSkin(false);
			int typeSize = list.size();// 多少种类
			System.out.println("种类:"+typeSize);
			int groupNumber = (int) Math.ceil((maxLevel*maxWidth*maxHeight+maxFlop)/(3f*typeSize));// 求得每种种类的个数
			System.out.println("每种组数:"+groupNumber);
			int groupCount = groupNumber*3;
			System.out.println("每种总数:"+groupCount);
			System.out.println("共计数量:"+(typeSize*groupCount+maxFlop));
			// 绘制卡槽
			int initX = 100;
			int initY = 50;
			CardSlotCantainer cardSlotCantainer = new CardSlotCantainer(imageCantainer,initX+((maxWidth-7)*FruitObject.defaultWidht)/2,+initY+FruitObject.defaultHeight*(maxHeight+2));
			// 随机生成卡片集合:注意打乱顺序
			List objects = new ArrayList<>();
			for (String temp : list) {
				try {
					BufferedImage bufferedImage = ImageIO.read(ReadResourceUtil.getUri("/"+temp));
					int count = groupCount+(maxFlop>0?random.nextInt(maxFlop):0);
					for (int i = 0; i < count; i++) {
						int size = objects.size()-1;
						Fruits fruits = new Fruits(imageCantainer,bufferedImage,temp);
						fruits.setPreferredSize(new Dimension(100, 100));
						int index = 0;
						if(size>10) {
							index = random.nextInt(size);
						}
						objects.add(index, new FruitObject(cardSlotCantainer,fruits, 0, 0, 0));
						maxFlop--;
					}
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			System.out.println("实际数量:"+objects.size());
			// 给每个对象设置坐标
			int index = 0;
			for (int i = 0; i < maxLevel; i++) {
				for (int x = 0; x < maxWidth; x++) {
					for (int y = 0; y < maxHeight; y++) {
						FruitObject fruitObject = objects.get(index++);
						fruitObject.setX(x);
						fruitObject.setY(y);
						fruitObject.setLevel(i);
						fruitObject.show(imageCantainer,initX-FruitObject.defaultWidht/4,initY-FruitObject.defaultHeight/4);
					}
				}
			}
			System.out.println("重叠数量:"+index);
			//  绘制翻牌区
			int size = objects.size();
			if(index
			
单词