我正在使用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?
提前告诉你们所有人!
答案 0 :(得分:4)
创建ArrayList<JButton>
,用所有按钮填充,在列表中调用Collections.shuffle(..)
,然后选择前N个按钮添加地雷。
说完这些之后,我真正的建议就是放弃所有这些并转到MVC路线,在那里您的数据模型,包括矿场所在的位置,以及您的GUI完全不同。
答案 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