2013-05-20 5 views
0

Я пишу небольшую игру, где на экране появляются 20 воздушных шаров, и мышь, выпущенная на них, расширяет их. Они должны «появляться», когда один воздушный шар касается другого, но в настоящее время, когда я нажимаю воздушный шар, он всплывает случайным образом и выдает исключение «Индекс массива за пределами». Я пробовал свой мозг, чтобы понять, почему мой код не работает, но просто не может его получить. Вот некоторые из кода, вызывающего проблему:Обнаружение столкновений и реакция java

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

Чтобы лучше помочь, опубликуйте [SSCCE] (http://sscce.org/). –

+0

так что просто весь мой код? нет ЧТО Я просто подумал, что было бы разумно опубликовать раздел с проблемой –

+0

BTW - «Короткие» могут быть 150 строк кода, если проблема * действительно нуждается в ней. –

ответ

1

это право?

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

Не позволяет ли я и j быть равным, поэтому вы в конечном итоге спрашиваете, касается ли воздушный шар сам по себе? Вы имеете в виду j = i + 1?

Если вы сейчас получаете исключения с нулевым указателем, войдите в отладчик и пройдите, пока не увидите, где. Я предполагаю, что вы посещаете элементы массива, которые были выскочены, и, следовательно, являются нулевыми.

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

Вы тестируете this.balloons [j] для null, после того как используете его. Я поставил несколько нулевых проверок, прежде чем пытаться работать с каждым элементом.

+0

Это то, что я хотел достичь, я только что скорректировал это, но я продолжаю получать исключения с нулевым указателем по адресу: 'if (this.balloons [i] .isTouching (this.balloons [j]) && this.balloons [j]! = null) ', который был отредактирован только для' if (this.balloons [i] .isTouching (this.balloons [j])) ' –

+0

' public boolean isTouching (Воздушный шар другой) { 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)

+0

Если вы установили воздушные шары [x] в null, вы не сможете вызов шаров [x] .popped у вас есть this.balloons [i] = null; и this.balloons [j] = null; – djna

Смежные вопросы