0

我正在编写一个小游戏,其中在屏幕上创建了 20 个气球,然后在它们上释放鼠标将它们展开。当一个气球碰到另一个气球时,它们应该“弹出”,但目前当我单击一个气球时,它会弹出一个随机气球并抛出“数组索引超出范围”异常。我绞尽脑汁想弄清楚为什么我的代码不起作用但就是无法理解。这是导致问题的一些代码:

import comp102.*;
import java.util.*;
import java.awt.Color;

public class BalloonGame implements UIButtonListener, UIMouseListener{
// Fields
private final int numBalloons = 20;
private int currentScore;   // the score for the current game
private int highScore = 0;  // highest score in all games so far.
private int totalPopped = 0;
Balloon balloons[] = new Balloon[numBalloons];

// Constructor 
/** Set up the GUI, start a new game.
 */
public BalloonGame(){
    UI.setMouseListener(this);
    UI.addButton("New Game", this);
    UI.addButton("Lock Score", this);
    this.newGame();
}

// GUI Methods to respond to buttons and mouse
/** Respond to button presses, to start a new game and to end the current game  */
public void buttonPerformed(String cmd){
    if (cmd.equals("New Game")) { this.newGame(); }
    else if (cmd.equals("Lock Score")) { this.endGame(); }
}

/** Respond to mouse released with the main action of the game*/
public void mousePerformed(String action, double x, double y) {
    if (action.equals("released")) {
        this.doAction(x, y);
    }
}

/** Start the game:
Clear the graphics pane
Initialise the score information 
Make a new set of Balloons at random positions
 */
public void newGame(){
    UI.clearGraphics();
    this.currentScore = 0;
    this.totalPopped = 0;
    for (int i = 0; i < this.balloons.length; i++) {
        this.balloons[i] = new Balloon(50 + Math.random()*400, 50 + Math.random()*400);
        this.balloons[i].draw();
    }
    UI.printMessage("New game: click on a balloon.  High score = "+this.highScore);
}

/** Main game action.
Find the balloon at (x,y) if any,
Expand it 
Check whether it is touching another balloon,
If so, update totalPopped, pop both balloons, and remove them from the list
Recalculate the score.
If there are no balloons left, end the game.
 */
public void doAction(double x, double y) {
    for (int i = 0; i < this.balloons.length; i++) {
        if (this.balloons[i].on(x, y) && !this.balloons[i].isPopped()) {
            this.balloons[i].expand();
        }
        for (int j = 1; j <this.balloons.length; j++) {
            if (this.balloons[i].isTouching(this.balloons[j]) && this.balloons[j] != null)
            {
                this.totalPopped +=2;
                this.balloons[i].pop();
                this.balloons[j].pop();
                this.balloons[i] = null;
                this.balloons[j] = null;
            }
        }
    }
    this.calculateScore();
    if (totalPopped == numBalloons) {
        this.endGame();
    }
}

/** Find a balloon that the point (x, y) is on.
 *  Returns null if point is not on any balloon*/
public Balloon findBalloon(double x, double y){
    return null;
}

/** Find and return another balloon that is touching this balloon
 * Returns null if no such Balloon. */
public Balloon findTouching(Balloon balloon){
    return null;
}

/** Calculate the score: sum of the sizes of current ballons, minus
the total of the popped balloons (totalPopped).
Report the score as a message */
public void calculateScore(){
    for (Balloon b: balloons) {
        this.currentScore += b.size();
    }
    if (currentScore >= highScore) {
        this.highScore = this.currentScore;
    }
    UI.printMessage("Score = "+this.currentScore+"    High score = "+this.highScore);
}

/** Returns true if all the balloons have been popped,
 *  Returns false if any of the balloons is not popped */
public boolean allPopped(){
    for (Balloon b : this.balloons){
        if (!b.isPopped()){
            return false;
        }
    }
    return true;
}

/** End the current game.
Record the the score as the new high score if it is better 
Print a message
Clear the list of balloons (so the player can't keep playing)
 */
public void endGame(){
    this.highScore = this.currentScore;
    UI.println("High score = " + this.highScore);
    Arrays.fill(balloons, null);
}

// Main
public static void main(String[] arguments){
    BalloonGame ob = new BalloonGame();
}   

}

也使用气球类:

import comp102.*;
import java.util.*;
import java.awt.Color;
import java.io.*;


/** Represents a balloon that can grow until it pops.
A Balloon can say whether a particular point is on it, and
whether it is touching another balloon.
It can also return its size.
Once it has popped, no point is on it, and it can't touch another balloon.
Also, its size is reported as a negative value.

*/
public class Balloon{
// Fields
private double radius = 10;
private double centerX, centerY;
private Color color;
private boolean popped = false;


// Constructors
/** Construct a new Balloon object. 
    Parameters are the coordinates of the center of the balloon
    Does NOT draw the balloon yet.
*/
public Balloon(double x, double y){
    this.centerX = x;
    this.centerY = y;
    this.color = Color.getHSBColor((float)Math.random(), 1.0f, 1.0f);
}

public void draw(){
    UI.setColor(color);
    UI.fillOval(centerX-radius, centerY-radius, radius*2, radius*2);
    if (!this.popped){
        UI.setColor(Color.black);
        UI.drawOval(centerX-radius, centerY-radius, radius*2, radius*2);
    }
}

/** Make the balloon larger by a random amount between 4 and 10*/
public void expand(){
    if (! this.popped){
        this.radius = this.radius + (Math.random()*6 + 4);
        this.draw();
    }
}

/** pop the balloon (changes colour to gray, draws, and pauses briefly)*/
public void pop(){
    this.color = Color.lightGray;
    this.popped = true;
    this.draw();
    UI.sleep(20);
}

/** Returns true if the balloon has been popped */
public boolean isPopped(){
    return this.popped;
}

/** Returns true if the point (x,y) is on the balloon, and false otherwise */
public boolean on(double x, double y){
    if (popped) return false;
    double dx = this.centerX - x;
    double dy = this.centerY - y;
    return ((dx*dx + dy*dy) < (this.radius * this.radius));
}

/** Returns true if this Balloon is touching the other balloon, and false otherwise
 *  Returns false if either balloon is popped. */
public boolean isTouching(Balloon other){
    if (this.popped || other.popped) return false;
    double dx = other.centerX - this.centerX;
    double dy = other.centerY - this.centerY;
    double dist = other.radius + this.radius;
    return (Math.hypot(dx,dy) < dist);
}

/** Calculates and returns the area of the balloon
 *  Returns it in "centi-pixels" (ie, number of pixels/100)
 *  to keep them in a reasonable range.
 *  Returns a negative size if it is popped.*/
public int size(){
    int s = (int) ((this.radius * this.radius * Math.PI)/100);
    if (popped) { s = 0 - s; }
    return s;
}



}
4

1 回答 1

1

这是正确的吗?

 for (int j = 1; j <this.balloons.length; j++) {

它不允许 i 和 j 相等,所以你最终会问气球是否在接触自己?你的意思是 j = i + 1 吗?

如果您现在遇到空指针异常,请进入调试器并单步执行,直到您看到哪里。我的猜测是您正在访问已弹出的数组项,因此为空。

  if (this.balloons[i].isTouching(this.balloons[j]) && this.balloons[j] != null)

使用 this.balloons[j] 后,您正在测试它是否为 null。在尝试使用每个项目之前,我会进行一些空检查。

于 2013-05-20T11:04:42.890 回答