用Java制作一个简单的Mine Sweeper游戏

时间:2015-07-05 01:09:44

标签: java swing jbutton actionlistener imageicon

我正在使用JButtons在java中创建一个简单的扫雷游戏。到目前为止,我有一个代码可以创建一个20x20的JButtons网格,但我不确定如何在游戏中随机将我的炸弹分配给多个JButton。

这是我到目前为止所写的内容:

MineSweeper课程:

import javax.swing.*;
import java.awt.GridLayout;
public class MineSweeper extends JFrame {
JPanel p = new JPanel();
bombButton points[][]= new bombButton[20][20];

public static void main(String args[]){
    new MineSweeper();
}

public MineSweeper(){
    super("Mine Sweeper Version: Beta");
    setSize(400,400);
    setResizable(false);
    setDefaultCloseOperation(EXIT_ON_CLOSE);

    p.setLayout(new GridLayout(20,20));
    int y=0;
    int counter=0;
    while(counter<20){   
        for(int x=0;x<20;x++){
            points[x][y] = new bombButton();
            p.add(points[x][y]);
        }
        y++;
        counter++;
    }
    add(p);

    setVisible(true);
}
}

炸弹爆炸类:

import javax.swing.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.net.URL;

public class bombButton extends JButton implements ActionListener {
ImageIcon Bomb,zero,one,two,three,four,five,six,seven,eight;

public bombButton(){
    URL imageBomb = getClass().getResource("Bomb.png");
    Bomb= new ImageIcon(imageBomb);

    URL imageZero = getClass().getResource("0.jpg");
    zero= new ImageIcon(imageZero);

    URL imageOne = getClass().getResource("1.jpg");
    one= new ImageIcon(imageOne);

    URL imageTwo = getClass().getResource("2.jpg");
    two= new ImageIcon(imageTwo);

    URL imageThree = getClass().getResource("3.jpg");
    three= new ImageIcon(imageThree);

    URL imageFour = getClass().getResource("4.jpg");
    four= new ImageIcon(imageFour);

    URL imageFive = getClass().getResource("5.jpg");
    five= new ImageIcon(imageFive);

    URL imageSix = getClass().getResource("6.jpg");
    six= new ImageIcon(imageSix);

    URL imageSeven = getClass().getResource("7.jpg");
    seven= new ImageIcon(imageSeven);

    URL imageEight = getClass().getResource("8.jpg");
    eight= new ImageIcon(imageEight);

    this.addActionListener(this);
}

public void actionPerformed(ActionEvent e){
    switch(){
        case 0:
            setIcon(null);
            break;
        case 1:
            setIcon(Bomb);
            break;
        case 2:
            setIcon(one);
            break;
        case 3:
            setIcon(two);
            break;
        case 4:
            setIcon(three);
            break;
        case 5:
            setIcon(four);
            break;
        case 6:
            setIcon(five);
            break;
        case 7:
            setIcon(six);
            break;
        case 8:
            setIcon(seven);
            break;    
        case 9:
            setIcon(eight);
            break;    
    }
}

int randomWithRange(int min, int max)
{
    int range = Math.abs(max - min) + 1;     
    return (int)(Math.random() * range) + (min <= max ? min : max);
}
}

正如您所看到的,我已经设置了随机数发生器,我只是不知道应该如何实现它。我应该使用(X,Y)坐标吗?如何将我的炸弹分配给随机JButtons?

提前告诉你们所有人!

3 个答案:

答案 0 :(得分:4)

创建ArrayList<JButton>,用所有按钮填充,在列表中调用Collections.shuffle(..),然后选择前N个按钮添加地雷。

说完这些之后,我真正的建议就是放弃所有这些并转到MVC路线,在那里您的数据模型,包括矿场所在的位置,以及您的GUI完全不同。

here are some of my prior musings on this problem from 2011

答案 1 :(得分:1)

这是我的Miseweeper克隆

    package MWeeper;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

public class MMWeeper extends JFrame implements Runnable {

    private JFrame  mainFrame ;
    private JPanel  mainPanel;
    
    private int boardX  = 15;
    private int boardY  = 15;
    private int bombs   = 35;
    
    private int bombsMarked;
    private int cleanFields;
    private int seconds;
    
    private boolean gameOver = false;
    
    private Map<Integer, Map<Integer, mweeperField>> boardMap;
    private Map<Integer,position> bombMap;
    private JPanel boardPanel;
    private JPanel headPanel;
    private JTextField bombsField;
    
    @Override
    public void run() {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                mainFrame = new JFrame("MMWEEEEEEPER");
                
                int w = Toolkit.getDefaultToolkit().getScreenSize().width;
                int h = Toolkit.getDefaultToolkit().getScreenSize().height;
                mainFrame.setPreferredSize(new Dimension(350,390));
                mainFrame.setResizable(true);
                
                mainPanel = new JPanel(new BorderLayout());
                
                init();
                //setContent();
                setPanel();
                
                mainFrame.add(mainPanel);
                mainFrame.setContentPane(mainFrame.getContentPane());
                mainFrame.pack();
                mainFrame.setLocationRelativeTo(null);
                mainFrame.setVisible(true);
                
                
            }
            });
    }
    
    private void init() {
        bombMap     = new HashMap<Integer, MMWeeper.position>();
        boardMap    = new HashMap<Integer, Map<Integer,mweeperField>>();
        bombsMarked = 0;
        cleanFields = (boardX * boardY) - bombs;
        seconds     = 0;
        
        for(int i = 1; i<= boardX; i++) {
            boardMap.put(i, new HashMap<Integer, mweeperField>());
            for(int j = 1; j <= boardY; j++) {
                boardMap.get(i).put(j, new mweeperField(i, j ));
            }
        }
        placeBombs();
    }
    
    
    private boolean placeBombs() {
        
        Random pX = new Random();
        Random pY = new Random();
        int bombCount = 0;
        //while( bombMap.size() < bombs ) {
        while(bombCount < bombs) {
            int x = (1 + pX.nextInt( boardX ) );
            int y = (1 + pY.nextInt( boardY ) );
            if(!boardMap.get(x).get(y).isBomb() ) {
                boardMap.get(x).get(y).setBomb();
                bombCount++;
                bombMap.put(bombCount, new position(x, y));
            }
        }
        return true;
    }
    
    private void setPanel() {
        
        mainPanel.add(head(), BorderLayout.PAGE_START);
        
        mainPanel.add(board(), BorderLayout.CENTER);
    }
    
    
    private JPanel head() {
        headPanel = new JPanel(new BorderLayout());
        
        bombsField = new JTextField(6);
        bombsField.setEditable(true);
        bombsField.setText( String.valueOf(bombs));
        
        JButton start = new JButton("Start");
        start.addActionListener( new mweeperAction(GameActions.START) );
        
        
        
        headPanel.add(bombsField, BorderLayout.LINE_START);
        
        headPanel.add(start, BorderLayout.LINE_END);
        return headPanel;
    }
    
    private JPanel board() {
        boardPanel = new JPanel();
        GridLayout gLayout = new GridLayout(15, 15, 0, 0 );
        boardPanel.setLayout(gLayout);
        
        for( Integer x : boardMap.keySet()) {
            for(Integer y : boardMap.get(x).keySet()) {
                boardPanel.add( boardMap.get(x).get(y).getButton() );
            }
        }
        
        return boardPanel;
    }
    
    private void gameOver() {
        this.gameOver = true;
        for( Integer x : boardMap.keySet()) {
            for(Integer y : boardMap.get(x).keySet()) {
                boardMap.get(x).get(y).trigger();
            }
        }
    }
    
    
    public class mweeperField implements mousePerformer {
        private position    pos;
        private FieldStatus status          = FieldStatus.HIDE_UNMARKED;
        private boolean     isBomb          = false;
        private int         bombsAroundMe   = 0;
        private JButton     but;
        private boolean     isTriggered     = false;
        
        public mweeperField( int x, int y ) {
            this.pos = new position(x, y);
            init();
        }
        public mweeperField( position p ) {
            this.pos = p;
            init();
        }
        public void resetField() {
            status          = FieldStatus.HIDE_UNMARKED;
            isBomb          = false;
            bombsAroundMe   = 0;
            isTriggered     = false;
            but.setFont(new Font("Arial", Font.BOLD, 13));
            but.setBackground(Color.LIGHT_GRAY);
            but.setText(" ");
            but.setEnabled(true);
        }
        public void setBomb() {
            this.isBomb = true;
        }
        public boolean isBomb() {
            return isBomb;
        }
        private void init() {
            but = new JButton(" ");
            but.setMaximumSize(new Dimension(16, 16));
            but.setMinimumSize(new Dimension(16, 16));
            but.setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY, 1));
            but.setMargin(new Insets(0, 0, 0, 0));
            but.setBackground(Color.LIGHT_GRAY);
            but.addMouseListener(new mweeperMouseListener(this.pos, this));
            but.setFont(new Font("Arial", Font.BOLD, 14));
        }
        
        private void setButton() {
            
            switch(status) {
                case HIDE_MARKED:
                    //but.setForeground( new Color(224, 124, 168) );
                    but.setForeground( Color.RED);
                    but.setText("@");
                    but.setEnabled(true);
                    break;
                case HIDE_UNMARKED: 
                    but.setForeground(Color.BLACK);
                    but.setText(" ");
                    but.setEnabled(true);
                    break;
                case OPEN_NOBOMB: 
                    switch(this.bombsAroundMe) {
                        case 1: 
                        case 2: 
                            but.setForeground(Color.BLUE);
                            break;
                        case 3:
                        case 4:
                            but.setForeground(Color.MAGENTA);
                            break;
                        case 5:
                        case 6:
                            but.setForeground(Color.RED);
                            break;
                        case 7:
                        case 8:
                            but.setForeground(Color.PINK);
                            break;
                    }
                    String butText = " ";
                    if(this.bombsAroundMe > 0) {
                        butText = String.valueOf(this.bombsAroundMe);
                    }
                    but.setEnabled(false);
                    but.setText( butText );
                    
                    break;
                    
                case OPEN_BOMB: // GAME OVER
                    but.setForeground(Color.BLACK);
                    but.setFont(new Font("Arial", Font.BOLD, 20));
                    but.setVerticalAlignment(SwingConstants.CENTER);
                    but.setHorizontalAlignment(SwingConstants.CENTER);
                    but.setText("*");
                    
                    break;
            }
//          but.setEnabled(false);
            but.validate();
            but.repaint();
            boardPanel.validate();
            boardPanel.repaint();
            mainPanel.repaint();
        }
        
        public JButton getButton() {
            return but;
        }
        
        /*
         +-----+-----+-----+
         | x-1 |  x  | x+1 |
         | y-1 | y-1 | y-1 |
         +-----+-----+-----+
         | x-1 | x/y | x+1 |
         |  y  |     |  y  |
         +-----+-----+-----+
         | x-1 |  x  | x+1 |
         | y+1 | y+1 | y+1 |
         +-----+-----+-----+
         */
        
        private void scan() {
            bombsAroundMe = 0;
            for(Integer k : pos.posAroundMe.keySet() ) {
                position p2 = pos.posAroundMe.get(k);
                if(boardMap.get(p2.x).get(p2.y).isBomb()) {
                    bombsAroundMe++;
                }
            }
        }
        
        public void trigger() {
            if(!isTriggered) {
                isTriggered = true;
                if(!isBomb) {
                    status = FieldStatus.OPEN_NOBOMB;
                }else {
                    status = FieldStatus.OPEN_BOMB;
                }
                scan();

                setButton();
                if(bombsAroundMe == 0) {
                    // um mich herum triggern
                    for(Integer k : pos.posAroundMe.keySet() ) {
                        position p2 = pos.posAroundMe.get(k);
                        boardMap.get(p2.x).get(p2.y).trigger();
                    }
                }
            }
        }
        
        @Override
        public void doClick(MouseEvent e, position pos) {
            switch(e.getButton()) {
                case 1: //Links Klick = triggern wenn nich markiert und hide
                        if(this.status.equals(FieldStatus.HIDE_UNMARKED)){
                            if(this.isBomb) {
                                // GAME OVER =8-(
                                status = FieldStatus.OPEN_BOMB;
                                but.setBackground(Color.RED);
                                gameOver();
                            }else {
                                trigger();
                            }   
                        }
                    break;
                    
                case 3: // Rechtsklick
                    
                    if(this.status.equals(FieldStatus.HIDE_UNMARKED)) {
                        // Mark Field
                        this.status = FieldStatus.HIDE_MARKED;
                        bombsMarked++;
                    }else {
                        // Umark Field
                        this.status = FieldStatus.HIDE_UNMARKED;
                        bombsMarked--;
                    }
                    setButton();
                    break;
            }
            
        }
        
        
    }
    
    public class position {
        public int x = 0;
        public int y = 0;
        public Map<Integer, position> posAroundMe;
        public position(int x, int y) {
            this.x = x;
            this.y = y;
            posAroundMe = new HashMap<Integer, MMWeeper.position>();
            setPosAroundMe();
        }
        public position(int x, int y, boolean setPos) {
            posAroundMe = new HashMap<Integer, MMWeeper.position>();
            this.x = x;
            this.y = y;
        }
        private void setPosAroundMe() {
            int c = 1;
            for(int x2 = (x-1); x2 <= (x+1); x2++) {
                for(int y2 = (y-1); y2 <= (y+1); y2++) {
                    if( ((x2 != x) || (y2 != y)) && ( x2>0 && x2<=boardX && y2>0 && y2<=boardY ) ){
                        posAroundMe.put(c++, new position(x2, y2, false));
                    }
                }
            }
        }
    }
    
    public enum FieldStatus{
        HIDE_UNMARKED,
        HIDE_MARKED,
        OPEN_NOBOMB,
        OPEN_BOMB;
    }
    
    public enum GameActions{
        START;
    }
    
    public class mweeperAction extends AbstractAction{
        private GameActions gameAction;
        
        public mweeperAction(GameActions ga ) {
            this.gameAction = ga;
        }
        
        @Override
        public void actionPerformed(ActionEvent ae) {
            switch(gameAction) {
            case START:
                    for( Integer x : boardMap.keySet()) {
                        for(Integer y : boardMap.get(x).keySet()) {
                            boardMap.get(x).get(y).resetField();;
                            boardMap.get(x).get(y).getButton().validate();
                            boardMap.get(x).get(y).getButton().repaint();;
                        }
                    }
                    int newBombCount = Integer.valueOf(bombsField.getText()) ;
                    if(newBombCount < 10) {
                        newBombCount = 10;
                    }
                    if(newBombCount > ((boardX * 2) + 20 ) ){
                        newBombCount = ((boardX * 2) + 20 ); 
                    }
                    bombs = newBombCount;
                    bombsField.setText(String.valueOf(bombs) );
                    placeBombs();
                    boardPanel.validate();
                    boardPanel.repaint();
                    mainPanel.repaint();
                break;
            }
        }
    }
    
    public class mweeperMouseListener implements MouseListener{
        private position pos;
        mousePerformer performer;
        public mweeperMouseListener(position pos, mousePerformer acPerf) {
            this.pos = pos;
            this.performer = acPerf;
        }

        @Override
        public void mouseClicked(MouseEvent e) {
            this.performer.doClick(e , pos );
        }

        @Override
        public void mouseEntered(MouseEvent e) {}

        @Override
        public void mouseExited(MouseEvent e) {}

        @Override
        public void mousePressed(MouseEvent e) {}

        @Override
        public void mouseReleased(MouseEvent e) {}
        
    }
    
    public interface mousePerformer{
        public void doClick(MouseEvent e, position pos   );
    }
    public interface actionPerformer{
        public void doAction(ActionEvent ae, GameActions ga );
    }
}

答案 2 :(得分:0)

AdUser

参考:Minesweeper Game Example