не работает маска java box - PullRequest
0 голосов
/ 18 июня 2010

Идея в том, чтобы создать сетку из ящиков.под черной сеткой находится еще одна сетка из разноцветных коробок.когда вы щелкаете поле, маска исчезает, показывая цветную рамку внизу.Затем вы нажимаете второе поле, если цвета соответствуют ура, если нет, то игра продолжается.Вот код.

import java.applet.Applet;
import java.awt.Button;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class GuessingGame extends Applet{
  /**
   * 
   */
  private static final long serialVersionUID = 1L;
  private final int START_X = 20;
  private final int START_Y = 40;
  private final int ROWS = 4;
  private final int COLS = 4;
  private final int BOX_WIDTH = 20;
  private final int BOX_HEIGHT = 20;
  //this is used to keep track of boxes that have been matched.
  private boolean matchedBoxes[][];
  //this is used to keep track of two boxes that have been clicked.
  private MaskableBox chosenBoxes[];
  private MaskableBox boxes[][];
  private Color boxColors[][];
  private Button resetButton;


  public void init() {
    boxes = new MaskableBox[ROWS][COLS];
    boxColors = new Color[ROWS][COLS];
    resetButton = new Button("Reset Colors");
     resetButton.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
           randomizeColors();
           buildBoxes();
           repaint();
       }
     });
     add(resetButton);
     //separate building colors so we can add a button later
     //to re-randomize them.
    randomizeColors();
    buildBoxes();
  }

  public void paint(Graphics g) {
    for (int row =0; row < boxes.length; row ++) {
      for (int col = 0; col < boxes[row].length; col++) {
        if(boxes[row][col].isClicked()) {
          //boxes[row][col].setMaskColor(Color.black);
          //boxes[row][col].setMask(!boxes[row][col].isMask());
          //boxes[row][col].setClicked(false);
        //}
          if (!matchedBoxes[row][col]) {
            gameLogic(boxes[row][col]);
            //boxes[row][col].draw(g);
          }
        }
      }
     }
  //loop through the boxes and draw them.
    for (int row = 0; row < boxes.length; row++) {
      for (int col = 0; col < boxes[row].length; col++) {
        boxes[row][col].draw(g);

      }
    }
  }


  public void gameLogic(MaskableBox box) {
    if ((chosenBoxes[0] != null)&&(chosenBoxes[1] != null)) {
      if(chosenBoxes[0].getBackColor() == chosenBoxes[1].getBackColor()) {  
        for (int i=0; 0 < chosenBoxes.length; i++ ) {
          for(int row = 0; row < boxes.length; row++) {         
            for(int col = 0; col < boxes[row].length; col++) {          
              if( boxes[row][col] == chosenBoxes[i] ) {
                System.out.println("boxes [row][col] == chosenBoxes[] at index: " + i  );             
                matchedBoxes[row][col] = true;
                break;
              }
            }
          }
        }
      }else {  
        chosenBoxes[0].setMask(true);
        chosenBoxes[1].setMask(true);
      } 
        chosenBoxes = new MaskableBox[2];

    }else {
      if (chosenBoxes[0] == null) { 
          chosenBoxes[0] = box;
          chosenBoxes[0].setMask(false);
          return;
      }else{     
        if (chosenBoxes[1] == null) {
          chosenBoxes[1] = box;
          chosenBoxes[1].setMask(false);       
        }   
      }
    }
  }


  private void removeMouseListeners() {
    for(int row = 0; row < boxes.length; row ++) {
        for(int col = 0; col < boxes[row].length; col++) {
            removeMouseListener(boxes[row][col]);
        }
    }
  }

  private void buildBoxes() {
    // need to clear any chosen boxes when building new array.
    chosenBoxes = new MaskableBox[2];
    // create a new matchedBoxes array
    matchedBoxes = new boolean [ROWS][COLS];
    removeMouseListeners();
    for(int row = 0; row < boxes.length; row++) {
      for(int col = 0; col < boxes[row].length; col++) {
        boxes[row][col] = 
          new MaskableBox(START_X + col * BOX_WIDTH,
                            START_Y + row * BOX_HEIGHT,
                            BOX_WIDTH,
                            BOX_HEIGHT,
                            Color.gray,
                            boxColors[row][col],
                            true,
                            true,
                            this);
        addMouseListener(boxes[row][col]);
      }
    }
  }





  private void randomizeColors() {
    int[] chosenColors = {0,0,0,0,0,0,0,0};
    Color[] availableColors = {Color.red, Color.blue, Color.green,
        Color.yellow, Color.cyan, Color.magenta, Color.pink, Color.orange };
    for(int row = 0; row < boxes.length; row++) {
      for (int col = 0; col < boxes[row].length; col++) {
        for (;;) {
          int rnd = (int) (Math.random() * 8);
          if (chosenColors[rnd]< 2) {
            chosenColors[rnd]++;
            boxColors[row][col] = availableColors[rnd];
            break;
          }
        }
      }
    }
  }
}

вот второй пакет кода, содержащий maskablebox

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;

public class MaskableBox extends ClickableBox {
  private boolean mask;
  private Color maskColor;
  Container parent;

  public MaskableBox(int x, int y, int width, int height, Color borderColor,
      Color backColor, boolean drawBorder, boolean mask, Container parent ) {
    super(x, y, width, height, borderColor, backColor, drawBorder, parent);
    this.parent = parent;
    this.mask = mask;
  }

  public void draw(Graphics g) {
    if(mask=false) {
      super.draw(g);
//      setOldColor(g.getColor());
//      g.setColor(maskColor);
//      g.fillRect(getX(),getY(),getWidth(), getHeight());
//      if(isDrawBorder()) {
//        g.setColor(getBorderColor());
//        g.drawRect(getX(),getY(),getWidth(),getHeight());
//      }
//      g.setColor(getOldColor());
    }else {
      if(mask=true) {
        //super.draw(g);
        setOldColor(g.getColor());
        g.setColor(maskColor);
        g.fillRect(getX(),getY(),getWidth(), getHeight());
        if(isDrawBorder()) {
          g.setColor(getBorderColor());
          g.drawRect(getX(),getY(),getWidth(),getHeight());
        }
        g.setColor(getOldColor());
      }
    }
  }


  public boolean isMask() {
    return mask;
  }

  public void setMask(boolean mask) {
    this.mask = mask;
  }

  public Color getMaskColor() {
    return maskColor;
  }

  public void setMaskColor(Color maskColor) {
    this.maskColor = maskColor;
  }
}

Теперь я получаю эти сообщения об ошибках.

Exception in thread "AWT-EventQueue-1" java.lang.NullPointerException
    at GuessingGame.gameLogic(GuessingGame.java:74)
    at GuessingGame.paint(GuessingGame.java:55)
    at java.awt.Container.update(Container.java:1801)
    at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239)
    at sun.awt.RepaintArea.paint(RepaintArea.java:216)
    at sun.awt.windows.WComponentPeer.handleEvent(WComponentPeer.java:306)
    at java.awt.Component.dispatchEventImpl(Component.java:4706)
    at java.awt.Container.dispatchEventImpl(Container.java:2099)
    at java.awt.Component.dispatchEvent(Component.java:4460)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)

Ответы [ 3 ]

8 голосов
/ 18 июня 2010

Посмотрите, сообщение об ошибке, которое вы видите там, называется: "трассировка стека"

. Оно содержит очень полезную информацию о том, что это была за ошибка:

Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: 2
 at GuessingGame.gameLogic(GuessingGame.java:77)     // This is where the error happened
 at GuessingGame.paint(GuessingGame.java:55)         // This is your code
 at java.awt.Container.update(Container.java:1801)            // not your code 
 at sun.awt.RepaintArea.updateComponent(RepaintArea.java:239) // not your code

Если вы ее видитеговорит: GuessingGame.java:77 это означает, что ошибка произошла в файле GuessingGame.java в строке 77. Других файлов нет в вашем исходном коде (Container.java и Repaint.java), поэтому они не там, где возникла проблема.

В GuessingGame.java в строке 77 вы пытались получить доступ к index за пределами границ массива (отсюда ArrayIndexOutOfBoundException), кроме того, число 2 это числоиндекс, который вы пытались использовать.

С этой информацией вы можете взглянуть на исходный код и увидеть, что строка 77 (по крайней мере, из опубликованного кода):

 if( boxes[row][col] == chosenBoxes[i] ) {

Итак,boxes не проблема (его размер равен 4, он был объявлен как boxes = new MaskableBox[ROWS][COLS];, а ROWS и COLS объявлены как 4).Таким образом, ответственный должен быть: chosenBoxes

Он был инициализирован как:

chosenBoxes = new MaskableBox[2];

Размер 2 , что означает, что единственными действительными индексами являются 0 и 1.При попытке использовать index = 2 возникает исключение.

Теперь, имея в виду эту информацию, вы можете искать код, который может ее вызвать.

Как указывают другие ответы, причина:

for (int i=0; 0 <= chosenBoxes.length; ++i ) {

Всего на 3 строки выше !.Он гласит: «пока ноль меньше или равен 2 ...» , который всегда будет возвращать true, потому что 0 всегда будет <2. </p>

Итак, вам просто нужно исправитьэту часть и перепроверьте.

Я надеюсь, что это объяснение поможет вам решить подобные проблемы в будущем.Очень важно научиться читать трассировку стека.

Я даже могу представить себе аббревиатуру в будущем: RTFST;)

2 голосов
/ 18 июня 2010

В вашем gameLogic методе у вас есть chosenBoxes, в котором есть два элемента, но вы переходите на i <= chosenBoxes.length (что будет i = 0, 1, 2). Вот почему вы получаете исключение. Измените его на i < chosenBoxes.length.

Редактировать

На самом деле, у вас есть:

for (int i=0; 0 <= chosenBoxes.length; ++i ) {

изменить это на:

for (int i=0; i < chosenBoxes.length; i++ ) {

Я не уверен, почему вы также увеличивали префикс i в этом цикле.

0 голосов
/ 18 июня 2010

Здесь:

for (int i=0; 0 <= chosenBoxes.length; ++i ) {

Ваше состояние всегда верно;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...