碰撞检测和反应java

时间:2013-05-20 06:56:41

标签: java arrays object collision

我正在写一个小游戏,在屏幕上创建了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;
}



}

1 个答案:

答案 0 :(得分:1)

这是对的吗?

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

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

如果您现在获得空指针异常,请进入调试器并逐步执行直到您看到位置。我的猜测是你正在访问已经弹出的数组项,因此是null。

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

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