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

📄 mainpanel.java

📁 连连看的源码
💻 JAVA
字号:
package nicholas.game.kyodai;

import java.awt.*;
import java.awt.event.*;
import java.util.Vector;
import javax.swing.*;
import javax.swing.border.Border;

import nicholas.game.kyodai.*;

public class MainPanel extends JPanel {
	
	private int BOMB = 5;
	private int BOMBP = 200;
	private int REFRESH = 4;
	private int REFRP = 250;
	private int TIP = 7;
	private int TIPP = 120;
	private int PROGRESS = 1200;
	
	private int xBound;
	private int yBound;
	private int pcount;
	private int score;
	private int refreshcount;
	private int bombcount;
	private int tipcount;
	
	private LevelInfo levelInfo;
	private GridMouseAdapter gma;
	private KyodaiGrid grid[][];
	private KyodaiGrid nexts, nexte;
	
	private Border selectedBorder;
	private Border opaqueBorder;
	private Border tipBorder;
	private Vector path[];
	
	private Thread pthread;
	private JProgressBar progress;
	private JLabel scoreLabel;
	private JLabel refreshLabel;
	private JLabel bombLabel;
	private JLabel tipLabel;
	
	private JPanel gridPanel;
	
	private boolean wingame;
	
	/**
	 *costructor
	 *@para li:game setting info
	 */
	public MainPanel(LevelInfo li) {
		
		super(new BorderLayout());
		levelInfo = li;
		
		path = new Vector[3];
		path[0] = new Vector();
		path[1] = new Vector();
		path[2] = new Vector();
		
		setBackground(Color.black);
		
		gma = new GridMouseAdapter();
		opaqueBorder = BorderFactory.createLineBorder(getBackground());
		selectedBorder = BorderFactory.createLineBorder(Color.red);
		tipBorder = BorderFactory.createLineBorder(Color.green);
		
//		setBorder(BorderFactory.createRaisedBevelBorder());
//		setForeground(new Color(198, 195, 198));

        setGridPanel();
        setStatusPanel();
	}
	
	/**
	 *set up status panel
	 */
	private void setStatusPanel() {
		
		wingame = false;
		
		JPanel panel = new JPanel();
		panel.setBackground(Color.black);
		
		JLabel label = new JLabel("剩余时间:");
		label.setForeground(Color.white);
		panel.add(label);
		
		progress = new JProgressBar(0,PROGRESS);
		progress.setValue(PROGRESS);
		progress.setPreferredSize(new Dimension(400,20));
		progress.setForeground(Color.blue);
		progress.setBorderPainted(false);
		panel.add(progress);
		
		score = 0;
		scoreLabel = new JLabel(""+score);
		scoreLabel.setForeground(Color.yellow);
		scoreLabel.setFont(new Font("Dialog",Font.BOLD,25));
		scoreLabel.setHorizontalAlignment(SwingConstants.RIGHT);
		scoreLabel.setPreferredSize(new Dimension(100,20));
		panel.add(scoreLabel);
		
		add(panel,BorderLayout.NORTH);
		
		panel = new JPanel();
		panel.setBackground(Color.black);
		
		label = new JLabel("剩余提示:");
		label.setForeground(Color.yellow);
		panel.add(label);
		
		tipcount = TIP;
		tipLabel = new JLabel(""+tipcount);
		tipLabel.setForeground(Color.green);
		panel.add(tipLabel);
		
		label = new JLabel("剩余炸弹:");
		label.setForeground(Color.yellow);
		panel.add(label);
		
		bombcount = BOMB;
		bombLabel = new JLabel(""+bombcount);
		bombLabel.setForeground(Color.green);
		panel.add(bombLabel);
		
		label = new JLabel("可用刷新:");
		label.setForeground(Color.yellow);
		panel.add(label);
		
		refreshcount = REFRESH;
		refreshLabel = new JLabel(""+refreshcount);
		refreshLabel.setForeground(Color.green);
		panel.add(refreshLabel);
		
		
		add(panel,BorderLayout.SOUTH);
		
		pthread = new ProgressThread();
		pthread.start();
	}
	
	/**
	 *initialize grid panel
	 */
	private void setGridPanel() {
		
		gridPanel = new JPanel();
		gridPanel.setBackground(getBackground());
		xBound = levelInfo.getXBound()+2;
		yBound = levelInfo.getYBound()+2;
		
		gridPanel.setLayout(new GridLayout(yBound,xBound,0,0));
		
		grid = new KyodaiGrid[yBound][xBound];
		int count = 0;
		int sub = levelInfo.getXBound()*levelInfo.getYBound()/4;
		KyodaiGrid temp[] = new KyodaiGrid[xBound*yBound];
		
		for(int y=0;y<yBound;y++) {
			for(int x=0;x<xBound;x++) {
				grid[y][x] = new KyodaiGrid(x, y);
				if(x==0||x==(xBound-1)||y==0||y==(yBound-1)) {
					grid[y][x].setIcon(ImageFactory.getInstance().getImageicon(39));
					grid[y][x].setVisible(false);
				} else {
					grid[y][x].setIcon(ImageFactory.getInstance().getImageicon(count%sub));
					grid[y][x].setBorder(opaqueBorder);
					grid[y][x].addMouseListener(gma);
					temp[count] = grid[y][x];
					count++;
				}
				gridPanel.add(grid[y][x]);
			}
		}
		JPanel t = new JPanel();
		t.setBackground(Color.black);
		t.add(gridPanel);
		add(t,BorderLayout.CENTER);
		shuffle(temp, count);
	}
	
	/**
	 *start a new game
	 */
	public void restart() {
		resetStatusPanel();
		resetGridPanel();
	}
	
	/**
	 *restet status panel and game symbol
	 */
	private void resetStatusPanel() {
		wingame = false;
		score = 0;
		scoreLabel.setText(""+score);
		bombcount = BOMB;
		bombLabel.setText(""+bombcount);
		refreshcount = REFRESH;
		refreshLabel.setText(""+refreshcount);
		tipcount = TIP;
		tipLabel.setText(""+tipcount);
		progress.setValue(PROGRESS);
		pthread.resume();
	}
	
	/**
	 *initialize grid panel when restart a new game
	 */
	private void resetGridPanel() {
		int count = 0;
		int sub = (xBound-2)*(yBound-2)/4;
		KyodaiGrid temp[] = new KyodaiGrid[xBound*yBound];
		for(int y=1;y<yBound-1;y++) {
			for(int x=1;x<xBound-1;x++){
				grid[y][x].setIcon(ImageFactory.getInstance().getImageicon(count%sub));
				grid[y][x].setBorder(opaqueBorder);
				grid[y][x].setVisible(true);
				temp[count] =grid[y][x];
				count++;
			}
		}
		shuffle(temp,count);
	}
	
	/**
	 *pause
	 */
	public void setPaused(boolean p) {
		if(p) {
			pthread.suspend();
			gridPanel.setVisible(false);
		} else {
			pthread.resume();
			gridPanel.setVisible(true);
		}
	}
	
	/**
	 *is paused?
	 */
	public boolean isPaused() {
		return !gridPanel.isVisible();
	}
	
	/**
	 *when no grids left,win;
	 *count score
	 */
	private void win() {
		wingame = true;
		pthread.suspend();
		score += progress.getValue()/20+bombcount*BOMBP+refreshcount*REFRP+tipcount*TIPP;
		scoreLabel.setText(""+score);
	}
	
	/**
	 *change the pics
	 */
	private void shuffle(KyodaiGrid array[], int count) {
		if(wingame) return;
		do {
			setVisible(false);
			int j,k;
			Icon temp;
			for(int i=0;i<count;i++) {
				j = (int)(Math.random()*count);
				k = (int)(Math.random()*count);
				temp = array[k].getIcon();
				array[k].setIcon(array[j].getIcon());
				array[j].setIcon(temp);
			}
			setVisible(true);
		} while(!findPair());
	}
	
	/**
	 *refresh gird panel to form a solution
	 */
	public void refresh() {
		if(wingame||progress.getValue()==0||refreshcount==0) return;
		KyodaiGrid temp[] = new KyodaiGrid[xBound*yBound];
		int count = 0;
		for(int y=1;y<yBound-1;y++) {
			for(int x=1;x<xBound-1;x++) {
				if(grid[y][x].isVisible()) {
					grid[y][x].setBorder(opaqueBorder);
					temp[count] = grid[y][x];
					count++;
				}
			}
		}
		if(count!=0) {
			refreshcount--;
			refreshLabel.setText(""+refreshcount);
			shuffle(temp,count);
		} else win();
	}
	
	/**
	 *@retrun whether passible on x direction
	 *@para start:start point
	 *@para end:end point
	 *@para path:the path node
	 */
	private boolean xdirect(KyodaiGrid start, KyodaiGrid end,Vector path) {
		if(start.getYpos()!=end.getYpos()) return false;
		int direct = 1;
		if(start.getXpos()>end.getXpos()) {
			direct = -1;
		}
		path.removeAllElements();
		for(int x=start.getXpos()+direct;x!=end.getXpos()&&x<xBound&&x>=0;x+=direct) {
			if(grid[start.getYpos()][x].isVisible()) return false;
			path.add(grid[start.getYpos()][x]);
		}
		path.add(end);
		return true;
	}
	
	/**
	 *@retrun whether passible on y direction
	 *@para start:start point
	 *@para end:end point
	 *@para path:the path node
	 */
	private boolean ydirect(KyodaiGrid start, KyodaiGrid end,Vector path) {
		if(start.getXpos()!=end.getXpos()) return false;
		int direct = 1;
		if(start.getYpos()>end.getYpos()) {
			direct = -1;
		}
		path.removeAllElements();
		for(int y=start.getYpos()+direct;y!=end.getYpos()&&y<yBound&&y>=0;y+=direct) {
			if(grid[y][start.getXpos()].isVisible()) return false;
			path.add(grid[y][start.getXpos()]);
		}
		path.add(end);
		return true;
	}
	
	/**
	 *find a path from start to end
	 *@para start: start point
	 *@para end: end point
	 *@return:count of the conner+1,0 when no path find
	 */
	private int findPath(KyodaiGrid start, KyodaiGrid end) {
		//0 conner
		if(xdirect(start,end,path[0])) {
			return 1;
		}
		if(ydirect(start,end,path[0])) {
			return 1;
		}
		//1 conner
		KyodaiGrid xy = grid[start.getYpos()][end.getXpos()];
		if(!xy.isVisible()&&xdirect(start,xy,path[0])&&ydirect(xy,end,path[1])) {
			return 2;
		}
		KyodaiGrid yx = grid[end.getYpos()][start.getXpos()];
		if(!yx.isVisible()&&ydirect(start,yx,path[0])&&xdirect(yx,end,path[1])) {
			return 2;
		}
		//2 conner
		//up
		path[0].removeAllElements();
		for(int y=start.getYpos()-1;y>=0;y--) {
			xy = grid[y][start.getXpos()];
			yx = grid[y][end.getXpos()];
			if(xy.isVisible()) break;
			path[0].add(xy);
			if(!yx.isVisible()&&xdirect(xy,yx,path[1])&&ydirect(yx,end,path[2])) {
				return 3;
			}
		}
		//down
		path[0].removeAllElements();
		for(int y=start.getYpos()+1;y<yBound;y++) {
			xy = grid[y][start.getXpos()];
			yx = grid[y][end.getXpos()];
			if(xy.isVisible()) break;
			path[0].add(xy);
			if(!yx.isVisible()&&xdirect(xy,yx,path[1])&&ydirect(yx,end,path[2])) {
				return 3;
			}
		}
		//left
		path[0].removeAllElements();
		for(int x=start.getXpos()-1;x>=0;x--) {
			yx = grid[start.getYpos()][x];
			xy = grid[end.getYpos()][x];
			if(yx.isVisible()) break;
			path[0].add(yx);
			if(!xy.isVisible()&&ydirect(yx,xy,path[1])&&xdirect(xy,end,path[2])) {
				return 3;
			}
		}
		//right
		path[0].removeAllElements();
		for(int x=start.getXpos()+1;x<xBound;x++) {
			yx = grid[start.getYpos()][x];
			xy = grid[end.getYpos()][x];
			if(yx.isVisible()) break;
			path[0].add(yx);
			if(!xy.isVisible()&&ydirect(yx,xy,path[1])&&xdirect(xy,end,path[2])) {
				return 3;
			}
		}
		return 0;
	}
	
	/**
	 *delete a pair of grids
	 *the path had been find when findpair() 
	 *or findpath() in mouse adapter
	 */
	private void deletePair(KyodaiGrid prev, KyodaiGrid current) {
		//try to find a path
		//if find a path
		//animate
		Vector temp = new Vector();
		temp.add(prev);
		for(int i=0;i<pcount;i++) {
			temp.addAll(path[i]);
			path[i].removeAllElements();
		}
		AnimateThread thread = new AnimateThread(temp);
		thread.start();
		score += progress.getValue()/20;
		scoreLabel.setText(""+score);
		progress.setValue(progress.getValue()+60);
	}
	
	/**
	 *show the found pair
	 */
	public void showNext() {
		if(wingame||progress.getValue()==0||tipcount==0) return;
		tipcount--;
		tipLabel.setText(""+tipcount);
		if(nexts!=null&&nexte!=null) {
			nexts.setBorder(tipBorder);
			nexte.setBorder(tipBorder);
		}
	}
	
	/**
	 *delete the found pair
	 */
	public void useBomb() {
		if(wingame||progress.getValue()==0||bombcount==0) return;
		bombcount--;
		bombLabel.setText(""+bombcount);
		if(nexts!=null&&nexte!=null) {
			deletePair(nexts,nexte);
		}
	}
	
	/**
	 *find a pair of point having a path
	 *@return whether pair find
	 */
	private boolean findPair() {
		nexts = null;
		nexte = null;
		for(int sy=1;sy<yBound-1;sy++) {
			for(int sx=1;sx<xBound-1;sx++) {
				if(!grid[sy][sx].isVisible()) continue;
				for(int ey=sy;ey<yBound-1;ey++) {
					for(int ex=1;ex<xBound-1;ex++) {
						if(!grid[ey][ex].isVisible()||(ey==sy&&ex==sx)) continue;
						if(grid[sy][sx].getIcon()==grid[ey][ex].getIcon()) {
							pcount = findPath(grid[sy][sx],grid[ey][ex]);
							if(pcount!=0) {
								nexts = grid[sy][sx];
								nexte = grid[ey][ex];
								return true;
							}
						}
					}
				}
			}
		}
		return false;
	}
	
	/**
	 *mouse listener
	 */
	private class GridMouseAdapter extends MouseAdapter {
		
		private KyodaiGrid prev;
		
		public void mouseClicked(MouseEvent me) {
			if(prev == null) {
				prev = (KyodaiGrid)me.getSource();
				prev.setBorder(selectedBorder);
			} else {
				if(progress.getValue()==0) return;
				KyodaiGrid current = (KyodaiGrid)me.getSource();
				if(current == prev) return;
				if(current.getIcon()==prev.getIcon()) {
					pcount = findPath(prev,current);
					if(pcount!=0) {
						deletePair(prev,current);
						//set
						prev = null;
						return;
					}
				}
				prev.setBorder(opaqueBorder);
				prev = current;
				prev.setBorder(selectedBorder);
				if(!findPair()) refresh();
			}
		}
	}
	
	/**
	 *thread to perform delete
	 */
	private class AnimateThread extends Thread {
		private Vector v;
		
		public AnimateThread(Vector temp) {
			v = temp;
		}
		
		public void run() {
			KyodaiGrid prev = null;
			KyodaiGrid current;
			int j = 0;
			while(j<v.size()) {
				prev = (KyodaiGrid)v.remove(0);
				prev.setVisible(true);
				v.add(prev);
				j++;
				try	{
					sleep(20);
				} catch(InterruptedException ire) {
					System.err.println("sleep interrupted");
				}
			}
			current = prev;
			prev = (KyodaiGrid)v.remove(0);
			while(!v.isEmpty()) {
				((KyodaiGrid)v.remove(0)).setVisible(false);
				try	{
					sleep(20);
				} catch(InterruptedException ire) {
					System.err.println("sleep interrupted");
				}
			}
			prev.setVisible(false);
			current.setVisible(false);
			current.setIcon(ImageFactory.getInstance().getImageicon(39));
			prev.setIcon(ImageFactory.getInstance().getImageicon(39));
			current.setBorder(opaqueBorder);
			prev.setBorder(opaqueBorder);
			if(!findPair()) refresh();
		}//end of method run
	}
	
	/**
	 *thread to animate progress bar
	 */
	private class ProgressThread extends Thread {
		
		public ProgressThread() {}
		
		public void run() {
			while(true) {
				while(progress.getValue()>0) {
					progress.setValue(progress.getValue()-1);
					try	{
						sleep(100);
					} catch(InterruptedException ire) {
						System.err.println("sleep interrupted");
					}
				}
				repaint();
				suspend();
			}
		}
	}
}

⌨️ 快捷键说明

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