我初学java,模仿写了个扫雷,只要将代码中wav文件路径设置正确,即可正常运行,希望大家狠批特批。对于布局以及背景音乐的问题,不知还有什么更好的方法?/**
   @version 1.0 2006-12-24
   @author widewolf
   @e-mail [email protected]
*/
import java.applet.*;
import java.net.URL;
import sun.audio.*; 
import java.io.*; 
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
 public class sweepmine 
{
public static void main(String[] args) 
{
 sweepmine initer = new sweepmine();
 initer.init();
 try//背景音乐
 {
/**AudioClip ac = Applet.newAudioClip(new URL("file:/c:/security.wav"));
 ac.loop();
 这里用了Applet里的方法,倒是能行,但有两问题:1,播放原生wav好像能行,但在循环播放一个从mp3转化而来的wav文件时cpu(PD820)占有率竟然持续高达100%;
 2 ,在调用不相关的菜单事件时,停止了播放。*/  InputStream in = new FileInputStream ("c:\\爱的废墟.wav");
 AudioStream as = new AudioStream (in);
 
 /**AudioData data = as.getData ();
这用了sun.audio.*和java.io.*来实现背景音乐,没有编译的是播放一次,原生wav和转化而来的wav都没有问题,循环播放时原生wav没有问题,转化而来的有一个问题(就上面这句):
java.io.IOException: could not create AudioData object
ContinuousAudioDataStream cas = new ContinuousAudioDataStream (data); 
 AudioPlayer.player.start (cas);*/ AudioPlayer.player.start (as);
 }
 catch (IOException  e)
 {
 System.err.println(e);
 }
}
 void init()
{
mineframe = new frame(9,9,10);
JMenuBar menubar = new JMenuBar();
    mineframe.setJMenuBar(menubar);
JMenu gamemenu= new JMenu("游戏(G)");
menubar.add(gamemenu);
JMenu helpmenu= new JMenu("帮助(H)");
menubar.add(helpmenu);
Action middleaction =new menuaction("开局(N)");
JMenuItem start = gamemenu.add(middleaction);
gamemenu.addSeparator();
ActionListener listener =new menulistener(); 
JMenuItem junior = new JMenuItem("初级(J)");
junior.setName("junior");
junior.addActionListener(listener);
gamemenu.add(junior);
JMenuItem middle = new JMenuItem("中级(M)");
middle.setName("middle");//下面监听器要用
middle.addActionListener(listener);
gamemenu.add(middle);
JMenuItem senior = new JMenuItem("高级(S)");
senior.setName("senior");
senior.addActionListener(listener);
gamemenu.add(senior);
mineframe.setTitle("扫雷");
mineframe.setSize(189,232);//因面板没有布局,所以只能制定框架的大小
mineframe.setLocation(400,300);
mineframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mineframe.setVisible(true);
mineframe.setResizable(false);
}
private class menulistener implements ActionListener
{
public void actionPerformed(ActionEvent event)

JMenuItem temp=(JMenuItem)event.getSource();
  String name = temp.getName();
mineframe.remove(mineframe.minepanel);//移除原面板
  if(name.equals("middle"))
{
mineframe.minepanel = new panel(16,16,40);//重新构造面板,面板为框架的属性
mineframe.setSize(329,372);
}
          else if(name.equals("junior"))
{
mineframe.minepanel = new panel(9,9,10);
mineframe.setSize(189,232);
}
  else
{
  mineframe.minepanel = new panel(30,16,99);
  mineframe.setSize(609,372);
  }
mineframe.add(mineframe.minepanel);
mineframe.minepanel.laymine();
mineframe.validate();//刷新界面
}
}
   private class menuaction extends AbstractAction//菜单动作
{
 public menuaction(String s)
{
super(s);
}
public void actionPerformed(ActionEvent event)
{
 mineframe.minepanel.refresh();
}
}
    frame mineframe;//框架为主类的属性
}
class frame extends JFrame
{
public frame(int m,int n,int o)
{
 minepanel = new panel(m,n,o);
 add(minepanel);
minepanel.laymine();
}
    panel minepanel;
}

解决方案 »

  1.   

    接上
    class panel extends JPanel
    {
      public panel(int m,int n,int count)
    {
     setLayout(null);//不知道有没有三维布局?
     button = new JButton[m][n];
     textfield = new JTextField[m][n];
     row=m;
     cols=n;
     minecount=count;
     for( int i=0;i<m;i++)
    {
    for(int j=0;j<n;j++)
    {
      button[i][j]= new JButton();
      textfield [i][j]= new JTextField();
      add(button[i][j],null);
      add(textfield[i][j],null);
                  button[i][j].setBounds(new Rectangle(i*20, j*20,20, 20));
      textfield [i][j].setBounds(new Rectangle(i*20, j*20,20, 20));//用这种方法实现三维布局
      textfield [i][j].setEditable(false);
      textfield [i][j].setVisible(false);
      textfield [i][j].setHorizontalAlignment(JTextField.CENTER);
      button[i][j].setMargin(new Insets(2,0,2,0)); //设置了边框
      button[i][j].addMouseListener(new buttonclick(i,j));
      textfield [i][j].addMouseListener(new textfieldclick(i,j));
    }
    }
    }
    public void refresh()//重新开局的实现
    {
    for( int i=0;i<row;i++)
    for(int j=0;j<cols;j++)
      {
    textfield [i][j].setVisible(false);
    textfield [i][j].setText("");
    button [i][j].setVisible(true);
    button[i][j].setText("");
    }
    flag=false;
    laymine();
    }
    public void ifsuccess()//判断是否扫雷成功
    {
    int total=0;
    for( int i=0;i<row;i++)
    for(int j=0;j<cols;j++)
    {
    if(button [i][j].isVisible()==true)
    {
    total+=1;
    }
    }
    if(total==minecount)
    {
    for( int i=0;i<row;i++)
    for(int j=0;j<cols;j++)
    {
    if(button [i][j].isVisible()==true)
    {
    button[i][j].setText("&");

    }
    }
    flag=true;

    }

    }
     public void laymine()//布雷方法
    {
    java.util.Random s=new java.util.Random();
       for( int i=0;i<minecount;i++)
    {
    int x =s.nextInt(row);
    int y =s.nextInt(cols);
    if(textfield[x][y].getText().equals("*"))//有可能重叠
    i--;
    else
    textfield [x][y].setText("*");
    }
    for( int i=0;i<row;i++)
    {
    for(int j=0;j<cols;j++)
    {
    String flag =textfield [i][j].getText();
    if(!flag.equals("*"))
    {
    int value=this.countmine(i,j);
    textfield [i][j].setText(""+value);
    }
    }
    }
    }
    public int countmine(int x,int y)//计算周围的雷数
    {
    int count =0;
    int a=x-1<0?0:x-1;
    int b=x+1>row-1?row-1:x+1;
    int c=y-1<0?0:y-1;
    int d=y+1>cols-1?cols-1:y+1;
    for(int i=a;i<=b;i++)
    for(int j=c;j<=d;j++)
    {
    String flag =textfield [i][j].getText();
           if(flag.equals("*"))
       count+=1;
       }
            return count;
    }
       private class buttonclick extends MouseAdapter//按钮的监听器
       {
         public buttonclick(int a,int b)
       {
     x=a;
     y=b;
       }
         public void mouseClicked(MouseEvent e)
       {
     if(flag==true)
     return;
       if(e.getButton()==MouseEvent.BUTTON1)//左键单击
       {
      button[x][y].setText("");
      button[x][y].setVisible(false);
      textfield[x][y].setVisible(true);
      if(textfield[x][y].getText().equals("*"))//如果是雷,游戏结束
       { 
      flag=true;
      for( int i=0;i<row;i++)
    for(int j=0;j<cols;j++)
    {
    String flag =textfield [i][j].getText();
    if(flag.equals("*"))
    {
    button[i][j].setVisible(false);
      textfield[i][j].setVisible(true);
    }
    }
    }
    if(textfield[x][y].getText().equals("0"))//如果不是雷且周围没有雷,则打开周围区域
       {
    textfield[x][y].setText("");
     open(x,y);
       }
      }
       if(e.getButton()==MouseEvent.BUTTON3)//右键单击
      {
      button[x][y].setText("&");

       }
       ifsuccess();
       }
       int x;
       int y;
       } 
       public void  open (int x,int y)//递归打开周围区域
       {
    int a=x-1<0?0:x-1;
    int b=x+1>row-1?row-1:x+1;
    int c=y-1<0?0:y-1;
    int d=y+1>cols-1?cols-1:y+1;
           for(int i=a;i<=b;i++)
    for(int j=c;j<=d;j++)
       {
       if(i==x && j==y)
       continue;
                      if(button[i][j].getText().equals("&"))
      continue;
      button[i][j].setText("");
      button[i][j].setVisible(false);
              textfield[i][j].setVisible(true);
      if(textfield[i][j].getText().equals("*"))//如果是雷,游戏结束
       {
      flag=true;
      for( int m=0;m<row;m++)
    for(int n=0;n<cols;n++)
    {
    String flag =textfield [m][n].getText();
    if(flag.equals("*"))
    {
    button[m][n].setVisible(false);
      textfield[m][n].setVisible(true);
    }
    }
       }
       }
     for(int i=a;i<=b;i++)
    for(int j=c;j<=d;j++)
       {
      if(textfield[i][j].getText().equals("0"))//递归打开
       {
    textfield[i][j].setText("");
        open(i,j);
       }
       }
       }
        private class textfieldclick extends MouseAdapter//文本域监听器
       {
    public textfieldclick (int a,int b)
       {
     x=a;
     y=b;
       }
         public void mousePressed(MouseEvent e)
       {
     if(flag==true)
     return;
     int test=(MouseEvent.BUTTON1_DOWN_MASK | MouseEvent.BUTTON3_DOWN_MASK);//左右键同时击下
    if(!textfield [x][y].getText().equals(""))
       {
    if ((e.getModifiersEx() &  test)==test)
       {
        int iconcount=0;
    int a=x-1<0?0:x-1;
    int b=x+1>row-1?row-1:x+1;
    int c=y-1<0?0:y-1;
    int d=y+1>cols-1?cols-1:y+1;
    for(int i=a;i<=b;i++)
    for(int j=c;j<=d;j++)
       {
       if(button[i][j].getText().equals("&"))
       {
     iconcount+=1;
              }
       }
    if( iconcount==Integer.parseInt(textfield [x][y].getText()))//如果周围雷数和标记的雷数一样,则打开周围非雷的区域
       {
    open(x,y);
       }
       }
       }
    ifsuccess();
       }
         int x;
     int y;
       }
    private JTextField[][] textfield;
    private JButton[][] button ;
    private boolean flag;
    private int row;
    private int cols;
    private int minecount;
    }
      

  2.   

    提问:学java多长时间就该具备编写这么多代码的能力?让我衡量自己,我也是初学者!
      

  3.   

    不要说指导,说交流吧:如果是我,我会写:
    一个方块类Block:封装一个方块的所有属性,包括对旁边八个方块的引用(指针,当然如果用二维数组就可以不要),方块的值(是雷还是数字),对应的图标等等.
    一个面板类Panel:里面有整齐布局的很多方块Block.
    当然还有对应的监听.
      

  4.   

    厉害!
    初学java就能写出扫雷,我学了这么久还不会写。