📄 mainpanel.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 + -